X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmips-tdep.c;h=0852851595f0eac5008283d992379415cda61831;hb=f1d293cc58bfe5f6b507dc2351f17632df8ab677;hp=cc67cd3bddd2683fadf3cb753a6b9fdeb1dad365;hpb=ea33cd9290063d977fb2c31ea6a8567da585ab88;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index cc67cd3bdd..0852851595 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger. - Copyright (C) 1988-2018 Free Software Foundation, Inc. + Copyright (C) 1988-2019 Free Software Foundation, Inc. Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin. @@ -58,8 +58,6 @@ #include "target-float.h" #include -static const struct objfile_data *mips_pdr_data; - static struct type *mips_register_type (struct gdbarch *gdbarch, int regnum); static int mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, @@ -214,6 +212,18 @@ static unsigned int mips_debug = 0; struct target_desc *mips_tdesc_gp32; struct target_desc *mips_tdesc_gp64; +/* The current set of options to be passed to the disassembler. */ +static char *mips_disassembler_options; + +/* Implicit disassembler options for individual ABIs. These tell + libopcodes to use general-purpose register names corresponding + to the ABI we have selected, perhaps via a `set mips abi ...' + override, rather than ones inferred from the ABI set in the ELF + headers of the binary file selected for debugging. */ +static const char mips_disassembler_options_o32[] = "gpr-names=32"; +static const char mips_disassembler_options_n32[] = "gpr-names=n32"; +static const char mips_disassembler_options_n64[] = "gpr-names=64"; + const struct mips_regnum * mips_regnum (struct gdbarch *gdbarch) { @@ -510,11 +520,9 @@ mips_xfer_register (struct gdbarch *gdbarch, struct regcache *regcache, fprintf_unfiltered (gdb_stdlog, "%02x", out[buf_offset + i]); } if (in != NULL) - regcache_cooked_read_part (regcache, reg_num, reg_offset, length, - in + buf_offset); + regcache->cooked_read_part (reg_num, reg_offset, length, in + buf_offset); if (out != NULL) - regcache_cooked_write_part (regcache, reg_num, reg_offset, length, - out + buf_offset); + regcache->cooked_write_part (reg_num, reg_offset, length, out + buf_offset); if (mips_debug && in != NULL) { int i; @@ -775,12 +783,12 @@ mips_pseudo_register_write (struct gdbarch *gdbarch, gdb_assert (cookednum >= gdbarch_num_regs (gdbarch) && cookednum < 2 * gdbarch_num_regs (gdbarch)); if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum)) - regcache_raw_write (regcache, rawnum, buf); + regcache->raw_write (rawnum, buf); else if (register_size (gdbarch, rawnum) > register_size (gdbarch, cookednum)) { if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p) - regcache_raw_write_part (regcache, rawnum, 0, 4, buf); + regcache->raw_write_part (rawnum, 0, 4, buf); else { /* Sign extend the shortened version of the register prior @@ -850,7 +858,7 @@ static int heuristic_fence_post = 0; register N. NOTE: This defines the pseudo register type so need to rebuild the architecture vector. */ -static int mips64_transfers_32bit_regs_p = 0; +static bool mips64_transfers_32bit_regs_p = false; static void set_mips64_transfers_32bit_regs (const char *args, int from_tty, @@ -1888,12 +1896,30 @@ micromips_next_pc (struct regcache *regcache, CORE_ADDR pc) switch (micromips_op (insn >> 16)) { case 0x00: /* POOL32A: bits 000000 */ - if (b0s6_op (insn) == 0x3c - /* POOL32Axf: bits 000000 ... 111100 */ - && (b6s10_ext (insn) & 0x2bf) == 0x3c) - /* JALR, JALR.HB: 000000 000x111100 111100 */ - /* JALRS, JALRS.HB: 000000 010x111100 111100 */ - pc = regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16)); + switch (b0s6_op (insn)) + { + case 0x3c: /* POOL32Axf: bits 000000 ... 111100 */ + switch (b6s10_ext (insn)) + { + case 0x3c: /* JALR: 000000 0000111100 111100 */ + case 0x7c: /* JALR.HB: 000000 0001111100 111100 */ + case 0x13c: /* JALRS: 000000 0100111100 111100 */ + case 0x17c: /* JALRS.HB: 000000 0101111100 111100 */ + pc = regcache_raw_get_signed (regcache, + b0s5_reg (insn >> 16)); + break; + case 0x22d: /* SYSCALL: 000000 1000101101 111100 */ + { + struct gdbarch_tdep *tdep; + + tdep = gdbarch_tdep (gdbarch); + if (tdep->syscall_next_pc != NULL) + pc = tdep->syscall_next_pc (get_current_frame ()); + } + break; + } + break; + } break; case 0x10: /* POOL32I: bits 010000 */ @@ -3795,8 +3821,8 @@ mips_stub_frame_sniffer (const struct frame_unwind *self, stub. The stub for foo is named ".pic.foo". */ msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym != NULL - && MSYMBOL_LINKAGE_NAME (msym.minsym) != NULL - && startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.")) + && msym.minsym->linkage_name () != NULL + && startswith (msym.minsym->linkage_name (), ".pic.")) return 1; return 0; @@ -3882,7 +3908,7 @@ mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr) static std::vector mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc) { - CORE_ADDR breaks[2] = {-1, -1}; + CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX}; CORE_ADDR loc = pc; CORE_ADDR branch_bp; /* Breakpoint at branch instruction's destination. */ ULONGEST insn; @@ -3985,7 +4011,7 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch, { const int atomic_sequence_length = 16; /* Instruction sequence length. */ int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ - CORE_ADDR breaks[2] = {-1, -1}; + CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX}; CORE_ADDR branch_bp = 0; /* Breakpoint at branch instruction's destination. */ CORE_ADDR loc = pc; @@ -4467,12 +4493,13 @@ static CORE_ADDR mips_eabi_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) { int argreg; int float_argreg; int argnum; - int len = 0; + int arg_space = 0; int stack_offset = 0; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = find_function_addr (function, NULL); @@ -4499,20 +4526,21 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, than necessary for EABI, because the first few arguments are passed in registers, but that's OK. */ for (argnum = 0; argnum < nargs; argnum++) - len += align_up (TYPE_LENGTH (value_type (args[argnum])), abi_regsize); - sp -= align_up (len, 16); + arg_space += align_up (TYPE_LENGTH (value_type (args[argnum])), abi_regsize); + sp -= align_up (arg_space, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, "mips_eabi_push_dummy_call: sp=%s allocated %ld\n", - paddress (gdbarch, sp), (long) align_up (len, 16)); + paddress (gdbarch, sp), + (long) align_up (arg_space, 16)); /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ - if (struct_return) + if (return_method == return_method_struct) { if (mips_debug) fprintf_unfiltered (gdb_stdlog, @@ -4861,12 +4889,13 @@ static CORE_ADDR mips_n32n64_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) { int argreg; int float_argreg; int argnum; - int len = 0; + int arg_space = 0; int stack_offset = 0; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = find_function_addr (function, NULL); @@ -4890,20 +4919,21 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Now make space on the stack for the args. */ for (argnum = 0; argnum < nargs; argnum++) - len += align_up (TYPE_LENGTH (value_type (args[argnum])), MIPS64_REGSIZE); - sp -= align_up (len, 16); + arg_space += align_up (TYPE_LENGTH (value_type (args[argnum])), MIPS64_REGSIZE); + sp -= align_up (arg_space, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, "mips_n32n64_push_dummy_call: sp=%s allocated %ld\n", - paddress (gdbarch, sp), (long) align_up (len, 16)); + paddress (gdbarch, sp), + (long) align_up (arg_space, 16)); /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ - if (struct_return) + if (return_method == return_method_struct) { if (mips_debug) fprintf_unfiltered (gdb_stdlog, @@ -5317,12 +5347,13 @@ static CORE_ADDR mips_o32_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) { int argreg; int float_argreg; int argnum; - int len = 0; + int arg_space = 0; int stack_offset = 0; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = find_function_addr (function, NULL); @@ -5351,23 +5382,24 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Align to double-word if necessary. */ if (mips_type_needs_double_align (arg_type)) - len = align_up (len, MIPS32_REGSIZE * 2); + arg_space = align_up (arg_space, MIPS32_REGSIZE * 2); /* Allocate space on the stack. */ - len += align_up (TYPE_LENGTH (arg_type), MIPS32_REGSIZE); + arg_space += align_up (TYPE_LENGTH (arg_type), MIPS32_REGSIZE); } - sp -= align_up (len, 16); + sp -= align_up (arg_space, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, "mips_o32_push_dummy_call: sp=%s allocated %ld\n", - paddress (gdbarch, sp), (long) align_up (len, 16)); + paddress (gdbarch, sp), + (long) align_up (arg_space, 16)); /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ - if (struct_return) + if (return_method == return_method_struct) { if (mips_debug) fprintf_unfiltered (gdb_stdlog, @@ -5841,12 +5873,12 @@ mips_o64_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) { int argreg; int float_argreg; int argnum; - int len = 0; + int arg_space = 0; int stack_offset = 0; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = find_function_addr (function, NULL); @@ -5874,21 +5906,22 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct type *arg_type = check_typedef (value_type (args[argnum])); /* Allocate space on the stack. */ - len += align_up (TYPE_LENGTH (arg_type), MIPS64_REGSIZE); + arg_space += align_up (TYPE_LENGTH (arg_type), MIPS64_REGSIZE); } - sp -= align_up (len, 16); + sp -= align_up (arg_space, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, "mips_o64_push_dummy_call: sp=%s allocated %ld\n", - paddress (gdbarch, sp), (long) align_up (len, 16)); + paddress (gdbarch, sp), + (long) align_up (arg_space, 16)); /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ - if (struct_return) + if (return_method == return_method_struct) { if (mips_debug) fprintf_unfiltered (gdb_stdlog, @@ -6465,8 +6498,7 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame, /* For GP registers, we print a separate row of names above the vals. */ for (col = 0, regnum = start_regnum; - col < ncols && regnum < gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch); + col < ncols && regnum < gdbarch_num_cooked_regs (gdbarch); regnum++) { if (*gdbarch_register_name (gdbarch, regnum) == '\0') @@ -6504,8 +6536,7 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame, /* Now print the values in hex, 4 or 8 to the row. */ for (col = 0, regnum = start_regnum; - col < ncols && regnum < gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch); + col < ncols && regnum < gdbarch_num_cooked_regs (gdbarch); regnum++) { if (*gdbarch_register_name (gdbarch, regnum) == '\0') @@ -6571,8 +6602,7 @@ mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, /* Do all (or most) registers. */ { regnum = gdbarch_num_regs (gdbarch); - while (regnum < gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch)) + while (regnum < gdbarch_num_cooked_regs (gdbarch)) { if (mips_float_register_p (gdbarch, regnum)) { @@ -6992,40 +7022,9 @@ gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info) memaddr &= (info->mach == bfd_mach_mips16 || info->mach == bfd_mach_mips_micromips) ? ~1 : ~3; - /* Set the disassembler options. */ - if (!info->disassembler_options) - /* This string is not recognized explicitly by the disassembler, - but it tells the disassembler to not try to guess the ABI from - the bfd elf headers, such that, if the user overrides the ABI - of a program linked as NewABI, the disassembly will follow the - register naming conventions specified by the user. */ - info->disassembler_options = "gpr-names=32"; - return default_print_insn (memaddr, info); } -static int -gdb_print_insn_mips_n32 (bfd_vma memaddr, struct disassemble_info *info) -{ - /* Set up the disassembler info, so that we get the right - register names from libopcodes. */ - info->disassembler_options = "gpr-names=n32"; - info->flavour = bfd_target_elf_flavour; - - return gdb_print_insn_mips (memaddr, info); -} - -static int -gdb_print_insn_mips_n64 (bfd_vma memaddr, struct disassemble_info *info) -{ - /* Set up the disassembler info, so that we get the right - register names from libopcodes. */ - info->disassembler_options = "gpr-names=64"; - info->flavour = bfd_target_elf_flavour; - - return gdb_print_insn_mips (memaddr, info); -} - /* Implement the breakpoint_kind_from_pc gdbarch method. */ static int @@ -7819,8 +7818,8 @@ mips_skip_pic_trampoline_code (struct frame_info *frame, CORE_ADDR pc) msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym == NULL || BMSYMBOL_VALUE_ADDRESS (msym) != pc - || MSYMBOL_LINKAGE_NAME (msym.minsym) == NULL - || !startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.")) + || msym.minsym->linkage_name () == NULL + || !startswith (msym.minsym->linkage_name (), ".pic.")) return 0; /* A two-instruction header. */ @@ -7976,7 +7975,7 @@ static void mips_find_abi_section (bfd *abfd, asection *sect, void *obj) { enum mips_abi *abip = (enum mips_abi *) obj; - const char *name = bfd_get_section_name (abfd, sect); + const char *name = bfd_section_name (sect); if (*abip != MIPS_ABI_UNKNOWN) return; @@ -8004,7 +8003,7 @@ static void mips_find_long_section (bfd *abfd, asection *sect, void *obj) { int *lbp = (int *) obj; - const char *name = bfd_get_section_name (abfd, sect); + const char *name = bfd_section_name (sect); if (startswith (name, ".gcc_compiled_long32")) *lbp = 32; @@ -8729,12 +8728,19 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_print_registers_info (gdbarch, mips_print_registers_info); - if (mips_abi == MIPS_ABI_N32) - set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips_n32); - else if (mips_abi == MIPS_ABI_N64) - set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips_n64); + set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips); + if (mips_abi == MIPS_ABI_N64) + set_gdbarch_disassembler_options_implicit + (gdbarch, (const char *) mips_disassembler_options_n64); + else if (mips_abi == MIPS_ABI_N32) + set_gdbarch_disassembler_options_implicit + (gdbarch, (const char *) mips_disassembler_options_n32); else - set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips); + set_gdbarch_disassembler_options_implicit + (gdbarch, (const char *) mips_disassembler_options_o32); + set_gdbarch_disassembler_options (gdbarch, &mips_disassembler_options); + set_gdbarch_valid_disassembler_options (gdbarch, + disassembler_options_mips ()); /* FIXME: cagney/2003-08-29: The macros target_have_steppable_watchpoint, HAVE_NONSTEPPABLE_WATCHPOINT, and target_have_continuable_watchpoint @@ -8977,8 +8983,6 @@ _initialize_mips_tdep (void) gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep); - mips_pdr_data = register_objfile_data (); - /* Create feature sets with the appropriate properties. The values are not important. */ mips_tdesc_gp32 = allocate_target_description ();