ChangeLog:
authorUlrich Weigand <uweigand@de.ibm.com>
Tue, 12 Jun 2007 14:38:32 +0000 (14:38 +0000)
committerUlrich Weigand <uweigand@de.ibm.com>
Tue, 12 Jun 2007 14:38:32 +0000 (14:38 +0000)
* 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.

gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/gdbserver/ChangeLog
gdb/gdbserver/remote-utils.c
gdb/gdbserver/server.c
gdb/gdbserver/server.h
gdb/gdbserver/spu-low.c
gdb/gdbserver/target.h
gdb/remote.c

index 0d16e47cdaa4195bdb4800f1c28162a0eb896b81..d35b3abe492ce6ca4437c8aa6c5305b0139f4d9c 100644 (file)
@@ -1,3 +1,12 @@
+2007-06-12  Ulrich Weigand  <uweigand@de.ibm.com>
+           Markus Deuling  <deuling@de.ibm.com>
+
+       * 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.
+
 2007-06-12  Ulrich Weigand  <uweigand@de.ibm.com>
 
        * target.h (enum target_object): Add TARGET_OBJECT_SPU.
index 7a73f3bf03175ef07c26707e0bbdd0c1668b6f4d..7c1850d3d686cb6d9a010c4f92a43dcd2c3a516e 100644 (file)
@@ -1,3 +1,9 @@
+2007-06-12  Ulrich Weigand  <uweigand@de.ibm.com>
+           Markus Deuling  <deuling@de.ibm.com>
+
+       * gdb.texinfo (General Query Packets): Document qXfer:spu:read
+       and qXfer:spu:write packets and mention them under qSupported.
+
 2007-06-12  Ulrich Weigand  <uweigand@de.ibm.com>
            Markus Deuling  <deuling@de.ibm.com>
 
index 0641386870cc4aa8dde1b7349654853addc7c7bd..5a3b0a99d71f17f2431e06d8cd7375efea495ab4 100644 (file)
@@ -23634,6 +23634,16 @@ These are the currently defined stub features and their properties:
 @tab @samp{-}
 @tab Yes
 
+@item @samp{qXfer:spu:read}
+@tab No
+@tab @samp{-}
+@tab Yes
+
+@item @samp{qXfer:spu:write}
+@tab No
+@tab @samp{-}
+@tab Yes
+
 @item @samp{QPassSignals}
 @tab No
 @tab @samp{-}
@@ -23667,6 +23677,14 @@ The remote stub understands the @samp{qXfer:features:read} packet
 The remote stub understands the @samp{qXfer:memory-map:read} packet
 (@pxref{qXfer memory map read}).
 
+@item qXfer:spu:read
+The remote stub understands the @samp{qXfer:spu:read} packet
+(@pxref{qXfer spu read}).
+
+@item qXfer:spu:write
+The remote stub understands the @samp{qXfer:spu:write} packet
+(@pxref{qXfer spu write}).
+
 @item QPassSignals
 The remote stub understands the @samp{QPassSignals} packet
 (@pxref{QPassSignals}).
@@ -23752,7 +23770,7 @@ packets.)
 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
+encoding of @var{annex} is specific to @var{object}; it can supply
 additional details about what data to access.
 
 Here are the specific requests of this form defined so far.  All
@@ -23783,6 +23801,17 @@ Access the target's @dfn{memory-map}.  @xref{Memory Map Format}.  The
 annex part of the generic @samp{qXfer} packet must be empty
 (@pxref{qXfer read}).
 
+This packet is not probed by default; the remote stub must request it,
+by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}).
+
+@item qXfer:spu:read:@var{annex}:@var{offset},@var{length}
+@anchor{qXfer spu read}
+Read contents of an @code{spufs} file on the target system.  The
+annex specifies which file to read; it must be of the form 
+@file{@var{id}/@var{name}}, where @var{id} specifies an SPU context ID
+in the target process, and @var{name} identifes the @code{spufs} file
+in that context to be accessed.
+
 This packet is not probed by default; the remote stub must request it,
 by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}).
 @end table
@@ -23822,14 +23851,27 @@ the stub, or that the object does not support reading.
 @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
+into the data.  @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
+is specific to @var{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.
+Here are the specific requests of this form defined so far.  All
+@samp{qXfer:@var{object}:write:@dots{}} requests use the same reply
+formats, listed below.
+
+@table @samp
+@item qXfer:@var{spu}:write:@var{annex}:@var{offset}:@var{data}@dots{}
+@anchor{qXfer spu write}
+Write @var{data} to an @code{spufs} file on the target system.  The
+annex specifies which file to write; it must be of the form
+@file{@var{id}/@var{name}}, where @var{id} specifies an SPU context ID
+in the target process, and @var{name} identifes the @code{spufs} file
+in that context to be accessed.
+
+This packet is not probed by default; the remote stub must request it,
+by supplying an appropriate @samp{qSupported} response (@pxref{qSupported}).
+@end table
 
 Reply:
 @table @samp
index c9229898e6b668e6cdf3035de4d8de658559dd87..994fe8d53e659f9253fdef542e308f1ab5429319 100644 (file)
@@ -1,3 +1,14 @@
+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
index 505e37c907d2f1847815de25f320cf967558c683..95591487ecdce79c957b7d493effe44690aa18d7 100644 (file)
@@ -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.  */
 
index 52b1e8d1ef8fba9e50d571e73080dacfea123fb9..bee1256403c37485a896a49d4cb094345ceb8da1 100644 (file)
@@ -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);
index b1ff238f4d6b873e5f396e0a8fb1bb173e5b6655..573bde28935ba2154b395e2745e6750320073874 100644 (file)
@@ -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);
index 4d888331ff6ba70bf4feaba116bede07124c2941..b747a5367800aca75567da83a0fc7b861bda555a 100644 (file)
@@ -574,7 +574,6 @@ spu_arch_string (void)
   return "spu";
 }
 
-\f
 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
index 66511c90b5838670a79be8045728dec98a3d9149..14d0e957029da5f1896548d6f676e0db80038ed1 100644 (file)
@@ -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;
index 4662437ef43c1a79098a7edac2551b4e8f7d37f3..2635857b25f3e99bd84358c3a6280be4beb4de6c 100644 (file)
@@ -908,6 +908,8 @@ enum {
   PACKET_qXfer_auxv,
   PACKET_qXfer_features,
   PACKET_qXfer_memory_map,
+  PACKET_qXfer_spu_read,
+  PACKET_qXfer_spu_write,
   PACKET_qGetTLSAddr,
   PACKET_qSupported,
   PACKET_QPassSignals,
@@ -5516,6 +5518,45 @@ the loaded file\n"));
     printf_filtered (_("No loaded section named '%s'.\n"), args);
 }
 
+/* Write LEN bytes from WRITEBUF into OBJECT_NAME/ANNEX at OFFSET
+   into remote target.  The number of bytes written to the remote
+   target is returned, or -1 for error.  */
+
+static LONGEST
+remote_write_qxfer (struct target_ops *ops, const char *object_name,
+                    const char *annex, const gdb_byte *writebuf, 
+                    ULONGEST offset, LONGEST len, 
+                    struct packet_config *packet)
+{
+  int i, buf_len;
+  ULONGEST n;
+  gdb_byte *wbuf;
+  struct remote_state *rs = get_remote_state ();
+  int max_size = get_memory_write_packet_size (); 
+
+  if (packet->support == PACKET_DISABLE)
+    return -1;
+
+  /* Insert header.  */
+  i = snprintf (rs->buf, max_size, 
+               "qXfer:%s:write:%s:%s:",
+               object_name, annex ? annex : "",
+               phex_nz (offset, sizeof offset));
+  max_size -= (i + 1);
+
+  /* Escape as much data as fits into rs->buf.  */
+  buf_len = remote_escape_output 
+    (writebuf, len, (rs->buf + i), &max_size, max_size);
+
+  if (putpkt_binary (rs->buf, i + buf_len) < 0
+      || getpkt_sane (&rs->buf, &rs->buf_size, 0) < 0
+      || packet_ok (rs->buf, packet) != PACKET_OK)
+    return -1;
+
+  unpack_varlen_hex (rs->buf, &n);
+  return n;
+}
+
 /* 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.
@@ -5588,9 +5629,9 @@ remote_read_qxfer (struct target_ops *ops, const char *object_name,
   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')
+     or possibly empty.  If we have the final block of a non-empty
+     object, record this fact to bypass a subsequent partial read.  */
+  if (rs->buf[0] == 'l' && offset + i > 0)
     {
       finished_object = xstrdup (object_name);
       finished_annex = xstrdup (annex ? annex : "");
@@ -5629,6 +5670,19 @@ remote_xfer_partial (struct target_ops *ops, enum target_object object,
        return -1;
     }
 
+  /* Handle SPU memory using qxfer packets. */
+  if (object == TARGET_OBJECT_SPU)
+    {
+      if (readbuf)
+       return remote_read_qxfer (ops, "spu", annex, readbuf, offset, len,
+                                 &remote_protocol_packets
+                                   [PACKET_qXfer_spu_read]);
+      else
+       return remote_write_qxfer (ops, "spu", annex, writebuf, offset, len,
+                                  &remote_protocol_packets
+                                    [PACKET_qXfer_spu_write]);
+    }
+
   /* Only handle flash writes.  */
   if (writebuf != NULL)
     {
@@ -6539,6 +6593,12 @@ Show the maximum size of the address (in bits) in a memory packet."), NULL,
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_memory_map],
                         "qXfer:memory-map:read", "memory-map", 0);
 
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_spu_read],
+                         "qXfer:spu:read", "read-spu-object", 0);
+
+  add_packet_config_cmd (&remote_protocol_packets[PACKET_qXfer_spu_write],
+                         "qXfer:spu:write", "write-spu-object", 0);
+
   add_packet_config_cmd (&remote_protocol_packets[PACKET_qGetTLSAddr],
                         "qGetTLSAddr", "get-thread-local-storage-address",
                         0);