diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2007-06-12 14:38:32 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@de.ibm.com> | 2007-06-12 14:38:32 +0000 |
commit | 0e7f50da78982a93a4603cddbb2e0c07019e9c1a (patch) | |
tree | a928a4426efc054ce836def5815ef3d3f8783fc1 /gdb/gdbserver | |
parent | 23d964e7b6625bec3822bcb9613f65362b9b3026 (diff) | |
download | gdb-0e7f50da78982a93a4603cddbb2e0c07019e9c1a.zip gdb-0e7f50da78982a93a4603cddbb2e0c07019e9c1a.tar.gz gdb-0e7f50da78982a93a4603cddbb2e0c07019e9c1a.tar.bz2 |
ChangeLog:
* remote.c (remote_write_qxfer): New function.
(remote_xfer_partial): Add handling for TARGET_OBJECT_SPU.
(remote_read_qxfer): Do not cache empty objects.
(_initialize_remote): Add PACKET_qXfer_spu_read and
PACKET_qXfer_spu_write.
doc/ChangeLog:
* gdb.texinfo (General Query Packets): Document qXfer:spu:read
and qXfer:spu:write packets and mention them under qSupported.
gdbserver/ChangeLog:
* remote-utils.c (decode_xfer_write): New function.
* server.h (decode_xfer_write): Add prototype.
* server.c (handle_query): Add PACKET_LEN argument. Support
qXfer:spu:read and qXfer:spu:write packets.
(main): Pass packet_len to handle_query.
* spu-low.c (spu_target_ops): Add spu_proc_xfer_spu.
* target.h (target_ops): Add qxfer_spu.
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r-- | gdb/gdbserver/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/gdbserver/remote-utils.c | 30 | ||||
-rw-r--r-- | gdb/gdbserver/server.c | 72 | ||||
-rw-r--r-- | gdb/gdbserver/server.h | 3 | ||||
-rw-r--r-- | gdb/gdbserver/spu-low.c | 2 | ||||
-rw-r--r-- | gdb/gdbserver/target.h | 4 |
6 files changed, 118 insertions, 4 deletions
diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index c922989..994fe8d 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,4 +1,15 @@ 2007-06-12 Ulrich Weigand <uweigand@de.ibm.com> + Markus Deuling <deuling@de.ibm.com> + + * remote-utils.c (decode_xfer_write): New function. + * server.h (decode_xfer_write): Add prototype. + * server.c (handle_query): Add PACKET_LEN argument. Support + qXfer:spu:read and qXfer:spu:write packets. + (main): Pass packet_len to handle_query. + * spu-low.c (spu_target_ops): Add spu_proc_xfer_spu. + * target.h (target_ops): Add qxfer_spu. + +2007-06-12 Ulrich Weigand <uweigand@de.ibm.com> * spu-low.c (spu_proc_xfer_spu): Do not return failure when accessing non-seekable spufs files. diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index 505e37c..9559148 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -1042,6 +1042,36 @@ decode_X_packet (char *from, int packet_len, CORE_ADDR *mem_addr_ptr, return 0; } +/* Decode a qXfer write request. */ +int +decode_xfer_write (char *buf, int packet_len, char **annex, CORE_ADDR *offset, + unsigned int *len, unsigned char *data) +{ + char ch; + + /* Extract and NUL-terminate the annex. */ + *annex = buf; + while (*buf && *buf != ':') + buf++; + if (*buf == '\0') + return -1; + *buf++ = 0; + + /* Extract the offset. */ + *offset = 0; + while ((ch = *buf++) != ':') + { + *offset = *offset << 4; + *offset |= fromhex (ch) & 0x0f; + } + + /* Get encoded data. */ + packet_len -= buf - *annex; + *len = remote_unescape_input ((const gdb_byte *) buf, packet_len, + data, packet_len); + return 0; +} + /* Ask GDB for the address of NAME, and return it in ADDRP if found. Returns 1 if the symbol is found, 0 if it is not, -1 on error. */ diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index 52b1e8d..bee1256 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -141,7 +141,7 @@ decode_xfer_read (char *buf, char **annex, CORE_ADDR *ofs, unsigned int *len) return -1; *buf++ = 0; - /* After the read/write marker and annex, qXfer looks like a + /* After the read marker and annex, qXfer looks like a traditional 'm' packet. */ decode_m_packet (buf, ofs, len); @@ -255,7 +255,7 @@ monitor_show_help (void) /* Handle all of the extended 'q' packets. */ void -handle_query (char *own_buf, int *new_packet_len_p) +handle_query (char *own_buf, int packet_len, int *new_packet_len_p) { static struct inferior_list_entry *thread_ptr; @@ -314,6 +314,69 @@ handle_query (char *own_buf, int *new_packet_len_p) return; } + if (the_target->qxfer_spu != NULL + && strncmp ("qXfer:spu:read:", own_buf, 15) == 0) + { + char *annex; + int n; + unsigned int len; + CORE_ADDR ofs; + unsigned char *spu_buf; + + strcpy (own_buf, "E00"); + if (decode_xfer_read (own_buf + 15, &annex, &ofs, &len) < 0) + return; + if (len > PBUFSIZ - 2) + len = PBUFSIZ - 2; + spu_buf = malloc (len + 1); + if (!spu_buf) + return; + + n = (*the_target->qxfer_spu) (annex, spu_buf, NULL, ofs, len + 1); + if (n < 0) + write_enn (own_buf); + else if (n > len) + *new_packet_len_p = write_qxfer_response + (own_buf, spu_buf, len, 1); + else + *new_packet_len_p = write_qxfer_response + (own_buf, spu_buf, n, 0); + + free (spu_buf); + return; + } + + if (the_target->qxfer_spu != NULL + && strncmp ("qXfer:spu:write:", own_buf, 16) == 0) + { + char *annex; + int n; + unsigned int len; + CORE_ADDR ofs; + unsigned char *spu_buf; + + strcpy (own_buf, "E00"); + spu_buf = malloc (packet_len - 15); + if (!spu_buf) + return; + if (decode_xfer_write (own_buf + 16, packet_len - 16, &annex, + &ofs, &len, spu_buf) < 0) + { + free (spu_buf); + return; + } + + n = (*the_target->qxfer_spu) + (annex, NULL, (unsigned const char *)spu_buf, ofs, len); + if (n < 0) + write_enn (own_buf); + else + sprintf (own_buf, "%x", n); + + free (spu_buf); + return; + } + if (the_target->read_auxv != NULL && strncmp ("qXfer:auxv:read:", own_buf, 16) == 0) { @@ -403,6 +466,9 @@ handle_query (char *own_buf, int *new_packet_len_p) if (the_target->read_auxv != NULL) strcat (own_buf, ";qXfer:auxv:read+"); + + if (the_target->qxfer_spu != NULL) + strcat (own_buf, ";qXfer:spu:read+;qXfer:spu:write+"); if (get_features_xml ("target.xml") != NULL) strcat (own_buf, ";qXfer:features:read+"); @@ -809,7 +875,7 @@ main (int argc, char *argv[]) switch (ch) { case 'q': - handle_query (own_buf, &new_packet_len); + handle_query (own_buf, packet_len, &new_packet_len); break; case 'Q': handle_general_set (own_buf); diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index b1ff238..573bde2 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -176,6 +176,9 @@ void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr, unsigned int *len_ptr, unsigned char *to); int decode_X_packet (char *from, int packet_len, CORE_ADDR * mem_addr_ptr, unsigned int *len_ptr, unsigned char *to); +int decode_xfer_write (char *buf, int packet_len, char **annex, + CORE_ADDR *offset, unsigned int *len, + unsigned char *data); int unhexify (char *bin, const char *hex, int count); int hexify (char *hex, const char *bin, int count); diff --git a/gdb/gdbserver/spu-low.c b/gdb/gdbserver/spu-low.c index 4d88833..b747a53 100644 --- a/gdb/gdbserver/spu-low.c +++ b/gdb/gdbserver/spu-low.c @@ -574,7 +574,6 @@ spu_arch_string (void) return "spu"; } - static struct target_ops spu_target_ops = { spu_create_inferior, spu_attach, @@ -598,6 +597,7 @@ static struct target_ops spu_target_ops = { NULL, NULL, spu_arch_string, + spu_proc_xfer_spu, }; void diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h index 66511c9..14d0e95 100644 --- a/gdb/gdbserver/target.h +++ b/gdb/gdbserver/target.h @@ -185,6 +185,10 @@ struct target_ops /* Return a string identifying the current architecture, or NULL if this operation is not supported. */ const char *(*arch_string) (void); + + /* Read/Write from/to spufs using qXfer packets. */ + int (*qxfer_spu) (const char *annex, unsigned char *readbuf, + unsigned const char *writebuf, CORE_ADDR offset, int len); }; extern struct target_ops *the_target; |