mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-23 08:23:50 +08:00
gdb/
* 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.
This commit is contained in:
parent
13547ab600
commit
0876f84a6a
@ -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
|
||||
|
10
gdb/NEWS
10
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
|
||||
|
@ -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''. */
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
182
gdb/remote.c
182
gdb/remote.c
@ -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;
|
||||
}
|
||||
|
||||
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",
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user