This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: patch for printing 64-bit values in i386 registers; STABS format
On Mon, Apr 28, 2003 at 12:37:12PM -0400, Andrew Cagney wrote:
> Hmm, I think it will be needed anyway, what happens when the user is
> debugging an i386 mode function (with 32 bit register based long long
> debug info) on an x86-64 target? That's the MIPS problem, and it needs
> that projection(1).
>
> Also, the next_regnum method assumes that all debug infos use the same
> register sequencing.
>
> A word of caution though, the projection, at the register level works.
> Frame's might need tweaking. The alternative is to start out with
> deprecated_next_regnum so that it is clear where this stands.
Here's a discussion piece. I've implemented your suggestion. Two
notes:
- Having done it, I still don't like it :) Using the register cache
in this way seems very wrong to me.
- It doesn't work for frames, because by the time
i386_pseudo_register_read is called the regcache is always
current_regcache. I believe this is because of
legacy_saved_regs_prev_register:
975 if (get_frame_saved_regs (frame) != NULL
976 && get_frame_saved_regs (frame)[regnum] != 0)
I guess doing this much without doing the rest of the conversion makes
the frame machinery quite sad.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
2003-04-28 Daniel Jacobowitz <drow at mvista dot com>
* i386-tdep.c (debug_register_to_gdb, gdb_to_debug_register)
(i386_num_debuginfo_regs, FIRST_DEBUGINFO_REGNUM)
(i386_debuginfo_regnum_p): New.
(i386_register_name, i386_stab_reg_to_regnum)
(i386_dwarf_reg_to_regnum, i386_pseudo_register_read)
(i386_pseudo_register_write, i386_register_reggroup_p): Use
i386_debuginfo_regnum_p and associates.
(i386_gdbarch_init): Update num_pseudo_regs.
Index: i386-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.c,v
retrieving revision 1.139
diff -u -p -r1.139 i386-tdep.c
--- i386-tdep.c 21 Apr 2003 18:55:52 -0000 1.139
+++ i386-tdep.c 28 Apr 2003 19:08:50 -0000
@@ -85,6 +85,43 @@ i386_mmx_regnum_p (int regnum)
&& regnum < MM0_REGNUM + i386_num_mmx_regs);
}
+/* Debug info registers. This is necessary because GDB assumes that
+ multi-word (double, long long) variables are held in consecutively
+ numbered registers. In the absence of better debug information to
+ explicitly say where the pieces are, arrange a set of extra
+ registers to match GCC's normal allocation order. These are used
+ by the various REG_TO_REGNUM methods. */
+
+/* GDB's registers are in the order:
+ eax ecx edx ebx esp ebp esi edi
+ GCC's are in the order:
+ eax edx ecx ebx esi edi ebp esp
+*/
+
+static int debug_register_to_gdb[] =
+{
+ 0, 2, 1, 3, 6, 7, 5, 4
+};
+
+static int gdb_to_debug_register[] =
+{
+ 0, 2, 1, 3, 7, 6, 4, 5
+};
+
+static const int i386_num_debuginfo_regs =
+ (sizeof (debug_register_to_gdb) / sizeof (debug_register_to_gdb[0]));
+
+#define FIRST_DEBUGINFO_REGNUM (MM0_REGNUM + i386_num_mmx_regs)
+
+static int
+i386_debuginfo_regnum_p (int regnum)
+{
+ if (regnum >= FIRST_DEBUGINFO_REGNUM
+ && regnum < FIRST_DEBUGINFO_REGNUM + i386_num_debuginfo_regs)
+ return 1;
+ return 0;
+}
+
/* FP register? */
int
@@ -128,6 +165,12 @@ i386_register_name (int reg)
if (i386_mmx_regnum_p (reg))
return i386_mmx_names[reg - MM0_REGNUM];
+ if (i386_debuginfo_regnum_p (reg))
+ {
+ int real_regno = debug_register_to_gdb[reg - FIRST_DEBUGINFO_REGNUM];
+ return i386_register_names[real_regno];
+ }
+
return NULL;
}
@@ -141,7 +184,7 @@ i386_stab_reg_to_regnum (int reg)
if (reg >= 0 && reg <= 7)
{
/* General registers. */
- return reg;
+ return FIRST_DEBUGINFO_REGNUM + gdb_to_debug_register[reg];
}
else if (reg >= 12 && reg <= 19)
{
@@ -171,11 +214,14 @@ i386_dwarf_reg_to_regnum (int reg)
{
/* The DWARF register numbering includes %eip and %eflags, and
numbers the floating point registers differently. */
- if (reg >= 0 && reg <= 9)
+
+ if (reg >= 0 && reg <= 7)
{
/* General registers. */
- return reg;
+ return FIRST_DEBUGINFO_REGNUM + gdb_to_debug_register[reg];
}
+ else if (reg >= 8 && reg <= 9)
+ return reg;
else if (reg >= 11 && reg <= 18)
{
/* Floating-point registers. */
@@ -1104,6 +1150,11 @@ i386_pseudo_register_read (struct gdbarc
regcache_raw_read (regcache, fpnum, mmx_buf);
memcpy (buf, mmx_buf, REGISTER_RAW_SIZE (regnum));
}
+ else if (i386_debuginfo_regnum_p (regnum))
+ {
+ int real_regnum = debug_register_to_gdb[regnum - FIRST_DEBUGINFO_REGNUM];
+ regcache_raw_read (regcache, real_regnum, buf);
+ }
else
regcache_raw_read (regcache, regnum, buf);
}
@@ -1124,6 +1175,11 @@ i386_pseudo_register_write (struct gdbar
/* ... Write. */
regcache_raw_write (regcache, fpnum, mmx_buf);
}
+ else if (i386_debuginfo_regnum_p (regnum))
+ {
+ int real_regnum = debug_register_to_gdb[regnum - FIRST_DEBUGINFO_REGNUM];
+ regcache_raw_write (regcache, real_regnum, buf);
+ }
else
regcache_raw_write (regcache, regnum, buf);
}
@@ -1407,6 +1463,8 @@ i386_register_reggroup_p (struct gdbarch
int fp_regnum_p = (i386_fp_regnum_p (regnum)
|| i386_fpc_regnum_p (regnum));
int mmx_regnum_p = (i386_mmx_regnum_p (regnum));
+ if (i386_debuginfo_regnum_p (regnum))
+ return 0;
if (group == i386_mmx_reggroup)
return mmx_regnum_p;
if (group == i386_sse_reggroup)
@@ -1541,8 +1599,8 @@ i386_gdbarch_init (struct gdbarch_info i
set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
set_gdbarch_pc_in_sigtramp (gdbarch, i386_pc_in_sigtramp);
- /* Wire in the MMX registers. */
- set_gdbarch_num_pseudo_regs (gdbarch, i386_num_mmx_regs);
+ /* Wire in the MMX and debuginfo registers. */
+ set_gdbarch_num_pseudo_regs (gdbarch, i386_num_mmx_regs + i386_num_debuginfo_regs);
set_gdbarch_pseudo_register_read (gdbarch, i386_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, i386_pseudo_register_write);