aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
authorUlrich Weigand <uweigand@de.ibm.com>2007-06-12 14:38:32 +0000
committerUlrich Weigand <uweigand@de.ibm.com>2007-06-12 14:38:32 +0000
commit0e7f50da78982a93a4603cddbb2e0c07019e9c1a (patch)
treea928a4426efc054ce836def5815ef3d3f8783fc1 /gdb/gdbserver
parent23d964e7b6625bec3822bcb9613f65362b9b3026 (diff)
downloadgdb-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/ChangeLog11
-rw-r--r--gdb/gdbserver/remote-utils.c30
-rw-r--r--gdb/gdbserver/server.c72
-rw-r--r--gdb/gdbserver/server.h3
-rw-r--r--gdb/gdbserver/spu-low.c2
-rw-r--r--gdb/gdbserver/target.h4
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;