This is the mail archive of the gdb-patches@sourceware.cygnus.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]

[patch] One 32 bit ABI mips bug on 64 bit ISA


FYI,

The attached fixes a bug with 32 bit ABIs on 64 bit MIPS ISAs.  The
generic version of fetch registers was reading in too many bytes.

	Andrew
Fri May 12 19:13:15 2000  Andrew Cagney  <cagney@b1.cygnus.com>

	* mips-tdep.c (mips_get_saved_register): New function.  Handle
 	case of 32 ABI saving 32 bit registers on stack when target has 64
 	bit ISA.
	(mips_gdbarch_init): Update.

Index: mips-tdep.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/mips-tdep.c,v
retrieving revision 1.216
diff -p -r1.216 mips-tdep.c
*** mips-tdep.c	2000/05/12 06:05:54	1.216
--- mips-tdep.c	2000/05/12 09:15:31
*************** mips_coerce_float_to_double (struct type
*** 3984,3989 ****
--- 3984,4055 ----
    return current_language->la_language == language_c;
  }
  
+ /* When debugging a 64 MIPS target running a 32 bit ABI, the size of
+    the register stored on the stack (32) is different to its real raw
+    size (64).  The below ensures that registers are fetched from the
+    stack using their ABI size and then stored into the RAW_BUFFER
+    using their raw size.
+ 
+    The alternative to adding this function would be to add an ABI
+    macro - REGISTER_STACK_SIZE(). */
+ 
+ static void
+ mips_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+      char *raw_buffer;
+      int *optimized;
+      CORE_ADDR *addrp;
+      struct frame_info *frame;
+      int regnum;
+      enum lval_type *lval;
+ {
+   CORE_ADDR addr;
+ 
+   if (!target_has_registers)
+     error ("No registers.");
+ 
+   /* Normal systems don't optimize out things with register numbers.  */
+   if (optimized != NULL)
+     *optimized = 0;
+   addr = find_saved_register (frame, regnum);
+   if (addr != 0)
+     {
+       if (lval != NULL)
+ 	*lval = lval_memory;
+       if (regnum == SP_REGNUM)
+ 	{
+ 	  if (raw_buffer != NULL)
+ 	    {
+ 	      /* Put it back in target format.  */
+ 	      store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+ 			     (LONGEST) addr);
+ 	    }
+ 	  if (addrp != NULL)
+ 	    *addrp = 0;
+ 	  return;
+ 	}
+       if (raw_buffer != NULL)
+ 	{
+ 	  LONGEST val;
+ 	  if (regnum < 32)
+ 	    /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
+                saved. */
+ 	    val = read_memory_integer (addr, MIPS_SAVED_REGSIZE);
+ 	  else
+ 	    val = read_memory_integer (addr, REGISTER_RAW_SIZE (regnum));
+ 	  store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), val);
+ 	}
+     }
+   else
+     {
+       if (lval != NULL)
+ 	*lval = lval_register;
+       addr = REGISTER_BYTE (regnum);
+       if (raw_buffer != NULL)
+ 	read_register_gen (regnum, raw_buffer);
+     }
+   if (addrp != NULL)
+     *addrp = addr;
+ }
  
  static gdbarch_init_ftype mips_gdbarch_init;
  static struct gdbarch *
*************** mips_gdbarch_init (info, arches)
*** 4276,4282 ****
    set_gdbarch_coerce_float_to_double (gdbarch, mips_coerce_float_to_double);
  
    set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
!   set_gdbarch_get_saved_register (gdbarch, default_get_saved_register);
  
    if (gdbarch_debug)
      {
--- 4342,4348 ----
    set_gdbarch_coerce_float_to_double (gdbarch, mips_coerce_float_to_double);
  
    set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
!   set_gdbarch_get_saved_register (gdbarch, mips_get_saved_register);
  
    if (gdbarch_debug)
      {

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