X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fmips-tdep.c;h=41cb9d82c6ef473c1fbbf86601914f9a4f462411;hb=8a6200ba863f207d93467312431d107f50f0e2ab;hp=9d9451c786219882319dbf70ee44ca1c4c350826;hpb=7cbd4a934e9cf3808e1199c62e65b4c25b24b4e5;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 9d9451c786..41cb9d82c6 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-2013 Free Software Foundation, Inc. + Copyright (C) 1988-2017 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. @@ -21,8 +21,6 @@ along with this program. If not, see . */ #include "defs.h" -#include "gdb_string.h" -#include "gdb_assert.h" #include "frame.h" #include "inferior.h" #include "symtab.h" @@ -46,6 +44,7 @@ #include "symcat.h" #include "sim-regno.h" #include "dis-asm.h" +#include "disasm.h" #include "frame-unwind.h" #include "frame-base.h" #include "trad-frame.h" @@ -57,16 +56,27 @@ #include "user-regs.h" #include "valprint.h" #include "ax.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 *, CORE_ADDR); -static int micromips_instruction_has_delay_slot (struct gdbarch *, CORE_ADDR, - int); -static int mips16_instruction_has_delay_slot (struct gdbarch *, CORE_ADDR, - int); +static int mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, + ULONGEST inst); +static int micromips_instruction_has_delay_slot (ULONGEST insn, int mustbe32); +static int mips16_instruction_has_delay_slot (unsigned short inst, + int mustbe32); + +static int mips32_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, + CORE_ADDR addr); +static int micromips_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, + CORE_ADDR addr, int mustbe32); +static int mips16_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, + CORE_ADDR addr, int mustbe32); + +static void mips_print_float_info (struct gdbarch *, struct ui_file *, + struct frame_info *, const char *); /* A useful bit in the CP0 status register (MIPS_PS_REGNUM). */ /* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip. */ @@ -99,6 +109,23 @@ static const char *const mips_abi_strings[] = { NULL }; +/* Enum describing the different kinds of breakpoints. */ + +enum mips_breakpoint_kind +{ + /* 16-bit MIPS16 mode breakpoint. */ + MIPS_BP_KIND_MIPS16 = 2, + + /* 16-bit microMIPS mode breakpoint. */ + MIPS_BP_KIND_MICROMIPS16 = 3, + + /* 32-bit standard MIPS mode breakpoint. */ + MIPS_BP_KIND_MIPS32 = 4, + + /* 32-bit microMIPS mode breakpoint. */ + MIPS_BP_KIND_MICROMIPS32 = 5, +}; + /* For backwards compatibility we default to MIPS16. This flag is overridden as soon as unambiguous ELF file flags tell us the compressed ISA encoding used. */ @@ -335,6 +362,15 @@ make_compact_addr (CORE_ADDR addr) return ((addr) | (CORE_ADDR) 1); } +/* Extern version of unmake_compact_addr; we use a separate function + so that unmake_compact_addr can be inlined throughout this file. */ + +CORE_ADDR +mips_unmake_compact_addr (CORE_ADDR addr) +{ + return unmake_compact_addr (addr); +} + /* Functions for setting and testing a bit in a minimal symbol that marks it as MIPS16 or microMIPS function. The MSB of the minimal symbol's "info" field is used for this purpose. @@ -343,8 +379,9 @@ make_compact_addr (CORE_ADDR addr) "special", i.e. refers to a MIPS16 or microMIPS function, and sets one of the "special" bits in a minimal symbol to mark it accordingly. The test checks an ELF-private flag that is valid for true function - symbols only; in particular synthetic symbols such as for PLT stubs - have no ELF-private part at all. + symbols only; for synthetic symbols such as for PLT stubs that have + no ELF-private part at all the MIPS BFD backend arranges for this + information to be carried in the asymbol's udata field instead. msymbol_is_mips16 and msymbol_is_micromips test the "special" bit in a minimal symbol. */ @@ -353,14 +390,25 @@ static void mips_elf_make_msymbol_special (asymbol * sym, struct minimal_symbol *msym) { elf_symbol_type *elfsym = (elf_symbol_type *) sym; + unsigned char st_other; - if ((sym->flags & BSF_SYNTHETIC) != 0) + if ((sym->flags & BSF_SYNTHETIC) == 0) + st_other = elfsym->internal_elf_sym.st_other; + else if ((sym->flags & BSF_FUNCTION) != 0) + st_other = sym->udata.i; + else return; - if (ELF_ST_IS_MICROMIPS (elfsym->internal_elf_sym.st_other)) - MSYMBOL_TARGET_FLAG_2 (msym) = 1; - else if (ELF_ST_IS_MIPS16 (elfsym->internal_elf_sym.st_other)) - MSYMBOL_TARGET_FLAG_1 (msym) = 1; + if (ELF_ST_IS_MICROMIPS (st_other)) + { + MSYMBOL_TARGET_FLAG_MICROMIPS (msym) = 1; + SET_MSYMBOL_VALUE_ADDRESS (msym, MSYMBOL_VALUE_RAW_ADDRESS (msym) | 1); + } + else if (ELF_ST_IS_MIPS16 (st_other)) + { + MSYMBOL_TARGET_FLAG_MIPS16 (msym) = 1; + SET_MSYMBOL_VALUE_ADDRESS (msym, MSYMBOL_VALUE_RAW_ADDRESS (msym) | 1); + } } /* Return one iff MSYM refers to standard ISA code. */ @@ -368,7 +416,8 @@ mips_elf_make_msymbol_special (asymbol * sym, struct minimal_symbol *msym) static int msymbol_is_mips (struct minimal_symbol *msym) { - return !(MSYMBOL_TARGET_FLAG_1 (msym) | MSYMBOL_TARGET_FLAG_2 (msym)); + return !(MSYMBOL_TARGET_FLAG_MIPS16 (msym) + | MSYMBOL_TARGET_FLAG_MICROMIPS (msym)); } /* Return one iff MSYM refers to MIPS16 code. */ @@ -376,7 +425,7 @@ msymbol_is_mips (struct minimal_symbol *msym) static int msymbol_is_mips16 (struct minimal_symbol *msym) { - return MSYMBOL_TARGET_FLAG_1 (msym); + return MSYMBOL_TARGET_FLAG_MIPS16 (msym); } /* Return one iff MSYM refers to microMIPS code. */ @@ -384,7 +433,36 @@ msymbol_is_mips16 (struct minimal_symbol *msym) static int msymbol_is_micromips (struct minimal_symbol *msym) { - return MSYMBOL_TARGET_FLAG_2 (msym); + return MSYMBOL_TARGET_FLAG_MICROMIPS (msym); +} + +/* Set the ISA bit in the main symbol too, complementing the corresponding + minimal symbol setting and reflecting the run-time value of the symbol. + The need for comes from the ISA bit having been cleared as code in + `_bfd_mips_elf_symbol_processing' separated it into the ELF symbol's + `st_other' STO_MIPS16 or STO_MICROMIPS annotation, making the values + of symbols referring to compressed code different in GDB to the values + used by actual code. That in turn makes them evaluate incorrectly in + expressions, producing results different to what the same expressions + yield when compiled into the program being debugged. */ + +static void +mips_make_symbol_special (struct symbol *sym, struct objfile *objfile) +{ + if (SYMBOL_CLASS (sym) == LOC_BLOCK) + { + /* We are in symbol reading so it is OK to cast away constness. */ + struct block *block = (struct block *) SYMBOL_BLOCK_VALUE (sym); + CORE_ADDR compact_block_start; + struct bound_minimal_symbol msym; + + compact_block_start = BLOCK_START (block) | 1; + msym = lookup_minimal_symbol_by_pc (compact_block_start); + if (msym.minsym && !msymbol_is_mips (msym.minsym)) + { + BLOCK_START (block) = compact_block_start; + } + } } /* XFER a value from the big/little/left end of the register. @@ -500,19 +578,6 @@ static const char *mips_generic_reg_names[NUM_MIPS_PROCESSOR_REGS] = { "fsr", "fir", }; -/* Names of IDT R3041 registers. */ - -static const char *mips_r3041_reg_names[] = { - "sr", "lo", "hi", "bad", "cause", "pc", - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - "fsr", "fir", "", /*"fp" */ "", - "", "", "bus", "ccfg", "", "", "", "", - "", "", "port", "cmp", "", "", "epc", "prid", -}; - /* Names of tx39 registers. */ static const char *mips_tx39_reg_names[NUM_MIPS_PROCESSOR_REGS] = { @@ -526,15 +591,6 @@ static const char *mips_tx39_reg_names[NUM_MIPS_PROCESSOR_REGS] = { "", "", "config", "cache", "debug", "depc", "epc", }; -/* Names of IRIX registers. */ -static const char *mips_irix_reg_names[NUM_MIPS_PROCESSOR_REGS] = { - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", - "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", - "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", - "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", - "pc", "cause", "bad", "hi", "lo", "fsr", "fir" -}; - /* Names of registers with Linux kernels. */ static const char *mips_linux_reg_names[NUM_MIPS_PROCESSOR_REGS] = { "sr", "lo", "hi", "bad", "cause", "pc", @@ -787,7 +843,7 @@ static const signed char mips_reg3_to_reg[8] = { 16, 17, 2, 3, 4, 5, 6, 7 }; time across a 2400 baud serial line. Allows the user to limit this search. */ -static unsigned int heuristic_fence_post = 0; +static int heuristic_fence_post = 0; /* Number of bytes of storage in the actual machine representation for register N. NOTE: This defines the pseudo register type so need to @@ -973,8 +1029,7 @@ mips_register_type (struct gdbarch *gdbarch, int regnum) if (rawnum == mips_regnum (gdbarch)->fp_control_status || rawnum == mips_regnum (gdbarch)->fp_implementation_revision) return builtin_type (gdbarch)->builtin_int32; - else if (gdbarch_osabi (gdbarch) != GDB_OSABI_IRIX - && gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX + else if (gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX && rawnum >= MIPS_FIRST_EMBED_REGNUM && rawnum <= MIPS_LAST_EMBED_REGNUM) /* The pseudo/cooked view of the embedded registers is always @@ -1014,11 +1069,18 @@ mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum) if (TYPE_LENGTH (rawtype) == 0) return rawtype; + /* Present the floating point registers however the hardware did; + do not try to convert between FPU layouts. */ if (mips_float_register_p (gdbarch, rawnum)) - /* Present the floating point registers however the hardware did; - do not try to convert between FPU layouts. */ return rawtype; + /* Floating-point control registers are always 32-bit even though for + backwards compatibility reasons 64-bit targets will transfer them + as 64-bit quantities even if using XML descriptions. */ + if (rawnum == mips_regnum (gdbarch)->fp_control_status + || rawnum == mips_regnum (gdbarch)->fp_implementation_revision) + return builtin_type (gdbarch)->builtin_int32; + /* Use pointer types for registers if we can. For n32 we can not, since we do not have a 64-bit pointer type. */ if (mips_abi_regsize (gdbarch) @@ -1043,19 +1105,16 @@ mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum) && rawnum < mips_regnum (gdbarch)->dspacc + 6))) return builtin_type (gdbarch)->builtin_int32; - if (gdbarch_osabi (gdbarch) != GDB_OSABI_IRIX - && gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX - && rawnum >= MIPS_EMBED_FP0_REGNUM + 32 + /* The pseudo/cooked view of embedded registers is always + 32-bit, even if the target transfers 64-bit values for them. + New targets relying on XML descriptions should only transfer + the necessary 32 bits, but older versions of GDB expected 64, + so allow the target to provide 64 bits without interfering + with the displayed type. */ + if (gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX + && rawnum >= MIPS_FIRST_EMBED_REGNUM && rawnum <= MIPS_LAST_EMBED_REGNUM) - { - /* The pseudo/cooked view of embedded registers is always - 32-bit, even if the target transfers 64-bit values for them. - New targets relying on XML descriptions should only transfer - the necessary 32 bits, but older versions of GDB expected 64, - so allow the target to provide 64 bits without interfering - with the displayed type. */ - return builtin_type (gdbarch)->builtin_int32; - } + return builtin_type (gdbarch)->builtin_int32; /* For all other registers, pass through the hardware type. */ return rawtype; @@ -1121,7 +1180,7 @@ mips_pc_is_mips (CORE_ADDR memaddr) stored by elfread.c in the high bit of the info field. Use this to decide if the function is standard MIPS. Otherwise if bit 0 of the address is clear, then this is a standard MIPS function. */ - sym = lookup_minimal_symbol_by_pc (memaddr); + sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); if (sym.minsym) return msymbol_is_mips (sym.minsym); else @@ -1139,7 +1198,7 @@ mips_pc_is_mips16 (struct gdbarch *gdbarch, CORE_ADDR memaddr) elfread.c in the high bit of the info field. Use this to decide if the function is MIPS16. Otherwise if bit 0 of the address is set, then ELF file flags will tell if this is a MIPS16 function. */ - sym = lookup_minimal_symbol_by_pc (memaddr); + sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); if (sym.minsym) return msymbol_is_mips16 (sym.minsym); else @@ -1158,7 +1217,7 @@ mips_pc_is_micromips (struct gdbarch *gdbarch, CORE_ADDR memaddr) if the function is microMIPS. Otherwise if bit 0 of the address is set, then ELF file flags will tell if this is a microMIPS function. */ - sym = lookup_minimal_symbol_by_pc (memaddr); + sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); if (sym.minsym) return msymbol_is_micromips (sym.minsym); else @@ -1178,7 +1237,7 @@ mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr) this to decide if the function is MIPS16 or microMIPS or normal MIPS. Otherwise if bit 0 of the address is set, then ELF file flags will tell if this is a MIPS16 or a microMIPS function. */ - sym = lookup_minimal_symbol_by_pc (memaddr); + sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr)); if (sym.minsym) { if (msymbol_is_micromips (sym.minsym)) @@ -1199,6 +1258,67 @@ mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr) } } +/* Set the ISA bit correctly in the PC, used by DWARF-2 machinery. + The need for comes from the ISA bit having been cleared, making + addresses in FDE, range records, etc. referring to compressed code + different to those in line information, the symbol table and finally + the PC register. That in turn confuses many operations. */ + +static CORE_ADDR +mips_adjust_dwarf2_addr (CORE_ADDR pc) +{ + pc = unmake_compact_addr (pc); + return mips_pc_is_mips (pc) ? pc : make_compact_addr (pc); +} + +/* Recalculate the line record requested so that the resulting PC has + the ISA bit set correctly, used by DWARF-2 machinery. The need for + this adjustment comes from some records associated with compressed + code having the ISA bit cleared, most notably at function prologue + ends. The ISA bit is in this context retrieved from the minimal + symbol covering the address requested, which in turn has been + constructed from the binary's symbol table rather than DWARF-2 + information. The correct setting of the ISA bit is required for + breakpoint addresses to correctly match against the stop PC. + + As line entries can specify relative address adjustments we need to + keep track of the absolute value of the last line address recorded + in line information, so that we can calculate the actual address to + apply the ISA bit adjustment to. We use PC for this tracking and + keep the original address there. + + As such relative address adjustments can be odd within compressed + code we need to keep track of the last line address with the ISA + bit adjustment applied too, as the original address may or may not + have had the ISA bit set. We use ADJ_PC for this tracking and keep + the adjusted address there. + + For relative address adjustments we then use these variables to + calculate the address intended by line information, which will be + PC-relative, and return an updated adjustment carrying ISA bit + information, which will be ADJ_PC-relative. For absolute address + adjustments we just return the same address that we store in ADJ_PC + too. + + As the first line entry can be relative to an implied address value + of 0 we need to have the initial address set up that we store in PC + and ADJ_PC. This is arranged with a call from `dwarf_decode_lines_1' + that sets PC to 0 and ADJ_PC accordingly, usually 0 as well. */ + +static CORE_ADDR +mips_adjust_dwarf2_line (CORE_ADDR addr, int rel) +{ + static CORE_ADDR adj_pc; + static CORE_ADDR pc; + CORE_ADDR isa_pc; + + pc = rel ? pc + addr : addr; + isa_pc = mips_adjust_dwarf2_addr (pc); + addr = rel ? isa_pc - adj_pc : isa_pc; + adj_pc = isa_pc; + return addr; +} + /* Various MIPS16 thunk (aka stub or trampoline) names. */ static const char mips_str_mips16_call_stub[] = "__mips16_call_stub_"; @@ -1225,14 +1345,13 @@ mips_in_frame_stub (CORE_ADDR pc) return 0; /* If the PC is in __mips16_call_stub_*, this is a call/return stub. */ - if (strncmp (name, mips_str_mips16_call_stub, - strlen (mips_str_mips16_call_stub)) == 0) + if (startswith (name, mips_str_mips16_call_stub)) return 1; /* If the PC is in __call_stub_*, this is a call/return or a call stub. */ - if (strncmp (name, mips_str_call_stub, strlen (mips_str_call_stub)) == 0) + if (startswith (name, mips_str_call_stub)) return 1; /* If the PC is in __fn_stub_*, this is a call stub. */ - if (strncmp (name, mips_str_fn_stub, strlen (mips_str_fn_stub)) == 0) + if (startswith (name, mips_str_fn_stub)) return 1; return 0; /* Not a stub. */ @@ -1245,11 +1364,9 @@ static CORE_ADDR mips_read_pc (struct regcache *regcache) { int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache)); - ULONGEST pc; + LONGEST pc; regcache_cooked_read_signed (regcache, regnum, &pc); - if (is_compact_addr (pc)) - pc = unmake_compact_addr (pc); return pc; } @@ -1259,8 +1376,6 @@ mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) CORE_ADDR pc; pc = frame_unwind_register_signed (next_frame, gdbarch_pc_regnum (gdbarch)); - if (is_compact_addr (pc)) - pc = unmake_compact_addr (pc); /* macro/2012-04-20: This hack skips over MIPS16 call thunks as intermediate frames. In this case we can get the caller's address from $ra, or if $ra contains an address within a thunk as well, then @@ -1270,15 +1385,9 @@ mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { pc = frame_unwind_register_signed (next_frame, gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM); - if (is_compact_addr (pc)) - pc = unmake_compact_addr (pc); if (mips_in_frame_stub (pc)) - { - pc = frame_unwind_register_signed - (next_frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM); - if (is_compact_addr (pc)) - pc = unmake_compact_addr (pc); - } + pc = frame_unwind_register_signed + (next_frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM); } return pc; } @@ -1312,10 +1421,7 @@ mips_write_pc (struct regcache *regcache, CORE_ADDR pc) { int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache)); - if (mips_pc_is_mips (pc)) - regcache_cooked_write_unsigned (regcache, regnum, pc); - else - regcache_cooked_write_unsigned (regcache, regnum, make_compact_addr (pc)); + regcache_cooked_write_unsigned (regcache, regnum, pc); } /* Fetch and return instruction from the specified location. Handle @@ -1323,12 +1429,12 @@ mips_write_pc (struct regcache *regcache, CORE_ADDR pc) static ULONGEST mips_fetch_instruction (struct gdbarch *gdbarch, - enum mips_isa isa, CORE_ADDR addr, int *statusp) + enum mips_isa isa, CORE_ADDR addr, int *errp) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte buf[MIPS_INSN32_SIZE]; int instlen; - int status; + int err; switch (isa) { @@ -1344,13 +1450,13 @@ mips_fetch_instruction (struct gdbarch *gdbarch, internal_error (__FILE__, __LINE__, _("invalid ISA")); break; } - status = target_read_memory (addr, buf, instlen); - if (statusp != NULL) - *statusp = status; - if (status) + err = target_read_memory (addr, buf, instlen); + if (errp != NULL) + *errp = err; + if (err != 0) { - if (statusp == NULL) - memory_error (status, addr); + if (errp == NULL) + memory_error (TARGET_XFER_E_IO, addr); return 0; } return extract_unsigned_integer (buf, instlen, byte_order); @@ -1412,10 +1518,8 @@ mips_insn_size (enum mips_isa isa, ULONGEST insn) switch (isa) { case ISA_MICROMIPS: - if (micromips_op (insn) == 0x1f) - return 3 * MIPS_INSN16_SIZE; - else if (((micromips_op (insn) & 0x4) == 0x4) - || ((micromips_op (insn) & 0x7) == 0x0)) + if ((micromips_op (insn) & 0x4) == 0x4 + || (micromips_op (insn) & 0x7) == 0x0) return 2 * MIPS_INSN16_SIZE; else return MIPS_INSN16_SIZE; @@ -1441,7 +1545,7 @@ mips32_relative_offset (ULONGEST inst) number of the floating condition bits tested by the branch. */ static CORE_ADDR -mips32_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame, +mips32_bc1_pc (struct gdbarch *gdbarch, struct regcache *regcache, ULONGEST inst, CORE_ADDR pc, int count) { int fcsr = mips_regnum (gdbarch)->fp_control_status; @@ -1455,7 +1559,7 @@ mips32_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame, /* No way to handle; it'll most likely trap anyway. */ return pc; - fcs = get_frame_register_unsigned (frame, fcsr); + fcs = regcache_raw_get_unsigned (regcache, fcsr); cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01); if (((cond >> cnum) & mask) != mask * !tf) @@ -1499,9 +1603,9 @@ is_octeon_bbit_op (int op, struct gdbarch *gdbarch) branch prediction. */ static CORE_ADDR -mips32_next_pc (struct frame_info *frame, CORE_ADDR pc) +mips32_next_pc (struct regcache *regcache, CORE_ADDR pc) { - struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); unsigned long inst; int op; inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL); @@ -1528,15 +1632,15 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc) } else if (op == 17 && itype_rs (inst) == 8) /* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */ - pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 1); + pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 1); else if (op == 17 && itype_rs (inst) == 9 && (itype_rt (inst) & 2) == 0) /* BC1ANY2F, BC1ANY2T: 010001 01001 xxx0x */ - pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 2); + pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 2); else if (op == 17 && itype_rs (inst) == 10 && (itype_rt (inst) & 2) == 0) /* BC1ANY4F, BC1ANY4T: 010001 01010 xxx0x */ - pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 4); + pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 4); else if (op == 29) /* JALX: 011101 */ /* The new PC will be alternate mode. */ @@ -1558,8 +1662,8 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc) if (op == 54 || op == 62) bit += 32; - if (((get_frame_register_signed (frame, - itype_rs (inst)) >> bit) & 1) + if (((regcache_raw_get_signed (regcache, + itype_rs (inst)) >> bit) & 1) == branch_if) pc += mips32_relative_offset (inst) + 4; else @@ -1582,15 +1686,15 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc) case 8: /* JR */ case 9: /* JALR */ /* Set PC to that address. */ - pc = get_frame_register_signed (frame, rtype_rs (inst)); + pc = regcache_raw_get_signed (regcache, rtype_rs (inst)); break; case 12: /* SYSCALL */ { struct gdbarch_tdep *tdep; - tdep = gdbarch_tdep (get_frame_arch (frame)); + tdep = gdbarch_tdep (gdbarch); if (tdep->syscall_next_pc != NULL) - pc = tdep->syscall_next_pc (frame); + pc = tdep->syscall_next_pc (get_current_frame ()); else pc += 4; } @@ -1610,7 +1714,7 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc) case 16: /* BLTZAL */ case 18: /* BLTZALL */ less_branch: - if (get_frame_register_signed (frame, itype_rs (inst)) < 0) + if (regcache_raw_get_signed (regcache, itype_rs (inst)) < 0) pc += mips32_relative_offset (inst) + 4; else pc += 8; /* after the delay slot */ @@ -1619,7 +1723,7 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc) case 3: /* BGEZL */ case 17: /* BGEZAL */ case 19: /* BGEZALL */ - if (get_frame_register_signed (frame, itype_rs (inst)) >= 0) + if (regcache_raw_get_signed (regcache, itype_rs (inst)) >= 0) pc += mips32_relative_offset (inst) + 4; else pc += 8; /* after the delay slot */ @@ -1636,8 +1740,8 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc) /* No way to handle; it'll most likely trap anyway. */ break; - if ((get_frame_register_unsigned (frame, - dspctl) & 0x7f) >= pos) + if ((regcache_raw_get_unsigned (regcache, + dspctl) & 0x7f) >= pos) pc += mips32_relative_offset (inst); else pc += 4; @@ -1660,22 +1764,22 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc) break; case 4: /* BEQ, BEQL */ equal_branch: - if (get_frame_register_signed (frame, itype_rs (inst)) == - get_frame_register_signed (frame, itype_rt (inst))) + if (regcache_raw_get_signed (regcache, itype_rs (inst)) == + regcache_raw_get_signed (regcache, itype_rt (inst))) pc += mips32_relative_offset (inst) + 4; else pc += 8; break; case 5: /* BNE, BNEL */ neq_branch: - if (get_frame_register_signed (frame, itype_rs (inst)) != - get_frame_register_signed (frame, itype_rt (inst))) + if (regcache_raw_get_signed (regcache, itype_rs (inst)) != + regcache_raw_get_signed (regcache, itype_rt (inst))) pc += mips32_relative_offset (inst) + 4; else pc += 8; break; case 6: /* BLEZ, BLEZL */ - if (get_frame_register_signed (frame, itype_rs (inst)) <= 0) + if (regcache_raw_get_signed (regcache, itype_rs (inst)) <= 0) pc += mips32_relative_offset (inst) + 4; else pc += 8; @@ -1683,7 +1787,7 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc) case 7: default: greater_branch: /* BGTZ, BGTZL */ - if (get_frame_register_signed (frame, itype_rs (inst)) > 0) + if (regcache_raw_get_signed (regcache, itype_rs (inst)) > 0) pc += mips32_relative_offset (inst) + 4; else pc += 8; @@ -1737,7 +1841,7 @@ micromips_pc_insn_size (struct gdbarch *gdbarch, CORE_ADDR pc) examined by the branch. */ static CORE_ADDR -micromips_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame, +micromips_bc1_pc (struct gdbarch *gdbarch, struct regcache *regcache, ULONGEST insn, CORE_ADDR pc, int count) { int fcsr = mips_regnum (gdbarch)->fp_control_status; @@ -1751,7 +1855,7 @@ micromips_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame, /* No way to handle; it'll most likely trap anyway. */ return pc; - fcs = get_frame_register_unsigned (frame, fcsr); + fcs = regcache_raw_get_unsigned (regcache, fcsr); cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01); if (((cond >> cnum) & mask) != mask * !tf) @@ -1766,21 +1870,15 @@ micromips_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame, after the instruction at the address PC. */ static CORE_ADDR -micromips_next_pc (struct frame_info *frame, CORE_ADDR pc) +micromips_next_pc (struct regcache *regcache, CORE_ADDR pc) { - struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); ULONGEST insn; insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL); pc += MIPS_INSN16_SIZE; switch (mips_insn_size (ISA_MICROMIPS, insn)) { - /* 48-bit instructions. */ - case 3 * MIPS_INSN16_SIZE: /* POOL48A: bits 011111 */ - /* No branch or jump instructions in this category. */ - pc += 2 * MIPS_INSN16_SIZE; - break; - /* 32-bit instructions. */ case 2 * MIPS_INSN16_SIZE: insn <<= 16; @@ -1794,7 +1892,7 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc) && (b6s10_ext (insn) & 0x2bf) == 0x3c) /* JALR, JALR.HB: 000000 000x111100 111100 */ /* JALRS, JALRS.HB: 000000 010x111100 111100 */ - pc = get_frame_register_signed (frame, b0s5_reg (insn >> 16)); + pc = regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16)); break; case 0x10: /* POOL32I: bits 010000 */ @@ -1803,8 +1901,8 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc) case 0x00: /* BLTZ: bits 010000 00000 */ case 0x01: /* BLTZAL: bits 010000 00001 */ case 0x11: /* BLTZALS: bits 010000 10001 */ - if (get_frame_register_signed (frame, - b0s5_reg (insn >> 16)) < 0) + if (regcache_raw_get_signed (regcache, + b0s5_reg (insn >> 16)) < 0) pc += micromips_relative_offset16 (insn); else pc += micromips_pc_insn_size (gdbarch, pc); @@ -1813,38 +1911,38 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc) case 0x02: /* BGEZ: bits 010000 00010 */ case 0x03: /* BGEZAL: bits 010000 00011 */ case 0x13: /* BGEZALS: bits 010000 10011 */ - if (get_frame_register_signed (frame, - b0s5_reg (insn >> 16)) >= 0) + if (regcache_raw_get_signed (regcache, + b0s5_reg (insn >> 16)) >= 0) pc += micromips_relative_offset16 (insn); else pc += micromips_pc_insn_size (gdbarch, pc); break; case 0x04: /* BLEZ: bits 010000 00100 */ - if (get_frame_register_signed (frame, - b0s5_reg (insn >> 16)) <= 0) + if (regcache_raw_get_signed (regcache, + b0s5_reg (insn >> 16)) <= 0) pc += micromips_relative_offset16 (insn); else pc += micromips_pc_insn_size (gdbarch, pc); break; case 0x05: /* BNEZC: bits 010000 00101 */ - if (get_frame_register_signed (frame, - b0s5_reg (insn >> 16)) != 0) + if (regcache_raw_get_signed (regcache, + b0s5_reg (insn >> 16)) != 0) pc += micromips_relative_offset16 (insn); break; case 0x06: /* BGTZ: bits 010000 00110 */ - if (get_frame_register_signed (frame, - b0s5_reg (insn >> 16)) > 0) + if (regcache_raw_get_signed (regcache, + b0s5_reg (insn >> 16)) > 0) pc += micromips_relative_offset16 (insn); else pc += micromips_pc_insn_size (gdbarch, pc); break; case 0x07: /* BEQZC: bits 010000 00111 */ - if (get_frame_register_signed (frame, - b0s5_reg (insn >> 16)) == 0) + if (regcache_raw_get_signed (regcache, + b0s5_reg (insn >> 16)) == 0) pc += micromips_relative_offset16 (insn); break; @@ -1865,8 +1963,8 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc) /* No way to handle; it'll most likely trap anyway. */ break; - if ((get_frame_register_unsigned (frame, - dspctl) & 0x7f) >= pos) + if ((regcache_raw_get_unsigned (regcache, + dspctl) & 0x7f) >= pos) pc += micromips_relative_offset16 (insn); else pc += micromips_pc_insn_size (gdbarch, pc); @@ -1878,14 +1976,14 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc) case 0x1d: /* BC1T: bits 010000 11101 xxx00 */ /* BC1ANY2T: bits 010000 11101 xxx01 */ if (((insn >> 16) & 0x2) == 0x0) - pc = micromips_bc1_pc (gdbarch, frame, insn, pc, + pc = micromips_bc1_pc (gdbarch, regcache, insn, pc, ((insn >> 16) & 0x1) + 1); break; case 0x1e: /* BC1ANY4F: bits 010000 11110 xxx01 */ case 0x1f: /* BC1ANY4T: bits 010000 11111 xxx01 */ if (((insn >> 16) & 0x3) == 0x1) - pc = micromips_bc1_pc (gdbarch, frame, insn, pc, 4); + pc = micromips_bc1_pc (gdbarch, regcache, insn, pc, 4); break; } break; @@ -1897,16 +1995,16 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc) break; case 0x25: /* BEQ: bits 100101 */ - if (get_frame_register_signed (frame, b0s5_reg (insn >> 16)) - == get_frame_register_signed (frame, b5s5_reg (insn >> 16))) + if (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16)) + == regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16))) pc += micromips_relative_offset16 (insn); else pc += micromips_pc_insn_size (gdbarch, pc); break; case 0x2d: /* BNE: bits 101101 */ - if (get_frame_register_signed (frame, b0s5_reg (insn >> 16)) - != get_frame_register_signed (frame, b5s5_reg (insn >> 16))) + if (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16)) + != regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16))) pc += micromips_relative_offset16 (insn); else pc += micromips_pc_insn_size (gdbarch, pc); @@ -1925,17 +2023,17 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc) case 0x11: /* POOL16C: bits 010001 */ if ((b5s5_op (insn) & 0x1c) == 0xc) /* JR16, JRC, JALR16, JALRS16: 010001 011xx */ - pc = get_frame_register_signed (frame, b0s5_reg (insn)); + pc = regcache_raw_get_signed (regcache, b0s5_reg (insn)); else if (b5s5_op (insn) == 0x18) /* JRADDIUSP: bits 010001 11000 */ - pc = get_frame_register_signed (frame, MIPS_RA_REGNUM); + pc = regcache_raw_get_signed (regcache, MIPS_RA_REGNUM); break; case 0x23: /* BEQZ16: bits 100011 */ { int rs = mips_reg3_to_reg[b7s3_reg (insn)]; - if (get_frame_register_signed (frame, rs) == 0) + if (regcache_raw_get_signed (regcache, rs) == 0) pc += micromips_relative_offset7 (insn); else pc += micromips_pc_insn_size (gdbarch, pc); @@ -1946,7 +2044,7 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc) { int rs = mips_reg3_to_reg[b7s3_reg (insn)]; - if (get_frame_register_signed (frame, rs) != 0) + if (regcache_raw_get_signed (regcache, rs) != 0) pc += micromips_relative_offset7 (insn); else pc += micromips_pc_insn_size (gdbarch, pc); @@ -2036,7 +2134,8 @@ fetch_mips_16 (struct gdbarch *gdbarch, CORE_ADDR pc) { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); gdb_byte buf[8]; - pc &= 0xfffffffe; /* Clear the low order bit. */ + + pc = unmake_compact_addr (pc); /* Clear the low order bit. */ target_read_memory (pc, buf, 2); return extract_unsigned_integer (buf, 2, byte_order); } @@ -2114,17 +2213,20 @@ unpack_mips16 (struct gdbarch *gdbarch, CORE_ADDR pc, } +/* Calculate the destination of a branch whose 16-bit opcode word is at PC, + and having a signed 16-bit OFFSET. */ + static CORE_ADDR add_offset_16 (CORE_ADDR pc, int offset) { - return ((offset << 2) | ((pc + 2) & (~(CORE_ADDR) 0x0fffffff))); + return pc + (offset << 1) + 2; } static CORE_ADDR -extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, +extended_mips16_next_pc (regcache *regcache, CORE_ADDR pc, unsigned int extension, unsigned int insn) { - struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); int op = (insn >> 11); switch (op) { @@ -2132,7 +2234,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, { struct upk_mips16 upk; unpack_mips16 (gdbarch, pc, extension, insn, itype, &upk); - pc += (upk.offset << 1) + 2; + pc = add_offset_16 (pc, upk.offset); break; } case 3: /* JAL , JALX - Watch out, these are 32 bit @@ -2140,7 +2242,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, { struct upk_mips16 upk; unpack_mips16 (gdbarch, pc, extension, insn, jalxtype, &upk); - pc = add_offset_16 (pc, upk.offset); + pc = ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)) | (upk.offset << 2); if ((insn >> 10) & 0x01) /* Exchange mode */ pc = pc & ~0x01; /* Clear low bit, indicate 32 bit mode. */ else @@ -2152,9 +2254,9 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, struct upk_mips16 upk; int reg; unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk); - reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]); + reg = regcache_raw_get_signed (regcache, mips_reg3_to_reg[upk.regx]); if (reg == 0) - pc += (upk.offset << 1) + 2; + pc = add_offset_16 (pc, upk.offset); else pc += 2; break; @@ -2164,9 +2266,9 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, struct upk_mips16 upk; int reg; unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk); - reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]); + reg = regcache_raw_get_signed (regcache, mips_reg3_to_reg[upk.regx]); if (reg != 0) - pc += (upk.offset << 1) + 2; + pc = add_offset_16 (pc, upk.offset); else pc += 2; break; @@ -2177,11 +2279,11 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, int reg; unpack_mips16 (gdbarch, pc, extension, insn, i8type, &upk); /* upk.regx contains the opcode */ - reg = get_frame_register_signed (frame, 24); /* Test register is 24 */ + /* Test register is 24 */ + reg = regcache_raw_get_signed (regcache, 24); if (((upk.regx == 0) && (reg == 0)) /* BTEZ */ || ((upk.regx == 1) && (reg != 0))) /* BTNEZ */ - /* pc = add_offset_16(pc,upk.offset) ; */ - pc += (upk.offset << 1) + 2; + pc = add_offset_16 (pc, upk.offset); else pc += 2; break; @@ -2200,7 +2302,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, reg = mips_reg3_to_reg[upk.regx]; else reg = 31; /* Function return instruction. */ - pc = get_frame_register_signed (frame, reg); + pc = regcache_raw_get_signed (regcache, reg); } else pc += 2; @@ -2212,7 +2314,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, that. */ { pc += 2; - pc = extended_mips16_next_pc (frame, pc, insn, + pc = extended_mips16_next_pc (regcache, pc, insn, fetch_mips_16 (gdbarch, pc)); break; } @@ -2226,29 +2328,71 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc, } static CORE_ADDR -mips16_next_pc (struct frame_info *frame, CORE_ADDR pc) +mips16_next_pc (struct regcache *regcache, CORE_ADDR pc) { - struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); unsigned int insn = fetch_mips_16 (gdbarch, pc); - return extended_mips16_next_pc (frame, pc, 0, insn); + return extended_mips16_next_pc (regcache, pc, 0, insn); } /* The mips_next_pc function supports single_step when the remote target monitor or stub is not developed enough to do a single_step. It works by decoding the current instruction and predicting where a - branch will go. This isnt hard because all the data is available. + branch will go. This isn't hard because all the data is available. The MIPS32, MIPS16 and microMIPS variants are quite different. */ static CORE_ADDR -mips_next_pc (struct frame_info *frame, CORE_ADDR pc) +mips_next_pc (struct regcache *regcache, CORE_ADDR pc) { - struct gdbarch *gdbarch = get_frame_arch (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); if (mips_pc_is_mips16 (gdbarch, pc)) - return mips16_next_pc (frame, pc); + return mips16_next_pc (regcache, pc); else if (mips_pc_is_micromips (gdbarch, pc)) - return micromips_next_pc (frame, pc); + return micromips_next_pc (regcache, pc); else - return mips32_next_pc (frame, pc); + return mips32_next_pc (regcache, pc); +} + +/* Return non-zero if the MIPS16 instruction INSN is a compact branch + or jump. */ + +static int +mips16_instruction_is_compact_branch (unsigned short insn) +{ + switch (insn & 0xf800) + { + case 0xe800: + return (insn & 0x009f) == 0x80; /* JALRC/JRC */ + case 0x6000: + return (insn & 0x0600) == 0; /* BTNEZ/BTEQZ */ + case 0x2800: /* BNEZ */ + case 0x2000: /* BEQZ */ + case 0x1000: /* B */ + return 1; + default: + return 0; + } +} + +/* Return non-zero if the microMIPS instruction INSN is a compact branch + or jump. */ + +static int +micromips_instruction_is_compact_branch (unsigned short insn) +{ + switch (micromips_op (insn)) + { + case 0x11: /* POOL16C: bits 010001 */ + return (b5s5_op (insn) == 0x18 + /* JRADDIUSP: bits 010001 11000 */ + || b5s5_op (insn) == 0xd); + /* JRC: bits 010011 01101 */ + case 0x10: /* POOL32I: bits 010000 */ + return (b5s5_op (insn) & 0x1d) == 0x5; + /* BEQZC/BNEZC: bits 010000 001x1 */ + default: + return 0; + } } struct mips_frame_cache @@ -2328,6 +2472,10 @@ mips16_scan_prologue (struct gdbarch *gdbarch, struct frame_info *this_frame, struct mips_frame_cache *this_cache) { + int prev_non_prologue_insn = 0; + int this_non_prologue_insn; + int non_prologue_insns = 0; + CORE_ADDR prev_pc; CORE_ADDR cur_pc; CORE_ADDR frame_addr = 0; /* Value of $r17, used as frame pointer. */ CORE_ADDR sp; @@ -2338,11 +2486,13 @@ mips16_scan_prologue (struct gdbarch *gdbarch, unsigned inst = 0; /* current instruction */ unsigned entry_inst = 0; /* the entry instruction */ unsigned save_inst = 0; /* the save instruction */ + int prev_delay_slot = 0; + int in_delay_slot; int reg, offset; int extend_bytes = 0; - int prev_extend_bytes; - CORE_ADDR end_prologue_addr = 0; + int prev_extend_bytes = 0; + CORE_ADDR end_prologue_addr; /* Can be called when there's no process, and hence when there's no THIS_FRAME. */ @@ -2355,9 +2505,16 @@ mips16_scan_prologue (struct gdbarch *gdbarch, if (limit_pc > start_pc + 200) limit_pc = start_pc + 200; + prev_pc = start_pc; + /* Permit at most one non-prologue non-control-transfer instruction + in the middle which may have been reordered by the compiler for + optimisation. */ for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSN16_SIZE) { + this_non_prologue_insn = 0; + in_delay_slot = 0; + /* Save the previous instruction. If it's an EXTEND, we'll extract the immediate offset extension from it in mips16_get_imm. */ prev_inst = inst; @@ -2447,21 +2604,40 @@ mips16_scan_prologue (struct gdbarch *gdbarch, if (prev_extend_bytes) /* extend */ save_inst |= prev_inst << 16; } - else if ((inst & 0xf800) == 0x1800) /* jal(x) */ - cur_pc += MIPS_INSN16_SIZE; /* 32-bit instruction */ else if ((inst & 0xff1c) == 0x6704) /* move reg,$a0-$a3 */ { /* This instruction is part of the prologue, but we don't need to do anything special to handle it. */ } + else if (mips16_instruction_has_delay_slot (inst, 0)) + /* JAL/JALR/JALX/JR */ + { + /* The instruction in the delay slot can be a part + of the prologue, so move forward once more. */ + in_delay_slot = 1; + if (mips16_instruction_has_delay_slot (inst, 1)) + /* JAL/JALX */ + { + prev_extend_bytes = MIPS_INSN16_SIZE; + cur_pc += MIPS_INSN16_SIZE; /* 32-bit instruction */ + } + } else { - /* This instruction is not an instruction typically found - in a prologue, so we must have reached the end of the - prologue. */ - if (end_prologue_addr == 0) - end_prologue_addr = cur_pc - prev_extend_bytes; + this_non_prologue_insn = 1; } + + non_prologue_insns += this_non_prologue_insn; + + /* A jump or branch, or enough non-prologue insns seen? If so, + then we must have reached the end of the prologue by now. */ + if (prev_delay_slot || non_prologue_insns > 1 + || mips16_instruction_is_compact_branch (inst)) + break; + + prev_non_prologue_insn = this_non_prologue_insn; + prev_delay_slot = in_delay_slot; + prev_pc = cur_pc - prev_extend_bytes; } /* The entry instruction is typically the first instruction in a function, @@ -2614,11 +2790,12 @@ mips16_scan_prologue (struct gdbarch *gdbarch, = this_cache->saved_regs[gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM]; } - /* If we didn't reach the end of the prologue when scanning the function - instructions, then set end_prologue_addr to the address of the - instruction immediately after the last one we scanned. */ - if (end_prologue_addr == 0) - end_prologue_addr = cur_pc; + /* Set end_prologue_addr to the address of the instruction immediately + after the last one we scanned. Unless the last one looked like a + non-prologue instruction (and we looked ahead), in which case use + its address instead. */ + end_prologue_addr = (prev_non_prologue_insn || prev_delay_slot + ? prev_pc : cur_pc - prev_extend_bytes); return end_prologue_addr; } @@ -2634,7 +2811,7 @@ mips_insn16_frame_cache (struct frame_info *this_frame, void **this_cache) struct mips_frame_cache *cache; if ((*this_cache) != NULL) - return (*this_cache); + return (struct mips_frame_cache *) (*this_cache); cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache); (*this_cache) = cache; cache->saved_regs = trad_frame_alloc_saved_regs (this_frame); @@ -2652,7 +2829,8 @@ mips_insn16_frame_cache (struct frame_info *this_frame, void **this_cache) if (start_addr == 0) return cache; - mips16_scan_prologue (gdbarch, start_addr, pc, this_frame, *this_cache); + mips16_scan_prologue (gdbarch, start_addr, pc, this_frame, + (struct mips_frame_cache *) *this_cache); } /* gdbarch_sp_regnum contains the value and not the address. */ @@ -2660,7 +2838,7 @@ mips_insn16_frame_cache (struct frame_info *this_frame, void **this_cache) gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM, cache->base); - return (*this_cache); + return (struct mips_frame_cache *) (*this_cache); } static void @@ -2755,14 +2933,15 @@ micromips_scan_prologue (struct gdbarch *gdbarch, struct frame_info *this_frame, struct mips_frame_cache *this_cache) { - CORE_ADDR end_prologue_addr = 0; + CORE_ADDR end_prologue_addr; int prev_non_prologue_insn = 0; int frame_reg = MIPS_SP_REGNUM; int this_non_prologue_insn; int non_prologue_insns = 0; long frame_offset = 0; /* Size of stack frame. */ long frame_adjust = 0; /* Offset of FP from SP. */ - CORE_ADDR frame_addr = 0; /* Value of $30, used as frame pointer. */ + int prev_delay_slot = 0; + int in_delay_slot; CORE_ADDR prev_pc; CORE_ADDR cur_pc; ULONGEST insn; /* current instruction */ @@ -2799,19 +2978,13 @@ micromips_scan_prologue (struct gdbarch *gdbarch, for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += loc) { this_non_prologue_insn = 0; + in_delay_slot = 0; sp_adj = 0; loc = 0; insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, cur_pc, NULL); loc += MIPS_INSN16_SIZE; switch (mips_insn_size (ISA_MICROMIPS, insn)) { - /* 48-bit instructions. */ - case 3 * MIPS_INSN16_SIZE: - /* No prologue instructions in this category. */ - this_non_prologue_insn = 1; - loc += 2 * MIPS_INSN16_SIZE; - break; - /* 32-bit instructions. */ case 2 * MIPS_INSN16_SIZE: insn <<= 16; @@ -2867,7 +3040,7 @@ micromips_scan_prologue (struct gdbarch *gdbarch, && ((reglist >= 1 && reglist <= 9) || (reglist >= 16 && reglist <= 25))) { - int sreglist = min(reglist & 0xf, 8); + int sreglist = std::min(reglist & 0xf, 8); s = 4 << ((b12s4_op (insn) & 0x2) == 0x2); for (i = 0; i < sreglist; i++) @@ -2895,7 +3068,6 @@ micromips_scan_prologue (struct gdbarch *gdbarch, else if (sreg == MIPS_SP_REGNUM && dreg == 30) /* (D)ADDIU $fp, $sp, imm */ { - frame_addr = sp + offset; frame_adjust = offset; frame_reg = 30; } @@ -2905,7 +3077,7 @@ micromips_scan_prologue (struct gdbarch *gdbarch, break; /* LUI $v1 is used for larger $sp adjustments. */ - /* Discard LUI $gp is used for PIC code. */ + /* Discard LUI $gp used for PIC code. */ case 0x10: /* POOL32I: bits 010000 */ if (b5s5_op (insn >> 16) == 0xd /* LUI: bits 010000 001101 */ @@ -2951,9 +3123,15 @@ micromips_scan_prologue (struct gdbarch *gdbarch, break; default: - this_non_prologue_insn = 1; + /* The instruction in the delay slot can be a part + of the prologue, so move forward once more. */ + if (micromips_instruction_has_delay_slot (insn, 0)) + in_delay_slot = 1; + else + this_non_prologue_insn = 1; break; } + insn >>= 16; break; /* 16-bit instructions. */ @@ -2965,10 +3143,7 @@ micromips_scan_prologue (struct gdbarch *gdbarch, dreg = b5s5_reg (insn); if (sreg == MIPS_SP_REGNUM && dreg == 30) /* MOVE $fp, $sp */ - { - frame_addr = sp; - frame_reg = 30; - } + frame_reg = 30; else if ((sreg & 0x1c) != 0x4) /* MOVE reg, $a0-$a3 */ this_non_prologue_insn = 1; @@ -3008,7 +3183,12 @@ micromips_scan_prologue (struct gdbarch *gdbarch, break; default: - this_non_prologue_insn = 1; + /* The instruction in the delay slot can be a part + of the prologue, so move forward once more. */ + if (micromips_instruction_has_delay_slot (insn << 16, 0)) + in_delay_slot = 1; + else + this_non_prologue_insn = 1; break; } break; @@ -3017,13 +3197,16 @@ micromips_scan_prologue (struct gdbarch *gdbarch, frame_offset -= sp_adj; non_prologue_insns += this_non_prologue_insn; - /* Enough non-prologue insns seen or positive stack adjustment? */ - if (end_prologue_addr == 0 && (non_prologue_insns > 1 || sp_adj > 0)) - { - end_prologue_addr = prev_non_prologue_insn ? prev_pc : cur_pc; - break; - } + + /* A jump or branch, enough non-prologue insns seen or positive + stack adjustment? If so, then we must have reached the end + of the prologue by now. */ + if (prev_delay_slot || non_prologue_insns > 1 || sp_adj > 0 + || micromips_instruction_is_compact_branch (insn)) + break; + prev_non_prologue_insn = this_non_prologue_insn; + prev_delay_slot = in_delay_slot; prev_pc = cur_pc; } @@ -3041,13 +3224,12 @@ micromips_scan_prologue (struct gdbarch *gdbarch, = this_cache->saved_regs[gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM]; } - /* If we didn't reach the end of the prologue when scanning the function - instructions, then set end_prologue_addr to the address of the - instruction immediately after the last one we scanned. Unless the - last one looked like a non-prologue instruction (and we looked ahead), - in which case use its address instead. */ - if (end_prologue_addr == 0) - end_prologue_addr = prev_non_prologue_insn ? prev_pc : cur_pc; + /* Set end_prologue_addr to the address of the instruction immediately + after the last one we scanned. Unless the last one looked like a + non-prologue instruction (and we looked ahead), in which case use + its address instead. */ + end_prologue_addr + = prev_non_prologue_insn || prev_delay_slot ? prev_pc : cur_pc; return end_prologue_addr; } @@ -3063,7 +3245,7 @@ mips_micro_frame_cache (struct frame_info *this_frame, void **this_cache) struct mips_frame_cache *cache; if ((*this_cache) != NULL) - return (*this_cache); + return (struct mips_frame_cache *) (*this_cache); cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache); (*this_cache) = cache; @@ -3082,7 +3264,8 @@ mips_micro_frame_cache (struct frame_info *this_frame, void **this_cache) if (start_addr == 0) return cache; - micromips_scan_prologue (gdbarch, start_addr, pc, this_frame, *this_cache); + micromips_scan_prologue (gdbarch, start_addr, pc, this_frame, + (struct mips_frame_cache *) *this_cache); } /* gdbarch_sp_regnum contains the value and not the address. */ @@ -3090,7 +3273,7 @@ mips_micro_frame_cache (struct frame_info *this_frame, void **this_cache) gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM, cache->base); - return (*this_cache); + return (struct mips_frame_cache *) (*this_cache); } static void @@ -3195,17 +3378,22 @@ mips32_scan_prologue (struct gdbarch *gdbarch, struct frame_info *this_frame, struct mips_frame_cache *this_cache) { - CORE_ADDR cur_pc; + int prev_non_prologue_insn; + int this_non_prologue_insn; + int non_prologue_insns; CORE_ADDR frame_addr = 0; /* Value of $r30. Used by gcc for frame-pointer. */ + int prev_delay_slot; + CORE_ADDR prev_pc; + CORE_ADDR cur_pc; CORE_ADDR sp; long frame_offset; int frame_reg = MIPS_SP_REGNUM; - CORE_ADDR end_prologue_addr = 0; + CORE_ADDR end_prologue_addr; int seen_sp_adjust = 0; int load_immediate_bytes = 0; - int in_delay_slot = 0; + int in_delay_slot; int regsize_is_64_bits = (mips_abi_regsize (gdbarch) == 8); /* Can be called when there's no process, and hence when there's no @@ -3221,28 +3409,39 @@ mips32_scan_prologue (struct gdbarch *gdbarch, limit_pc = start_pc + 200; restart: + prev_non_prologue_insn = 0; + non_prologue_insns = 0; + prev_delay_slot = 0; + prev_pc = start_pc; + /* Permit at most one non-prologue non-control-transfer instruction + in the middle which may have been reordered by the compiler for + optimisation. */ frame_offset = 0; for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSN32_SIZE) { - unsigned long inst, high_word, low_word; + unsigned long inst, high_word; + long offset; int reg; + this_non_prologue_insn = 0; + in_delay_slot = 0; + /* Fetch the instruction. */ inst = (unsigned long) mips_fetch_instruction (gdbarch, ISA_MIPS, cur_pc, NULL); /* Save some code by pre-extracting some useful fields. */ high_word = (inst >> 16) & 0xffff; - low_word = inst & 0xffff; + offset = ((inst & 0xffff) ^ 0x8000) - 0x8000; reg = high_word & 0x1f; if (high_word == 0x27bd /* addiu $sp,$sp,-i */ || high_word == 0x23bd /* addi $sp,$sp,-i */ || high_word == 0x67bd) /* daddiu $sp,$sp,-i */ { - if (low_word & 0x8000) /* Negative stack adjustment? */ - frame_offset += 0x10000 - low_word; + if (offset < 0) /* Negative stack adjustment? */ + frame_offset -= offset; else /* Exit loop if a positive stack adjustment is found, which usually means that the stack cleanup code in the function @@ -3253,19 +3452,19 @@ restart: else if (((high_word & 0xFFE0) == 0xafa0) /* sw reg,offset($sp) */ && !regsize_is_64_bits) { - set_reg_offset (gdbarch, this_cache, reg, sp + low_word); + set_reg_offset (gdbarch, this_cache, reg, sp + offset); } else if (((high_word & 0xFFE0) == 0xffa0) /* sd reg,offset($sp) */ && regsize_is_64_bits) { /* Irix 6.2 N32 ABI uses sd instructions for saving $gp and $ra. */ - set_reg_offset (gdbarch, this_cache, reg, sp + low_word); + set_reg_offset (gdbarch, this_cache, reg, sp + offset); } else if (high_word == 0x27be) /* addiu $30,$sp,size */ { /* Old gcc frame, r30 is virtual frame pointer. */ - if ((long) low_word != frame_offset) - frame_addr = sp + low_word; + if (offset != frame_offset) + frame_addr = sp + offset; else if (this_frame && frame_reg == MIPS_SP_REGNUM) { unsigned alloca_adjust; @@ -3275,7 +3474,7 @@ restart: (this_frame, gdbarch_num_regs (gdbarch) + 30); frame_offset = 0; - alloca_adjust = (unsigned) (frame_addr - (sp + low_word)); + alloca_adjust = (unsigned) (frame_addr - (sp + offset)); if (alloca_adjust > 0) { /* FP > SP + frame_size. This may be because of @@ -3324,7 +3523,7 @@ restart: else if ((high_word & 0xFFE0) == 0xafc0 /* sw reg,offset($30) */ && !regsize_is_64_bits) { - set_reg_offset (gdbarch, this_cache, reg, frame_addr + low_word); + set_reg_offset (gdbarch, this_cache, reg, frame_addr + offset); } else if ((high_word & 0xFFE0) == 0xE7A0 /* swc1 freg,n($sp) */ || (high_word & 0xF3E0) == 0xA3C0 /* sx reg,n($s8) */ @@ -3344,6 +3543,7 @@ restart: initialize a local variable, so we accept them only before a stack adjustment instruction was seen. */ else if (!seen_sp_adjust + && !prev_delay_slot && (high_word == 0x3c01 /* lui $at,n */ || high_word == 0x3c08 /* lui $t0,n */ || high_word == 0x3421 /* ori $at,$at,n */ @@ -3352,31 +3552,32 @@ restart: || high_word == 0x3408 /* ori $t0,$zero,n */ )) { - if (end_prologue_addr == 0) - load_immediate_bytes += MIPS_INSN32_SIZE; /* FIXME! */ + load_immediate_bytes += MIPS_INSN32_SIZE; /* FIXME! */ + } + /* Check for branches and jumps. The instruction in the delay + slot can be a part of the prologue, so move forward once more. */ + else if (mips32_instruction_has_delay_slot (gdbarch, inst)) + { + in_delay_slot = 1; } + /* This instruction is not an instruction typically found + in a prologue, so we must have reached the end of the + prologue. */ else { - /* This instruction is not an instruction typically found - in a prologue, so we must have reached the end of the - prologue. */ - /* FIXME: brobecker/2004-10-10: Can't we just break out of this - loop now? Why would we need to continue scanning the function - instructions? */ - if (end_prologue_addr == 0) - end_prologue_addr = cur_pc; - - /* Check for branches and jumps. For now, only jump to - register are caught (i.e. returns). */ - if ((itype_op (inst) & 0x07) == 0 && rtype_funct (inst) == 8) - in_delay_slot = 1; + this_non_prologue_insn = 1; } - /* If the previous instruction was a jump, we must have reached - the end of the prologue by now. Stop scanning so that we do - not go past the function return. */ - if (in_delay_slot) + non_prologue_insns += this_non_prologue_insn; + + /* A jump or branch, or enough non-prologue insns seen? If so, + then we must have reached the end of the prologue by now. */ + if (prev_delay_slot || non_prologue_insns > 1) break; + + prev_non_prologue_insn = this_non_prologue_insn; + prev_delay_slot = in_delay_slot; + prev_pc = cur_pc; } if (this_cache != NULL) @@ -3394,14 +3595,12 @@ restart: + MIPS_RA_REGNUM]; } - /* If we didn't reach the end of the prologue when scanning the function - instructions, then set end_prologue_addr to the address of the - instruction immediately after the last one we scanned. */ - /* brobecker/2004-10-10: I don't think this would ever happen, but - we may as well be careful and do our best if we have a null - end_prologue_addr. */ - if (end_prologue_addr == 0) - end_prologue_addr = cur_pc; + /* Set end_prologue_addr to the address of the instruction immediately + after the last one we scanned. Unless the last one looked like a + non-prologue instruction (and we looked ahead), in which case use + its address instead. */ + end_prologue_addr + = prev_non_prologue_insn || prev_delay_slot ? prev_pc : cur_pc; /* In a frameless function, we might have incorrectly skipped some load immediate instructions. Undo the skipping @@ -3424,7 +3623,7 @@ mips_insn32_frame_cache (struct frame_info *this_frame, void **this_cache) struct mips_frame_cache *cache; if ((*this_cache) != NULL) - return (*this_cache); + return (struct mips_frame_cache *) (*this_cache); cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache); (*this_cache) = cache; @@ -3443,7 +3642,8 @@ mips_insn32_frame_cache (struct frame_info *this_frame, void **this_cache) if (start_addr == 0) return cache; - mips32_scan_prologue (gdbarch, start_addr, pc, this_frame, *this_cache); + mips32_scan_prologue (gdbarch, start_addr, pc, this_frame, + (struct mips_frame_cache *) *this_cache); } /* gdbarch_sp_regnum contains the value and not the address. */ @@ -3451,7 +3651,7 @@ mips_insn32_frame_cache (struct frame_info *this_frame, void **this_cache) gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM, cache->base); - return (*this_cache); + return (struct mips_frame_cache *) (*this_cache); } static void @@ -3533,7 +3733,7 @@ mips_stub_frame_cache (struct frame_info *this_frame, void **this_cache) int num_regs = gdbarch_num_regs (gdbarch); if ((*this_cache) != NULL) - return (*this_cache); + return (struct trad_frame_cache *) (*this_cache); this_trad_cache = trad_frame_cache_zalloc (this_frame); (*this_cache) = this_trad_cache; @@ -3588,23 +3788,15 @@ mips_stub_frame_sniffer (const struct frame_unwind *self, if (target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0) return 1; - if (in_plt_section (pc, NULL)) - return 1; - - /* Binutils for MIPS puts lazy resolution stubs into .MIPS.stubs. */ - s = find_pc_section (pc); - - if (s != NULL - && strcmp (bfd_get_section_name (s->objfile->obfd, s->the_bfd_section), - ".MIPS.stubs") == 0) + if (in_plt_section (pc) || in_mips_stubs_section (pc)) return 1; /* Calling a PIC function from a non-PIC function passes through a stub. The stub for foo is named ".pic.foo". */ msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym != NULL - && SYMBOL_LINKAGE_NAME (msym.minsym) != NULL - && strncmp (SYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) == 0) + && MSYMBOL_LINKAGE_NAME (msym.minsym) != NULL + && startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.")) return 1; return 0; @@ -3653,9 +3845,6 @@ mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - if (is_compact_addr (addr)) - addr = unmake_compact_addr (addr); - if (mips_mask_address_p (tdep) && (((ULONGEST) addr) >> 32 == 0xffffffffUL)) /* This hack is a work-around for existing boards using PMON, the simulator, and any other 64-bit targets that doesn't have true @@ -3690,9 +3879,8 @@ mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr) #define SC_OPCODE 0x38 #define SCD_OPCODE 0x3c -static int -mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, - struct address_space *aspace, CORE_ADDR pc) +static VEC (CORE_ADDR) * +mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc) { CORE_ADDR breaks[2] = {-1, -1}; CORE_ADDR loc = pc; @@ -3702,11 +3890,12 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, int index; int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ const int atomic_sequence_length = 16; /* Instruction sequence length. */ + VEC (CORE_ADDR) *next_pcs = NULL; insn = mips_fetch_instruction (gdbarch, ISA_MIPS, loc, NULL); /* Assume all atomic sequences start with a ll/lld instruction. */ if (itype_op (insn) != LL_OPCODE && itype_op (insn) != LLD_OPCODE) - return 0; + return NULL; /* Assume that no atomic sequence is longer than "atomic_sequence_length" instructions. */ @@ -3770,7 +3959,7 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, /* Assume that the atomic sequence ends with a sc/scd instruction. */ if (itype_op (insn) != SC_OPCODE && itype_op (insn) != SCD_OPCODE) - return 0; + return NULL; loc += MIPS_INSN32_SIZE; @@ -3784,14 +3973,13 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, /* Effectively inserts the breakpoints. */ for (index = 0; index <= last_breakpoint; index++) - insert_single_step_breakpoint (gdbarch, aspace, breaks[index]); + VEC_safe_push (CORE_ADDR, next_pcs, breaks[index]); - return 1; + return next_pcs; } -static int +static VEC (CORE_ADDR) * micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch, - struct address_space *aspace, CORE_ADDR pc) { const int atomic_sequence_length = 16; /* Instruction sequence length. */ @@ -3804,16 +3992,17 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch, ULONGEST insn; int insn_count; int index; + VEC (CORE_ADDR) *next_pcs = NULL; /* Assume all atomic sequences start with a ll/lld instruction. */ insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL); if (micromips_op (insn) != 0x18) /* POOL32C: bits 011000 */ - return 0; + return NULL; loc += MIPS_INSN16_SIZE; insn <<= 16; insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL); if ((b12s4_op (insn) & 0xb) != 0x3) /* LL, LLD: bits 011000 0x11 */ - return 0; + return NULL; loc += MIPS_INSN16_SIZE; /* Assume all atomic sequences end with an sc/scd instruction. Assume @@ -3833,11 +4022,6 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch, its destination address. */ switch (mips_insn_size (ISA_MICROMIPS, insn)) { - /* 48-bit instructions. */ - case 3 * MIPS_INSN16_SIZE: /* POOL48A: bits 011111 */ - loc += 2 * MIPS_INSN16_SIZE; - break; - /* 32-bit instructions. */ case 2 * MIPS_INSN16_SIZE: switch (micromips_op (insn)) @@ -3915,24 +4099,24 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch, && b5s5_op (insn) != 0x18) /* JRADDIUSP: bits 010001 11000 */ break; - return 0; /* Fall back to the standard single-step code. */ + return NULL; /* Fall back to the standard single-step code. */ case 0x33: /* B16: bits 110011 */ - return 0; /* Fall back to the standard single-step code. */ + return NULL; /* Fall back to the standard single-step code. */ } break; } if (is_branch) { if (last_breakpoint >= 1) - return 0; /* More than one branch found, fallback to the + return NULL; /* More than one branch found, fallback to the standard single-step code. */ breaks[1] = branch_bp; last_breakpoint++; } } if (!sc_found) - return 0; + return NULL; /* Insert a breakpoint right after the end of the atomic sequence. */ breaks[0] = loc; @@ -3944,21 +4128,20 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch, /* Effectively inserts the breakpoints. */ for (index = 0; index <= last_breakpoint; index++) - insert_single_step_breakpoint (gdbarch, aspace, breaks[index]); + VEC_safe_push (CORE_ADDR, next_pcs, breaks[index]); - return 1; + return next_pcs; } -static int -deal_with_atomic_sequence (struct gdbarch *gdbarch, - struct address_space *aspace, CORE_ADDR pc) +static VEC (CORE_ADDR) * +deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc) { if (mips_pc_is_mips (pc)) - return mips_deal_with_atomic_sequence (gdbarch, aspace, pc); + return mips_deal_with_atomic_sequence (gdbarch, pc); else if (mips_pc_is_micromips (gdbarch, pc)) - return micromips_deal_with_atomic_sequence (gdbarch, aspace, pc); + return micromips_deal_with_atomic_sequence (gdbarch, pc); else - return 0; + return NULL; } /* mips_software_single_step() is called just before we want to resume @@ -3966,21 +4149,22 @@ deal_with_atomic_sequence (struct gdbarch *gdbarch, or kernel single-step support (MIPS on GNU/Linux for example). We find the target of the coming instruction and breakpoint it. */ -int -mips_software_single_step (struct frame_info *frame) +VEC (CORE_ADDR) * +mips_software_single_step (struct regcache *regcache) { - struct gdbarch *gdbarch = get_frame_arch (frame); - struct address_space *aspace = get_frame_address_space (frame); + struct gdbarch *gdbarch = get_regcache_arch (regcache); CORE_ADDR pc, next_pc; + VEC (CORE_ADDR) *next_pcs; - pc = get_frame_pc (frame); - if (deal_with_atomic_sequence (gdbarch, aspace, pc)) - return 1; + pc = regcache_read_pc (regcache); + next_pcs = deal_with_atomic_sequence (gdbarch, pc); + if (next_pcs != NULL) + return next_pcs; - next_pc = mips_next_pc (frame, pc); + next_pc = mips_next_pc (regcache, pc); - insert_single_step_breakpoint (gdbarch, aspace, next_pc); - return 1; + VEC_safe_push (CORE_ADDR, next_pcs, next_pc); + return next_pcs; } /* Test whether the PC points to the return instruction at the @@ -4021,7 +4205,7 @@ heuristic_proc_start (struct gdbarch *gdbarch, CORE_ADDR pc) if (start_pc == 0) return 0; - if (heuristic_fence_post == UINT_MAX || fence < VM_MIN_ADDRESS) + if (heuristic_fence_post == -1 || fence < VM_MIN_ADDRESS) fence = VM_MIN_ADDRESS; instlen = mips_pc_is_mips (pc) ? MIPS_INSN32_SIZE : MIPS_INSN16_SIZE; @@ -4354,25 +4538,9 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, "mips_eabi_push_dummy_call: %d len=%d type=%d", argnum + 1, len, (int) typecode); - /* Function pointer arguments to mips16 code need to be made into - mips16 pointers. */ - if (typecode == TYPE_CODE_PTR - && TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC) - { - CORE_ADDR addr = extract_signed_integer (value_contents (arg), - len, byte_order); - if (mips_pc_is_mips (addr)) - val = value_contents (arg); - else - { - store_signed_integer (valbuf, len, byte_order, - make_compact_addr (addr)); - val = valbuf; - } - } /* The EABI passes structures that do not fit in a register by reference. */ - else if (len > regsize + if (len > regsize && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) { store_unsigned_integer (valbuf, regsize, byte_order, @@ -5330,8 +5498,6 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, } while (len > 0) { - /* Remember if the argument was written to the stack. */ - int stack_used_p = 0; int partial_len = (len < MIPS32_REGSIZE ? len : MIPS32_REGSIZE); if (mips_debug) @@ -5346,7 +5512,6 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, promoted to int before being stored? */ int longword_offset = 0; CORE_ADDR addr; - stack_used_p = 1; if (mips_debug) { @@ -5737,7 +5902,6 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, for (argnum = 0; argnum < nargs; argnum++) { const gdb_byte *val; - gdb_byte valbuf[MAX_REGISTER_SIZE]; struct value *arg = args[argnum]; struct type *arg_type = check_typedef (value_type (arg)); int len = TYPE_LENGTH (arg_type); @@ -5750,21 +5914,6 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, val = value_contents (arg); - /* Function pointer arguments to mips16 code need to be made into - mips16 pointers. */ - if (typecode == TYPE_CODE_PTR - && TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC) - { - CORE_ADDR addr = extract_signed_integer (value_contents (arg), - len, byte_order); - if (!mips_pc_is_mips (addr)) - { - store_signed_integer (valbuf, len, byte_order, - make_compact_addr (addr)); - val = valbuf; - } - } - /* Floating point arguments passed in registers have to be treated specially. On 32-bit architectures, doubles are passed in register pairs; the even FP register gets the @@ -5804,8 +5953,6 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, && len % MIPS64_REGSIZE != 0); while (len > 0) { - /* Remember if the argument was written to the stack. */ - int stack_used_p = 0; int partial_len = (len < MIPS64_REGSIZE ? len : MIPS64_REGSIZE); if (mips_debug) @@ -5820,7 +5967,6 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, promoted to int before being stored? */ int longword_offset = 0; CORE_ADDR addr; - stack_used_p = 1; if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) { if ((typecode == TYPE_CODE_INT @@ -6032,7 +6178,7 @@ mips_read_fp_register_single (struct frame_info *frame, int regno, { struct gdbarch *gdbarch = get_frame_arch (frame); int raw_size = register_size (gdbarch, regno); - gdb_byte *raw_buffer = alloca (raw_size); + gdb_byte *raw_buffer = (gdb_byte *) alloca (raw_size); if (!deprecated_frame_register_read (frame, regno, raw_buffer)) error (_("can't read register %d (%s)"), @@ -6108,8 +6254,9 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame, double doub, flt1; /* Doubles extracted from raw hex data. */ int inv1, inv2; - raw_buffer = alloca (2 * register_size (gdbarch, - mips_regnum (gdbarch)->fp0)); + raw_buffer + = ((gdb_byte *) + alloca (2 * register_size (gdbarch, mips_regnum (gdbarch)->fp0))); fprintf_filtered (file, "%s:", gdbarch_register_name (gdbarch, regnum)); fprintf_filtered (file, "%*s", @@ -6197,12 +6344,6 @@ mips_print_register (struct ui_file *file, struct frame_info *frame, } val = get_frame_register_value (frame, regnum); - if (value_optimized_out (val)) - { - fprintf_filtered (file, "%s: [Invalid]", - gdbarch_register_name (gdbarch, regnum)); - return; - } fputs_filtered (gdbarch_register_name (gdbarch, regnum), file); @@ -6217,12 +6358,99 @@ mips_print_register (struct ui_file *file, struct frame_info *frame, get_formatted_print_options (&opts, 'x'); val_print_scalar_formatted (value_type (val), - value_contents_for_printing (val), value_embedded_offset (val), val, &opts, 0, file); } +/* Print IEEE exception condition bits in FLAGS. */ + +static void +print_fpu_flags (struct ui_file *file, int flags) +{ + if (flags & (1 << 0)) + fputs_filtered (" inexact", file); + if (flags & (1 << 1)) + fputs_filtered (" uflow", file); + if (flags & (1 << 2)) + fputs_filtered (" oflow", file); + if (flags & (1 << 3)) + fputs_filtered (" div0", file); + if (flags & (1 << 4)) + fputs_filtered (" inval", file); + if (flags & (1 << 5)) + fputs_filtered (" unimp", file); + fputc_filtered ('\n', file); +} + +/* Print interesting information about the floating point processor + (if present) or emulator. */ + +static void +mips_print_float_info (struct gdbarch *gdbarch, struct ui_file *file, + struct frame_info *frame, const char *args) +{ + int fcsr = mips_regnum (gdbarch)->fp_control_status; + enum mips_fpu_type type = MIPS_FPU_TYPE (gdbarch); + ULONGEST fcs = 0; + int i; + + if (fcsr == -1 || !read_frame_register_unsigned (frame, fcsr, &fcs)) + type = MIPS_FPU_NONE; + + fprintf_filtered (file, "fpu type: %s\n", + type == MIPS_FPU_DOUBLE ? "double-precision" + : type == MIPS_FPU_SINGLE ? "single-precision" + : "none / unused"); + + if (type == MIPS_FPU_NONE) + return; + + fprintf_filtered (file, "reg size: %d bits\n", + register_size (gdbarch, mips_regnum (gdbarch)->fp0) * 8); + + fputs_filtered ("cond :", file); + if (fcs & (1 << 23)) + fputs_filtered (" 0", file); + for (i = 1; i <= 7; i++) + if (fcs & (1 << (24 + i))) + fprintf_filtered (file, " %d", i); + fputc_filtered ('\n', file); + + fputs_filtered ("cause :", file); + print_fpu_flags (file, (fcs >> 12) & 0x3f); + fputs ("mask :", stdout); + print_fpu_flags (file, (fcs >> 7) & 0x1f); + fputs ("flags :", stdout); + print_fpu_flags (file, (fcs >> 2) & 0x1f); + + fputs_filtered ("rounding: ", file); + switch (fcs & 3) + { + case 0: fputs_filtered ("nearest\n", file); break; + case 1: fputs_filtered ("zero\n", file); break; + case 2: fputs_filtered ("+inf\n", file); break; + case 3: fputs_filtered ("-inf\n", file); break; + } + + fputs_filtered ("flush :", file); + if (fcs & (1 << 21)) + fputs_filtered (" nearest", file); + if (fcs & (1 << 22)) + fputs_filtered (" override", file); + if (fcs & (1 << 24)) + fputs_filtered (" zero", file); + if ((fcs & (0xb << 21)) == 0) + fputs_filtered (" no", file); + fputc_filtered ('\n', file); + + fprintf_filtered (file, "nan2008 : %s\n", fcs & (1 << 18) ? "yes" : "no"); + fprintf_filtered (file, "abs2008 : %s\n", fcs & (1 << 19) ? "yes" : "no"); + fputc_filtered ('\n', file); + + default_print_float_info (gdbarch, file, frame, args); +} + /* Replacement for generic do_registers_info. Print regs in pretty columns. */ @@ -6379,11 +6607,11 @@ mips_single_step_through_delay (struct gdbarch *gdbarch, int size; if ((mips_pc_is_mips (pc) - && !mips32_instruction_has_delay_slot (gdbarch, pc)) + && !mips32_insn_at_pc_has_delay_slot (gdbarch, pc)) || (mips_pc_is_micromips (gdbarch, pc) - && !micromips_instruction_has_delay_slot (gdbarch, pc, 0)) + && !micromips_insn_at_pc_has_delay_slot (gdbarch, pc, 0)) || (mips_pc_is_mips16 (gdbarch, pc) - && !mips16_instruction_has_delay_slot (gdbarch, pc, 0))) + && !mips16_insn_at_pc_has_delay_slot (gdbarch, pc, 0))) return 0; isa = mips_pc_isa (gdbarch, pc); @@ -6417,7 +6645,7 @@ mips_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) CORE_ADDR post_prologue_pc = skip_prologue_using_sal (gdbarch, func_addr); if (post_prologue_pc != 0) - return max (pc, post_prologue_pc); + return std::max (pc, post_prologue_pc); } /* Can't determine prologue from the symbol table, need to examine @@ -6438,10 +6666,11 @@ mips_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) return mips32_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL); } -/* Check whether the PC is in a function epilogue (32-bit version). - This is a helper function for mips_in_function_epilogue_p. */ +/* Implement the stack_frame_destroyed_p gdbarch method (32-bit version). + This is a helper function for mips_stack_frame_destroyed_p. */ + static int -mips32_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +mips32_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) { CORE_ADDR func_addr = 0, func_end = 0; @@ -6476,11 +6705,11 @@ mips32_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) return 0; } -/* Check whether the PC is in a function epilogue (microMIPS version). - This is a helper function for mips_in_function_epilogue_p. */ +/* Implement the stack_frame_destroyed_p gdbarch method (microMIPS version). + This is a helper function for mips_stack_frame_destroyed_p. */ static int -micromips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +micromips_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) { CORE_ADDR func_addr = 0; CORE_ADDR func_end = 0; @@ -6509,11 +6738,6 @@ micromips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) loc += MIPS_INSN16_SIZE; switch (mips_insn_size (ISA_MICROMIPS, insn)) { - /* 48-bit instructions. */ - case 3 * MIPS_INSN16_SIZE: - /* No epilogue instructions in this category. */ - return 0; - /* 32-bit instructions. */ case 2 * MIPS_INSN16_SIZE: insn <<= 16; @@ -6577,10 +6801,11 @@ micromips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) return 1; } -/* Check whether the PC is in a function epilogue (16-bit version). - This is a helper function for mips_in_function_epilogue_p. */ +/* Implement the stack_frame_destroyed_p gdbarch method (16-bit version). + This is a helper function for mips_stack_frame_destroyed_p. */ + static int -mips16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +mips16_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) { CORE_ADDR func_addr = 0, func_end = 0; @@ -6617,17 +6842,20 @@ mips16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) return 0; } -/* The epilogue is defined here as the area at the end of a function, +/* Implement the stack_frame_destroyed_p gdbarch method. + + The epilogue is defined here as the area at the end of a function, after an instruction which destroys the function's stack frame. */ + static int -mips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +mips_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) { if (mips_pc_is_mips16 (gdbarch, pc)) - return mips16_in_function_epilogue_p (gdbarch, pc); + return mips16_stack_frame_destroyed_p (gdbarch, pc); else if (mips_pc_is_micromips (gdbarch, pc)) - return micromips_in_function_epilogue_p (gdbarch, pc); + return micromips_stack_frame_destroyed_p (gdbarch, pc); else - return mips32_in_function_epilogue_p (gdbarch, pc); + return mips32_stack_frame_destroyed_p (gdbarch, pc); } /* Root of all "set mips "/"show mips " commands. This will eventually be @@ -6742,25 +6970,6 @@ set_mipsfpu_auto_command (char *args, int from_tty) mips_fpu_type_auto = 1; } -/* Attempt to identify the particular processor model by reading the - processor id. NOTE: cagney/2003-11-15: Firstly it isn't clear that - the relevant processor still exists (it dates back to '94) and - secondly this is not the way to do this. The processor type should - be set by forcing an architecture change. */ - -void -deprecated_mips_set_processor_regs_hack (void) -{ - struct regcache *regcache = get_current_regcache (); - struct gdbarch *gdbarch = get_regcache_arch (regcache); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - ULONGEST prid; - - regcache_cooked_read_unsigned (regcache, MIPS_PRID_REGNUM, &prid); - if ((prid & ~0xf) == 0x700) - tdep->mips_processor_reg_names = mips_r3041_reg_names; -} - /* Just like reinit_frame_cache, but with the right arguments to be callable as an sfunc. */ @@ -6774,7 +6983,9 @@ reinit_frame_cache_sfunc (char *args, int from_tty, static int gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info) { - struct gdbarch *gdbarch = info->application_data; + gdb_disassembler *di + = static_cast(info->application_data); + struct gdbarch *gdbarch = di->arch (); /* FIXME: cagney/2003-06-26: Is this even necessary? The disassembler needs to be able to locally determine the ISA, and @@ -6827,169 +7038,104 @@ gdb_print_insn_mips_n64 (bfd_vma memaddr, struct disassemble_info *info) return gdb_print_insn_mips (memaddr, info); } -/* This function implements gdbarch_breakpoint_from_pc. It uses the - program counter value to determine whether a 16- or 32-bit breakpoint - should be used. It returns a pointer to a string of bytes that encode a - breakpoint instruction, stores the length of the string to *lenptr, and - adjusts pc (if necessary) to point to the actual memory location where - the breakpoint should be inserted. */ +/* Implement the breakpoint_kind_from_pc gdbarch method. */ -static const gdb_byte * -mips_breakpoint_from_pc (struct gdbarch *gdbarch, - CORE_ADDR *pcptr, int *lenptr) +static int +mips_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr) { CORE_ADDR pc = *pcptr; - if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + if (mips_pc_is_mips16 (gdbarch, pc)) { - if (mips_pc_is_mips16 (gdbarch, pc)) - { - static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 }; - *pcptr = unmake_compact_addr (pc); - *lenptr = sizeof (mips16_big_breakpoint); - return mips16_big_breakpoint; - } - else if (mips_pc_is_micromips (gdbarch, pc)) - { - static gdb_byte micromips16_big_breakpoint[] = { 0x46, 0x85 }; - static gdb_byte micromips32_big_breakpoint[] = { 0, 0x5, 0, 0x7 }; - ULONGEST insn; - int status; - int size; - - insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status); - size = status ? 2 - : mips_insn_size (ISA_MICROMIPS, insn) == 2 ? 2 : 4; - *pcptr = unmake_compact_addr (pc); - *lenptr = size; - return (size == 2) ? micromips16_big_breakpoint - : micromips32_big_breakpoint; - } - else - { - /* The IDT board uses an unusual breakpoint value, and - sometimes gets confused when it sees the usual MIPS - breakpoint instruction. */ - static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd }; - static gdb_byte pmon_big_breakpoint[] = { 0, 0, 0, 0xd }; - static gdb_byte idt_big_breakpoint[] = { 0, 0, 0x0a, 0xd }; - /* Likewise, IRIX appears to expect a different breakpoint, - although this is not apparent until you try to use pthreads. */ - static gdb_byte irix_big_breakpoint[] = { 0, 0, 0, 0xd }; - - *lenptr = sizeof (big_breakpoint); - - if (strcmp (target_shortname, "mips") == 0) - return idt_big_breakpoint; - else if (strcmp (target_shortname, "ddb") == 0 - || strcmp (target_shortname, "pmon") == 0 - || strcmp (target_shortname, "lsi") == 0) - return pmon_big_breakpoint; - else if (gdbarch_osabi (gdbarch) == GDB_OSABI_IRIX) - return irix_big_breakpoint; - else - return big_breakpoint; - } + *pcptr = unmake_compact_addr (pc); + return MIPS_BP_KIND_MIPS16; } - else + else if (mips_pc_is_micromips (gdbarch, pc)) { - if (mips_pc_is_mips16 (gdbarch, pc)) - { - static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 }; - *pcptr = unmake_compact_addr (pc); - *lenptr = sizeof (mips16_little_breakpoint); - return mips16_little_breakpoint; - } - else if (mips_pc_is_micromips (gdbarch, pc)) - { - static gdb_byte micromips16_little_breakpoint[] = { 0x85, 0x46 }; - static gdb_byte micromips32_little_breakpoint[] = { 0x5, 0, 0x7, 0 }; - ULONGEST insn; - int status; - int size; - - insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status); - size = status ? 2 - : mips_insn_size (ISA_MICROMIPS, insn) == 2 ? 2 : 4; - *pcptr = unmake_compact_addr (pc); - *lenptr = size; - return (size == 2) ? micromips16_little_breakpoint - : micromips32_little_breakpoint; - } + ULONGEST insn; + int status; + + *pcptr = unmake_compact_addr (pc); + insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status); + if (status || (mips_insn_size (ISA_MICROMIPS, insn) == 2)) + return MIPS_BP_KIND_MICROMIPS16; else - { - static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 }; - static gdb_byte pmon_little_breakpoint[] = { 0xd, 0, 0, 0 }; - static gdb_byte idt_little_breakpoint[] = { 0xd, 0x0a, 0, 0 }; - - *lenptr = sizeof (little_breakpoint); - - if (strcmp (target_shortname, "mips") == 0) - return idt_little_breakpoint; - else if (strcmp (target_shortname, "ddb") == 0 - || strcmp (target_shortname, "pmon") == 0 - || strcmp (target_shortname, "lsi") == 0) - return pmon_little_breakpoint; - else - return little_breakpoint; - } + return MIPS_BP_KIND_MICROMIPS32; } + else + return MIPS_BP_KIND_MIPS32; } -/* Determine the remote breakpoint kind suitable for the PC. The following - kinds are used: +/* Implement the sw_breakpoint_from_kind gdbarch method. */ - * 2 -- 16-bit MIPS16 mode breakpoint, +static const gdb_byte * +mips_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size) +{ + enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); - * 3 -- 16-bit microMIPS mode breakpoint, + switch (kind) + { + case MIPS_BP_KIND_MIPS16: + { + static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 }; + static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 }; - * 4 -- 32-bit standard MIPS mode breakpoint, + *size = 2; + if (byte_order_for_code == BFD_ENDIAN_BIG) + return mips16_big_breakpoint; + else + return mips16_little_breakpoint; + } + case MIPS_BP_KIND_MICROMIPS16: + { + static gdb_byte micromips16_big_breakpoint[] = { 0x46, 0x85 }; + static gdb_byte micromips16_little_breakpoint[] = { 0x85, 0x46 }; - * 5 -- 32-bit microMIPS mode breakpoint. */ + *size = 2; -static void -mips_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, - int *kindptr) -{ - CORE_ADDR pc = *pcptr; + if (byte_order_for_code == BFD_ENDIAN_BIG) + return micromips16_big_breakpoint; + else + return micromips16_little_breakpoint; + } + case MIPS_BP_KIND_MICROMIPS32: + { + static gdb_byte micromips32_big_breakpoint[] = { 0, 0x5, 0, 0x7 }; + static gdb_byte micromips32_little_breakpoint[] = { 0x5, 0, 0x7, 0 }; - if (mips_pc_is_mips16 (gdbarch, pc)) - { - *pcptr = unmake_compact_addr (pc); - *kindptr = 2; - } - else if (mips_pc_is_micromips (gdbarch, pc)) - { - ULONGEST insn; - int status; - int size; + *size = 4; + if (byte_order_for_code == BFD_ENDIAN_BIG) + return micromips32_big_breakpoint; + else + return micromips32_little_breakpoint; + } + case MIPS_BP_KIND_MIPS32: + { + static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd }; + static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 }; - insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status); - size = status ? 2 : mips_insn_size (ISA_MICROMIPS, insn) == 2 ? 2 : 4; - *pcptr = unmake_compact_addr (pc); - *kindptr = size | 1; - } - else - *kindptr = 4; + *size = 4; + if (byte_order_for_code == BFD_ENDIAN_BIG) + return big_breakpoint; + else + return little_breakpoint; + } + default: + gdb_assert_not_reached ("unexpected mips breakpoint kind"); + }; } -/* Return non-zero if the ADDR instruction has a branch delay slot - (i.e. it is a jump or branch instruction). This function is based - on mips32_next_pc. */ +/* Return non-zero if the standard MIPS instruction INST has a branch + delay slot (i.e. it is a jump or branch instruction). This function + is based on mips32_next_pc. */ static int -mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr) +mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, ULONGEST inst) { - unsigned long inst; - int status; int op; int rs; int rt; - inst = mips_fetch_instruction (gdbarch, ISA_MIPS, addr, &status); - if (status) - return 0; - op = itype_op (inst); if ((inst & 0xe0000000) != 0) { @@ -7029,93 +7175,141 @@ mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr) } } -/* Return non-zero if the ADDR instruction, which must be a 32-bit - instruction if MUSTBE32 is set or can be any instruction otherwise, - has a branch delay slot (i.e. it is a non-compact jump instruction). */ +/* Return non-zero if a standard MIPS instruction at ADDR has a branch + delay slot (i.e. it is a jump or branch instruction). */ static int -micromips_instruction_has_delay_slot (struct gdbarch *gdbarch, - CORE_ADDR addr, int mustbe32) +mips32_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr) { ULONGEST insn; int status; - insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status); + insn = mips_fetch_instruction (gdbarch, ISA_MIPS, addr, &status); if (status) return 0; - if (!mustbe32) /* 16-bit instructions. */ - return (micromips_op (insn) == 0x11 - /* POOL16C: bits 010001 */ - && (b5s5_op (insn) == 0xc + return mips32_instruction_has_delay_slot (gdbarch, insn); +} + +/* Return non-zero if the microMIPS instruction INSN, comprising the + 16-bit major opcode word in the high 16 bits and any second word + in the low 16 bits, has a branch delay slot (i.e. it is a non-compact + jump or branch instruction). The instruction must be 32-bit if + MUSTBE32 is set or can be any instruction otherwise. */ + +static int +micromips_instruction_has_delay_slot (ULONGEST insn, int mustbe32) +{ + ULONGEST major = insn >> 16; + + switch (micromips_op (major)) + { + /* 16-bit instructions. */ + case 0x33: /* B16: bits 110011 */ + case 0x2b: /* BNEZ16: bits 101011 */ + case 0x23: /* BEQZ16: bits 100011 */ + return !mustbe32; + case 0x11: /* POOL16C: bits 010001 */ + return (!mustbe32 + && ((b5s5_op (major) == 0xc /* JR16: bits 010001 01100 */ - || (b5s5_op (insn) & 0x1e) == 0xe)) + || (b5s5_op (major) & 0x1e) == 0xe))); /* JALR16, JALRS16: bits 010001 0111x */ - || (micromips_op (insn) & 0x37) == 0x23 - /* BEQZ16, BNEZ16: bits 10x011 */ - || micromips_op (insn) == 0x33; - /* B16: bits 110011 */ - - /* 32-bit instructions. */ - if (micromips_op (insn) == 0x0) - /* POOL32A: bits 000000 */ - { - insn <<= 16; - insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status); - if (status) - return 0; - return 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 */ - } - - return (micromips_op (insn) == 0x10 - /* POOL32I: bits 010000 */ - && ((b5s5_op (insn) & 0x1c) == 0x0 + /* 32-bit instructions. */ + case 0x3d: /* JAL: bits 111101 */ + case 0x3c: /* JALX: bits 111100 */ + case 0x35: /* J: bits 110101 */ + case 0x2d: /* BNE: bits 101101 */ + case 0x25: /* BEQ: bits 100101 */ + case 0x1d: /* JALS: bits 011101 */ + return 1; + case 0x10: /* POOL32I: bits 010000 */ + return ((b5s5_op (major) & 0x1c) == 0x0 /* BLTZ, BLTZAL, BGEZ, BGEZAL: 010000 000xx */ - || (b5s5_op (insn) & 0x1d) == 0x4 + || (b5s5_op (major) & 0x1d) == 0x4 /* BLEZ, BGTZ: bits 010000 001x0 */ - || (b5s5_op (insn) & 0x1d) == 0x11 + || (b5s5_op (major) & 0x1d) == 0x11 /* BLTZALS, BGEZALS: bits 010000 100x1 */ - || ((b5s5_op (insn) & 0x1e) == 0x14 - && (insn & 0x3) == 0x0) + || ((b5s5_op (major) & 0x1e) == 0x14 + && (major & 0x3) == 0x0) /* BC2F, BC2T: bits 010000 1010x xxx00 */ - || (b5s5_op (insn) & 0x1e) == 0x1a + || (b5s5_op (major) & 0x1e) == 0x1a /* BPOSGE64, BPOSGE32: bits 010000 1101x */ - || ((b5s5_op (insn) & 0x1e) == 0x1c - && (insn & 0x3) == 0x0) + || ((b5s5_op (major) & 0x1e) == 0x1c + && (major & 0x3) == 0x0) /* BC1F, BC1T: bits 010000 1110x xxx00 */ - || ((b5s5_op (insn) & 0x1c) == 0x1c - && (insn & 0x3) == 0x1))) + || ((b5s5_op (major) & 0x1c) == 0x1c + && (major & 0x3) == 0x1)); /* BC1ANY*: bits 010000 111xx xxx01 */ - || (micromips_op (insn) & 0x1f) == 0x1d - /* JALS, JAL: bits x11101 */ - || (micromips_op (insn) & 0x37) == 0x25 - /* BEQ, BNE: bits 10x101 */ - || micromips_op (insn) == 0x35 - /* J: bits 110101 */ - || micromips_op (insn) == 0x3c; - /* JALX: bits 111100 */ + case 0x0: /* POOL32A: bits 000000 */ + return (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 */ + default: + return 0; + } } +/* Return non-zero if a microMIPS instruction at ADDR has a branch delay + slot (i.e. it is a non-compact jump instruction). The instruction + must be 32-bit if MUSTBE32 is set or can be any instruction otherwise. */ + static int -mips16_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr, - int mustbe32) +micromips_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, + CORE_ADDR addr, int mustbe32) { - unsigned short inst; + ULONGEST insn; int status; + int size; - inst = mips_fetch_instruction (gdbarch, ISA_MIPS16, addr, &status); + insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status); if (status) return 0; + size = mips_insn_size (ISA_MICROMIPS, insn); + insn <<= 16; + if (size == 2 * MIPS_INSN16_SIZE) + { + insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status); + if (status) + return 0; + } - if (!mustbe32) - return (inst & 0xf89f) == 0xe800; /* JR/JALR (16-bit instruction) */ + return micromips_instruction_has_delay_slot (insn, mustbe32); +} + +/* Return non-zero if the MIPS16 instruction INST, which must be + a 32-bit instruction if MUSTBE32 is set or can be any instruction + otherwise, has a branch delay slot (i.e. it is a non-compact jump + instruction). This function is based on mips16_next_pc. */ + +static int +mips16_instruction_has_delay_slot (unsigned short inst, int mustbe32) +{ + if ((inst & 0xf89f) == 0xe800) /* JR/JALR (16-bit instruction) */ + return !mustbe32; return (inst & 0xf800) == 0x1800; /* JAL/JALX (32-bit instruction) */ } +/* Return non-zero if a MIPS16 instruction at ADDR has a branch delay + slot (i.e. it is a non-compact jump instruction). The instruction + must be 32-bit if MUSTBE32 is set or can be any instruction otherwise. */ + +static int +mips16_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, + CORE_ADDR addr, int mustbe32) +{ + unsigned short insn; + int status; + + insn = mips_fetch_instruction (gdbarch, ISA_MIPS16, addr, &status); + if (status) + return 0; + + return mips16_instruction_has_delay_slot (insn, mustbe32); +} + /* Calculate the starting address of the MIPS memory segment BPADDR is in. This assumes KSSEG exists. */ @@ -7207,12 +7401,12 @@ mips_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr) /* If the previous instruction has a branch delay slot, we have to move the breakpoint to the branch instruction. */ prev_addr = bpaddr - 4; - if (mips32_instruction_has_delay_slot (gdbarch, prev_addr)) + if (mips32_insn_at_pc_has_delay_slot (gdbarch, prev_addr)) bpaddr = prev_addr; } else { - int (*instruction_has_delay_slot) (struct gdbarch *, CORE_ADDR, int); + int (*insn_at_pc_has_delay_slot) (struct gdbarch *, CORE_ADDR, int); CORE_ADDR addr, jmpaddr; int i; @@ -7226,9 +7420,9 @@ mips_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr) 2 bytes, so the idea is the same. FIXME: We have to assume that bpaddr is not the second half of an extended instruction. */ - instruction_has_delay_slot = (mips_pc_is_micromips (gdbarch, bpaddr) - ? micromips_instruction_has_delay_slot - : mips16_instruction_has_delay_slot); + insn_at_pc_has_delay_slot = (mips_pc_is_micromips (gdbarch, bpaddr) + ? micromips_insn_at_pc_has_delay_slot + : mips16_insn_at_pc_has_delay_slot); jmpaddr = 0; addr = bpaddr; @@ -7237,12 +7431,12 @@ mips_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr) if (unmake_compact_addr (addr) == boundary) break; addr -= MIPS_INSN16_SIZE; - if (i == 1 && instruction_has_delay_slot (gdbarch, addr, 0)) + if (i == 1 && insn_at_pc_has_delay_slot (gdbarch, addr, 0)) /* Looks like a JR/JALR at [target-1], but it could be the second word of a previous JAL/JALX, so record it and check back one more. */ jmpaddr = addr; - else if (i > 1 && instruction_has_delay_slot (gdbarch, addr, 1)) + else if (i > 1 && insn_at_pc_has_delay_slot (gdbarch, addr, 1)) { if (i == 2) /* Looks like a JAL/JALX at [target-2], but it could also @@ -7550,8 +7744,8 @@ mips_skip_mips16_trampoline_code (struct frame_info *frame, CORE_ADDR pc) /* If the PC is in __call_stub_* or __fn_stub*, this is one of the compiler-generated call or call/return stubs. */ - if (strncmp (name, mips_str_fn_stub, strlen (mips_str_fn_stub)) == 0 - || strncmp (name, mips_str_call_stub, strlen (mips_str_call_stub)) == 0) + if (startswith (name, mips_str_fn_stub) + || startswith (name, mips_str_call_stub)) { if (pc == start_addr) /* This is the 'call' part of a call stub. Call this helper @@ -7636,9 +7830,9 @@ mips_skip_pic_trampoline_code (struct frame_info *frame, CORE_ADDR pc) which jumps to foo. */ msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym == NULL - || SYMBOL_VALUE_ADDRESS (msym.minsym) != pc - || SYMBOL_LINKAGE_NAME (msym.minsym) == NULL - || strncmp (SYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) != 0) + || BMSYMBOL_VALUE_ADDRESS (msym) != pc + || MSYMBOL_LINKAGE_NAME (msym.minsym) == NULL + || !startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.")) return 0; /* A two-instruction header. */ @@ -7687,27 +7881,15 @@ mips_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) new_pc = mips_skip_mips16_trampoline_code (frame, pc); if (new_pc) - { - pc = new_pc; - if (is_compact_addr (pc)) - pc = unmake_compact_addr (pc); - } + pc = new_pc; new_pc = find_solib_trampoline_target (frame, pc); if (new_pc) - { - pc = new_pc; - if (is_compact_addr (pc)) - pc = unmake_compact_addr (pc); - } + pc = new_pc; new_pc = mips_skip_pic_trampoline_code (frame, pc); if (new_pc) - { - pc = new_pc; - if (is_compact_addr (pc)) - pc = unmake_compact_addr (pc); - } + pc = new_pc; } while (pc != target_pc); @@ -7732,9 +7914,7 @@ mips_stab_reg_to_regnum (struct gdbarch *gdbarch, int num) else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 72 && num < 78) regnum = num + mips_regnum (gdbarch)->dspacc - 72; else - /* This will hopefully (eventually) provoke a warning. Should - we be calling complaint() here? */ - return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + return -1; return gdbarch_num_regs (gdbarch) + regnum; } @@ -7757,9 +7937,7 @@ mips_dwarf_dwarf2_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int num) else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 66 && num < 72) regnum = num + mips_regnum (gdbarch)->dspacc - 66; else - /* This will hopefully (eventually) provoke a warning. Should we - be calling complaint() here? */ - return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch); + return -1; return gdbarch_num_regs (gdbarch) + regnum; } @@ -7815,7 +7993,7 @@ mips_find_abi_section (bfd *abfd, asection *sect, void *obj) if (*abip != MIPS_ABI_UNKNOWN) return; - if (strncmp (name, ".mdebug.", 8) != 0) + if (!startswith (name, ".mdebug.")) return; if (strcmp (name, ".mdebug.abi32") == 0) @@ -7840,11 +8018,11 @@ mips_find_long_section (bfd *abfd, asection *sect, void *obj) int *lbp = (int *) obj; const char *name = bfd_get_section_name (abfd, sect); - if (strncmp (name, ".gcc_compiled_long32", 20) == 0) + if (startswith (name, ".gcc_compiled_long32")) *lbp = 32; - else if (strncmp (name, ".gcc_compiled_long64", 20) == 0) + else if (startswith (name, ".gcc_compiled_long64")) *lbp = 64; - else if (strncmp (name, ".gcc_compiled_long", 18) == 0) + else if (startswith (name, ".gcc_compiled_long")) warning (_("unrecognized .gcc_compiled_longXX")); } @@ -7897,7 +8075,7 @@ mips_register_g_packet_guesses (struct gdbarch *gdbarch) static struct value * value_of_mips_user_reg (struct frame_info *frame, const void *baton) { - const int *reg_p = baton; + const int *reg_p = (const int *) baton; return value_of_register (*reg_p, frame); } @@ -7911,7 +8089,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int i, num_regs; enum mips_fpu_type fpu_type; struct tdesc_arch_data *tdesc_data = NULL; - int elf_fpu_type = 0; + int elf_fpu_type = Val_GNU_MIPS_ABI_FP_ANY; const char **reg_names; struct mips_regnum mips_regnum, *regnum; enum mips_isa mips_isa; @@ -7919,22 +8097,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int dspctl; /* Fill in the OS dependent register numbers and names. */ - if (info.osabi == GDB_OSABI_IRIX) - { - mips_regnum.fp0 = 32; - mips_regnum.pc = 64; - mips_regnum.cause = 65; - mips_regnum.badvaddr = 66; - mips_regnum.hi = 67; - mips_regnum.lo = 68; - mips_regnum.fp_control_status = 69; - mips_regnum.fp_implementation_revision = 70; - mips_regnum.dspacc = dspacc = -1; - mips_regnum.dspctl = dspctl = -1; - num_regs = 71; - reg_names = mips_irix_reg_names; - } - else if (info.osabi == GDB_OSABI_LINUX) + if (info.osabi == GDB_OSABI_LINUX) { mips_regnum.fp0 = 38; mips_regnum.pc = 37; @@ -7948,7 +8111,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) mips_regnum.dspctl = -1; dspacc = 72; dspctl = 78; - num_regs = 79; + num_regs = 90; reg_names = mips_linux_reg_names; } else @@ -8067,6 +8230,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) return NULL; } + num_regs = mips_regnum.fp_implementation_revision + 1; + if (dspacc >= 0) { feature = tdesc_find_feature (info.target_desc, @@ -8100,6 +8265,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) mips_regnum.dspacc = dspacc; mips_regnum.dspctl = dspctl; + + num_regs = mips_regnum.dspctl + 1; } } @@ -8170,7 +8337,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* On Irix, ELF64 executables use the N64 ABI. The pseudo-sections which describe the ABI aren't present on IRIX. (Even for executables created by gcc.) */ - if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour + if (info.abfd != NULL + && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour && elf_elfheader (info.abfd)->e_ident[EI_CLASS] == ELFCLASS64) found_abi = MIPS_ABI_N64; else @@ -8236,17 +8404,17 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (!mips_fpu_type_auto) fpu_type = mips_fpu_type; - else if (elf_fpu_type != 0) + else if (elf_fpu_type != Val_GNU_MIPS_ABI_FP_ANY) { switch (elf_fpu_type) { - case 1: + case Val_GNU_MIPS_ABI_FP_DOUBLE: fpu_type = MIPS_FPU_DOUBLE; break; - case 2: + case Val_GNU_MIPS_ABI_FP_SINGLE: fpu_type = MIPS_FPU_SINGLE; break; - case 3: + case Val_GNU_MIPS_ABI_FP_SOFT: default: /* Soft float or unknown. */ fpu_type = MIPS_FPU_NONE; @@ -8297,12 +8465,14 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) arches != NULL; arches = gdbarch_list_lookup_by_info (arches->next, &info)) { - /* MIPS needs to be pedantic about which ABI the object is - using. */ + /* MIPS needs to be pedantic about which ABI and the compressed + ISA variation the object is using. */ if (gdbarch_tdep (arches->gdbarch)->elf_flags != elf_flags) continue; if (gdbarch_tdep (arches->gdbarch)->mips_abi != mips_abi) continue; + if (gdbarch_tdep (arches->gdbarch)->mips_isa != mips_isa) + continue; /* Need to be pedantic about which register virtual size is used. */ if (gdbarch_tdep (arches->gdbarch)->mips64_transfers_32bit_regs_p @@ -8318,7 +8488,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } /* Need a new architecture. Fill in a target specific vector. */ - tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep)); + tdep = XNEW (struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); tdep->elf_flags = elf_flags; tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p; @@ -8328,10 +8498,6 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->mips_fpu_type = fpu_type; tdep->register_size_valid_p = 0; tdep->register_size = 0; - tdep->gregset = NULL; - tdep->gregset64 = NULL; - tdep->fpregset = NULL; - tdep->fpregset64 = NULL; if (info.target_desc) { @@ -8365,6 +8531,9 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_elf_make_msymbol_special (gdbarch, mips_elf_make_msymbol_special); + set_gdbarch_make_symbol_special (gdbarch, mips_make_symbol_special); + set_gdbarch_adjust_dwarf2_addr (gdbarch, mips_adjust_dwarf2_addr); + set_gdbarch_adjust_dwarf2_line (gdbarch, mips_adjust_dwarf2_line); regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct mips_regnum); *regnum = mips_regnum; @@ -8544,20 +8713,21 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_push_dummy_code (gdbarch, mips_push_dummy_code); set_gdbarch_frame_align (gdbarch, mips_frame_align); + set_gdbarch_print_float_info (gdbarch, mips_print_float_info); + set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p); set_gdbarch_register_to_value (gdbarch, mips_register_to_value); set_gdbarch_value_to_register (gdbarch, mips_value_to_register); set_gdbarch_inner_than (gdbarch, core_addr_lessthan); - set_gdbarch_breakpoint_from_pc (gdbarch, mips_breakpoint_from_pc); - set_gdbarch_remote_breakpoint_from_pc (gdbarch, - mips_remote_breakpoint_from_pc); + set_gdbarch_breakpoint_kind_from_pc (gdbarch, mips_breakpoint_kind_from_pc); + set_gdbarch_sw_breakpoint_from_kind (gdbarch, mips_sw_breakpoint_from_kind); set_gdbarch_adjust_breakpoint_address (gdbarch, mips_adjust_breakpoint_address); set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue); - set_gdbarch_in_function_epilogue_p (gdbarch, mips_in_function_epilogue_p); + set_gdbarch_stack_frame_destroyed_p (gdbarch, mips_stack_frame_destroyed_p); set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address); set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer); @@ -8603,7 +8773,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) mips_register_g_packet_guesses (gdbarch); /* Hook in OS ABI-specific overrides, if they have been registered. */ - info.tdep_info = (void *) tdesc_data; + info.tdep_info = tdesc_data; gdbarch_init_osabi (info, gdbarch); /* The hook may have adjusted num_regs, fetch the final value and