From c21236dc7563a54e2de9a8edd11ec697cd112a66 Mon Sep 17 00:00:00 2001 From: Pedro Alves Date: Wed, 20 Apr 2011 17:54:08 +0000 Subject: [PATCH] 2011-04-20 Pedro Alves gdb/ * regcache.c: Include remote.h. (enum regcache_dump_what) : 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 | 14 +++++++++ gdb/doc/ChangeLog | 5 ++++ gdb/doc/gdb.texinfo | 14 +++++---- gdb/regcache.c | 33 +++++++++++++++++++++- gdb/remote.c | 69 ++++++++++++++++++++++++++++++++++----------- gdb/remote.h | 4 +++ 6 files changed, 117 insertions(+), 22 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 96b1c8991b..aac555332f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2011-04-20 Pedro Alves + + * regcache.c: Include remote.h. + (enum regcache_dump_what) : 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 * regcache.c (get_thread_arch_regcache): If creating a regcache for diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog index 4115b7b323..88e5fffc64 100644 --- a/gdb/doc/ChangeLog +++ b/gdb/doc/ChangeLog @@ -1,3 +1,8 @@ +2011-04-20 Pedro Alves + + * gdb.texinfo (Maintenance Commands): Document `maint print + remote-registers'. + 2011-04-20 Tom Tromey * gdb.texinfo (Trace File Format): Move node later. diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 387227c558..a48dac0b37 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -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 diff --git a/gdb/regcache.c b/gdb/regcache.c index 8b4d77ccc0..f603c331d1 100644 --- a/gdb/regcache.c +++ b/gdb/regcache.c @@ -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); } diff --git a/gdb/remote.c b/gdb/remote.c index ac9d9cedd4..fdb4573436 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -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 = ®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 *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++] = ®s[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 diff --git a/gdb/remote.h b/gdb/remote.h index 25f5ccc26c..fae7f25d15 100644 --- a/gdb/remote.h +++ b/gdb/remote.h @@ -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 -- 2.34.1