re-ordered i386 regcache

Andrew Cagney
2003-04-28T22:52:06Z

[-- Attachment #1: Type: text/plain, Size: 1737 bytes --]

[I changed subjects, this thread is too long]

> 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.

Got another way of getting MIPS (32 on 64), i386 on x86-64 (or even
ia64?), e500 on PPC, sh4 on sh64, ... all working?

> - 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.

Should there be a frame equivalent to the regcache's cooked->raw
projection? Should the read side of the cooked->raw projection be moved
to the frame?

Note that things like the m68hc11 some of the cooked registers are
mapped onto memory so the cooked->raw writes would likely still need to
remain.

Andrew

[-- Attachment #2: mailbox-message://ac131313@movemail/fsf/gdb/patches#3703853 --]
[-- Type: message/rfc822, Size: 9464 bytes --]

From: Daniel Jacobowitz <drow@mvista.com>
To: Andrew Cagney <ac131313@redhat.com>
Cc: Mark Kettenis <kettenis@chello.nl>, colins@google.com, gdb-patches@sources.redhat.com
Subject: Re: patch for printing 64-bit values in i386 registers; STABS format
Date: Mon, 28 Apr 2003 15:25:07 -0400
Message-ID: <20030428192506.GA11978@nevyn.them.org>

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@mvista.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);