gdb/
authorDaniel Jacobowitz <drow@false.org>
Wed, 12 Jul 2006 18:50:18 +0000 (18:50 +0000)
committerDaniel Jacobowitz <drow@false.org>
Wed, 12 Jul 2006 18:50:18 +0000 (18:50 +0000)
* remote.c (PACKET_qXfer_auxv): New, renamed from PACKET_qPart_auxv.
(remote_supported_packet): Remove #if 0.
(remote_protocol_features): Add qPart:auxv:read.
(remote_unescape_input): New function.
(readchar): Don't mask off the high bit.
(read_frame): Use fputstrn_filtered for packet data.
(getpkt_sane): Return the number of bytes read or -1.  Use
fputstrn_unfiltered.
(remote_read_qxfer): New.
(remote_xfer_partial): Use it for TARGET_OBJECT_AUXV.
(_initialize_remote): Update packet registration.
* defs.h (fputstrn_filtered): New prototype.
* utils.c (fputstrn_filtered): New.
* NEWS: Mention qXfer.
gdb/doc/
* gdb.texinfo (OS Information): Update qPart reference to
qXfer.
(Remote configuration): Likewise.
(Overview): Move @cindex to the start of a paragraph.  Talk
about binary data encoding.
(Packets): Refer to the overview for the details of the X
packet encoding.
(General Query Packets): Remove qPart description.  Add qXfer
description.  Add an anchor to qSupported.  Correct feature
table title.  Add a new feature for qXfer:auxv:read.
(Interrupts): Add a missing parenthesis.
gdb/gdbserver/
* server.c (decode_xfer_read, write_qxfer_response): New.
(handle_query): Take a packet length argument.  Handle
qXfer:auxv:read instead of qPart:auxv:read.  Mention it in
the qSupported response.
(main): Update call to handle_query.

gdb/ChangeLog
gdb/NEWS
gdb/defs.h
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/gdbserver/ChangeLog
gdb/gdbserver/server.c
gdb/remote.c
gdb/utils.c

index c1445bc61787c876c1f60f25d73cbfefc7c910b3..2140b8876fffc1f59b6d39ac878cca4fcc5cf890 100644 (file)
@@ -1,3 +1,20 @@
+2006-07-12  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * remote.c (PACKET_qXfer_auxv): New, renamed from PACKET_qPart_auxv.
+       (remote_supported_packet): Remove #if 0.
+       (remote_protocol_features): Add qPart:auxv:read.
+       (remote_unescape_input): New function.
+       (readchar): Don't mask off the high bit.
+       (read_frame): Use fputstrn_filtered for packet data.
+       (getpkt_sane): Return the number of bytes read or -1.  Use
+       fputstrn_unfiltered.
+       (remote_read_qxfer): New.
+       (remote_xfer_partial): Use it for TARGET_OBJECT_AUXV.
+       (_initialize_remote): Update packet registration.
+       * defs.h (fputstrn_filtered): New prototype.
+       * utils.c (fputstrn_filtered): New.
+       * NEWS: Mention qXfer.
+
 2006-07-12  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * target.c (target_read): Stop if target_read_partial returns 0
index 404b0fd5ac6b77eb76d77c35195705ef9d25b966..984585ef684d56273adca0c4797739d644212e28 100644 (file)
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -19,6 +19,16 @@ qSupported:
   packets required and improve performance when connected to a remote
   target.
 
+qXfer:auxv:read:
+  Fetch an OS auxilliary vector from the remote stub.  This packet is a
+  more efficient replacement for qPart:auxv:read.
+
+* Removed remote packets
+
+qPart:auxv:read:
+  This packet has been replaced by qXfer:auxv:read.  Only GDB 6.4 and 6.5
+  used it, and only gdbserver implemented it.
+
 *** Changes in GDB 6.5
 
 * New targets
index d472f8de5aabd28aff6961df790b927ae2c3e59c..aab91c2bf0cfcefe9c95348a93a660bffa51304f 100644 (file)
@@ -510,6 +510,8 @@ extern void fputstr_filtered (const char *str, int quotr, struct ui_file * strea
 
 extern void fputstr_unfiltered (const char *str, int quotr, struct ui_file * stream);
 
+extern void fputstrn_filtered (const char *str, int n, int quotr, struct ui_file * stream);
+
 extern void fputstrn_unfiltered (const char *str, int n, int quotr, struct ui_file * stream);
 
 /* Display the host ADDR on STREAM formatted as ``0x%x''. */
index fccf6ccdf28e3f3b396ec51007fda32ccbf447a6..5d8a02a8243e162fd827cb960b64ea60824b21e4 100644 (file)
@@ -1,3 +1,17 @@
+2006-07-12  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * gdb.texinfo (OS Information): Update qPart reference to
+       qXfer.
+       (Remote configuration): Likewise.
+       (Overview): Move @cindex to the start of a paragraph.  Talk
+       about binary data encoding.
+       (Packets): Refer to the overview for the details of the X
+       packet encoding.
+       (General Query Packets): Remove qPart description.  Add qXfer
+       description.  Add an anchor to qSupported.  Correct feature
+       table title.  Add a new feature for qXfer:auxv:read.
+       (Interrupts): Add a missing parenthesis.
+
 2006-07-05  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * doc/gdb.texinfo (KOD): Remove node.
index c5669711d1e8baff3152df7c18d19fdc7a79758d..a16e4d017fb46322b115ab724f86f0b00c9dd3fd 100644 (file)
@@ -6597,7 +6597,7 @@ identified by an integer tag; the meanings are well-known but system-specific.
 Depending on the configuration and operating system facilities,
 @value{GDBN} may be able to show you this information.  For remote
 targets, this functionality may further depend on the remote stub's
-support of the @samp{qPart:auxv:read} packet, see @ref{Remote
+support of the @samp{qXfer:auxv:read} packet, see @ref{Remote
 configuration, auxiliary vector}.
 
 @table @code
@@ -12655,16 +12655,16 @@ downloads.
 @item set remote read-aux-vector-packet
 @cindex auxiliary vector of remote target
 @cindex @code{auxv}, and remote targets
-Set the use of the remote protocol's @samp{qPart:auxv:read} (target
-auxiliary vector read) request.  This request is used to fetch the
+Set the use of the remote protocol's @samp{qXfer:auxv:read} (target
+auxiliary vector) request.  This request is used to fetch the
 remote target's @dfn{auxiliary vector}, see @ref{OS Information,
 Auxiliary Vector}.  The default setting depends on the remote stub's
 support of this request (@value{GDBN} queries the stub when this
-request is first required).  @xref{General Query Packets, qPart}, for
+request is first required).  @xref{General Query Packets, qXfer}, for
 more information about this request.
 
 @item show remote read-aux-vector-packet
-Show the current setting of use of the @samp{qPart:auxv:read} request.
+Show the current setting of use of the @samp{qXfer:auxv:read} request.
 
 @item set remote symbol-lookup-packet
 @cindex remote symbol lookup request
@@ -22563,8 +22563,8 @@ when the operation has completed (the target has again stopped).
 exception of @samp{#} and @samp{$} (see @samp{X} packet for additional
 exceptions).
 
-Fields within the packet should be separated using @samp{,} @samp{;} or
 @cindex remote protocol, field separator
+Fields within the packet should be separated using @samp{,} @samp{;} or
 @samp{:}.  Except where otherwise noted all numbers are represented in
 @sc{hex} with leading zeros suppressed.
 
@@ -22572,6 +22572,26 @@ Implementors should note that prior to @value{GDBN} 5.0, the character
 @samp{:} could not appear as the third character in a packet (as it
 would potentially conflict with the @var{sequence-id}).
 
+@cindex remote protocol, binary data
+@anchor{Binary Data}
+Binary data in most packets is encoded either as two hexadecimal
+digits per byte of binary data.  This allowed the traditional remote
+protocol to work over connections which were only seven-bit clean.
+Some packets designed more recently assume an eight-bit clean
+connection, and use a more efficient encoding to send and receive
+binary data.
+
+The binary data representation uses @code{7d} (@sc{ascii} @samp{@}})
+as an escape character.  Any escaped byte is transmitted as the escape
+character followed by the original character XORed with @code{0x20}.
+For example, the byte @code{0x7d} would be transmitted as the two
+bytes @code{0x7d 0x5d}.  The bytes @code{0x23} (@sc{ascii} @samp{#}),
+@code{0x24} (@sc{ascii} @samp{$}), and @code{0x7d} (@sc{ascii}
+@samp{@}}) must always be escaped.  Responses sent by the stub
+must also escape @code{0x2a} (@sc{ascii} @samp{*}), so that it
+is not interpreted as the start of a run-length encoded sequence
+(described next).
+
 Response @var{data} can be run-length encoded to save space.  A @samp{*}
 means that the next character is an @sc{ascii} encoding giving a repeat count
 which stands for that many repetitions of the character preceding the
@@ -22980,12 +23000,7 @@ The @samp{vCont} packet is not supported.
 @cindex @samp{X} packet
 Write data to memory, where the data is transmitted in binary.
 @var{addr} is address, @var{length} is number of bytes,
-@samp{@var{XX}@dots{}} is binary data.  The bytes @code{0x23}
-(@sc{ascii} @samp{#}), @code{0x24} (@sc{ascii} @samp{$}), and
-@code{0x7d} (@sc{ascii} @samp{@}}) are escaped using @code{0x7d}
-(@sc{ascii} @samp{@}}), and then XORed with @code{0x20}.  For example,
-the byte @code{0x7d} would be transmitted as the two bytes @code{0x7d
-0x5d}.
+@samp{@var{XX}@dots{}} is binary data (@pxref{Binary Data}).
 
 Reply:
 @table @samp
@@ -23381,87 +23396,6 @@ Don't use this packet; use the @samp{qThreadExtraInfo} query instead
 
 Reply: see @code{remote.c:remote_unpack_thread_info_response()}.
 
-@item qPart:@var{object}:read:@var{annex}:@var{offset},@var{length}
-@cindex read special object, remote request
-@cindex @samp{qPart} packet
-Read uninterpreted bytes from the target's special data area
-identified by the keyword @var{object}.  Request @var{length} bytes
-starting at @var{offset} bytes into the data.  The content and
-encoding of @var{annex} is specific to the object; it can supply
-additional details about what data to access.
-
-Since this packet is ambiguous with the older @code{qP} packet, we
-plan to rename it.
-
-Here are the specific requests of this form defined so far.  All
-@samp{qPart:@var{object}:read:@dots{}} requests use the same reply
-formats, listed below.
-
-@table @samp
-@item qPart:auxv:read::@var{offset},@var{length}
-Access the target's @dfn{auxiliary vector}.  @xref{OS Information,
-auxiliary vector}, and see @ref{Remote configuration,
-read-aux-vector-packet}.  Note @var{annex} must be empty.
-@end table
-
-Reply:
-@table @samp
-@item OK
-The @var{offset} in the request is at the end of the data.
-There is no more data to be read.
-
-@item @var{XX}@dots{}
-Hex encoded data bytes read.
-This may be fewer bytes than the @var{length} in the request.
-
-@item E00
-The request was malformed, or @var{annex} was invalid.
-
-@item E @var{nn}
-The offset was invalid, or there was an error encountered reading the data.
-@var{nn} is a hex-encoded @code{errno} value.
-
-@item
-An empty reply indicates the @var{object} or @var{annex} string was not
-recognized by the stub.
-@end table
-
-@item qPart:@var{object}:write:@var{annex}:@var{offset}:@var{data}@dots{}
-@cindex write data into object, remote request
-Write uninterpreted bytes into the target's special data area
-identified by the keyword @var{object}, starting at @var{offset} bytes
-into the data.  @samp{@var{data}@dots{}} is the hex-encoded data to be
-written.  The content and encoding of @var{annex} is specific to the
-object; it can supply additional details about what data to access.
-
-No requests of this form are presently in use.  This specification
-serves as a placeholder to document the common format that new
-specific request specifications ought to use.
-
-Reply:
-@table @samp
-@item @var{nn}
-@var{nn} (hex encoded) is the number of bytes written.
-This may be fewer bytes than supplied in the request.
-
-@item E00
-The request was malformed, or @var{annex} was invalid.
-
-@item E @var{nn}
-The offset was invalid, or there was an error encountered writing the data.
-@var{nn} is a hex-encoded @code{errno} value.
-
-@item
-An empty reply indicates the @var{object} or @var{annex} string was not
-recognized by the stub, or that the object does not support writing.
-@end table
-
-@item qPart:@var{object}:@var{operation}:@dots{}
-Requests of this form may be added in the future.  When a stub does
-not recognize the @var{object} keyword, or its support for
-@var{object} does not recognize the @var{operation} keyword, the stub
-must respond with an empty packet.
-
 @item qRcmd,@var{command}
 @cindex execute remote command, remote request
 @cindex @samp{qRcmd} packet
@@ -23493,6 +23427,7 @@ packets.)
 @cindex supported packets, remote query
 @cindex features of the remote protocol
 @cindex @samp{qSupported} packet
+@anchor{qSupported}
 Tell the remote stub about features supported by @value{GDBN}, and
 query the stub for features it supports.  This packet allows
 @value{GDBN} and the remote stub to take advantage of each others'
@@ -23584,7 +23519,7 @@ These are the currently defined stub features and their properties:
 @multitable @columnfractions 0.25 0.2 0.2 0.2
 @c NOTE: The first row should be @headitem, but we do not yet require
 @c a new enough version of Texinfo (4.7) to use @headitem.
-@item Packet Name
+@item Feature Name
 @tab Value Required
 @tab Default
 @tab Probe Allowed
@@ -23594,6 +23529,11 @@ These are the currently defined stub features and their properties:
 @tab @samp{-}
 @tab No
 
+@item @samp{qXfer:auxv:read}
+@tab No
+@tab @samp{-}
+@tab Yes
+
 @end multitable
 
 These are the currently defined stub features, in more detail:
@@ -23610,6 +23550,10 @@ stores packets in a NUL-terminated format, it should allow an extra
 byte in its buffer for the NUL.  If this stub feature is not supported,
 @value{GDBN} guesses based on the size of the @samp{g} packet response.
 
+@item qXfer:auxv:read
+The remote stub understands the @samp{qXfer:auxv:read} packet
+(@pxref{qXfer auxiliary vector read}).
+
 @end table
 
 @item qSymbol::
@@ -23684,6 +23628,98 @@ packets.)
 @itemx qTStatus   
 @xref{Tracepoint Packets}.
 
+@item qXfer:@var{object}:read:@var{annex}:@var{offset},@var{length}
+@cindex read special object, remote request
+@cindex @samp{qXfer} packet
+Read uninterpreted bytes from the target's special data area
+identified by the keyword @var{object}.  Request @var{length} bytes
+starting at @var{offset} bytes into the data.  The content and
+encoding of @var{annex} is specific to the object; it can supply
+additional details about what data to access.
+
+Here are the specific requests of this form defined so far.  All
+@samp{qXfer:@var{object}:read:@dots{}} requests use the same reply
+formats, listed below.
+
+@table @samp
+@item qXfer:auxv:read::@var{offset},@var{length}
+@anchor{qXfer auxiliary vector read}
+Access the target's @dfn{auxiliary vector}.  @xref{OS Information,
+auxiliary vector}, and @ref{Remote configuration,
+read-aux-vector-packet}.  Note @var{annex} must be empty.
+
+This packet is not probed by default; the remote stub must request it,
+by suppling an appropriate @samp{qSupported} response (@pxref{qSupported}).
+@end table
+
+Reply:
+@table @samp
+@item m @var{data}
+Data @var{data} (@pxref{Binary Data}) has been read from the
+target.  There may be more data at a higher address (although
+it is permitted to return @samp{m} even for the last valid
+block of data, as long as at least one byte of data was read).
+@var{data} may have fewer bytes than the @var{length} in the
+request.
+
+@item l @var{data}
+Data @var{data} (@pxref{Binary Data}) has been read from the target.
+There is no more data to be read.  @var{data} may have fewer bytes
+than the @var{length} in the request.
+
+@item l
+The @var{offset} in the request is at the end of the data.
+There is no more data to be read.
+
+@item E00
+The request was malformed, or @var{annex} was invalid.
+
+@item E @var{nn}
+The offset was invalid, or there was an error encountered reading the data.
+@var{nn} is a hex-encoded @code{errno} value.
+
+@item
+An empty reply indicates the @var{object} string was not recognized by
+the stub, or that the object does not support reading.
+@end table
+
+@item qXfer:@var{object}:write:@var{annex}:@var{offset}:@var{data}@dots{}
+@cindex write data into object, remote request
+Write uninterpreted bytes into the target's special data area
+identified by the keyword @var{object}, starting at @var{offset} bytes
+into the data.  @samp{@var{data}@dots{}} is the binary-encoded data
+(@pxref{Binary Data}) to be written.  The content and encoding of @var{annex}
+is specific to the object; it can supply additional details about what data
+to access.
+
+No requests of this form are presently in use.  This specification
+serves as a placeholder to document the common format that new
+specific request specifications ought to use.
+
+Reply:
+@table @samp
+@item @var{nn}
+@var{nn} (hex encoded) is the number of bytes written.
+This may be fewer bytes than supplied in the request.
+
+@item E00
+The request was malformed, or @var{annex} was invalid.
+
+@item E @var{nn}
+The offset was invalid, or there was an error encountered writing the data.
+@var{nn} is a hex-encoded @code{errno} value.
+
+@item
+An empty reply indicates the @var{object} string was not
+recognized by the stub, or that the object does not support writing.
+@end table
+
+@item qXfer:@var{object}:@var{operation}:@dots{}
+Requests of this form may be added in the future.  When a stub does
+not recognize the @var{object} keyword, or its support for
+@var{object} does not recognize the @var{operation} keyword, the stub
+must respond with an empty packet.
+
 @end table
 
 @node Register Packet Format
@@ -23898,7 +23934,7 @@ transport mechanisms.  It is represented by sending the single byte
 the Overview section (@pxref{Overview}).  When a @code{0x03} byte is
 transmitted as part of a packet, it is considered to be packet data
 and does @emph{not} represent an interrupt.  E.g., an @samp{X} packet
-(@pxref{X packet}, used for binary downloads, may include an unescaped
+(@pxref{X packet}), used for binary downloads, may include an unescaped
 @code{0x03} as part of its packet.
 
 Stubs are not required to recognize these interrupt mechanisms and the
index 5758995ef6c98982fd30e40605addc0f00c20ffc..d9b7672b762185fab3850a2ad0c0288968f73307 100644 (file)
@@ -1,3 +1,11 @@
+2006-07-12  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * server.c (decode_xfer_read, write_qxfer_response): New.
+       (handle_query): Take a packet length argument.  Handle
+       qXfer:auxv:read instead of qPart:auxv:read.  Mention it in
+       the qSupported response.
+       (main): Update call to handle_query.
+
 2006-06-22  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * remote-utils.c (remote_escape_output, remote_unescape_input): New.
index f8803d6555a1683d460c5cc49e3e0cb62b44e3e2..4b8120a1d84bc01d111d479fda52f76310368e38 100644 (file)
@@ -91,9 +91,48 @@ attach_inferior (int pid, char *statusptr, int *sigptr)
 
 extern int remote_debug;
 
+/* Decode a qXfer read request.  Return 0 if everything looks OK,
+   or -1 otherwise.  */
+
+static int
+decode_xfer_read (char *buf, char **annex, CORE_ADDR *ofs, unsigned int *len)
+{
+  /* Extract and NUL-terminate the annex.  */
+  *annex = buf;
+  while (*buf && *buf != ':')
+    buf++;
+  if (*buf == '\0')
+    return -1;
+  *buf++ = 0;
+
+  /* After the read/write marker and annex, qXfer looks like a
+     traditional 'm' packet.  */
+  decode_m_packet (buf, ofs, len);
+
+  return 0;
+}
+
+/* Write the response to a successful qXfer read.  Returns the
+   length of the (binary) data stored in BUF, corresponding
+   to as much of DATA/LEN as we could fit.  IS_MORE controls
+   the first character of the response.  */
+static int
+write_qxfer_response (char *buf, unsigned char *data, int len, int is_more)
+{
+  int out_len;
+
+  if (is_more)
+    buf[0] = 'm';
+  else
+    buf[0] = 'l';
+
+  return remote_escape_output (data, len, (unsigned char *) buf + 1, &out_len,
+                              PBUFSIZ - 2) + 1;
+}
+
 /* Handle all of the extended 'q' packets.  */
 void
-handle_query (char *own_buf)
+handle_query (char *own_buf, int *new_packet_len_p)
 {
   static struct inferior_list_entry *thread_ptr;
 
@@ -144,22 +183,35 @@ handle_query (char *own_buf)
     }
 
   if (the_target->read_auxv != NULL
-      && strncmp ("qPart:auxv:read::", own_buf, 17) == 0)
+      && strncmp ("qXfer:auxv:read:", own_buf, 16) == 0)
     {
-      unsigned char data[(PBUFSIZ - 1) / 2];
+      unsigned char *data;
+      int n;
       CORE_ADDR ofs;
       unsigned int len;
-      int n;
-      decode_m_packet (&own_buf[17], &ofs, &len); /* "OFS,LEN" */
-      if (len > sizeof data)
-       len = sizeof data;
-      n = (*the_target->read_auxv) (ofs, data, len);
-      if (n == 0)
-       write_ok (own_buf);
-      else if (n < 0)
-       write_enn (own_buf);
+      char *annex;
+
+      /* Reject any annex; grab the offset and length.  */
+      if (decode_xfer_read (own_buf + 16, &annex, &ofs, &len) < 0
+         || annex[0] != '\0')
+       {
+         strcpy (own_buf, "E00");
+         return;
+       }
+
+      /* Read one extra byte, as an indicator of whether there is
+        more.  */
+      if (len > PBUFSIZ - 2)
+       len = PBUFSIZ - 2;
+      data = malloc (len + 1);
+      n = (*the_target->read_auxv) (ofs, data, len + 1);
+      if (n > len)
+       *new_packet_len_p = write_qxfer_response (own_buf, data, len, 1);
       else
-       convert_int_to_ascii (data, own_buf, n);
+       *new_packet_len_p = write_qxfer_response (own_buf, data, n, 0);
+
+      free (data);
+
       return;
     }
 
@@ -168,6 +220,10 @@ handle_query (char *own_buf)
       && (own_buf[10] == ':' || own_buf[10] == '\0'))
     {
       sprintf (own_buf, "PacketSize=%x", PBUFSIZ - 1);
+
+      if (the_target->read_auxv != NULL)
+       strcat (own_buf, ";qPart:auxv:read+");
+
       return;
     }
 
@@ -455,7 +511,7 @@ main (int argc, char *argv[])
          switch (ch)
            {
            case 'q':
-             handle_query (own_buf);
+             handle_query (own_buf, &new_packet_len);
              break;
            case 'd':
              remote_debug = !remote_debug;
index eef8bf2f5f4590a6a36510490063e13bd9c59d95..6e1a8fa2996b22102b7cabb8586320f9418aa864 100644 (file)
@@ -813,7 +813,7 @@ enum {
   PACKET_Z2,
   PACKET_Z3,
   PACKET_Z4,
-  PACKET_qPart_auxv,
+  PACKET_qXfer_auxv,
   PACKET_qGetTLSAddr,
   PACKET_qSupported,
   PACKET_MAX
@@ -2106,7 +2106,6 @@ struct protocol_feature
   int packet;
 };
 
-#if 0
 static void
 remote_supported_packet (const struct protocol_feature *feature,
                         enum packet_support support,
@@ -2123,7 +2122,6 @@ remote_supported_packet (const struct protocol_feature *feature,
       == PACKET_SUPPORT_UNKNOWN)
     remote_protocol_packets[feature->packet].support = support;
 }
-#endif
 
 static void
 remote_packet_size (const struct protocol_feature *feature,
@@ -2165,7 +2163,9 @@ remote_packet_size (const struct protocol_feature *feature,
 }
 
 static struct protocol_feature remote_protocol_features[] = {
-  { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 }
+  { "PacketSize", PACKET_DISABLE, remote_packet_size, -1 },
+  { "qPart:auxv:read", PACKET_DISABLE, remote_supported_packet,
+    PACKET_qXfer_auxv }
 };
 
 static void
@@ -3728,6 +3728,52 @@ remote_escape_output (const gdb_byte *buffer, int len,
   return output_index;
 }
 
+/* Convert BUFFER, escaped data LEN bytes long, into binary data
+   in OUT_BUF.  Return the number of bytes written to OUT_BUF.
+   Raise an error if the total number of bytes exceeds OUT_MAXLEN.
+
+   This function reverses remote_escape_output.  It allows more
+   escaped characters than that function does, in particular because
+   '*' must be escaped to avoid the run-length encoding processing
+   in reading packets.  */
+
+static int
+remote_unescape_input (const gdb_byte *buffer, int len,
+                      gdb_byte *out_buf, int out_maxlen)
+{
+  int input_index, output_index;
+  int escaped;
+
+  output_index = 0;
+  escaped = 0;
+  for (input_index = 0; input_index < len; input_index++)
+    {
+      gdb_byte b = buffer[input_index];
+
+      if (output_index + 1 > out_maxlen)
+       {
+         warning (_("Received too much data from remote target;"
+                    " ignoring overflow."));
+         return output_index;
+       }
+
+      if (escaped)
+       {
+         out_buf[output_index++] = b ^ 0x20;
+         escaped = 0;
+       }
+      else if (b == '}')
+       escaped = 1;
+      else
+       out_buf[output_index++] = b;
+    }
+
+  if (escaped)
+    error (_("Unmatched escape character in target response."));
+
+  return output_index;
+}
+
 /* Determine whether the remote target supports binary downloading.
    This is accomplished by sending a no-op memory write of zero length
    to the target at the specified address. It does not suffice to send
@@ -4040,8 +4086,7 @@ remote_files_info (struct target_ops *ignore)
 /* Stuff for dealing with the packets which are part of this protocol.
    See comment at top of file for details.  */
 
-/* Read a single character from the remote end, masking it down to 7
-   bits.  */
+/* Read a single character from the remote end.  */
 
 static int
 readchar (int timeout)
@@ -4051,7 +4096,7 @@ readchar (int timeout)
   ch = serial_readchar (remote_desc, timeout);
 
   if (ch >= 0)
-    return (ch & 0x7f);
+    return ch;
 
   switch ((enum serial_rc) ch)
     {
@@ -4335,7 +4380,7 @@ read_frame (char **buf_p,
                fprintf_filtered (gdb_stdlog,
                              "Bad checksum, sentsum=0x%x, csum=0x%x, buf=",
                                  pktcsum, csum);
-               fputs_filtered (buf, gdb_stdlog);
+               fputstrn_filtered (buf, bc, 0, gdb_stdlog);
                fputs_filtered ("\n", gdb_stdlog);
              }
            /* Number of characters in buffer ignoring trailing
@@ -4414,7 +4459,8 @@ getpkt (char **buf,
    rather than timing out; this is used (in synchronous mode) to wait
    for a target that is is executing user code to stop.  If FOREVER ==
    0, this function is allowed to time out gracefully and return an
-   indication of this to the caller.  */
+   indication of this to the caller.  Otherwise return the number
+   of bytes read.  */
 static int
 getpkt_sane (char **buf, long *sizeof_buf, int forever)
 {
@@ -4475,11 +4521,11 @@ getpkt_sane (char **buf, long *sizeof_buf, int forever)
          if (remote_debug)
            {
              fprintf_unfiltered (gdb_stdlog, "Packet received: ");
-             fputstr_unfiltered (*buf, 0, gdb_stdlog);
+             fputstrn_unfiltered (*buf, val, 0, gdb_stdlog);
              fprintf_unfiltered (gdb_stdlog, "\n");
            }
          serial_write (remote_desc, "+", 1);
-         return 0;
+         return val;
        }
 
       /* Try the whole thing again.  */
@@ -4492,7 +4538,7 @@ getpkt_sane (char **buf, long *sizeof_buf, int forever)
 
   printf_unfiltered (_("Ignoring packet error, continuing...\n"));
   serial_write (remote_desc, "+", 1);
-  return 1;
+  return -1;
 }
 \f
 static void
@@ -5097,6 +5143,90 @@ the loaded file\n"));
     printf_filtered (_("No loaded section named '%s'.\n"), args);
 }
 
+/* Read OBJECT_NAME/ANNEX from the remote target using a qXfer packet.
+   Data at OFFSET, of up to LEN bytes, is read into READBUF; the
+   number of bytes read is returned, or 0 for EOF, or -1 for error.
+   The number of bytes read may be less than LEN without indicating an
+   EOF.  PACKET is checked and updated to indicate whether the remote
+   target supports this object.  */
+
+static LONGEST
+remote_read_qxfer (struct target_ops *ops, const char *object_name,
+                  const char *annex,
+                  gdb_byte *readbuf, ULONGEST offset, LONGEST len,
+                  struct packet_config *packet)
+{
+  static char *finished_object;
+  static char *finished_annex;
+  static ULONGEST finished_offset;
+
+  struct remote_state *rs = get_remote_state ();
+  unsigned int total = 0;
+  LONGEST i, n, packet_len;
+
+  if (packet->support == PACKET_DISABLE)
+    return -1;
+
+  /* Check whether we've cached an end-of-object packet that matches
+     this request.  */
+  if (finished_object)
+    {
+      if (strcmp (object_name, finished_object) == 0
+         && strcmp (annex ? annex : "", finished_annex) == 0
+         && offset == finished_offset)
+       return 0;
+
+      /* Otherwise, we're now reading something different.  Discard
+        the cache.  */
+      xfree (finished_object);
+      xfree (finished_annex);
+      finished_object = NULL;
+      finished_annex = NULL;
+    }
+
+  /* Request only enough to fit in a single packet.  The actual data
+     may not, since we don't know how much of it will need to be escaped;
+     the target is free to respond with slightly less data.  We subtract
+     five to account for the response type and the protocol frame.  */
+  n = min (get_remote_packet_size () - 5, len);
+  snprintf (rs->buf, get_remote_packet_size () - 4, "qXfer:%s:read:%s:%s,%s",
+           object_name, annex ? annex : "",
+           phex_nz (offset, sizeof offset),
+           phex_nz (n, sizeof n));
+  i = putpkt (rs->buf);
+  if (i < 0)
+    return -1;
+
+  rs->buf[0] = '\0';
+  packet_len = getpkt_sane (&rs->buf, &rs->buf_size, 0);
+  if (packet_len < 0 || packet_ok (rs->buf, packet) != PACKET_OK)
+    return -1;
+
+  if (rs->buf[0] != 'l' && rs->buf[0] != 'm')
+    error (_("Unknown remote qXfer reply: %s"), rs->buf);
+
+  /* 'm' means there is (or at least might be) more data after this
+     batch.  That does not make sense unless there's at least one byte
+     of data in this reply.  */
+  if (rs->buf[0] == 'm' && packet_len == 1)
+    error (_("Remote qXfer reply contained no data."));
+
+  /* Got some data.  */
+  i = remote_unescape_input (rs->buf + 1, packet_len - 1, readbuf, n);
+
+  /* 'l' is an EOF marker, possibly including a final block of data,
+     or possibly empty.  Record it to bypass the next read, if one is
+     issued.  */
+  if (rs->buf[0] == 'l')
+    {
+      finished_object = xstrdup (object_name);
+      finished_annex = xstrdup (annex ? annex : "");
+      finished_offset = offset + i;
+    }
+
+  return i;
+}
+
 static LONGEST
 remote_xfer_partial (struct target_ops *ops, enum target_object object,
                     const char *annex, gdb_byte *readbuf,
@@ -5145,27 +5275,9 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
       break;
 
     case TARGET_OBJECT_AUXV:
-      if (remote_protocol_packets[PACKET_qPart_auxv].support != PACKET_DISABLE)
-       {
-         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;
+      gdb_assert (annex == NULL);
+      return remote_read_qxfer (ops, "auxv", annex, readbuf, offset, len,
+                               &remote_protocol_packets[PACKET_qXfer_auxv]);
 
     default:
       return -1;
@@ -5913,8 +6025,8 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_Z4],
                         "Z4", "access-watchpoint", 0);
 
-  add_packet_config_cmd (&remote_protocol_packets[PACKET_qPart_auxv],
-                        "qPart:auxv", "read-aux-vector", 0);
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_auxv],
+                        "qXfer:auxv:read", "read-aux-vector", 0);
 
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qGetTLSAddr],
                         "qGetTLSAddr", "get-thread-local-storage-address",
index 00a060b2c57c9421281277d6e37637d36f4a9d6a..6c4afb7daac784c6abec995ac6f6fef4dd6bce56 100644 (file)
@@ -1543,6 +1543,15 @@ fputstr_unfiltered (const char *str, int quoter, struct ui_file *stream)
     printchar (*str++, fputs_unfiltered, fprintf_unfiltered, stream, quoter);
 }
 
+void
+fputstrn_filtered (const char *str, int n, int quoter,
+                  struct ui_file *stream)
+{
+  int i;
+  for (i = 0; i < n; i++)
+    printchar (str[i], fputs_filtered, fprintf_filtered, stream, quoter);
+}
+
 void
 fputstrn_unfiltered (const char *str, int n, int quoter,
                     struct ui_file *stream)