[RFC] Info registers command produces no output for "standard register names"

Fred Fish
2005-05-27T21:38:05Z

The "info register sp" command prints no output of any kind, not even
a message that this is not supported. Same thing for the other "user
registers" (fp, pc, ps).

For example, run any executable to a breakpoint and try "info register sp".

(gdb) br main
Breakpoint 1 at 0x8048350: file t.c, line 3.
(gdb) run
Starting program: /links/build/sourceware/gdb/i686-pc-linux-gnu/gdb/t

Breakpoint 1, main () at t.c:3
3 }
(gdb) info register sp
(gdb) info register esp
esp 0xbffff5d0 0xbffff5d0
(gdb)

The attached patch fixes the problem, but may or may not be the best
way to deal with the issue. Perhaps gdb should simply say that info
registers only supports printing using the canonical mnemonics for
registers (to use the terms in the gdb documentation).

This is reported as gdb bug #1926:

http://sources.redhat.com/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gdb&pr=1926

-Fred

============================================================================

2005-05-27 Fred Fish <fnf@specifixinc.com>
* user-regs.h (default_print_user_registers_info): Declare.
* user-regs.c: Include value.h and regcache.h.
(default_print_user_registers_info): New function.
* infcmd.c: Include user-regs.h.
(default_print_registers_info): Handle user registers by
calling default_print_user_registers_info.

Index: infcmd.c
===================================================================
RCS file: /cvs/src/src/gdb/infcmd.c,v
retrieving revision 1.136
diff -c -p -r1.136 infcmd.c
*** infcmd.c 8 Mar 2005 22:17:34 -0000 1.136
--- infcmd.c 25 Apr 2005 14:25:39 -0000
***************
*** 46,51 ****
--- 46,52 ----
#include "block.h"
#include <ctype.h>
#include "gdb_assert.h"
+ #include "user-regs.h"

/* Functions exported for general use, in inferior.h: */

*************** default_print_registers_info (struct gdb
*** 1525,1530 ****
--- 1526,1538 ----
const int numregs = NUM_REGS + NUM_PSEUDO_REGS;
char buffer[MAX_REGISTER_SIZE];

+ /* If this is a user register, try to print it */
+ if (regnum >= numregs)
+ {
+ default_print_user_registers_info (gdbarch, file, frame, regnum);
+ return;
+ }
+
for (i = 0; i < numregs; i++)
{
/* Decide between printing all regs, non-float / vector regs, or
Index: user-regs.c
===================================================================
RCS file: /cvs/src/src/gdb/user-regs.c,v
retrieving revision 1.5
diff -c -p -r1.5 user-regs.c
*** user-regs.c 15 Mar 2004 20:38:08 -0000 1.5
--- user-regs.c 25 Apr 2005 14:25:39 -0000
***************
*** 27,32 ****
--- 27,34 ----
#include "gdb_string.h"
#include "gdb_assert.h"
#include "frame.h"
+ #include "value.h"
+ #include "regcache.h"

/* A table of user registers.

*************** value_of_user_reg (int regnum, struct fr
*** 202,207 ****
--- 204,251 ----
return reg->read (frame);
}

+ /* Print user register in same format as "info registers" so natural
+ things like "info register sp" works as expected.
+
+ FIXME: Assumes size and type of user reg is same as size of first
+ architecture register.
+
+ FIXME: Needs to track any changes in default_print_registers_info
+ formatting. */
+
+ void
+ default_print_user_registers_info (struct gdbarch *gdbarch,
+ struct ui_file *file,
+ struct frame_info *frame,
+ int regnum)
+ {
+ const char *regname;
+ char raw_buffer[MAX_REGISTER_SIZE];
+ struct value *regval;
+ struct type *regtype;
+ int regsize;
+
+ regname = user_reg_map_regnum_to_name (gdbarch, regnum);
+ fputs_filtered (regname, file);
+ print_spaces_filtered (15 - strlen (regname), file);
+
+ regval = value_of_user_reg (regnum, frame);
+ if (! regval)
+ {
+ fprintf_filtered (file, "*value not available*\n");
+ }
+ else
+ {
+ regtype = register_type (gdbarch, 0); /* FIXME */
+ regsize = register_size (gdbarch, 0); /* FIXME */
+ memcpy (raw_buffer, value_contents_raw (regval), regsize);
+ val_print (regtype, raw_buffer, 0, 0, file, 'x', 1, 0, Val_pretty_default);
+ fprintf_filtered (file, "\t");
+ val_print (regtype, raw_buffer, 0, 0, file, 0, 1, 0, Val_pretty_default);
+ fprintf_filtered (file, "\n");
+ }
+ }
+
extern initialize_file_ftype _initialize_user_regs; /* -Wmissing-prototypes */

void
Index: user-regs.h
===================================================================
RCS file: /cvs/src/src/gdb/user-regs.h,v
retrieving revision 1.2
diff -c -p -r1.2 user-regs.h
*** user-regs.h 18 Jul 2003 19:01:14 -0000 1.2
--- user-regs.h 25 Apr 2005 14:25:39 -0000
***************
*** 37,43 ****
/* TODO: cagney/2003-06-27: Need to think more about how these
registers are added, read, and modified. At present they are kind
of assumed to be read-only. Should it, for instance, return a
! register descriptor that contains all the relvent access methods. */

struct frame_info;
struct gdbarch;
--- 37,43 ----
/* TODO: cagney/2003-06-27: Need to think more about how these
registers are added, read, and modified. At present they are kind
of assumed to be read-only. Should it, for instance, return a
! register descriptor that contains all the relevent access methods. */

struct frame_info;
struct gdbarch;
*************** extern const char *user_reg_map_regnum_t
*** 55,65 ****

Note; These methods return a "struct value" instead of the raw
bytes as, at the time the register is being added, the type needed
! to describe the register has not bee initialized. */

typedef struct value *(user_reg_read_ftype) (struct frame_info *frame);
extern struct value *value_of_user_reg (int regnum, struct frame_info *frame);

/* Add a builtin register (present in all architectures). */
extern void user_reg_add_builtin (const char *name,
user_reg_read_ftype *read);
--- 55,71 ----

Note; These methods return a "struct value" instead of the raw
bytes as, at the time the register is being added, the type needed
! to describe the register has not been initialized. */

typedef struct value *(user_reg_read_ftype) (struct frame_info *frame);
extern struct value *value_of_user_reg (int regnum, struct frame_info *frame);

+ /* Print user register in same format as "info registers". */
+ extern void default_print_user_registers_info (struct gdbarch *gdbarch,
+ struct ui_file *file,
+ struct frame_info *frame,
+ int regnum);
+
/* Add a builtin register (present in all architectures). */
extern void user_reg_add_builtin (const char *name,
user_reg_read_ftype *read);