* target.c (target_read): Stop if target_read_partial returns 0
authorDaniel Jacobowitz <drow@false.org>
Wed, 12 Jul 2006 18:13:45 +0000 (18:13 +0000)
committerDaniel Jacobowitz <drow@false.org>
Wed, 12 Jul 2006 18:13:45 +0000 (18:13 +0000)
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.

gdb/ChangeLog
gdb/auxv.c
gdb/auxv.h
gdb/avr-tdep.c
gdb/ia64-tdep.c
gdb/linux-nat.c
gdb/procfs.c
gdb/remote.c
gdb/sparc-tdep.c
gdb/target.c
gdb/target.h

index fdad78fe077a217b5ab20fc8d5317e5fe6bc4b51..c1445bc61787c876c1f60f25d73cbfefc7c910b3 100644 (file)
@@ -1,3 +1,24 @@
+2006-07-12  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * 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.
+
 2006-07-12  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * arm-linux-tdep.c: Doc fixes.
index 557da3d416d03d01bd844df74bba3504517b06d3..d822c7f24aa47544ac09cf3d84e1aef2785a0ae1 100644 (file)
@@ -1,6 +1,6 @@
 /* Auxiliary vector support for GDB, the GNU debugger.
 
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -76,43 +76,6 @@ procfs_xfer_auxv (struct target_ops *ops,
   return n;
 }
 
-/* Read all the auxv data into a contiguous xmalloc'd buffer,
-   stored in *DATA.  Return the size in bytes of this data.
-   If zero, there is no data and *DATA is null.
-   if < 0, there was an error and *DATA is null.  */
-LONGEST
-target_auxv_read (struct target_ops *ops, gdb_byte **data)
-{
-  size_t auxv_alloc = 512, auxv_pos = 0;
-  gdb_byte *auxv = xmalloc (auxv_alloc);
-  int n;
-
-  while (1)
-    {
-      n = target_read_partial (ops, TARGET_OBJECT_AUXV,
-                              NULL, &auxv[auxv_pos], 0,
-                              auxv_alloc - auxv_pos);
-      if (n <= 0)
-       break;
-      auxv_pos += n;
-      if (auxv_pos < auxv_alloc) /* Read all there was.  */
-       break;
-      gdb_assert (auxv_pos == auxv_alloc);
-      auxv_alloc *= 2;
-      auxv = xrealloc (auxv, auxv_alloc);
-    }
-
-  if (auxv_pos == 0)
-    {
-      xfree (auxv);
-      *data = NULL;
-      return n;
-    }
-
-  *data = auxv;
-  return auxv_pos;
-}
-
 /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
    Return 0 if *READPTR is already at the end of the buffer.
    Return -1 if there is insufficient buffer for a whole entry.
@@ -148,7 +111,7 @@ target_auxv_search (struct target_ops *ops, CORE_ADDR match, CORE_ADDR *valp)
 {
   CORE_ADDR type, val;
   gdb_byte *data;
-  int n = target_auxv_read (ops, &data);
+  LONGEST n = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL, &data);
   gdb_byte *ptr = data;
   int ents = 0;
 
@@ -184,7 +147,8 @@ fprint_target_auxv (struct ui_file *file, struct target_ops *ops)
 {
   CORE_ADDR type, val;
   gdb_byte *data;
-  int len = target_auxv_read (ops, &data);
+  LONGEST len = target_read_alloc (ops, TARGET_OBJECT_AUXV, NULL,
+                                  &data);
   gdb_byte *ptr = data;
   int ents = 0;
 
index 92f7b541a6f251f15db396104a163cbfd4faeac8..49723b81a068812e5ff96d1c604c74e46e52ef48 100644 (file)
@@ -1,6 +1,6 @@
 /* Auxiliary vector support for GDB, the GNU debugger.
 
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 struct target_ops;             /* Forward declaration.  */
 
 
-/* Read all the auxv data into a contiguous xmalloc'd buffer,
-   stored in *DATA.  Return the size in bytes of this data.
-   If zero, there is no data and *DATA is null.
-   if < 0, there was an error and *DATA is null.  */
-extern LONGEST target_auxv_read (struct target_ops *ops, gdb_byte **data);
-
 /* Read one auxv entry from *READPTR, not reading locations >= ENDPTR.
    Return 0 if *READPTR is already at the end of the buffer.
    Return -1 if there is insufficient buffer for a whole entry.
index 9c6566e9210662376f39297edd210ad7849fcd14..f61e5a0b63942b839699a6078c333a1094b6cbf8 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-dependent code for Atmel AVR, for GDB.
 
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-   2005 Free Software Foundation, Inc.
+   2005, 2006 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -1323,35 +1323,22 @@ static void
 avr_io_reg_read_command (char *args, int from_tty)
 {
   LONGEST bufsiz = 0;
-  char buf[400];
+  gdb_byte *buf;
   char query[400];
   char *p;
   unsigned int nreg = 0;
   unsigned int val;
   int i, j, k, step;
 
-  /* Just get the maximum buffer size. */
-  bufsiz = target_read_partial (&current_target, TARGET_OBJECT_AVR,
-                               NULL, NULL, 0, 0);
-  if (bufsiz < 0)
-    {
-      fprintf_unfiltered (gdb_stderr,
-                         _("ERR: info io_registers NOT supported "
-                           "by current target\n"));
-      return;
-    }
-  if (bufsiz > sizeof (buf))
-    bufsiz = sizeof (buf);
-
   /* Find out how many io registers the target has. */
-  strcpy (query, "avr.io_reg");
-  target_read_partial (&current_target, TARGET_OBJECT_AVR, query, buf, 0,
-                      bufsiz);
+  bufsiz = target_read_alloc (&current_target, TARGET_OBJECT_AVR,
+                             "avr.io_reg", &buf);
 
-  if (strncmp (buf, "", bufsiz) == 0)
+  if (bufsiz <= 0)
     {
       fprintf_unfiltered (gdb_stderr,
-                         _("info io_registers NOT supported by target\n"));
+                         _("ERR: info io_registers NOT supported "
+                           "by current target\n"));
       return;
     }
 
@@ -1359,9 +1346,12 @@ avr_io_reg_read_command (char *args, int from_tty)
     {
       fprintf_unfiltered (gdb_stderr,
                          _("Error fetching number of io registers\n"));
+      xfree (buf);
       return;
     }
 
+  xfree (buf);
+
   reinitialize_more_filter ();
 
   printf_unfiltered (_("Target has %u io registers:\n\n"), nreg);
@@ -1377,8 +1367,8 @@ avr_io_reg_read_command (char *args, int from_tty)
         j = nreg - i;           /* last block is less than 8 registers */
 
       snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
-      target_read_partial (&current_target, TARGET_OBJECT_AVR, query, buf,
-                          0, bufsiz);
+      bufsiz = target_read_alloc (&current_target, TARGET_OBJECT_AVR,
+                                 query, &buf);
 
       p = buf;
       for (k = i; k < (i + j); k++)
@@ -1393,6 +1383,8 @@ avr_io_reg_read_command (char *args, int from_tty)
                break;
            }
        }
+
+      xfree (buf);
     }
 }
 
index 897d272d918512fb657b582379f6aadcc952444c..a65c56f9589cd0f2098172433a54e3d7ec09269a 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-dependent code for the IA-64 for GDB, the GNU debugger.
 
-   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
-   Foundation, Inc.
+   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -2458,8 +2458,8 @@ ia64_access_mem (unw_addr_space_t as,
 }
 
 /* Call low-level function to access the kernel unwind table.  */
-static int
-getunwind_table (void *buf, size_t len)
+static LONGEST
+getunwind_table (gdb_byte **buf_p)
 {
   LONGEST x;
 
@@ -2470,10 +2470,11 @@ getunwind_table (void *buf, size_t len)
      we want to preserve fall back to the running kernel's table, then
      we should find a way to override the corefile layer's
      xfer_partial method.  */
-  x = target_read_partial (&current_target, TARGET_OBJECT_UNWIND_TABLE, NULL,
-                          buf, 0, len);
 
-  return (int)x;
+  x = target_read_alloc (&current_target, TARGET_OBJECT_UNWIND_TABLE,
+                        NULL, buf_p);
+
+  return x;
 }
 
 /* Get the kernel unwind table.  */                             
@@ -2484,14 +2485,15 @@ get_kernel_table (unw_word_t ip, unw_dyn_info_t *di)
 
   if (!ktab) 
     {
+      gdb_byte *ktab_buf;
       size_t size;
-      size = getunwind_table (NULL, 0);
-      if ((int)size < 0)
-        return -UNW_ENOINFO;
-      ktab_size = size;
-      ktab = xmalloc (ktab_size);
-      getunwind_table (ktab, ktab_size);
-                         
+
+      ktab_size = getunwind_table (&ktab_buf);
+      if (ktab_size <= 0)
+       return -UNW_ENOINFO;
+      else
+       ktab = (struct ia64_table_entry *) ktab_buf;
+
       for (etab = ktab; etab->start_offset; ++etab)
         etab->info_offset += KERNEL_START;
     }
index 932119edfc58ce38fcb2954bc0948487f7ddc9fa..6c63ba97a8511cc0f10dd246e7065db427f42fbe 100644 (file)
@@ -2697,7 +2697,8 @@ linux_nat_make_corefile_notes (bfd *obfd, int *note_size)
       note_data = thread_args.note_data;
     }
 
-  auxv_len = target_auxv_read (&current_target, &auxv);
+  auxv_len = target_read_alloc (&current_target, TARGET_OBJECT_AUXV,
+                               NULL, &auxv);
   if (auxv_len > 0)
     {
       note_data = elfcore_write_note (obfd, note_data, note_size,
index 03fcadd017a9f1c9e406a9b28082064ce3e2d248..23ee3fb9250215d65d7d7ec1362f48d1a551b1e3 100644 (file)
@@ -6130,7 +6130,8 @@ procfs_make_note_section (bfd *obfd, int *note_size)
       note_data = thread_args.note_data;
     }
 
-  auxv_len = target_auxv_read (&current_target, &auxv);
+  auxv_len = target_read_alloc (&current_target, TARGET_OBJECT_AUXV,
+                               NULL, &auxv);
   if (auxv_len > 0)
     {
       note_data = elfcore_write_note (obfd, note_data, note_size,
index da0f5ca7d1199d193f31e7e93d7aac3f41196ef1..eef8bf2f5f4590a6a36510490063e13bd9c59d95 100644 (file)
@@ -5147,35 +5147,23 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
     case TARGET_OBJECT_AUXV:
       if (remote_protocol_packets[PACKET_qPart_auxv].support != PACKET_DISABLE)
        {
-         unsigned int total = 0;
-         while (len > 0)
-           {
-             LONGEST n = min ((get_remote_packet_size () - 2) / 2, len);
-             snprintf (rs->buf, get_remote_packet_size (),
-                       "qPart:auxv:read::%s,%s",
-                       phex_nz (offset, sizeof offset),
-                       phex_nz (n, sizeof n));
-             i = putpkt (rs->buf);
-             if (i < 0)
-               return total > 0 ? total : i;
-             rs->buf[0] = '\0';
-             getpkt (&rs->buf, &rs->buf_size, 0);
-             if (packet_ok (rs->buf, &remote_protocol_packets[PACKET_qPart_auxv])
-                 != PACKET_OK)
-               return total > 0 ? total : -1;
-             if (strcmp (rs->buf, "OK") == 0)
-               break;          /* Got EOF indicator.  */
-             /* Got some data.  */
-             i = hex2bin (rs->buf, readbuf, len);
-             if (i > 0)
-               {
-                 readbuf = (void *) ((char *) readbuf + i);
-                 offset += i;
-                 len -= i;
-                 total += i;
-               }
-           }
-         return total;
+         LONGEST n = min ((get_remote_packet_size () - 2) / 2, len);
+         snprintf (rs->buf, get_remote_packet_size (),
+                   "qPart:auxv:read::%s,%s",
+                   phex_nz (offset, sizeof offset),
+                   phex_nz (n, sizeof n));
+         i = putpkt (rs->buf);
+         if (i < 0)
+           return i;
+         rs->buf[0] = '\0';
+         getpkt (&rs->buf, &rs->buf_size, 0);
+         if (packet_ok (rs->buf, &remote_protocol_packets[PACKET_qPart_auxv])
+             != PACKET_OK)
+           return -1;
+         if (strcmp (rs->buf, "OK") == 0)
+           return 0;           /* Got EOF indicator.  */
+         /* Got some data.  */
+         return hex2bin (rs->buf, readbuf, len);
        }
       return -1;
 
index 797e2400536fe90792e02e1650d31e9b144f55b2..6c6f27692e00fcd52e033913544cddc080b2e311 100644 (file)
@@ -158,7 +158,7 @@ sparc_fetch_wcookie (void)
   gdb_byte buf[8];
   int len;
 
-  len = target_read_partial (ops, TARGET_OBJECT_WCOOKIE, NULL, buf, 0, 8);
+  len = target_read (ops, TARGET_OBJECT_WCOOKIE, NULL, buf, 0, 8);
   if (len == -1)
     return 0;
 
index bcb47deec381c54a82656b399f5809dbd9497a4e..c378ce56f74e2ea4906b884d8b7beae0c1b2c54f 100644 (file)
@@ -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
index 7018c52ce828bc9d8c1301974c3a52f9d283642d..2bb47fb2389af1be2d004c376f3a124f32a55663 100644 (file)
@@ -180,38 +180,8 @@ extern char *target_signal_to_name (enum target_signal);
 /* Given a name (SIGHUP, etc.), return its signal.  */
 enum target_signal target_signal_from_name (char *);
 \f
-/* Request the transfer of up to LEN 8-bit bytes of the target's
-   OBJECT.  The OFFSET, for a seekable object, specifies the starting
-   point.  The ANNEX can be used to provide additional data-specific
-   information to the target.
-
-   Return the number of bytes actually transfered, zero when no
-   further transfer is possible, and -1 when the transfer is not
-   supported.
-
-   NOTE: cagney/2003-10-17: The current interface does not support a
-   "retry" mechanism.  Instead it assumes that at least one byte will
-   be transfered on each call.
-
-   NOTE: cagney/2003-10-17: The current interface can lead to
-   fragmented transfers.  Lower target levels should not implement
-   hacks, such as enlarging the transfer, in an attempt to compensate
-   for this.  Instead, the target stack should be extended so that it
-   implements supply/collect methods and a look-aside object cache.
-   With that available, the lowest target can safely and freely "push"
-   data up the stack.
-
-   NOTE: cagney/2003-10-17: Unlike the old query and the memory
-   transfer mechanisms, these methods are explicitly parameterized by
-   the target that it should be applied to.
-
-   NOTE: cagney/2003-10-17: Just like the old query and memory xfer
-   methods, these new methods perform partial transfers.  The only
-   difference is that these new methods thought to include "partial"
-   in the name.  The old code's failure to do this lead to much
-   confusion and duplication of effort as each target object attempted
-   to locally take responsibility for something it didn't have to
-   worry about.  */
+/* Target objects which can be transfered using target_read,
+   target_write, et cetera.  */
 
 enum target_object
 {
@@ -229,17 +199,17 @@ enum target_object
   /* Possible future objects: TARGET_OBJECT_FILE, TARGET_OBJECT_PROC, ... */
 };
 
-extern LONGEST target_read_partial (struct target_ops *ops,
-                                   enum target_object object,
-                                   const char *annex, gdb_byte *buf,
-                                   ULONGEST offset, LONGEST len);
+/* Request that OPS transfer up to LEN 8-bit bytes of the target's
+   OBJECT.  The OFFSET, for a seekable object, specifies the
+   starting point.  The ANNEX can be used to provide additional
+   data-specific information to the target.
 
-extern LONGEST target_write_partial (struct target_ops *ops,
-                                    enum target_object object,
-                                    const char *annex, const gdb_byte *buf,
-                                    ULONGEST offset, LONGEST len);
+   Return the number of bytes actually transfered, or -1 if the
+   transfer is not supported or otherwise fails.  Return of a positive
+   value less than LEN indicates that no further transfer is possible.
+   Unlike the raw to_xfer_partial interface, callers of these
+   functions do not need to retry partial transfers.  */
 
-/* Wrappers to perform the full transfer.  */
 extern LONGEST target_read (struct target_ops *ops,
                            enum target_object object,
                            const char *annex, gdb_byte *buf,
@@ -250,6 +220,22 @@ extern LONGEST target_write (struct target_ops *ops,
                             const char *annex, const gdb_byte *buf,
                             ULONGEST offset, LONGEST 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.  */
+
+extern LONGEST target_read_alloc (struct target_ops *ops,
+                                 enum target_object object,
+                                 const char *annex, gdb_byte **buf_p);
+
 /* Wrappers to target read/write that perform memory transfers.  They
    throw an error if the memory transfer fails.
 
@@ -409,9 +395,33 @@ struct target_ops
                                              CORE_ADDR load_module_addr,
                                              CORE_ADDR offset);
 
-    /* Perform partial transfers on OBJECT.  See target_read_partial
-       and target_write_partial for details of each variant.  One, and
-       only one, of readbuf or writebuf must be non-NULL.  */
+    /* Request that OPS transfer up to LEN 8-bit bytes of the target's
+       OBJECT.  The OFFSET, for a seekable object, specifies the
+       starting point.  The ANNEX can be used to provide additional
+       data-specific information to the target.
+
+       Return the number of bytes actually transfered, zero when no
+       further transfer is possible, and -1 when the transfer is not
+       supported.  Return of a positive value smaller than LEN does
+       not indicate the end of the object, only the end of the
+       transfer; higher level code should continue transferring if
+       desired.  This is handled in target.c.
+
+       The interface does not support a "retry" mechanism.  Instead it
+       assumes that at least one byte will be transfered on each
+       successful call.
+
+       NOTE: cagney/2003-10-17: The current interface can lead to
+       fragmented transfers.  Lower target levels should not implement
+       hacks, such as enlarging the transfer, in an attempt to
+       compensate for this.  Instead, the target stack should be
+       extended so that it implements supply/collect methods and a
+       look-aside object cache.  With that available, the lowest
+       target can safely and freely "push" data up the stack.
+
+       See target_read and target_write for more information.  One,
+       and only one, of readbuf or writebuf must be non-NULL.  */
+
     LONGEST (*to_xfer_partial) (struct target_ops *ops,
                                enum target_object object, const char *annex,
                                gdb_byte *readbuf, const gdb_byte *writebuf,