diff options
author | Daniel Jacobowitz <drow@false.org> | 2006-07-12 18:50:18 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2006-07-12 18:50:18 +0000 |
commit | 0876f84a6a8150efc48e1a6658531994906acea2 (patch) | |
tree | a4bd8e1fcc052f1159ce803f241a579254ad18c1 /gdb/gdbserver/server.c | |
parent | 13547ab600a0929b12f354dc144f1aef37938f30 (diff) | |
download | gdb-0876f84a6a8150efc48e1a6658531994906acea2.zip gdb-0876f84a6a8150efc48e1a6658531994906acea2.tar.gz gdb-0876f84a6a8150efc48e1a6658531994906acea2.tar.bz2 |
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.
Diffstat (limited to 'gdb/gdbserver/server.c')
-rw-r--r-- | gdb/gdbserver/server.c | 84 |
1 files changed, 70 insertions, 14 deletions
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index f8803d6..4b8120a 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -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; |