2011-04-20 Pedro Alves <pedro@codesourcery.com>
authorPedro Alves <palves@redhat.com>
Wed, 20 Apr 2011 17:54:08 +0000 (17:54 +0000)
committerPedro Alves <palves@redhat.com>
Wed, 20 Apr 2011 17:54:08 +0000 (17:54 +0000)
gdb/
* regcache.c: Include remote.h.
(enum regcache_dump_what) <regcache_dump_remote>: New enum value.
(regcache_dump): Handle regcache_dump_remote.
(maintenance_print_remote_registers): New function.
(_initialize_regcache): Install "maint print remote-registers"
command.
* remote.c (map_regcache_remote_table): New function, factored out
from ...
(init_remote_state): ... here.
(remote_register_number_and_offset): New.
* remote.h (remote_register_number_and_offset): Declare.

gdb/doc/
* gdb.texinfo (Maintenance Commands): Document `maint print
remote-registers'.

gdb/ChangeLog
gdb/doc/ChangeLog
gdb/doc/gdb.texinfo
gdb/regcache.c
gdb/remote.c
gdb/remote.h

index 96b1c89..aac5553 100644 (file)
@@ -1,5 +1,19 @@
 2011-04-20  Pedro Alves  <pedro@codesourcery.com>
 
+       * regcache.c: Include remote.h.
+       (enum regcache_dump_what) <regcache_dump_remote>: New enum value.
+       (regcache_dump): Handle regcache_dump_remote.
+       (maintenance_print_remote_registers): New function.
+       (_initialize_regcache): Install "maint print remote-registers"
+       command.
+       * remote.c (map_regcache_remote_table): New function, factored out
+       from ...
+       (init_remote_state): ... here.
+       (remote_register_number_and_offset): New.
+       * remote.h (remote_register_number_and_offset): Declare.
+
+2011-04-20  Pedro Alves  <pedro@codesourcery.com>
+
        * regcache.c (get_thread_arch_regcache): If creating a regcache for
        null_ptid, assume and allow a NULL address space, instead of
        asking the target for the ptid's address space.
index 4115b7b..88e5fff 100644 (file)
@@ -1,3 +1,8 @@
+2011-04-20  Pedro Alves  <pedro@codesourcery.com>
+
+       * gdb.texinfo (Maintenance Commands): Document `maint print
+       remote-registers'.
+
 2011-04-20  Tom Tromey  <tromey@redhat.com>
 
        * gdb.texinfo (Trace File Format): Move node later.
index 387227c..a48dac0 100644 (file)
@@ -31678,18 +31678,22 @@ Takes an optional file parameter.
 @kindex maint print raw-registers
 @kindex maint print cooked-registers
 @kindex maint print register-groups
+@kindex maint print remote-registers
 @item maint print registers @r{[}@var{file}@r{]}
 @itemx maint print raw-registers @r{[}@var{file}@r{]}
 @itemx maint print cooked-registers @r{[}@var{file}@r{]}
 @itemx maint print register-groups @r{[}@var{file}@r{]}
+@itemx maint print remote-registers @r{[}@var{file}@r{]}
 Print @value{GDBN}'s internal register data structures.
 
 The command @code{maint print raw-registers} includes the contents of
-the raw register cache; the command @code{maint print cooked-registers}
-includes the (cooked) value of all registers, including registers which
-aren't available on the target nor visible to user; and the
-command @code{maint print register-groups} includes the groups that each
-register is a member of.  @xref{Registers,, Registers, gdbint,
+the raw register cache; the command @code{maint print
+cooked-registers} includes the (cooked) value of all registers,
+including registers which aren't available on the target nor visible
+to user; the command @code{maint print register-groups} includes the
+groups that each register is a member of; and the command @code{maint
+print remote-registers} includes the remote target's register numbers
+and offsets in the `G' packets.  @xref{Registers,, Registers, gdbint,
 @value{GDBN} Internals}.
 
 These commands take an optional parameter, a file name to which to
index 8b4d77c..f603c33 100644 (file)
@@ -30,6 +30,7 @@
 #include "gdbcmd.h"            /* For maintenanceprintlist.  */
 #include "observer.h"
 #include "exceptions.h"
+#include "remote.h"
 
 /*
  * DATA STRUCTURE
@@ -1053,7 +1054,8 @@ dump_endian_bytes (struct ui_file *file, enum bfd_endian endian,
 enum regcache_dump_what
 {
   regcache_dump_none, regcache_dump_raw,
-  regcache_dump_cooked, regcache_dump_groups
+  regcache_dump_cooked, regcache_dump_groups,
+  regcache_dump_remote
 };
 
 static void
@@ -1251,6 +1253,23 @@ regcache_dump (struct regcache *regcache, struct ui_file *file,
            }
        }
 
+      /* Remote packet configuration.  */
+      if (what_to_dump == regcache_dump_remote)
+       {
+         if (regnum < 0)
+           {
+             fprintf_unfiltered (file, "Rmt Nr  g/G Offset");
+           }
+         else if (regnum < regcache->descr->nr_raw_registers)
+           {
+             int pnum, poffset;
+
+             if (remote_register_number_and_offset (get_regcache_arch (regcache), regnum,
+                                                    &pnum, &poffset))
+               fprintf_unfiltered (file, "%7d %11d", pnum, poffset);
+           }
+       }
+
       fprintf_unfiltered (file, "\n");
     }
 
@@ -1309,6 +1328,12 @@ maintenance_print_register_groups (char *args, int from_tty)
   regcache_print (args, regcache_dump_groups);
 }
 
+static void
+maintenance_print_remote_registers (char *args, int from_tty)
+{
+  regcache_print (args, regcache_dump_remote);
+}
+
 extern initialize_file_ftype _initialize_regcache; /* -Wmissing-prototype */
 
 void
@@ -1342,5 +1367,11 @@ _initialize_regcache (void)
             "including each register's group.\n"
             "Takes an optional file parameter."),
           &maintenanceprintlist);
+  add_cmd ("remote-registers", class_maintenance,
+          maintenance_print_remote_registers, _("\
+Print the internal register configuration including each register's\n\
+remote register number and buffer offset in the g/G packets.\n\
+Takes an optional file parameter."),
+          &maintenanceprintlist);
 
 }
index ac9d9ce..fdb4573 100644 (file)
@@ -535,24 +535,15 @@ compare_pnums (const void *lhs_, const void *rhs_)
     return 1;
 }
 
-static void *
-init_remote_state (struct gdbarch *gdbarch)
+static int
+map_regcache_remote_table (struct gdbarch *gdbarch, struct packet_reg *regs)
 {
   int regnum, num_remote_regs, offset;
-  struct remote_state *rs = get_remote_state_raw ();
-  struct remote_arch_state *rsa;
   struct packet_reg **remote_regs;
 
-  rsa = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_arch_state);
-
-  /* Use the architecture to build a regnum<->pnum table, which will be
-     1:1 unless a feature set specifies otherwise.  */
-  rsa->regs = GDBARCH_OBSTACK_CALLOC (gdbarch,
-                                     gdbarch_num_regs (gdbarch),
-                                     struct packet_reg);
   for (regnum = 0; regnum < gdbarch_num_regs (gdbarch); regnum++)
     {
-      struct packet_reg *r = &rsa->regs[regnum];
+      struct packet_reg *r = &regs[regnum];
 
       if (register_size (gdbarch, regnum) == 0)
        /* Do not try to fetch zero-sized (placeholder) registers.  */
@@ -568,12 +559,12 @@ init_remote_state (struct gdbarch *gdbarch)
      number.  */
 
   remote_regs = alloca (gdbarch_num_regs (gdbarch)
-                         * sizeof (struct packet_reg *));
+                       * sizeof (struct packet_reg *));
   for (num_remote_regs = 0, regnum = 0;
        regnum < gdbarch_num_regs (gdbarch);
        regnum++)
-    if (rsa->regs[regnum].pnum != -1)
-      remote_regs[num_remote_regs++] = &rsa->regs[regnum];
+    if (regs[regnum].pnum != -1)
+      remote_regs[num_remote_regs++] = &regs[regnum];
 
   qsort (remote_regs, num_remote_regs, sizeof (struct packet_reg *),
         compare_pnums);
@@ -585,9 +576,55 @@ init_remote_state (struct gdbarch *gdbarch)
       offset += register_size (gdbarch, remote_regs[regnum]->regnum);
     }
 
+  return offset;
+}
+
+/* Given the architecture described by GDBARCH, return the remote
+   protocol register's number and the register's offset in the g/G
+   packets of GDB register REGNUM, in PNUM and POFFSET respectively.
+   If the target does not have a mapping for REGNUM, return false,
+   otherwise, return true.  */
+
+int
+remote_register_number_and_offset (struct gdbarch *gdbarch, int regnum,
+                                  int *pnum, int *poffset)
+{
+  int sizeof_g_packet;
+  struct packet_reg *regs;
+  struct cleanup *old_chain;
+
+  gdb_assert (regnum < gdbarch_num_regs (gdbarch));
+
+  regs = xcalloc (gdbarch_num_regs (gdbarch), sizeof (struct packet_reg));
+  old_chain = make_cleanup (xfree, regs);
+
+  sizeof_g_packet = map_regcache_remote_table (gdbarch, regs);
+
+  *pnum = regs[regnum].pnum;
+  *poffset = regs[regnum].offset;
+
+  do_cleanups (old_chain);
+
+  return *pnum != -1;
+}
+
+static void *
+init_remote_state (struct gdbarch *gdbarch)
+{
+  struct remote_state *rs = get_remote_state_raw ();
+  struct remote_arch_state *rsa;
+
+  rsa = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct remote_arch_state);
+
+  /* Use the architecture to build a regnum<->pnum table, which will be
+     1:1 unless a feature set specifies otherwise.  */
+  rsa->regs = GDBARCH_OBSTACK_CALLOC (gdbarch,
+                                     gdbarch_num_regs (gdbarch),
+                                     struct packet_reg);
+
   /* Record the maximum possible size of the g packet - it may turn out
      to be smaller.  */
-  rsa->sizeof_g_packet = offset;
+  rsa->sizeof_g_packet = map_regcache_remote_table (gdbarch, rsa->regs);
 
   /* Default maximum number of characters in a packet body.  Many
      remote stubs have a hardwired buffer size of 400 bytes
index 25f5ccc..fae7f25 100644 (file)
@@ -56,4 +56,8 @@ bfd *remote_bfd_open (const char *remote_file, const char *target);
 
 int remote_filename_p (const char *filename);
 
+extern int remote_register_number_and_offset (struct gdbarch *gdbarch,
+                                             int regnum, int *pnum,
+                                             int *poffset);
+
 #endif