X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fsh-tdep.c;h=7e01469b058257612d5beb80159d654c134e41a0;hb=3c83b96e241336be0c3e26c06f2bf901d0fe8edd;hp=58a142aad7b4c57754b36c286d93ed9d13570c43;hpb=c055b1010f3ff41e33e30b195f809e05d68af989;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/sh-tdep.c b/gdb/sh-tdep.c index 58a142aad7..7e01469b05 100644 --- a/gdb/sh-tdep.c +++ b/gdb/sh-tdep.c @@ -1,7 +1,7 @@ /* Target-dependent code for Renesas Super-H, for GDB. Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. + 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GDB. @@ -43,6 +43,7 @@ #include "doublest.h" #include "osabi.h" #include "reggroups.h" +#include "regset.h" #include "sh-tdep.h" @@ -51,7 +52,7 @@ /* sh flags */ #include "elf/sh.h" -#include "elf/dwarf2.h" +#include "dwarf2.h" /* registers numbers shared with the simulator */ #include "gdb/sim-sh.h" @@ -519,18 +520,12 @@ sh_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr) #define IS_ADD_REG_TO_FP(x) (((x) & 0xff0f) == 0x3e0c) #define IS_ADD_IMM_FP(x) (((x) & 0xff00) == 0x7e00) -/* Disassemble an instruction. */ -static int -gdb_print_insn_sh (bfd_vma memaddr, disassemble_info * info) -{ - info->endian = gdbarch_byte_order (current_gdbarch); - return print_insn_sh (memaddr, info); -} - static CORE_ADDR -sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, +sh_analyze_prologue (struct gdbarch *gdbarch, + CORE_ADDR pc, CORE_ADDR current_pc, struct sh_frame_cache *cache, ULONGEST fpscr) { + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST inst; CORE_ADDR opc; int offset; @@ -544,7 +539,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, cache->uses_fp = 0; for (opc = pc + (2 * 28); pc < opc; pc += 2) { - inst = read_memory_unsigned_integer (pc, 2); + inst = read_memory_unsigned_integer (pc, 2, byte_order); /* See where the registers will be saved to */ if (IS_PUSH (inst)) { @@ -588,7 +583,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, sav_reg = reg; offset = (inst & 0xff) << 1; sav_offset = - read_memory_integer ((pc + 4) + offset, 2); + read_memory_integer ((pc + 4) + offset, 2, byte_order); } } } @@ -602,7 +597,8 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, sav_reg = reg; offset = (inst & 0xff) << 2; sav_offset = - read_memory_integer (((pc & 0xfffffffc) + 4) + offset, 4); + read_memory_integer (((pc & 0xfffffffc) + 4) + offset, + 4, byte_order); } } } @@ -617,7 +613,8 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, sav_offset = GET_SOURCE_REG (inst) << 16; /* MOVI20 is a 32 bit instruction! */ pc += 2; - sav_offset |= read_memory_unsigned_integer (pc, 2); + sav_offset + |= read_memory_unsigned_integer (pc, 2, byte_order); /* Now sav_offset contains an unsigned 20 bit value. It must still get sign extended. */ if (sav_offset & 0x00080000) @@ -656,7 +653,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, pc += 2; for (opc = pc + 12; pc < opc; pc += 2) { - inst = read_memory_integer (pc, 2); + inst = read_memory_integer (pc, 2, byte_order); if (IS_MOV_ARG_TO_IND_R14 (inst)) { reg = GET_SOURCE_REG (inst); @@ -686,7 +683,7 @@ sh_analyze_prologue (CORE_ADDR pc, CORE_ADDR current_pc, jsr, which will be very confusing. Most likely the next instruction is going to be IS_MOV_SP_FP in the delay slot. If so, note that before returning the current pc. */ - inst = read_memory_integer (pc + 2, 2); + inst = read_memory_integer (pc + 2, 2, byte_order); if (IS_MOV_SP_FP (inst)) cache->uses_fp = 1; break; @@ -749,7 +746,7 @@ sh_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc) return max (pc, start_pc); cache.sp_offset = -4; - pc = sh_analyze_prologue (start_pc, (CORE_ADDR) -1, &cache, 0); + pc = sh_analyze_prologue (gdbarch, start_pc, (CORE_ADDR) -1, &cache, 0); if (!cache.uses_fp) return start_pc; @@ -1063,6 +1060,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int stack_offset = 0; int argreg = ARG0_REGNUM; int flt_argreg = 0; @@ -1080,7 +1078,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, non-vararg argument to be on the stack, no matter how many registers have been used so far. */ if (sh_is_renesas_calling_convention (func_type) - && (TYPE_FLAGS (func_type) & TYPE_FLAG_VARARGS)) + && TYPE_VARARGS (func_type)) last_reg_arg = TYPE_NFIELDS (func_type) - 2; /* first force sp to a 4-byte alignment */ @@ -1138,7 +1136,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, { /* Argument goes in a float argument register. */ reg_size = register_size (gdbarch, flt_argreg); - regval = extract_unsigned_integer (val, reg_size); + regval = extract_unsigned_integer (val, reg_size, byte_order); /* In little endian mode, float types taking two registers (doubles on sh4, long doubles on sh2e, sh3e and sh4) must be stored swapped in the argument registers. The below @@ -1153,7 +1151,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, regval); val += reg_size; len -= reg_size; - regval = extract_unsigned_integer (val, reg_size); + regval = extract_unsigned_integer (val, reg_size, byte_order); } regcache_cooked_write_unsigned (regcache, flt_argreg++, regval); } @@ -1161,7 +1159,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, { /* there's room in a register */ reg_size = register_size (gdbarch, argreg); - regval = extract_unsigned_integer (val, reg_size); + regval = extract_unsigned_integer (val, reg_size, byte_order); regcache_cooked_write_unsigned (regcache, argreg++, regval); } /* Store the value one register at a time or in one step on stack. */ @@ -1175,7 +1173,7 @@ sh_push_dummy_call_fpu (struct gdbarch *gdbarch, if (sh_is_renesas_calling_convention (func_type)) /* If the function uses the Renesas ABI, subtract another 4 bytes from the stack and store the struct return address there. */ - write_memory_unsigned_integer (sp -= 4, 4, struct_addr); + write_memory_unsigned_integer (sp -= 4, 4, byte_order, struct_addr); else /* Using the gcc ABI, the "struct return pointer" pseudo-argument has its own dedicated register. */ @@ -1202,6 +1200,7 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch, CORE_ADDR sp, int struct_return, CORE_ADDR struct_addr) { + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int stack_offset = 0; int argreg = ARG0_REGNUM; int argnum; @@ -1217,7 +1216,7 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch, non-vararg argument to be on the stack, no matter how many registers have been used so far. */ if (sh_is_renesas_calling_convention (func_type) - && (TYPE_FLAGS (func_type) & TYPE_FLAG_VARARGS)) + && TYPE_VARARGS (func_type)) last_reg_arg = TYPE_NFIELDS (func_type) - 2; /* first force sp to a 4-byte alignment */ @@ -1261,7 +1260,7 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch, { /* there's room in a register */ reg_size = register_size (gdbarch, argreg); - regval = extract_unsigned_integer (val, reg_size); + regval = extract_unsigned_integer (val, reg_size, byte_order); regcache_cooked_write_unsigned (regcache, argreg++, regval); } /* Store the value reg_size bytes at a time. This means that things @@ -1277,7 +1276,7 @@ sh_push_dummy_call_nofpu (struct gdbarch *gdbarch, if (sh_is_renesas_calling_convention (func_type)) /* If the function uses the Renesas ABI, subtract another 4 bytes from the stack and store the struct return address there. */ - write_memory_unsigned_integer (sp -= 4, 4, struct_addr); + write_memory_unsigned_integer (sp -= 4, 4, byte_order, struct_addr); else /* Using the gcc ABI, the "struct return pointer" pseudo-argument has its own dedicated register. */ @@ -1303,6 +1302,8 @@ static void sh_extract_return_value_nofpu (struct type *type, struct regcache *regcache, void *valbuf) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int len = TYPE_LENGTH (type); int return_register = R0_REGNUM; int offset; @@ -1312,7 +1313,7 @@ sh_extract_return_value_nofpu (struct type *type, struct regcache *regcache, ULONGEST c; regcache_cooked_read_unsigned (regcache, R0_REGNUM, &c); - store_unsigned_integer (valbuf, len, c); + store_unsigned_integer (valbuf, len, byte_order, c); } else if (len == 8) { @@ -1353,12 +1354,14 @@ static void sh_store_return_value_nofpu (struct type *type, struct regcache *regcache, const void *valbuf) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST val; int len = TYPE_LENGTH (type); if (len <= 4) { - val = extract_unsigned_integer (valbuf, len); + val = extract_unsigned_integer (valbuf, len, byte_order); regcache_cooked_write_unsigned (regcache, R0_REGNUM, val); } else @@ -1426,9 +1429,9 @@ sh_generic_show_regs (struct frame_info *frame) { printf_filtered (" PC %s SR %08lx PR %08lx MACH %08lx\n", - paddr (get_frame_register_unsigned (frame, - gdbarch_pc_regnum - (get_frame_arch (frame)))), + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), (long) get_frame_register_unsigned (frame, SR_REGNUM), (long) get_frame_register_unsigned (frame, PR_REGNUM), (long) get_frame_register_unsigned (frame, MACH_REGNUM)); @@ -1466,9 +1469,9 @@ sh3_show_regs (struct frame_info *frame) { printf_filtered (" PC %s SR %08lx PR %08lx MACH %08lx\n", - paddr (get_frame_register_unsigned (frame, - gdbarch_pc_regnum - (get_frame_arch (frame)))), + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), (long) get_frame_register_unsigned (frame, SR_REGNUM), (long) get_frame_register_unsigned (frame, PR_REGNUM), (long) get_frame_register_unsigned (frame, MACH_REGNUM)); @@ -1511,8 +1514,8 @@ sh2e_show_regs (struct frame_info *frame) struct gdbarch *gdbarch = get_frame_arch (frame); printf_filtered (" PC %s SR %08lx PR %08lx MACH %08lx\n", - paddr (get_frame_register_unsigned (frame, - gdbarch_pc_regnum (gdbarch))), + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum (gdbarch)), 4), (long) get_frame_register_unsigned (frame, SR_REGNUM), (long) get_frame_register_unsigned (frame, PR_REGNUM), (long) get_frame_register_unsigned (frame, MACH_REGNUM)); @@ -1596,8 +1599,8 @@ sh2a_show_regs (struct frame_info *frame) printf_filtered (" PC %s SR %08lx PR %08lx MACH %08lx\n", - paddr (get_frame_register_unsigned (frame, - gdbarch_pc_regnum (gdbarch))), + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum (gdbarch)), 4), (long) get_frame_register_unsigned (frame, SR_REGNUM), (long) get_frame_register_unsigned (frame, PR_REGNUM), (long) get_frame_register_unsigned (frame, MACH_REGNUM)); @@ -1711,9 +1714,9 @@ sh2a_nofpu_show_regs (struct frame_info *frame) printf_filtered (" PC %s SR %08lx PR %08lx MACH %08lx\n", - paddr (get_frame_register_unsigned (frame, - gdbarch_pc_regnum - (get_frame_arch (frame)))), + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), (long) get_frame_register_unsigned (frame, SR_REGNUM), (long) get_frame_register_unsigned (frame, PR_REGNUM), (long) get_frame_register_unsigned (frame, MACH_REGNUM)); @@ -1788,8 +1791,8 @@ sh3e_show_regs (struct frame_info *frame) struct gdbarch *gdbarch = get_frame_arch (frame); printf_filtered (" PC %s SR %08lx PR %08lx MACH %08lx\n", - paddr (get_frame_register_unsigned (frame, - gdbarch_pc_regnum (gdbarch))), + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum (gdbarch)), 4), (long) get_frame_register_unsigned (frame, SR_REGNUM), (long) get_frame_register_unsigned (frame, PR_REGNUM), (long) get_frame_register_unsigned (frame, MACH_REGNUM)); @@ -1870,9 +1873,9 @@ sh3_dsp_show_regs (struct frame_info *frame) { printf_filtered (" PC %s SR %08lx PR %08lx MACH %08lx\n", - paddr (get_frame_register_unsigned (frame, - gdbarch_pc_regnum - (get_frame_arch (frame)))), + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), (long) get_frame_register_unsigned (frame, SR_REGNUM), (long) get_frame_register_unsigned (frame, PR_REGNUM), (long) get_frame_register_unsigned (frame, MACH_REGNUM)); @@ -1937,8 +1940,8 @@ sh4_show_regs (struct frame_info *frame) printf_filtered (" PC %s SR %08lx PR %08lx MACH %08lx\n", - paddr (get_frame_register_unsigned (frame, - gdbarch_pc_regnum (gdbarch))), + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum (gdbarch)), 4), (long) get_frame_register_unsigned (frame, SR_REGNUM), (long) get_frame_register_unsigned (frame, PR_REGNUM), (long) get_frame_register_unsigned (frame, MACH_REGNUM)); @@ -2021,9 +2024,9 @@ sh4_nofpu_show_regs (struct frame_info *frame) { printf_filtered (" PC %s SR %08lx PR %08lx MACH %08lx\n", - paddr (get_frame_register_unsigned (frame, - gdbarch_pc_regnum - (get_frame_arch (frame)))), + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), (long) get_frame_register_unsigned (frame, SR_REGNUM), (long) get_frame_register_unsigned (frame, PR_REGNUM), (long) get_frame_register_unsigned (frame, MACH_REGNUM)); @@ -2067,9 +2070,9 @@ sh_dsp_show_regs (struct frame_info *frame) { printf_filtered (" PC %s SR %08lx PR %08lx MACH %08lx\n", - paddr (get_frame_register_unsigned (frame, - gdbarch_pc_regnum - (get_frame_arch (frame)))), + phex (get_frame_register_unsigned (frame, + gdbarch_pc_regnum + (get_frame_arch (frame))), 4), (long) get_frame_register_unsigned (frame, SR_REGNUM), (long) get_frame_register_unsigned (frame, PR_REGNUM), (long) get_frame_register_unsigned (frame, MACH_REGNUM)); @@ -2132,11 +2135,11 @@ sh_sh2a_register_type (struct gdbarch *gdbarch, int reg_nr) { if ((reg_nr >= gdbarch_fp0_regnum (gdbarch) && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM)) - return builtin_type_float; + return builtin_type (gdbarch)->builtin_float; else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM) - return builtin_type_double; + return builtin_type (gdbarch)->builtin_double; else - return builtin_type_int; + return builtin_type (gdbarch)->builtin_int; } /* Return the GDB type object for the "standard" data type @@ -2146,18 +2149,16 @@ sh_sh3e_register_type (struct gdbarch *gdbarch, int reg_nr) { if ((reg_nr >= gdbarch_fp0_regnum (gdbarch) && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM)) - return builtin_type_float; + return builtin_type (gdbarch)->builtin_float; else - return builtin_type_int; + return builtin_type (gdbarch)->builtin_int; } static struct type * -sh_sh4_build_float_register_type (int high) +sh_sh4_build_float_register_type (struct gdbarch *gdbarch, int high) { - struct type *temp; - - temp = create_range_type (NULL, builtin_type_int, 0, high); - return create_array_type (NULL, builtin_type_float, temp); + return lookup_array_range_type (builtin_type (gdbarch)->builtin_float, + 0, high); } static struct type * @@ -2165,26 +2166,26 @@ sh_sh4_register_type (struct gdbarch *gdbarch, int reg_nr) { if ((reg_nr >= gdbarch_fp0_regnum (gdbarch) && (reg_nr <= FP_LAST_REGNUM)) || (reg_nr == FPUL_REGNUM)) - return builtin_type_float; + return builtin_type (gdbarch)->builtin_float; else if (reg_nr >= DR0_REGNUM && reg_nr <= DR_LAST_REGNUM) - return builtin_type_double; + return builtin_type (gdbarch)->builtin_double; else if (reg_nr >= FV0_REGNUM && reg_nr <= FV_LAST_REGNUM) - return sh_sh4_build_float_register_type (3); + return sh_sh4_build_float_register_type (gdbarch, 3); else - return builtin_type_int; + return builtin_type (gdbarch)->builtin_int; } static struct type * sh_default_register_type (struct gdbarch *gdbarch, int reg_nr) { - return builtin_type_int; + return builtin_type (gdbarch)->builtin_int; } /* Is a register in a reggroup? The default code in reggroup.c doesn't identify system registers, some float registers or any of the vector registers. TODO: sh2a and dsp registers. */ -int +static int sh_register_reggroup_p (struct gdbarch *gdbarch, int regnum, struct reggroup *reggroup) { @@ -2442,7 +2443,7 @@ sh_sh2a_register_sim_regno (struct gdbarch *gdbarch, int nr) static void sh_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, struct dwarf2_frame_state_reg *reg, - struct frame_info *next_frame) + struct frame_info *this_frame) { /* Mark the PC as the destination for the return address. */ if (regnum == gdbarch_pc_regnum (gdbarch)) @@ -2512,8 +2513,9 @@ sh_alloc_frame_cache (void) } static struct sh_frame_cache * -sh_frame_cache (struct frame_info *next_frame, void **this_cache) +sh_frame_cache (struct frame_info *this_frame, void **this_cache) { + struct gdbarch *gdbarch = get_frame_arch (this_frame); struct sh_frame_cache *cache; CORE_ADDR current_pc; int i; @@ -2529,17 +2531,17 @@ sh_frame_cache (struct frame_info *next_frame, void **this_cache) However, for functions that don't need it, the frame pointer is optional. For these "frameless" functions the frame pointer is actually the frame pointer of the calling frame. */ - cache->base = frame_unwind_register_unsigned (next_frame, FP_REGNUM); + cache->base = get_frame_register_unsigned (this_frame, FP_REGNUM); if (cache->base == 0) return cache; - cache->pc = frame_func_unwind (next_frame, NORMAL_FRAME); - current_pc = frame_pc_unwind (next_frame); + cache->pc = get_frame_func (this_frame); + current_pc = get_frame_pc (this_frame); if (cache->pc != 0) { ULONGEST fpscr; - fpscr = frame_unwind_register_unsigned (next_frame, FPSCR_REGNUM); - sh_analyze_prologue (cache->pc, current_pc, cache, fpscr); + fpscr = get_frame_register_unsigned (this_frame, FPSCR_REGNUM); + sh_analyze_prologue (gdbarch, cache->pc, current_pc, cache, fpscr); } if (!cache->uses_fp) @@ -2551,9 +2553,8 @@ sh_frame_cache (struct frame_info *next_frame, void **this_cache) setup yet. Try to reconstruct the base address for the stack frame by looking at the stack pointer. For truly "frameless" functions this might work too. */ - cache->base = frame_unwind_register_unsigned - (next_frame, - gdbarch_sp_regnum (get_frame_arch (next_frame))); + cache->base = get_frame_register_unsigned + (this_frame, gdbarch_sp_regnum (gdbarch)); } /* Now that we have the base address for the stack frame we can @@ -2569,30 +2570,17 @@ sh_frame_cache (struct frame_info *next_frame, void **this_cache) return cache; } -static void -sh_frame_prev_register (struct frame_info *next_frame, void **this_cache, - int regnum, int *optimizedp, - enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, gdb_byte *valuep) +static struct value * +sh_frame_prev_register (struct frame_info *this_frame, + void **this_cache, int regnum) { - struct gdbarch *gdbarch = get_frame_arch (next_frame); - struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache); + struct gdbarch *gdbarch = get_frame_arch (this_frame); + struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache); gdb_assert (regnum >= 0); if (regnum == gdbarch_sp_regnum (gdbarch) && cache->saved_sp) - { - *optimizedp = 0; - *lvalp = not_lval; - *addrp = 0; - *realnump = -1; - if (valuep) - { - /* Store the value. */ - store_unsigned_integer (valuep, 4, cache->saved_sp); - } - return; - } + return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp); /* The PC of the previous frame is stored in the PR register of the current frame. Frob regnum so that we pull the value from @@ -2601,33 +2589,17 @@ sh_frame_prev_register (struct frame_info *next_frame, void **this_cache, regnum = PR_REGNUM; if (regnum < SH_NUM_REGS && cache->saved_regs[regnum] != -1) - { - *optimizedp = 0; - *lvalp = lval_memory; - *addrp = cache->saved_regs[regnum]; - *realnump = -1; - if (valuep) - { - /* Read the value in from memory. */ - read_memory (*addrp, valuep, - register_size (gdbarch, regnum)); - } - return; - } + return frame_unwind_got_memory (this_frame, regnum, + cache->saved_regs[regnum]); - *optimizedp = 0; - *lvalp = lval_register; - *addrp = 0; - *realnump = regnum; - if (valuep) - frame_unwind_register (next_frame, (*realnump), valuep); + return frame_unwind_got_register (this_frame, regnum, regnum); } static void -sh_frame_this_id (struct frame_info *next_frame, void **this_cache, +sh_frame_this_id (struct frame_info *this_frame, void **this_cache, struct frame_id *this_id) { - struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache); + struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache); /* This marks the outermost frame. */ if (cache->base == 0) @@ -2639,15 +2611,11 @@ sh_frame_this_id (struct frame_info *next_frame, void **this_cache, static const struct frame_unwind sh_frame_unwind = { NORMAL_FRAME, sh_frame_this_id, - sh_frame_prev_register + sh_frame_prev_register, + NULL, + default_frame_sniffer }; -static const struct frame_unwind * -sh_frame_sniffer (struct frame_info *next_frame) -{ - return &sh_frame_unwind; -} - static CORE_ADDR sh_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) { @@ -2663,16 +2631,17 @@ sh_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) } static struct frame_id -sh_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame) +sh_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) { - return frame_id_build (sh_unwind_sp (gdbarch, next_frame), - frame_pc_unwind (next_frame)); + CORE_ADDR sp = get_frame_register_unsigned (this_frame, + gdbarch_sp_regnum (gdbarch)); + return frame_id_build (sp, get_frame_pc (this_frame)); } static CORE_ADDR -sh_frame_base_address (struct frame_info *next_frame, void **this_cache) +sh_frame_base_address (struct frame_info *this_frame, void **this_cache) { - struct sh_frame_cache *cache = sh_frame_cache (next_frame, this_cache); + struct sh_frame_cache *cache = sh_frame_cache (this_frame, this_cache); return cache->base; } @@ -2690,6 +2659,7 @@ static const struct frame_base sh_frame_base = { static int sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) { + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = 0, func_end = 0; if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) @@ -2707,7 +2677,7 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) /* First search forward until hitting an rts. */ while (addr < func_end - && !IS_RTS (read_memory_unsigned_integer (addr, 2))) + && !IS_RTS (read_memory_unsigned_integer (addr, 2, byte_order))) addr += 2; if (addr >= func_end) return 0; @@ -2715,33 +2685,35 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) /* At this point we should find a mov.l @r15+,r14 instruction, either before or after the rts. If not, then the function has probably no "normal" epilogue and we bail out here. */ - inst = read_memory_unsigned_integer (addr - 2, 2); - if (IS_RESTORE_FP (read_memory_unsigned_integer (addr - 2, 2))) + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); + if (IS_RESTORE_FP (read_memory_unsigned_integer (addr - 2, 2, + byte_order))) addr -= 2; - else if (!IS_RESTORE_FP (read_memory_unsigned_integer (addr + 2, 2))) + else if (!IS_RESTORE_FP (read_memory_unsigned_integer (addr + 2, 2, + byte_order))) return 0; - inst = read_memory_unsigned_integer (addr - 2, 2); + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); /* Step over possible lds.l @r15+,macl. */ if (IS_MACL_LDS (inst)) { addr -= 2; - inst = read_memory_unsigned_integer (addr - 2, 2); + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); } /* Step over possible lds.l @r15+,pr. */ if (IS_LDS (inst)) { addr -= 2; - inst = read_memory_unsigned_integer (addr - 2, 2); + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); } /* Step over possible mov r14,r15. */ if (IS_MOV_FP_SP (inst)) { addr -= 2; - inst = read_memory_unsigned_integer (addr - 2, 2); + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); } /* Now check for FP adjustments, using add #imm,r14 or add rX, r14 @@ -2750,7 +2722,7 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) && (IS_ADD_REG_TO_FP (inst) || IS_ADD_IMM_FP (inst))) { addr -= 2; - inst = read_memory_unsigned_integer (addr - 2, 2); + inst = read_memory_unsigned_integer (addr - 2, 2, byte_order); } /* On SH2a check if the previous instruction was perhaps a MOVI20. @@ -2758,7 +2730,8 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) if ((gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_sh2a || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_sh2a_nofpu) && addr > func_addr + 6 - && IS_MOVI20 (read_memory_unsigned_integer (addr - 4, 2))) + && IS_MOVI20 (read_memory_unsigned_integer (addr - 4, 2, + byte_order))) addr -= 4; if (pc >= addr) @@ -2766,12 +2739,98 @@ sh_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) } return 0; } + + +/* Supply register REGNUM from the buffer specified by REGS and LEN + in the register set REGSET to register cache REGCACHE. + REGTABLE specifies where each register can be found in REGS. + If REGNUM is -1, do this for all registers in REGSET. */ + +void +sh_corefile_supply_regset (const struct regset *regset, + struct regcache *regcache, + int regnum, const void *regs, size_t len) +{ + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + const struct sh_corefile_regmap *regmap = (regset == &sh_corefile_gregset + ? tdep->core_gregmap + : tdep->core_fpregmap); + int i; + + for (i = 0; regmap[i].regnum != -1; i++) + { + if ((regnum == -1 || regnum == regmap[i].regnum) + && regmap[i].offset + 4 <= len) + regcache_raw_supply (regcache, regmap[i].regnum, + (char *)regs + regmap[i].offset); + } +} + +/* Collect register REGNUM in the register set REGSET from register cache + REGCACHE into the buffer specified by REGS and LEN. + REGTABLE specifies where each register can be found in REGS. + If REGNUM is -1, do this for all registers in REGSET. */ + +void +sh_corefile_collect_regset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *regs, size_t len) +{ + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + const struct sh_corefile_regmap *regmap = (regset == &sh_corefile_gregset + ? tdep->core_gregmap + : tdep->core_fpregmap); + int i; + + for (i = 0; regmap[i].regnum != -1; i++) + { + if ((regnum == -1 || regnum == regmap[i].regnum) + && regmap[i].offset + 4 <= len) + regcache_raw_collect (regcache, regmap[i].regnum, + (char *)regs + regmap[i].offset); + } +} + +/* The following two regsets have the same contents, so it is tempting to + unify them, but they are distiguished by their address, so don't. */ + +struct regset sh_corefile_gregset = +{ + NULL, + sh_corefile_supply_regset, + sh_corefile_collect_regset +}; + +static struct regset sh_corefile_fpregset = +{ + NULL, + sh_corefile_supply_regset, + sh_corefile_collect_regset +}; + +static const struct regset * +sh_regset_from_core_section (struct gdbarch *gdbarch, const char *sect_name, + size_t sect_size) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + if (tdep->core_gregmap && strcmp (sect_name, ".reg") == 0) + return &sh_corefile_gregset; + + if (tdep->core_fpregmap && strcmp (sect_name, ".reg2") == 0) + return &sh_corefile_fpregset; + + return NULL; +} static struct gdbarch * sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { struct gdbarch *gdbarch; + struct gdbarch_tdep *tdep; sh_show_regs = sh_generic_show_regs; switch (info.bfd_arch_info->mach) @@ -2790,10 +2849,13 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) break; case bfd_mach_sh3: + case bfd_mach_sh3_nommu: + case bfd_mach_sh2a_nofpu_or_sh3_nommu: sh_show_regs = sh3_show_regs; break; case bfd_mach_sh3e: + case bfd_mach_sh2a_or_sh3e: sh_show_regs = sh3e_show_regs; break; @@ -2804,11 +2866,14 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) case bfd_mach_sh4: case bfd_mach_sh4a: + case bfd_mach_sh2a_or_sh4: sh_show_regs = sh4_show_regs; break; case bfd_mach_sh4_nofpu: + case bfd_mach_sh4_nommu_nofpu: case bfd_mach_sh4a_nofpu: + case bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu: sh_show_regs = sh4_nofpu_show_regs; break; @@ -2825,7 +2890,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* None found, create a new architecture from the information provided. */ - gdbarch = gdbarch_alloc (&info, NULL); + tdep = XZALLOC (struct gdbarch_tdep); + gdbarch = gdbarch_alloc (&info, tdep); set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT); @@ -2847,7 +2913,7 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_breakpoint_from_pc (gdbarch, sh_breakpoint_from_pc); - set_gdbarch_print_insn (gdbarch, gdb_print_insn_sh); + set_gdbarch_print_insn (gdbarch, print_insn_sh); set_gdbarch_register_sim_regno (gdbarch, legacy_register_sim_regno); set_gdbarch_return_value (gdbarch, sh_return_value_nofpu); @@ -2862,13 +2928,15 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_frame_align (gdbarch, sh_frame_align); set_gdbarch_unwind_sp (gdbarch, sh_unwind_sp); set_gdbarch_unwind_pc (gdbarch, sh_unwind_pc); - set_gdbarch_unwind_dummy_id (gdbarch, sh_unwind_dummy_id); + set_gdbarch_dummy_id (gdbarch, sh_dummy_id); frame_base_set_default (gdbarch, &sh_frame_base); set_gdbarch_in_function_epilogue_p (gdbarch, sh_in_function_epilogue_p); dwarf2_frame_set_init_reg (gdbarch, sh_dwarf2_frame_init_reg); + set_gdbarch_regset_from_core_section (gdbarch, sh_regset_from_core_section); + switch (info.bfd_arch_info->mach) { case bfd_mach_sh: @@ -2942,6 +3010,7 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) case bfd_mach_sh4: case bfd_mach_sh4a: + case bfd_mach_sh2a_or_sh4: set_gdbarch_register_name (gdbarch, sh_sh4_register_name); set_gdbarch_register_type (gdbarch, sh_sh4_register_type); set_gdbarch_fp0_regnum (gdbarch, 25); @@ -2956,7 +3025,6 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) case bfd_mach_sh4a_nofpu: case bfd_mach_sh4_nommu_nofpu: case bfd_mach_sh2a_nofpu_or_sh4_nommu_nofpu: - case bfd_mach_sh2a_or_sh4: set_gdbarch_register_name (gdbarch, sh_sh4_nofpu_register_name); break; @@ -2973,8 +3041,8 @@ sh_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Hook in ABI-specific overrides, if they have been registered. */ gdbarch_init_osabi (info, gdbarch); - frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer); - frame_unwind_append_sniffer (gdbarch, sh_frame_sniffer); + dwarf2_append_unwinders (gdbarch); + frame_unwind_append_unwinder (gdbarch, &sh_frame_unwind); return gdbarch; }