Handle case of 32 ABI saving 32 bit registers on stack when target
authorAndrew Cagney <cagney@redhat.com>
Fri, 12 May 2000 09:21:30 +0000 (09:21 +0000)
committerAndrew Cagney <cagney@redhat.com>
Fri, 12 May 2000 09:21:30 +0000 (09:21 +0000)
has 64 bit ISA.

gdb/ChangeLog
gdb/mips-tdep.c

index 6c524ed0ad6ee2e13fff0e641757b2dac6f4628d..6753da2dad27efe8e8ff51d6e9d7fe8912959141 100644 (file)
@@ -1,3 +1,10 @@
+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.
+
 Fri May 12 14:46:52 2000  Andrew Cagney  <cagney@b1.cygnus.com>
 
        * mips-tdep.c (MIPS_EABI): Fix typo.  Test for MIPS_ABI_EABI64.
index 1db55446a500b00275288d761cb912fd5b60412c..cb790b2095f8340791d0bb4b03427530e1d54542 100644 (file)
@@ -3751,6 +3751,72 @@ mips_coerce_float_to_double (struct type *formal, struct type *actual)
   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 *
@@ -4010,7 +4076,7 @@ mips_gdbarch_init (info, arches)
   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);
+  set_gdbarch_get_saved_register (gdbarch, mips_get_saved_register);
 
   if (gdbarch_debug)
     {