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'.
This commit is contained in:
parent
b78974c3b4
commit
c21236dc75
6 changed files with 117 additions and 22 deletions
|
@ -1,3 +1,17 @@
|
|||
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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
69
gdb/remote.c
69
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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue