diff options
author | Daniel Jacobowitz <dan@debian.org> | 2006-07-12 18:13:45 +0000 |
---|---|---|
committer | Daniel Jacobowitz <dan@debian.org> | 2006-07-12 18:13:45 +0000 |
commit | 20b5ceaa3a5f4f3f36bb26600ec685c0b071834c (patch) | |
tree | a7b2d9bb42c515d0f8f0ba0f1c788ebca0cc5254 /gdb/target.c | |
parent | f828b7d4359cb6d35f4cc1c4ca80e89b58128179 (diff) | |
download | gdb-20b5ceaa3a5f4f3f36bb26600ec685c0b071834c.tar.gz |
* target.c (target_read): Stop if target_read_partial returns 0
when some bytes have already been read.
(target_write): Likewise for target_write_partial.
(target_read_partial, target_write_partial): Make static.
(target_read_alloc): New.
* target.h: Doc fixes.
(target_read_partial, target_write_partial): Delete prototypes.
(target_read_alloc): New prototype.
* auxv.c (target_auxv_read): Delete.
(target_auxv_search, fprint_target_auxv): Use target_read_alloc.
* auxv.h (target_auxv_read): Delete prototype.
* avr-tdep.c (avr_io_reg_read_command): Use target_read_alloc.
* ia64-tdep.c (getunwind_table, get_kernel_table): Likewise.
* linux-nat.c (linux_nat_make_corefile_notes): Likewise.
* procfs.c (procfs_make_note_section): Likewise.
* remote.c (remote_xfer_partial): Don't loop here.
* sparc-tdep.c (sparc_fetch_wcookie): Use target_read.
Diffstat (limited to 'gdb/target.c')
-rw-r--r-- | gdb/target.c | 80 |
1 files changed, 74 insertions, 6 deletions
diff --git a/gdb/target.c b/gdb/target.c index bcb47deec38..c378ce56f74 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -1341,7 +1341,7 @@ default_xfer_partial (struct target_ops *ops, enum target_object object, (inbuf, outbuf)", instead of separate read/write methods, make life easier. */ -LONGEST +static LONGEST target_read_partial (struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *buf, @@ -1350,7 +1350,7 @@ target_read_partial (struct target_ops *ops, return target_xfer_partial (ops, object, annex, buf, NULL, offset, len); } -LONGEST +static LONGEST target_write_partial (struct target_ops *ops, enum target_object object, const char *annex, const gdb_byte *buf, @@ -1373,8 +1373,9 @@ target_read (struct target_ops *ops, (gdb_byte *) buf + xfered, offset + xfered, len - xfered); /* Call an observer, notifying them of the xfer progress? */ - if (xfer <= 0) - /* Call memory_error? */ + if (xfer == 0) + return xfered; + if (xfer < 0) return -1; xfered += xfer; QUIT; @@ -1395,8 +1396,9 @@ target_write (struct target_ops *ops, (gdb_byte *) buf + xfered, offset + xfered, len - xfered); /* Call an observer, notifying them of the xfer progress? */ - if (xfer <= 0) - /* Call memory_error? */ + if (xfer == 0) + return xfered; + if (xfer < 0) return -1; xfered += xfer; QUIT; @@ -1404,6 +1406,72 @@ target_write (struct target_ops *ops, return len; } +/* Wrapper to perform a full read of unknown size. OBJECT/ANNEX will + be read using OPS. The return value will be -1 if the transfer + fails or is not supported; 0 if the object is empty; or the length + of the object otherwise. If a positive value is returned, a + sufficiently large buffer will be allocated using xmalloc and + returned in *BUF_P containing the contents of the object. + + This method should be used for objects sufficiently small to store + in a single xmalloc'd buffer, when no fixed bound on the object's + size is known in advance. Don't try to read TARGET_OBJECT_MEMORY + through this function. */ + +LONGEST +target_read_alloc (struct target_ops *ops, + enum target_object object, + const char *annex, gdb_byte **buf_p) +{ + size_t buf_alloc, buf_pos; + gdb_byte *buf; + LONGEST n; + + /* This function does not have a length parameter; it reads the + entire OBJECT). Also, it doesn't support objects fetched partly + from one target and partly from another (in a different stratum, + e.g. a core file and an executable). Both reasons make it + unsuitable for reading memory. */ + gdb_assert (object != TARGET_OBJECT_MEMORY); + + /* Start by reading up to 4K at a time. The target will throttle + this number down if necessary. */ + buf_alloc = 4096; + buf = xmalloc (buf_alloc); + buf_pos = 0; + while (1) + { + n = target_read_partial (ops, object, annex, &buf[buf_pos], + buf_pos, buf_alloc - buf_pos); + if (n < 0) + { + /* An error occurred. */ + xfree (buf); + return -1; + } + else if (n == 0) + { + /* Read all there was. */ + if (buf_pos == 0) + xfree (buf); + else + *buf_p = buf; + return buf_pos; + } + + buf_pos += n; + + /* If the buffer is filling up, expand it. */ + if (buf_alloc < buf_pos * 2) + { + buf_alloc *= 2; + buf = xrealloc (buf, buf_alloc); + } + + QUIT; + } +} + /* Memory transfer methods. */ void |