From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20192 invoked by alias); 28 May 2005 18:07:12 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 19653 invoked by uid 22791); 28 May 2005 18:07:04 -0000 Received: from nevyn.them.org (HELO nevyn.them.org) (66.93.172.17) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Sat, 28 May 2005 18:07:04 +0000 Received: from drow by nevyn.them.org with local (Exim 4.50) id 1Dc5i5-0002ga-Tw; Sat, 28 May 2005 14:06:58 -0400 Date: Sat, 28 May 2005 18:39:00 -0000 From: Daniel Jacobowitz To: Fred Fish Cc: gdb-patches@sources.redhat.com Subject: Re: [RFC] Info registers command produces no output for "standard register names" Message-ID: <20050528180657.GC26806@nevyn.them.org> Mail-Followup-To: Fred Fish , gdb-patches@sources.redhat.com References: <200505271737.58430.fnf@specifixinc.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200505271737.58430.fnf@specifixinc.com> User-Agent: Mutt/1.5.8i X-SW-Source: 2005-05/txt/msg00583.txt.bz2 On Fri, May 27, 2005 at 05:37:58PM -0400, Fred Fish wrote: > 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). Well, I agree that we shouldn't leave it the way it is. The final result should be more-or-less consistent across targets; it looks like every target with its own print_registers_info method will already do this. I only tested MIPS. Your patch is overcomplicated for the problem. The value of a user register _can_ be read by value_of_user_reg, but it can also be read just like any other register. The only reason there's a problem is that we iterate in [0, NUM_REGS + NUM_PSEUDO_REGS) and the user registers are numbered outside that range. Hmm, and we need a different hook to get the register name. How do you feel about this patch instead? It brings the default implementation in line with the few specializations; if you ask fo the value of a user register, that's what you get. While proofreading I noticed that some targets will issue an internal error if you try to do this - for example SH. There needs to be a test case for this; I'm not going to commit the patch until I've done that. However, the patch has raised some questions for me about register names... the fact that there are acceptable REGNUM values that can't be passed to gdbarch_register_name(), or most other gdbarch methods, is really quite ugly. I need to spend some more time thinking about this. Also, there should probably be a register_name() function encapsulating the current uses of user_reg_map_regnum_to_name. -- Daniel Jacobowitz CodeSourcery, LLC 2005-05-28 Daniel Jacobowitz gdb/1926 * Makefile.in (infcmd.o): Update dependencies. * infcmd.c: Include "user-regs.h". (default_print_register): New function, based on default_print_registers_info. Use user_reg_map_regnum_to_name and common_val_print. (default_print_registers_info): Use it. Index: Makefile.in =================================================================== RCS file: /cvs/src/src/gdb/Makefile.in,v retrieving revision 1.733 diff -u -p -r1.733 Makefile.in --- Makefile.in 22 May 2005 20:36:18 -0000 1.733 +++ Makefile.in 28 May 2005 18:03:08 -0000 @@ -2113,7 +2113,7 @@ infcmd.o: infcmd.c $(defs_h) $(gdb_strin $(symfile_h) $(gdbcore_h) $(target_h) $(language_h) $(symfile_h) \ $(objfiles_h) $(completer_h) $(ui_out_h) $(event_top_h) \ $(parser_defs_h) $(regcache_h) $(reggroups_h) $(block_h) \ - $(solib_h) $(gdb_assert_h) + $(solib_h) $(user_regs_h) $(gdb_assert_h) inf-loop.o: inf-loop.c $(defs_h) $(inferior_h) $(target_h) $(event_loop_h) \ $(event_top_h) $(inf_loop_h) $(remote_h) $(exceptions_h) inflow.o: inflow.c $(defs_h) $(frame_h) $(inferior_h) $(command_h) \ Index: infcmd.c =================================================================== RCS file: /cvs/src/src/gdb/infcmd.c,v retrieving revision 1.138 diff -u -p -r1.138 infcmd.c --- infcmd.c 22 May 2005 14:53:34 -0000 1.138 +++ infcmd.c 28 May 2005 18:03:09 -0000 @@ -45,6 +45,8 @@ #include "reggroups.h" #include "block.h" #include "solib.h" +#include "user-regs.h" + #include #include "gdb_assert.h" @@ -1505,9 +1507,77 @@ path_command (char *dirname, int from_tt } -/* Print out the machine register regnum. If regnum is -1, print all - registers (print_all == 1) or all non-float and non-vector - registers (print_all == 0). +/* Print the value of machine register REGNUM from FRAME to FILE, in the + default format. REGNUM must be a valid register number. */ + +void +default_print_register (struct gdbarch *gdbarch, struct ui_file *file, + struct frame_info *frame, int regnum) +{ + struct value *regval; + const char *name; + + name = user_reg_map_regnum_to_name (gdbarch, regnum); + + /* If the register name is empty, it is undefined for this processor, so + don't display anything. */ + if (name == NULL) + return; + + fputs_filtered (name, file); + print_spaces_filtered (15 - strlen (name), file); + + /* Read the value. */ + regval = value_of_register (regnum, frame); + if (regval == NULL) + { + fprintf_filtered (file, "*value not available*\n"); + return; + } + + /* If virtual format is floating, print it that way, and in raw + hex. */ + if (TYPE_CODE (value_type (regval)) == TYPE_CODE_FLT) + { + int j, len; + const gdb_byte *buffer; + + common_val_print (regval, file, 0, 1, 0, Val_pretty_default); + + fprintf_filtered (file, "\t(raw 0x"); + len = TYPE_LENGTH (value_type (regval)); + buffer = value_contents (regval); + for (j = 0; j < len; j++) + { + int idx; + if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) + idx = j; + else + idx = len - 1 - j; + fprintf_filtered (file, "%02x", (unsigned char) buffer[idx]); + } + fprintf_filtered (file, ")"); + } + else + { + /* Print the register in hex. */ + common_val_print (regval, file, 'x', 1, 0, Val_pretty_default); + + /* If not a vector register, print it also according to its + natural format. */ + if (TYPE_VECTOR (value_type (regval)) == 0) + { + fprintf_filtered (file, "\t"); + common_val_print (regval, file, 0, 1, 0, Val_pretty_default); + } + } + + fprintf_filtered (file, "\n"); +} + +/* Print out the machine register REGNUM. If regnum is -1, print all + registers (PRINT_ALL == 1) or all non-float and non-vector + registers (PRINT_ALL == 0). For most machines, having all_registers_info() print the register(s) one per line is good enough. If a different format is @@ -1524,83 +1594,22 @@ default_print_registers_info (struct gdb { int i; const int numregs = NUM_REGS + NUM_PSEUDO_REGS; - gdb_byte buffer[MAX_REGISTER_SIZE]; - for (i = 0; i < numregs; i++) + if (regnum >= 0) { - /* Decide between printing all regs, non-float / vector regs, or - specific reg. */ - if (regnum == -1) - { - if (print_all) - { - if (!gdbarch_register_reggroup_p (gdbarch, i, all_reggroup)) - continue; - } - else - { - if (!gdbarch_register_reggroup_p (gdbarch, i, general_reggroup)) - continue; - } - } - else - { - if (i != regnum) - continue; - } - - /* If the register name is empty, it is undefined for this - processor, so don't display anything. */ - if (REGISTER_NAME (i) == NULL || *(REGISTER_NAME (i)) == '\0') - continue; - - fputs_filtered (REGISTER_NAME (i), file); - print_spaces_filtered (15 - strlen (REGISTER_NAME (i)), file); - - /* Get the data in raw format. */ - if (! frame_register_read (frame, i, buffer)) - { - fprintf_filtered (file, "*value not available*\n"); - continue; - } - - /* If virtual format is floating, print it that way, and in raw - hex. */ - if (TYPE_CODE (register_type (current_gdbarch, i)) == TYPE_CODE_FLT) - { - int j; - - val_print (register_type (current_gdbarch, i), buffer, 0, 0, - file, 0, 1, 0, Val_pretty_default); - - fprintf_filtered (file, "\t(raw 0x"); - for (j = 0; j < register_size (current_gdbarch, i); j++) - { - int idx; - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - idx = j; - else - idx = register_size (current_gdbarch, i) - 1 - j; - fprintf_filtered (file, "%02x", (unsigned char) buffer[idx]); - } - fprintf_filtered (file, ")"); - } - else - { - /* Print the register in hex. */ - val_print (register_type (current_gdbarch, i), buffer, 0, 0, - file, 'x', 1, 0, Val_pretty_default); - /* If not a vector register, print it also according to its - natural format. */ - if (TYPE_VECTOR (register_type (current_gdbarch, i)) == 0) - { - fprintf_filtered (file, "\t"); - val_print (register_type (current_gdbarch, i), buffer, 0, 0, - file, 0, 1, 0, Val_pretty_default); - } - } + default_print_register (gdbarch, file, frame, regnum); + return; + } - fprintf_filtered (file, "\n"); + for (i = 0; i < numregs; i++) + { + /* Decide between printing all regs or non-float / vector regs. */ + if (print_all + && gdbarch_register_reggroup_p (gdbarch, i, all_reggroup)) + default_print_register (gdbarch, file, frame, i); + else if (!print_all + && gdbarch_register_reggroup_p (gdbarch, i, general_reggroup)) + default_print_register (gdbarch, file, frame, i); } }