summaryrefslogtreecommitdiff
path: root/gdb/target.c
diff options
context:
space:
mode:
authorDaniel Jacobowitz <dan@debian.org>2006-07-12 18:13:45 +0000
committerDaniel Jacobowitz <dan@debian.org>2006-07-12 18:13:45 +0000
commit20b5ceaa3a5f4f3f36bb26600ec685c0b071834c (patch)
treea7b2d9bb42c515d0f8f0ba0f1c788ebca0cc5254 /gdb/target.c
parentf828b7d4359cb6d35f4cc1c4ca80e89b58128179 (diff)
downloadgdb-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.c80
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