This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFA] new "maint print remote-registers" command
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Wed, 20 Apr 2011 18:29:35 +0100
- Subject: [RFA] new "maint print remote-registers" command
This adds a new variant of "maint print registers",
that prints what the remote register numbers are, compared
to the internal regcache numbers, and what the offset of
the raw registers is in the layout of the g/G packets.
Here's an example:
(gdb) maint print remote-registers
Name Nr Rel Offset Size Type Rmt Nr g/G Offset
r0 0 0 0 4 long 0 0
r1 1 1 4 4 long 1 4
r2 2 2 8 4 long 2 8
r3 3 3 12 4 long 3 12
r4 4 4 16 4 long 4 16
r5 5 5 20 4 long 5 20
r6 6 6 24 4 long 6 24
r7 7 7 28 4 long 7 28
r8 8 8 32 4 long 8 32
r9 9 9 36 4 long 9 36
r10 10 10 40 4 long 10 40
r11 11 11 44 4 long 11 44
r12 12 12 48 4 long 12 48
sp 13 13 52 4 *1 13 52
lr 14 14 56 4 long 14 56
pc 15 15 60 4 *1 15 60
'' 16 16 64 0 int0_t
'' 17 17 64 0 int0_t
'' 18 18 64 0 int0_t
'' 19 19 64 0 int0_t
'' 20 20 64 0 int0_t
'' 21 21 64 0 int0_t
'' 22 22 64 0 int0_t
'' 23 23 64 0 int0_t
'' 24 24 64 0 int0_t
xpsr 25 25 64 4 long 25 164
'' 26 26 68 0 int0_t
'' 27 27 68 0 int0_t
'' 28 28 68 0 int0_t
'' 29 29 68 0 int0_t
'' 30 30 68 0 int0_t
'' 31 31 68 0 int0_t
'' 32 32 68 0 int0_t
'' 33 33 68 0 int0_t
'' 34 34 68 0 int0_t
'' 35 35 68 0 int0_t
'' 36 36 68 0 int0_t
'' 37 37 68 0 int0_t
'' 38 38 68 0 int0_t
'' 39 39 68 0 int0_t
'' 40 40 68 0 int0_t
'' 41 41 68 0 int0_t
'' 42 42 68 0 int0_t
'' 43 43 68 0 int0_t
'' 44 44 68 0 int0_t
'' 45 45 68 0 int0_t
'' 46 46 68 0 int0_t
'' 47 47 68 0 int0_t
'' 48 48 68 0 int0_t
'' 49 49 68 0 int0_t
'' 50 50 68 0 int0_t
'' 51 51 68 0 int0_t
'' 52 52 68 0 int0_t
'' 53 53 68 0 int0_t
'' 54 54 68 0 int0_t
'' 55 55 68 0 int0_t
'' 56 56 68 0 int0_t
'' 57 57 68 0 int0_t
'' 58 58 68 0 int0_t
'' 59 59 68 0 int0_t
'' 60 60 68 0 int0_t
'' 61 61 68 0 int0_t
'' 62 62 68 0 int0_t
'' 63 63 68 0 int0_t
'' 64 64 68 0 int0_t
'' 65 65 68 0 int0_t
'' 66 66 68 0 int0_t
'' 67 67 68 0 int0_t
'' 68 68 68 0 int0_t
'' 69 69 68 0 int0_t
'' 70 70 68 0 int0_t
'' 71 71 68 0 int0_t
'' 72 72 68 0 int0_t
'' 73 73 68 0 int0_t
'' 74 74 68 0 int0_t
'' 75 75 68 0 int0_t
'' 76 76 68 0 int0_t
'' 77 77 68 0 int0_t
'' 78 78 68 0 int0_t
'' 79 79 68 0 int0_t
'' 80 80 68 0 int0_t
'' 81 81 68 0 int0_t
'' 82 82 68 0 int0_t
'' 83 83 68 0 int0_t
'' 84 84 68 0 int0_t
'' 85 85 68 0 int0_t
'' 86 86 68 0 int0_t
'' 87 87 68 0 int0_t
'' 88 88 68 0 int0_t
'' 89 89 68 0 int0_t
'' 90 90 68 0 int0_t
'' 91 91 68 12 _arm_ext 16 64
'' 92 92 80 12 _arm_ext 17 76
'' 93 93 92 12 _arm_ext 18 88
'' 94 94 104 12 _arm_ext 19 100
'' 95 95 116 12 _arm_ext 20 112
'' 96 96 128 12 _arm_ext 21 124
'' 97 97 140 12 _arm_ext 22 136
'' 98 98 152 12 _arm_ext 23 148
'' 99 99 164 4 long 24 160
*1: Register type's name NULL.
(gdb)
Implementation-wise, I'm rebuilding the remote g/G packet layout
once for each register, but not doing that would require exporting
more from remote.c's internals than I'd like. It's not like there's
an architecture out there that has so many registers one would
notice. :-)
Do the docs changes look okay?
Pedro Alves
2011-04-20 Pedro Alves <pedro@codesourcery.com>
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/doc/gdb.texinfo | 14 ++++++----
gdb/regcache.c | 33 ++++++++++++++++++++++++
gdb/remote.c | 69 +++++++++++++++++++++++++++++++++++++++-------------
gdb/remote.h | 4 +++
4 files changed, 98 insertions(+), 22 deletions(-)
Index: src/gdb/regcache.c
===================================================================
--- src.orig/gdb/regcache.c 2011-04-20 18:14:11.466406001 +0100
+++ src/gdb/regcache.c 2011-04-20 18:17:45.686406001 +0100
@@ -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 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
}
}
+ /* 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
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: src/gdb/remote.c
===================================================================
--- src.orig/gdb/remote.c 2011-04-20 16:56:34.906406000 +0100
+++ src/gdb/remote.c 2011-04-20 18:27:02.035266005 +0100
@@ -535,24 +535,15 @@ compare_pnums (const void *lhs_, const v
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 = ®s[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 *gdbar
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++] = ®s[regnum];
qsort (remote_regs, num_remote_regs, sizeof (struct packet_reg *),
compare_pnums);
@@ -585,9 +576,55 @@ init_remote_state (struct gdbarch *gdbar
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: src/gdb/remote.h
===================================================================
--- src.orig/gdb/remote.h 2011-04-20 16:56:34.906406000 +0100
+++ src/gdb/remote.h 2011-04-20 18:14:27.816406002 +0100
@@ -56,4 +56,8 @@ bfd *remote_bfd_open (const char *remote
int remote_filename_p (const char *filename);
+extern int remote_register_number_and_offset (struct gdbarch *gdbarch,
+ int regnum, int *pnum,
+ int *poffset);
+
#endif
Index: src/gdb/doc/gdb.texinfo
===================================================================
--- src.orig/gdb/doc/gdb.texinfo 2011-04-20 16:56:34.906406000 +0100
+++ src/gdb/doc/gdb.texinfo 2011-04-20 18:14:27.866406002 +0100
@@ -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