This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
[patch] One 32 bit ABI mips bug on 64 bit ISA
- To: GDB Patches <gdb-patches at sourceware dot cygnus dot com>
- Subject: [patch] One 32 bit ABI mips bug on 64 bit ISA
- From: Andrew Cagney <ac131313 at cygnus dot com>
- Date: Fri, 12 May 2000 19:18:01 +1000
- Organization: Cygnus Solutions
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)
{