X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ffrv-tdep.c;h=a80c0437cb64a42107a93621f082a84dd832e01c;hb=036003a671233c43e35b3004f91e4cbd61255cf3;hp=80d02d5151208ea8c8fd89b1a2819a203622b62e;hpb=7b6bb8daaceb9ecf3f42dea57ae82733d6a3b2f6;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/frv-tdep.c b/gdb/frv-tdep.c index 80d02d5151..a80c0437cb 100644 --- a/gdb/frv-tdep.c +++ b/gdb/frv-tdep.c @@ -1,7 +1,6 @@ /* Target-dependent code for the Fujitsu FR-V, for GDB, the GNU Debugger. - Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010, 2011 - Free Software Foundation, Inc. + Copyright (C) 2002-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -19,7 +18,6 @@ along with this program. If not, see . */ #include "defs.h" -#include "gdb_string.h" #include "inferior.h" #include "gdbcore.h" #include "arch-utils.h" @@ -29,7 +27,6 @@ #include "frame-base.h" #include "trad-frame.h" #include "dis-asm.h" -#include "gdb_assert.h" #include "sim-regno.h" #include "gdb/sim-frv.h" #include "opcodes/frv-desc.h" /* for the H_SPR_... enums */ @@ -40,8 +37,7 @@ #include "infcall.h" #include "solib.h" #include "frv-tdep.h" - -extern void _initialize_frv_tdep (void); +#include "objfiles.h" struct frv_unwind_cache /* was struct frame_extra_info */ { @@ -89,7 +85,7 @@ struct gdbarch_tdep int num_hw_breakpoints; /* Register names. */ - char **register_names; + const char **register_names; }; /* Return the FR-V ABI associated with GDBARCH. */ @@ -137,11 +133,9 @@ new_variant (void) { struct gdbarch_tdep *var; int r; - char buf[20]; - var = xmalloc (sizeof (*var)); - memset (var, 0, sizeof (*var)); - + var = XCNEW (struct gdbarch_tdep); + var->frv_abi = FRV_ABI_EABI; var->num_gprs = 64; var->num_fprs = 64; @@ -151,8 +145,8 @@ new_variant (void) /* By default, don't supply any general-purpose or floating-point register names. */ var->register_names - = (char **) xmalloc ((frv_num_regs + frv_num_pseudo_regs) - * sizeof (char *)); + = (const char **) xmalloc ((frv_num_regs + frv_num_pseudo_regs) + * sizeof (const char *)); for (r = 0; r < frv_num_regs + frv_num_pseudo_regs; r++) var->register_names[r] = ""; @@ -235,7 +229,7 @@ set_variant_num_gprs (struct gdbarch_tdep *var, int num_gprs) { char buf[20]; - sprintf (buf, "gr%d", r); + xsnprintf (buf, sizeof (buf), "gr%d", r); var->register_names[first_gpr_regnum + r] = xstrdup (buf); } } @@ -254,7 +248,7 @@ set_variant_num_fprs (struct gdbarch_tdep *var, int num_fprs) { char buf[20]; - sprintf (buf, "fr%d", r); + xsnprintf (buf, sizeof (buf), "fr%d", r); var->register_names[first_fpr_regnum + r] = xstrdup (buf); } } @@ -264,7 +258,8 @@ set_variant_abi_fdpic (struct gdbarch_tdep *var) { var->frv_abi = FRV_ABI_FDPIC; var->register_names[fdpic_loadmap_exec_regnum] = xstrdup ("loadmap_exec"); - var->register_names[fdpic_loadmap_interp_regnum] = xstrdup ("loadmap_interp"); + var->register_names[fdpic_loadmap_interp_regnum] + = xstrdup ("loadmap_interp"); } static void @@ -299,14 +294,17 @@ frv_register_type (struct gdbarch *gdbarch, int reg) return builtin_type (gdbarch)->builtin_int32; } -static void -frv_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, +static enum register_status +frv_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int reg, gdb_byte *buffer) { + enum register_status status; + if (reg == iacc0_regnum) { - regcache_raw_read (regcache, iacc0h_regnum, buffer); - regcache_raw_read (regcache, iacc0l_regnum, (bfd_byte *) buffer + 4); + status = regcache->raw_read (iacc0h_regnum, buffer); + if (status == REG_VALID) + status = regcache->raw_read (iacc0l_regnum, (bfd_byte *) buffer + 4); } else if (accg0_regnum <= reg && reg <= accg7_regnum) { @@ -315,14 +313,22 @@ frv_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, int raw_regnum = accg0123_regnum + (reg - accg0_regnum) / 4; int byte_num = (reg - accg0_regnum) % 4; - bfd_byte buf[4]; + gdb_byte buf[4]; - regcache_raw_read (regcache, raw_regnum, buf); - memset (buffer, 0, 4); - /* FR-V is big endian, so put the requested byte in the first byte - of the buffer allocated to hold the pseudo-register. */ - ((bfd_byte *) buffer)[0] = buf[byte_num]; + status = regcache->raw_read (raw_regnum, buf); + if (status == REG_VALID) + { + memset (buffer, 0, 4); + /* FR-V is big endian, so put the requested byte in the + first byte of the buffer allocated to hold the + pseudo-register. */ + buffer[0] = buf[byte_num]; + } } + else + gdb_assert_not_reached ("invalid pseudo register number"); + + return status; } static void @@ -331,8 +337,8 @@ frv_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, { if (reg == iacc0_regnum) { - regcache_raw_write (regcache, iacc0h_regnum, buffer); - regcache_raw_write (regcache, iacc0l_regnum, (bfd_byte *) buffer + 4); + regcache->raw_write (iacc0h_regnum, buffer); + regcache->raw_write (iacc0l_regnum, (bfd_byte *) buffer + 4); } else if (accg0_regnum <= reg && reg <= accg7_regnum) { @@ -341,11 +347,11 @@ frv_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, int raw_regnum = accg0123_regnum + (reg - accg0_regnum) / 4; int byte_num = (reg - accg0_regnum) % 4; - char buf[4]; + gdb_byte buf[4]; - regcache_raw_read (regcache, raw_regnum, buf); + regcache->raw_read (raw_regnum, buf); buf[byte_num] = ((bfd_byte *) buffer)[0]; - regcache_raw_write (regcache, raw_regnum, buf); + regcache->raw_write (raw_regnum, buf); } } @@ -416,13 +422,9 @@ frv_register_sim_regno (struct gdbarch *gdbarch, int reg) internal_error (__FILE__, __LINE__, _("Bad register number %d"), reg); } -static const unsigned char * -frv_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenp) -{ - static unsigned char breakpoint[] = {0xc0, 0x70, 0x00, 0x01}; - *lenp = sizeof (breakpoint); - return breakpoint; -} +constexpr gdb_byte frv_break_insn[] = {0xc0, 0x70, 0x00, 0x01}; + +typedef BP_MANIPULATION (frv_break_insn) frv_breakpoint; /* Define the maximum number of instructions which may be packed into a bundle (VLIW instruction). */ @@ -443,10 +445,10 @@ frv_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr) /* Find the end of the previous packing sequence. This will be indicated by either attempting to access some inaccessible memory or by finding - an instruction word whose packing bit is set to one. */ + an instruction word whose packing bit is set to one. */ while (count-- > 0 && addr >= func_start) { - char instr[frv_instr_size]; + gdb_byte instr[frv_instr_size]; int status; status = target_read_memory (addr, instr, sizeof instr); @@ -522,7 +524,7 @@ frv_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, J - The register number of GRj in the instruction description. K - The register number of GRk in the instruction description. I - The register number of GRi. - S - a signed imediate offset. + S - a signed immediate offset. U - an unsigned immediate offset. The dots below the numbers indicate where hex digit boundaries @@ -536,7 +538,7 @@ frv_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, the stack pointer to frame pointer: fp = sp + fp_offset. */ int fp_offset = 0; - /* Total size of frame prior to any alloca operations. */ + /* Total size of frame prior to any alloca operations. */ int framesize = 0; /* Flag indicating if lr has been saved on the stack. */ @@ -559,7 +561,7 @@ frv_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, /* The address of the most recently scanned prologue instruction. */ CORE_ADDR last_prologue_pc; - /* The address of the next instruction. */ + /* The address of the next instruction. */ CORE_ADDR next_pc; /* The upper bound to of the pc values to scan. */ @@ -592,7 +594,7 @@ frv_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, /* Scan the prologue. */ while (pc < lim_pc) { - char buf[frv_instr_size]; + gdb_byte buf[frv_instr_size]; LONGEST op; if (target_read_memory (pc, buf, sizeof buf) != 0) @@ -954,7 +956,8 @@ frv_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, /* If LR was saved on the stack, record its location. */ if (lr_saved_on_stack) - info->saved_regs[lr_regnum].addr = this_base - fp_offset + lr_sp_offset; + info->saved_regs[lr_regnum].addr + = this_base - fp_offset + lr_sp_offset; /* The call instruction moves the caller's PC in the callee's LR. Since this is an unwind, do the reverse. Copy the location of LR @@ -1022,7 +1025,7 @@ frv_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) to the call instruction. Skip over this instruction if present. It won't be present in - non-PIC code, and even in PIC code, it might not be present. + non-PIC code, and even in PIC code, it might not be present. (This is due to the fact that GR15, the FDPIC register, already contains the correct value.) @@ -1061,7 +1064,7 @@ frv_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { LONGEST displ; CORE_ADDR call_dest; - struct minimal_symbol *s; + struct bound_minimal_symbol s; displ = ((op & 0xfe000000) >> 7) | (op & 0x0003ffff); if ((displ & 0x00800000) != 0) @@ -1070,9 +1073,9 @@ frv_skip_main_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) call_dest = pc + 4 * displ; s = lookup_minimal_symbol_by_pc (call_dest); - if (s != NULL - && SYMBOL_LINKAGE_NAME (s) != NULL - && strcmp (SYMBOL_LINKAGE_NAME (s), "__main") == 0) + if (s.minsym != NULL + && s.minsym->linkage_name () != NULL + && strcmp (s.minsym->linkage_name (), "__main") == 0) { pc += 4; return pc; @@ -1087,12 +1090,10 @@ frv_frame_unwind_cache (struct frame_info *this_frame, void **this_prologue_cache) { struct gdbarch *gdbarch = get_frame_arch (this_frame); - CORE_ADDR pc; - ULONGEST this_base; struct frv_unwind_cache *info; if ((*this_prologue_cache)) - return (*this_prologue_cache); + return (struct frv_unwind_cache *) (*this_prologue_cache); info = FRAME_OBSTACK_ZALLOC (struct frv_unwind_cache); (*this_prologue_cache) = info; @@ -1109,7 +1110,7 @@ static void frv_extract_return_value (struct type *type, struct regcache *regcache, gdb_byte *valbuf) { - struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch *gdbarch = regcache->arch (); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int len = TYPE_LENGTH (type); @@ -1122,13 +1123,15 @@ frv_extract_return_value (struct type *type, struct regcache *regcache, else if (len == 8) { ULONGEST regval; + regcache_cooked_read_unsigned (regcache, 8, ®val); store_unsigned_integer (valbuf, 4, byte_order, regval); regcache_cooked_read_unsigned (regcache, 9, ®val); store_unsigned_integer ((bfd_byte *) valbuf + 4, 4, byte_order, regval); } else - internal_error (__FILE__, __LINE__, _("Illegal return value length: %d"), len); + internal_error (__FILE__, __LINE__, + _("Illegal return value length: %d"), len); } static CORE_ADDR @@ -1143,7 +1146,7 @@ find_func_descr (struct gdbarch *gdbarch, CORE_ADDR entry_point) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR descr; - char valbuf[4]; + gdb_byte valbuf[4]; CORE_ADDR start_addr; /* If we can't find the function in the symbol table, then we assume @@ -1190,13 +1193,14 @@ static CORE_ADDR frv_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) + function_call_return_method return_method, + CORE_ADDR struct_addr) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int argreg; int argnum; - char *val; - char valbuf[4]; + const gdb_byte *val; + gdb_byte valbuf[4]; struct value *arg; struct type *arg_type; int len; @@ -1220,14 +1224,14 @@ frv_push_dummy_call (struct gdbarch *gdbarch, struct value *function, if (stack_space > 0) sp -= stack_space; - /* Make sure stack is dword aligned. */ + /* Make sure stack is dword aligned. */ sp = align_down (sp, 8); stack_offset = 0; argreg = 8; - if (struct_return) + if (return_method == return_method_struct) regcache_cooked_write_unsigned (regcache, struct_return_regnum, struct_addr); @@ -1263,7 +1267,7 @@ frv_push_dummy_call (struct gdbarch *gdbarch, struct value *function, } else { - val = (char *) value_contents (arg); + val = value_contents (arg); } while (len > 0) @@ -1284,7 +1288,8 @@ frv_push_dummy_call (struct gdbarch *gdbarch, struct value *function, { #if 0 printf(" Argnum %d data %x -> offset %d (%x)\n", - argnum, *((int *)val), stack_offset, (int) (sp + stack_offset)); + argnum, *((int *)val), stack_offset, + (int) (sp + stack_offset)); #endif write_memory (sp + stack_offset, val, partial_len); stack_offset += align_up (partial_len, 4); @@ -1323,12 +1328,12 @@ frv_store_return_value (struct type *type, struct regcache *regcache, bfd_byte val[4]; memset (val, 0, sizeof (val)); memcpy (val + (4 - len), valbuf, len); - regcache_cooked_write (regcache, 8, val); + regcache->cooked_write (8, val); } else if (len == 8) { - regcache_cooked_write (regcache, 8, valbuf); - regcache_cooked_write (regcache, 9, (bfd_byte *) valbuf + 4); + regcache->cooked_write (8, valbuf); + regcache->cooked_write (9, (bfd_byte *) valbuf + 4); } else internal_error (__FILE__, __LINE__, @@ -1336,7 +1341,7 @@ frv_store_return_value (struct type *type, struct regcache *regcache, } static enum return_value_convention -frv_return_value (struct gdbarch *gdbarch, struct type *func_type, +frv_return_value (struct gdbarch *gdbarch, struct value *function, struct type *valtype, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { @@ -1362,78 +1367,6 @@ frv_return_value (struct gdbarch *gdbarch, struct type *func_type, return RETURN_VALUE_REGISTER_CONVENTION; } - -/* Hardware watchpoint / breakpoint support for the FR500 - and FR400. */ - -int -frv_check_watch_resources (struct gdbarch *gdbarch, int type, int cnt, int ot) -{ - struct gdbarch_tdep *var = gdbarch_tdep (gdbarch); - - /* Watchpoints not supported on simulator. */ - if (strcmp (target_shortname, "sim") == 0) - return 0; - - if (type == bp_hardware_breakpoint) - { - if (var->num_hw_breakpoints == 0) - return 0; - else if (cnt <= var->num_hw_breakpoints) - return 1; - } - else - { - if (var->num_hw_watchpoints == 0) - return 0; - else if (ot) - return -1; - else if (cnt <= var->num_hw_watchpoints) - return 1; - } - return -1; -} - - -int -frv_stopped_data_address (CORE_ADDR *addr_p) -{ - struct frame_info *frame = get_current_frame (); - CORE_ADDR brr, dbar0, dbar1, dbar2, dbar3; - - brr = get_frame_register_unsigned (frame, brr_regnum); - dbar0 = get_frame_register_unsigned (frame, dbar0_regnum); - dbar1 = get_frame_register_unsigned (frame, dbar1_regnum); - dbar2 = get_frame_register_unsigned (frame, dbar2_regnum); - dbar3 = get_frame_register_unsigned (frame, dbar3_regnum); - - if (brr & (1<<11)) - *addr_p = dbar0; - else if (brr & (1<<10)) - *addr_p = dbar1; - else if (brr & (1<<9)) - *addr_p = dbar2; - else if (brr & (1<<8)) - *addr_p = dbar3; - else - return 0; - - return 1; -} - -int -frv_have_stopped_data_address (void) -{ - CORE_ADDR addr = 0; - return frv_stopped_data_address (&addr); -} - -static CORE_ADDR -frv_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) -{ - return frame_unwind_register_unsigned (next_frame, pc_regnum); -} - /* Given a GDB frame, determine the address of the calling function's frame. This will be used to create a new GDB frame struct. */ @@ -1445,7 +1378,7 @@ frv_frame_this_id (struct frame_info *this_frame, = frv_frame_unwind_cache (this_frame, this_prologue_cache); CORE_ADDR base; CORE_ADDR func; - struct minimal_symbol *msym_stack; + struct bound_minimal_symbol msym_stack; struct frame_id id; /* The FUNC is easy. */ @@ -1453,7 +1386,7 @@ frv_frame_this_id (struct frame_info *this_frame, /* Check if the stack is empty. */ msym_stack = lookup_minimal_symbol ("_stack", NULL, NULL); - if (msym_stack && info->base == SYMBOL_VALUE_ADDRESS (msym_stack)) + if (msym_stack.minsym && info->base == BMSYMBOL_VALUE_ADDRESS (msym_stack)) return; /* Hopefully the prologue analysis either correctly determined the @@ -1478,6 +1411,7 @@ frv_frame_prev_register (struct frame_info *this_frame, static const struct frame_unwind frv_frame_unwind = { NORMAL_FRAME, + default_frame_unwind_stop_reason, frv_frame_this_id, frv_frame_prev_register, NULL, @@ -1499,24 +1433,6 @@ static const struct frame_base frv_frame_base = { frv_frame_base_address }; -static CORE_ADDR -frv_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) -{ - return frame_unwind_register_unsigned (next_frame, sp_regnum); -} - - -/* Assuming THIS_FRAME is a dummy, return the frame ID of that dummy - frame. The frame ID's base needs to match the TOS value saved by - save_dummy_frame_tos(), and the PC match the dummy frame's breakpoint. */ - -static struct frame_id -frv_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) -{ - CORE_ADDR sp = get_frame_register_unsigned (this_frame, sp_regnum); - return frame_id_build (sp, get_frame_pc (this_frame)); -} - static struct gdbarch * frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { @@ -1536,6 +1452,7 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { case bfd_mach_frv: case bfd_mach_frvsimple: + case bfd_mach_fr300: case bfd_mach_fr500: case bfd_mach_frvtomcat: case bfd_mach_fr550: @@ -1591,15 +1508,14 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_skip_prologue (gdbarch, frv_skip_prologue); set_gdbarch_skip_main_prologue (gdbarch, frv_skip_main_prologue); - set_gdbarch_breakpoint_from_pc (gdbarch, frv_breakpoint_from_pc); + set_gdbarch_breakpoint_kind_from_pc (gdbarch, frv_breakpoint::kind_from_pc); + set_gdbarch_sw_breakpoint_from_kind (gdbarch, frv_breakpoint::bp_from_kind); set_gdbarch_adjust_breakpoint_address (gdbarch, frv_adjust_breakpoint_address); set_gdbarch_return_value (gdbarch, frv_return_value); /* Frame stuff. */ - set_gdbarch_unwind_pc (gdbarch, frv_unwind_pc); - set_gdbarch_unwind_sp (gdbarch, frv_unwind_sp); set_gdbarch_frame_align (gdbarch, frv_frame_align); frame_base_set_default (gdbarch, &frv_frame_base); /* We set the sniffer lower down after the OSABI hooks have been @@ -1607,7 +1523,6 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Settings for calling functions in the inferior. */ set_gdbarch_push_dummy_call (gdbarch, frv_push_dummy_call); - set_gdbarch_dummy_id (gdbarch, frv_dummy_id); /* Settings that should be unnecessary. */ set_gdbarch_inner_than (gdbarch, core_addr_lessthan); @@ -1617,6 +1532,7 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { case bfd_mach_frv: case bfd_mach_frvsimple: + case bfd_mach_fr300: case bfd_mach_fr500: case bfd_mach_frvtomcat: /* fr500-style hardware debugging support. */ @@ -1638,7 +1554,6 @@ frv_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) break; } - set_gdbarch_print_insn (gdbarch, print_insn_frv); if (frv_abi (gdbarch) == FRV_ABI_FDPIC) set_gdbarch_convert_from_func_ptr_addr (gdbarch, frv_convert_from_func_ptr_addr);