This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

re-ordered i386 regcache


[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
--- Begin Message ---
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);
 


--- End Message ---

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]