diff options
author | Andrew Cagney <cagney@redhat.com> | 2000-05-12 09:21:30 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2000-05-12 09:21:30 +0000 |
commit | a8201f3ee7a54d24ea435acd5b05848cf1a6b0e2 (patch) | |
tree | 8c5ec5cecb33c4c8588839ee0f31c0833985c4b6 | |
parent | 91b956bae8ed169c21f552cafef404c10abb5d12 (diff) | |
download | gdb-a8201f3ee7a54d24ea435acd5b05848cf1a6b0e2.tar.gz |
Handle case of 32 ABI saving 32 bit registers on stack when target
has 64 bit ISA.
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/mips-tdep.c | 68 |
2 files changed, 74 insertions, 1 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6c524ed0ad6..6753da2dad2 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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. diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 1db55446a50..cb790b2095f 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -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) { |