X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmips-tdep.c;h=2599f825e83d9c0b0dcccdfc8e03ffbc223852cd;hb=9822cb57f7570a3b2c8fd95ec2f7b9f9890e30a4;hp=bcbdcc5519f9aacdf4ac1f373fa821a278ae68f0;hpb=3373342d6421686a4c7424a7ef3d5d492d0e4fa8;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index bcbdcc5519..2599f825e8 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-2020 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,27 +44,37 @@ #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" #include "infcall.h" -#include "floatformat.h" #include "remote.h" #include "target-descriptions.h" -#include "dwarf2-frame.h" +#include "dwarf2/frame.h" #include "user-regs.h" #include "valprint.h" #include "ax.h" - -static const struct objfile_data *mips_pdr_data; +#include "target-float.h" +#include 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 +107,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. */ @@ -187,6 +212,18 @@ static unsigned int mips_debug = 0; struct target_desc *mips_tdesc_gp32; struct target_desc *mips_tdesc_gp64; +/* The current set of options to be passed to the disassembler. */ +static char *mips_disassembler_options; + +/* Implicit disassembler options for individual ABIs. These tell + libopcodes to use general-purpose register names corresponding + to the ABI we have selected, perhaps via a `set mips abi ...' + override, rather than ones inferred from the ABI set in the ELF + headers of the binary file selected for debugging. */ +static const char mips_disassembler_options_o32[] = "gpr-names=32"; +static const char mips_disassembler_options_n32[] = "gpr-names=n32"; +static const char mips_disassembler_options_n64[] = "gpr-names=64"; + const struct mips_regnum * mips_regnum (struct gdbarch *gdbarch) { @@ -244,6 +281,9 @@ mips_isa_regsize (struct gdbarch *gdbarch) / gdbarch_bfd_arch_info (gdbarch)->bits_per_byte); } +/* Max saved register size. */ +#define MAX_MIPS_ABI_REGSIZE 8 + /* Return the currently configured (or set) saved register size. */ unsigned int @@ -335,6 +375,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. @@ -364,9 +413,15 @@ mips_elf_make_msymbol_special (asymbol * sym, struct minimal_symbol *msym) return; if (ELF_ST_IS_MICROMIPS (st_other)) - MSYMBOL_TARGET_FLAG_2 (msym) = 1; + { + 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_1 (msym) = 1; + { + 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. */ @@ -374,7 +429,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. */ @@ -382,7 +438,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. */ @@ -390,7 +446,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. @@ -435,11 +520,9 @@ mips_xfer_register (struct gdbarch *gdbarch, struct regcache *regcache, fprintf_unfiltered (gdb_stdlog, "%02x", out[buf_offset + i]); } if (in != NULL) - regcache_cooked_read_part (regcache, reg_num, reg_offset, length, - in + buf_offset); + regcache->cooked_read_part (reg_num, reg_offset, length, in + buf_offset); if (out != NULL) - regcache_cooked_write_part (regcache, reg_num, reg_offset, length, - out + buf_offset); + regcache->cooked_write_part (reg_num, reg_offset, length, out + buf_offset); if (mips_debug && in != NULL) { int i; @@ -481,8 +564,6 @@ mips2_fp_compat (struct frame_info *frame) static CORE_ADDR heuristic_proc_start (struct gdbarch *, CORE_ADDR); -static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *); - /* The list of available "set mips " and "show mips " commands. */ static struct cmd_list_element *setmipscmdlist = NULL; @@ -506,19 +587,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] = { @@ -532,15 +600,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", @@ -558,7 +617,7 @@ mips_register_name (struct gdbarch *gdbarch, int regno) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); /* GPR names for all ABIs other than n32/n64. */ - static char *mips_gpr_names[] = { + static const char *mips_gpr_names[] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", @@ -566,7 +625,7 @@ mips_register_name (struct gdbarch *gdbarch, int regno) }; /* GPR names for n32 and n64 ABIs. */ - static char *mips_n32_n64_gpr_names[] = { + static const char *mips_n32_n64_gpr_names[] = { "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3", "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", @@ -686,26 +745,26 @@ mips_tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regnum, registers. Take care of alignment and size problems. */ static enum register_status -mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, +mips_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache, int cookednum, gdb_byte *buf) { int rawnum = cookednum % gdbarch_num_regs (gdbarch); gdb_assert (cookednum >= gdbarch_num_regs (gdbarch) && cookednum < 2 * gdbarch_num_regs (gdbarch)); if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum)) - return regcache_raw_read (regcache, rawnum, buf); + return regcache->raw_read (rawnum, buf); else if (register_size (gdbarch, rawnum) > register_size (gdbarch, cookednum)) { if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p) - return regcache_raw_read_part (regcache, rawnum, 0, 4, buf); + return regcache->raw_read_part (rawnum, 0, 4, buf); else { enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); LONGEST regval; enum register_status status; - status = regcache_raw_read_signed (regcache, rawnum, ®val); + status = regcache->raw_read (rawnum, ®val); if (status == REG_VALID) store_signed_integer (buf, 4, byte_order, regval); return status; @@ -724,12 +783,12 @@ mips_pseudo_register_write (struct gdbarch *gdbarch, gdb_assert (cookednum >= gdbarch_num_regs (gdbarch) && cookednum < 2 * gdbarch_num_regs (gdbarch)); if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum)) - regcache_raw_write (regcache, rawnum, buf); + regcache->raw_write (rawnum, buf); else if (register_size (gdbarch, rawnum) > register_size (gdbarch, cookednum)) { if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p) - regcache_raw_write_part (regcache, rawnum, 0, 4, buf); + regcache->raw_write_part (rawnum, 0, 4, buf); else { /* Sign extend the shortened version of the register prior @@ -799,10 +858,10 @@ static int heuristic_fence_post = 0; register N. NOTE: This defines the pseudo register type so need to rebuild the architecture vector. */ -static int mips64_transfers_32bit_regs_p = 0; +static bool mips64_transfers_32bit_regs_p = false; static void -set_mips64_transfers_32bit_regs (char *args, int from_tty, +set_mips64_transfers_32bit_regs (const char *args, int from_tty, struct cmd_list_element *c) { struct gdbarch_info info; @@ -979,8 +1038,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 @@ -1020,11 +1078,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) @@ -1049,26 +1114,23 @@ 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; } /* Should the upper word of 64-bit addresses be zeroed? */ -enum auto_boolean mask_address_var = AUTO_BOOLEAN_AUTO; +static enum auto_boolean mask_address_var = AUTO_BOOLEAN_AUTO; static int mips_mask_address_p (struct gdbarch_tdep *tdep) @@ -1127,7 +1189,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 @@ -1145,7 +1207,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 @@ -1164,7 +1226,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 @@ -1184,7 +1246,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)) @@ -1205,6 +1267,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_"; @@ -1231,14 +1354,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. */ @@ -1248,14 +1370,12 @@ mips_in_frame_stub (CORE_ADDR pc) all registers should be sign extended for simplicity? */ static CORE_ADDR -mips_read_pc (struct regcache *regcache) +mips_read_pc (readable_regcache *regcache) { - int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache)); + int regnum = gdbarch_pc_regnum (regcache->arch ()); LONGEST pc; - regcache_cooked_read_signed (regcache, regnum, &pc); - if (is_compact_addr (pc)) - pc = unmake_compact_addr (pc); + regcache->cooked_read (regnum, &pc); return pc; } @@ -1265,8 +1385,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 @@ -1276,15 +1394,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; } @@ -1316,12 +1428,9 @@ mips_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) void mips_write_pc (struct regcache *regcache, CORE_ADDR pc) { - int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache)); + int regnum = gdbarch_pc_regnum (regcache->arch ()); - 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 @@ -1329,12 +1438,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) { @@ -1350,13 +1459,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); @@ -1418,10 +1527,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; @@ -1447,7 +1554,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; @@ -1461,7 +1568,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) @@ -1505,9 +1612,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 = regcache->arch (); unsigned long inst; int op; inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL); @@ -1534,15 +1641,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. */ @@ -1564,8 +1671,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 @@ -1588,15 +1695,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; } @@ -1616,7 +1723,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 */ @@ -1625,7 +1732,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 */ @@ -1642,8 +1749,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; @@ -1666,22 +1773,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; @@ -1689,7 +1796,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; @@ -1743,7 +1850,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; @@ -1757,7 +1864,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) @@ -1772,21 +1879,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 = regcache->arch (); 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; @@ -1795,12 +1896,30 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc) switch (micromips_op (insn >> 16)) { case 0x00: /* POOL32A: bits 000000 */ - if (b0s6_op (insn) == 0x3c - /* POOL32Axf: bits 000000 ... 111100 */ - && (b6s10_ext (insn) & 0x2bf) == 0x3c) - /* JALR, JALR.HB: 000000 000x111100 111100 */ - /* JALRS, JALRS.HB: 000000 010x111100 111100 */ - pc = get_frame_register_signed (frame, b0s5_reg (insn >> 16)); + switch (b0s6_op (insn)) + { + case 0x3c: /* POOL32Axf: bits 000000 ... 111100 */ + switch (b6s10_ext (insn)) + { + case 0x3c: /* JALR: 000000 0000111100 111100 */ + case 0x7c: /* JALR.HB: 000000 0001111100 111100 */ + case 0x13c: /* JALRS: 000000 0100111100 111100 */ + case 0x17c: /* JALRS.HB: 000000 0101111100 111100 */ + pc = regcache_raw_get_signed (regcache, + b0s5_reg (insn >> 16)); + break; + case 0x22d: /* SYSCALL: 000000 1000101101 111100 */ + { + struct gdbarch_tdep *tdep; + + tdep = gdbarch_tdep (gdbarch); + if (tdep->syscall_next_pc != NULL) + pc = tdep->syscall_next_pc (get_current_frame ()); + } + break; + } + break; + } break; case 0x10: /* POOL32I: bits 010000 */ @@ -1809,8 +1928,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); @@ -1819,38 +1938,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; @@ -1871,8 +1990,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); @@ -1884,14 +2003,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; @@ -1903,16 +2022,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); @@ -1931,17 +2050,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); @@ -1952,7 +2071,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); @@ -2121,17 +2240,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 = regcache->arch (); int op = (insn >> 11); switch (op) { @@ -2139,7 +2261,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 @@ -2147,7 +2269,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 @@ -2159,9 +2281,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; @@ -2171,9 +2293,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; @@ -2184,11 +2306,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; @@ -2207,7 +2329,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; @@ -2219,7 +2341,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; } @@ -2233,11 +2355,11 @@ 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 = regcache->arch (); 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 @@ -2246,16 +2368,58 @@ mips16_next_pc (struct frame_info *frame, CORE_ADDR pc) 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 = regcache->arch (); 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 @@ -2335,6 +2499,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; @@ -2345,11 +2513,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. */ @@ -2362,9 +2532,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; @@ -2454,21 +2631,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, @@ -2621,11 +2817,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; } @@ -2641,7 +2838,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); @@ -2659,7 +2856,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. */ @@ -2667,7 +2865,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 @@ -2762,14 +2960,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 */ @@ -2806,19 +3005,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; @@ -2874,7 +3067,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++) @@ -2902,7 +3095,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; } @@ -2958,9 +3150,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. */ @@ -2972,10 +3170,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; @@ -3015,7 +3210,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; @@ -3024,13 +3224,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; } @@ -3048,13 +3251,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; } @@ -3070,7 +3272,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; @@ -3089,7 +3291,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. */ @@ -3097,7 +3300,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 @@ -3202,17 +3405,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 @@ -3228,28 +3436,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 @@ -3260,19 +3479,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; @@ -3282,7 +3501,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 @@ -3331,7 +3550,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) */ @@ -3351,6 +3570,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 */ @@ -3359,31 +3579,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) @@ -3401,14 +3622,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 @@ -3431,7 +3650,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; @@ -3450,7 +3669,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. */ @@ -3458,7 +3678,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 @@ -3540,7 +3760,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; @@ -3587,7 +3807,6 @@ mips_stub_frame_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, void **this_cache) { gdb_byte dummy[4]; - struct obj_section *s; CORE_ADDR pc = get_frame_address_in_block (this_frame); struct bound_minimal_symbol msym; @@ -3602,8 +3821,8 @@ mips_stub_frame_sniffer (const struct frame_unwind *self, stub. The stub for foo is named ".pic.foo". */ msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym != NULL - && SYMBOL_LINKAGE_NAME (msym.minsym) != NULL - && strncmp (SYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) == 0) + && msym.minsym->linkage_name () != NULL + && startswith (msym.minsym->linkage_name (), ".pic.")) return 1; return 0; @@ -3652,9 +3871,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 @@ -3689,11 +3905,10 @@ 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 std::vector +mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc) { - CORE_ADDR breaks[2] = {-1, -1}; + CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX}; CORE_ADDR loc = pc; CORE_ADDR branch_bp; /* Breakpoint at branch instruction's destination. */ ULONGEST insn; @@ -3705,7 +3920,7 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, 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 {}; /* Assume that no atomic sequence is longer than "atomic_sequence_length" instructions. */ @@ -3722,7 +3937,7 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, { case 0: /* SPECIAL */ if (rtype_funct (insn) >> 1 == 4) /* JR, JALR */ - return 0; /* fallback to the standard single-step code. */ + return {}; /* fallback to the standard single-step code. */ break; case 1: /* REGIMM */ is_branch = ((itype_rt (insn) & 0xc) == 0 /* B{LT,GE}Z* */ @@ -3731,7 +3946,7 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, break; case 2: /* J */ case 3: /* JAL */ - return 0; /* fallback to the standard single-step code. */ + return {}; /* fallback to the standard single-step code. */ case 4: /* BEQ */ case 5: /* BNE */ case 6: /* BLEZ */ @@ -3757,8 +3972,8 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, { branch_bp = loc + mips32_relative_offset (insn) + 4; if (last_breakpoint >= 1) - return 0; /* More than one branch found, fallback to the - standard single-step code. */ + return {}; /* More than one branch found, fallback to the + standard single-step code. */ breaks[1] = branch_bp; last_breakpoint++; } @@ -3769,7 +3984,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 {}; loc += MIPS_INSN32_SIZE; @@ -3781,21 +3996,22 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, if (last_breakpoint && pc <= breaks[1] && breaks[1] <= breaks[0]) last_breakpoint = 0; + std::vector next_pcs; + /* Effectively inserts the breakpoints. */ for (index = 0; index <= last_breakpoint; index++) - insert_single_step_breakpoint (gdbarch, aspace, breaks[index]); + next_pcs.push_back (breaks[index]); - return 1; + return next_pcs; } -static int +static std::vector micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch, - struct address_space *aspace, CORE_ADDR pc) { const int atomic_sequence_length = 16; /* Instruction sequence length. */ int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ - CORE_ADDR breaks[2] = {-1, -1}; + CORE_ADDR breaks[2] = {CORE_ADDR_MAX, CORE_ADDR_MAX}; CORE_ADDR branch_bp = 0; /* Breakpoint at branch instruction's destination. */ CORE_ADDR loc = pc; @@ -3807,12 +4023,12 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch, /* 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 {}; 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 {}; loc += MIPS_INSN16_SIZE; /* Assume all atomic sequences end with an sc/scd instruction. Assume @@ -3832,11 +4048,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)) @@ -3887,7 +4098,7 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch, case 0x35: /* J: bits 110101 */ case 0x3d: /* JAL: bits 111101 */ case 0x3c: /* JALX: bits 111100 */ - return 0; /* Fall back to the standard single-step code. */ + return {}; /* Fall back to the standard single-step code. */ case 0x18: /* POOL32C: bits 011000 */ if ((b12s4_op (insn) & 0xb) == 0xb) @@ -3914,24 +4125,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 {}; /* Fall back to the standard single-step code. */ case 0x33: /* B16: bits 110011 */ - return 0; /* Fall back to the standard single-step code. */ + return {}; /* 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 - standard single-step code. */ + return {}; /* More than one branch found, fallback to the + standard single-step code. */ breaks[1] = branch_bp; last_breakpoint++; } } if (!sc_found) - return 0; + return {}; /* Insert a breakpoint right after the end of the atomic sequence. */ breaks[0] = loc; @@ -3941,23 +4152,24 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch, if (last_breakpoint && pc <= breaks[1] && breaks[1] <= breaks[0]) last_breakpoint = 0; + std::vector next_pcs; + /* Effectively inserts the breakpoints. */ for (index = 0; index <= last_breakpoint; index++) - insert_single_step_breakpoint (gdbarch, aspace, breaks[index]); + next_pcs.push_back (breaks[index]); - return 1; + return next_pcs; } -static int -deal_with_atomic_sequence (struct gdbarch *gdbarch, - struct address_space *aspace, CORE_ADDR pc) +static std::vector +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 {}; } /* mips_software_single_step() is called just before we want to resume @@ -3965,21 +4177,21 @@ 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) +std::vector +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 = regcache->arch (); CORE_ADDR pc, next_pc; - pc = get_frame_pc (frame); - if (deal_with_atomic_sequence (gdbarch, aspace, pc)) - return 1; + pc = regcache_read_pc (regcache); + std::vector next_pcs = deal_with_atomic_sequence (gdbarch, pc); - next_pc = mips_next_pc (frame, pc); + if (!next_pcs.empty ()) + return next_pcs; - insert_single_step_breakpoint (gdbarch, aspace, next_pc); - return 1; + next_pc = mips_next_pc (regcache, pc); + + return {next_pc}; } /* Test whether the PC points to the return instruction at the @@ -4281,16 +4493,17 @@ static CORE_ADDR mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) + function_call_return_method return_method, + CORE_ADDR struct_addr) { int argreg; int float_argreg; int argnum; - int len = 0; + int arg_space = 0; int stack_offset = 0; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = find_function_addr (function, NULL); - int regsize = mips_abi_regsize (gdbarch); + int abi_regsize = mips_abi_regsize (gdbarch); /* For shared libraries, "t9" needs to point at the function address. */ @@ -4313,20 +4526,21 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, than necessary for EABI, because the first few arguments are passed in registers, but that's OK. */ for (argnum = 0; argnum < nargs; argnum++) - len += align_up (TYPE_LENGTH (value_type (args[argnum])), regsize); - sp -= align_up (len, 16); + arg_space += align_up (TYPE_LENGTH (value_type (args[argnum])), abi_regsize); + sp -= align_up (arg_space, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, "mips_eabi_push_dummy_call: sp=%s allocated %ld\n", - paddress (gdbarch, sp), (long) align_up (len, 16)); + paddress (gdbarch, sp), + (long) align_up (arg_space, 16)); /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ - if (struct_return) + if (return_method == return_method_struct) { if (mips_debug) fprintf_unfiltered (gdb_stdlog, @@ -4342,7 +4556,9 @@ mips_eabi_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]; + /* This holds the address of structures that are passed by + reference. */ + gdb_byte ref_valbuf[MAX_MIPS_ABI_REGSIZE]; struct value *arg = args[argnum]; struct type *arg_type = check_typedef (value_type (arg)); int len = TYPE_LENGTH (arg_type); @@ -4353,32 +4569,17 @@ 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 > abi_regsize && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)) { - store_unsigned_integer (valbuf, regsize, byte_order, + gdb_assert (abi_regsize <= ARRAY_SIZE (ref_valbuf)); + store_unsigned_integer (ref_valbuf, abi_regsize, byte_order, value_address (arg)); typecode = TYPE_CODE_PTR; - len = regsize; - val = valbuf; + len = abi_regsize; + val = ref_valbuf; if (mips_debug) fprintf_unfiltered (gdb_stdlog, " push"); } @@ -4390,7 +4591,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, up before the check to see if there are any FP registers left. Non MIPS_EABI targets also pass the FP in the integer registers so also round up normal registers. */ - if (regsize < 8 && fp_register_arg_p (gdbarch, typecode, arg_type)) + if (abi_regsize < 8 && fp_register_arg_p (gdbarch, typecode, arg_type)) { if ((float_argreg & 1)) float_argreg++; @@ -4456,12 +4657,12 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Copy the argument to general registers or the stack in register-sized pieces. Large arguments are split between registers and stack. */ - /* Note: structs whose size is not a multiple of regsize + /* Note: structs whose size is not a multiple of abi_regsize are treated specially: Irix cc passes them in registers where gcc sometimes puts them on the stack. For maximum compatibility, we will put them in both places. */ - int odd_sized_struct = (len > regsize && len % regsize != 0); + int odd_sized_struct = (len > abi_regsize && len % abi_regsize != 0); /* Note: Floating-point values that didn't fit into an FP register are only written to memory. */ @@ -4469,7 +4670,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, { /* Remember if the argument was written to the stack. */ int stack_used_p = 0; - int partial_len = (len < regsize ? len : regsize); + int partial_len = (len < abi_regsize ? len : abi_regsize); if (mips_debug) fprintf_unfiltered (gdb_stdlog, " -- partial=%d", @@ -4487,15 +4688,15 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, stack_used_p = 1; if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) { - if (regsize == 8 + if (abi_regsize == 8 && (typecode == TYPE_CODE_INT || typecode == TYPE_CODE_PTR || typecode == TYPE_CODE_FLT) && len <= 4) - longword_offset = regsize - len; + longword_offset = abi_regsize - len; else if ((typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION) - && TYPE_LENGTH (arg_type) < regsize) - longword_offset = regsize - len; + && TYPE_LENGTH (arg_type) < abi_regsize) + longword_offset = abi_regsize - len; } if (mips_debug) @@ -4536,7 +4737,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, if (mips_debug) fprintf_filtered (gdb_stdlog, " - reg=%d val=%s", argreg, - phex (regval, regsize)); + phex (regval, abi_regsize)); regcache_cooked_write_signed (regcache, argreg, regval); argreg++; } @@ -4551,7 +4752,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, only needs to be adjusted when it has been used. */ if (stack_used_p) - stack_offset += align_up (partial_len, regsize); + stack_offset += align_up (partial_len, abi_regsize); } } if (mips_debug) @@ -4688,12 +4889,13 @@ static CORE_ADDR mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) + function_call_return_method return_method, + CORE_ADDR struct_addr) { int argreg; int float_argreg; int argnum; - int len = 0; + int arg_space = 0; int stack_offset = 0; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = find_function_addr (function, NULL); @@ -4717,20 +4919,21 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Now make space on the stack for the args. */ for (argnum = 0; argnum < nargs; argnum++) - len += align_up (TYPE_LENGTH (value_type (args[argnum])), MIPS64_REGSIZE); - sp -= align_up (len, 16); + arg_space += align_up (TYPE_LENGTH (value_type (args[argnum])), MIPS64_REGSIZE); + sp -= align_up (arg_space, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, "mips_n32n64_push_dummy_call: sp=%s allocated %ld\n", - paddress (gdbarch, sp), (long) align_up (len, 16)); + paddress (gdbarch, sp), + (long) align_up (arg_space, 16)); /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ - if (struct_return) + if (return_method == return_method_struct) { if (mips_debug) fprintf_unfiltered (gdb_stdlog, @@ -5144,12 +5347,13 @@ static CORE_ADDR mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) + function_call_return_method return_method, + CORE_ADDR struct_addr) { int argreg; int float_argreg; int argnum; - int len = 0; + int arg_space = 0; int stack_offset = 0; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = find_function_addr (function, NULL); @@ -5178,23 +5382,24 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Align to double-word if necessary. */ if (mips_type_needs_double_align (arg_type)) - len = align_up (len, MIPS32_REGSIZE * 2); + arg_space = align_up (arg_space, MIPS32_REGSIZE * 2); /* Allocate space on the stack. */ - len += align_up (TYPE_LENGTH (arg_type), MIPS32_REGSIZE); + arg_space += align_up (TYPE_LENGTH (arg_type), MIPS32_REGSIZE); } - sp -= align_up (len, 16); + sp -= align_up (arg_space, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, "mips_o32_push_dummy_call: sp=%s allocated %ld\n", - paddress (gdbarch, sp), (long) align_up (len, 16)); + paddress (gdbarch, sp), + (long) align_up (arg_space, 16)); /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ - if (struct_return) + if (return_method == return_method_struct) { if (mips_debug) fprintf_unfiltered (gdb_stdlog, @@ -5329,8 +5534,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) @@ -5345,7 +5548,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) { @@ -5592,7 +5794,6 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct value *function, /* A struct that contains one or two floats. Each value is part in the least significant part of their floating point register.. */ - gdb_byte reg[MAX_REGISTER_SIZE]; int regnum; int field; for (field = 0, regnum = mips_regnum (gdbarch)->fp0; @@ -5672,12 +5873,12 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct regcache *regcache, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) + function_call_return_method return_method, CORE_ADDR struct_addr) { int argreg; int float_argreg; int argnum; - int len = 0; + int arg_space = 0; int stack_offset = 0; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR func_addr = find_function_addr (function, NULL); @@ -5705,21 +5906,22 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function, struct type *arg_type = check_typedef (value_type (args[argnum])); /* Allocate space on the stack. */ - len += align_up (TYPE_LENGTH (arg_type), MIPS64_REGSIZE); + arg_space += align_up (TYPE_LENGTH (arg_type), MIPS64_REGSIZE); } - sp -= align_up (len, 16); + sp -= align_up (arg_space, 16); if (mips_debug) fprintf_unfiltered (gdb_stdlog, "mips_o64_push_dummy_call: sp=%s allocated %ld\n", - paddress (gdbarch, sp), (long) align_up (len, 16)); + paddress (gdbarch, sp), + (long) align_up (arg_space, 16)); /* Initialize the integer and float register pointers. */ argreg = MIPS_A0_REGNUM; float_argreg = mips_fpa0_regnum (gdbarch); /* The struct_return pointer occupies the first parameter-passing reg. */ - if (struct_return) + if (return_method == return_method_struct) { if (mips_debug) fprintf_unfiltered (gdb_stdlog, @@ -5736,7 +5938,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); @@ -5749,21 +5950,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 @@ -5803,8 +5989,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) @@ -5819,7 +6003,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 @@ -5923,7 +6106,6 @@ mips_o64_return_value (struct gdbarch *gdbarch, struct value *function, { CORE_ADDR func_addr = function ? find_function_addr (function, NULL) : 0; int mips16 = mips_pc_is_mips16 (gdbarch, func_addr); - struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); enum mips_fval_reg fval_reg; fval_reg = readbuf ? mips16 ? mips_fval_gpr : mips_fval_fpr : mips_fval_both; @@ -6031,7 +6213,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)"), @@ -6104,11 +6286,14 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame, { /* Do values for FP (float) regs. */ struct gdbarch *gdbarch = get_frame_arch (frame); gdb_byte *raw_buffer; - double doub, flt1; /* Doubles extracted from raw hex data. */ - int inv1, inv2; + std::string flt_str, dbl_str; - raw_buffer = alloca (2 * register_size (gdbarch, - mips_regnum (gdbarch)->fp0)); + const struct type *flt_type = builtin_type (gdbarch)->builtin_float; + const struct type *dbl_type = builtin_type (gdbarch)->builtin_double; + + 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", @@ -6122,31 +6307,21 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame, /* 4-byte registers: Print hex and floating. Also print even numbered registers as doubles. */ mips_read_fp_register_single (frame, regnum, raw_buffer); - flt1 = unpack_double (builtin_type (gdbarch)->builtin_float, - raw_buffer, &inv1); + flt_str = target_float_to_string (raw_buffer, flt_type, "%-17.9g"); get_formatted_print_options (&opts, 'x'); print_scalar_formatted (raw_buffer, builtin_type (gdbarch)->builtin_uint32, &opts, 'w', file); - fprintf_filtered (file, " flt: "); - if (inv1) - fprintf_filtered (file, " "); - else - fprintf_filtered (file, "%-17.9g", flt1); + fprintf_filtered (file, " flt: %s", flt_str.c_str ()); if ((regnum - gdbarch_num_regs (gdbarch)) % 2 == 0) { mips_read_fp_register_double (frame, regnum, raw_buffer); - doub = unpack_double (builtin_type (gdbarch)->builtin_double, - raw_buffer, &inv2); + dbl_str = target_float_to_string (raw_buffer, dbl_type, "%-24.17g"); - fprintf_filtered (file, " dbl: "); - if (inv2) - fprintf_filtered (file, ""); - else - fprintf_filtered (file, "%-24.17g", doub); + fprintf_filtered (file, " dbl: %s", dbl_str.c_str ()); } } else @@ -6155,29 +6330,18 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame, /* Eight byte registers: print each one as hex, float and double. */ mips_read_fp_register_single (frame, regnum, raw_buffer); - flt1 = unpack_double (builtin_type (gdbarch)->builtin_float, - raw_buffer, &inv1); + flt_str = target_float_to_string (raw_buffer, flt_type, "%-17.9g"); mips_read_fp_register_double (frame, regnum, raw_buffer); - doub = unpack_double (builtin_type (gdbarch)->builtin_double, - raw_buffer, &inv2); + dbl_str = target_float_to_string (raw_buffer, dbl_type, "%-24.17g"); get_formatted_print_options (&opts, 'x'); print_scalar_formatted (raw_buffer, builtin_type (gdbarch)->builtin_uint64, &opts, 'g', file); - fprintf_filtered (file, " flt: "); - if (inv1) - fprintf_filtered (file, ""); - else - fprintf_filtered (file, "%-17.9g", flt1); - - fprintf_filtered (file, " dbl: "); - if (inv2) - fprintf_filtered (file, ""); - else - fprintf_filtered (file, "%-24.17g", doub); + fprintf_filtered (file, " flt: %s", flt_str.c_str ()); + fprintf_filtered (file, " dbl: %s", dbl_str.c_str ()); } } @@ -6196,12 +6360,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); @@ -6216,12 +6374,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. */ @@ -6244,7 +6489,8 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame, { struct gdbarch *gdbarch = get_frame_arch (frame); /* Do values for GP (int) regs. */ - gdb_byte raw_buffer[MAX_REGISTER_SIZE]; + const gdb_byte *raw_buffer; + struct value *value; int ncols = (mips_abi_regsize (gdbarch) == 8 ? 4 : 8); /* display cols per row. */ int col, byte; @@ -6252,8 +6498,7 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame, /* For GP registers, we print a separate row of names above the vals. */ for (col = 0, regnum = start_regnum; - col < ncols && regnum < gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch); + col < ncols && regnum < gdbarch_num_cooked_regs (gdbarch); regnum++) { if (*gdbarch_register_name (gdbarch, regnum) == '\0') @@ -6291,8 +6536,7 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame, /* Now print the values in hex, 4 or 8 to the row. */ for (col = 0, regnum = start_regnum; - col < ncols && regnum < gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch); + col < ncols && regnum < gdbarch_num_cooked_regs (gdbarch); regnum++) { if (*gdbarch_register_name (gdbarch, regnum) == '\0') @@ -6303,14 +6547,23 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame, break; /* End row: large register. */ /* OK: get the data in raw format. */ - if (!deprecated_frame_register_read (frame, regnum, raw_buffer)) - error (_("can't read register %d (%s)"), - regnum, gdbarch_register_name (gdbarch, regnum)); + value = get_frame_register_value (frame, regnum); + if (value_optimized_out (value) + || !value_entirely_available (value)) + { + fprintf_filtered (file, "%*s ", + (int) mips_abi_regsize (gdbarch) * 2, + (mips_abi_regsize (gdbarch) == 4 ? "" + : "")); + col++; + continue; + } + raw_buffer = value_contents_all (value); /* pad small registers */ for (byte = 0; byte < (mips_abi_regsize (gdbarch) - register_size (gdbarch, regnum)); byte++) - printf_filtered (" "); + fprintf_filtered (file, " "); /* Now print the register value in hex, endian order. */ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) for (byte = @@ -6349,8 +6602,7 @@ mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file, /* Do all (or most) registers. */ { regnum = gdbarch_num_regs (gdbarch); - while (regnum < gdbarch_num_regs (gdbarch) - + gdbarch_num_pseudo_regs (gdbarch)) + while (regnum < gdbarch_num_cooked_regs (gdbarch)) { if (mips_float_register_p (gdbarch, regnum)) { @@ -6369,27 +6621,26 @@ static int mips_single_step_through_delay (struct gdbarch *gdbarch, struct frame_info *frame) { - enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); CORE_ADDR pc = get_frame_pc (frame); - struct address_space *aspace; enum mips_isa isa; ULONGEST insn; - int status; 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); /* _has_delay_slot above will have validated the read. */ insn = mips_fetch_instruction (gdbarch, isa, pc, NULL); size = mips_insn_size (isa, insn); - aspace = get_frame_address_space (frame); + + const address_space *aspace = get_frame_address_space (frame); + return breakpoint_here_p (aspace, pc + size) != no_breakpoint_here; } @@ -6416,7 +6667,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 @@ -6437,10 +6688,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; @@ -6475,11 +6727,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; @@ -6508,11 +6760,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; @@ -6576,10 +6823,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; @@ -6616,30 +6864,33 @@ 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 used for all MIPS-specific commands. */ static void -show_mips_command (char *args, int from_tty) +show_mips_command (const char *args, int from_tty) { help_list (showmipscmdlist, "show mips ", all_commands, gdb_stdout); } static void -set_mips_command (char *args, int from_tty) +set_mips_command (const char *args, int from_tty) { printf_unfiltered ("\"set mips\" must be followed by an appropriate subcommand.\n"); @@ -6649,9 +6900,9 @@ set_mips_command (char *args, int from_tty) /* Commands to show/set the MIPS FPU type. */ static void -show_mipsfpu_command (char *args, int from_tty) +show_mipsfpu_command (const char *args, int from_tty) { - char *fpu; + const char *fpu; if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_mips) { @@ -6686,7 +6937,7 @@ show_mipsfpu_command (char *args, int from_tty) static void -set_mipsfpu_command (char *args, int from_tty) +set_mipsfpu_command (const char *args, int from_tty) { printf_unfiltered ("\"set mipsfpu\" must be followed by \"double\", " "\"single\",\"none\" or \"auto\".\n"); @@ -6694,7 +6945,7 @@ set_mipsfpu_command (char *args, int from_tty) } static void -set_mipsfpu_single_command (char *args, int from_tty) +set_mipsfpu_single_command (const char *args, int from_tty) { struct gdbarch_info info; gdbarch_info_init (&info); @@ -6708,7 +6959,7 @@ set_mipsfpu_single_command (char *args, int from_tty) } static void -set_mipsfpu_double_command (char *args, int from_tty) +set_mipsfpu_double_command (const char *args, int from_tty) { struct gdbarch_info info; gdbarch_info_init (&info); @@ -6722,7 +6973,7 @@ set_mipsfpu_double_command (char *args, int from_tty) } static void -set_mipsfpu_none_command (char *args, int from_tty) +set_mipsfpu_none_command (const char *args, int from_tty) { struct gdbarch_info info; gdbarch_info_init (&info); @@ -6736,35 +6987,16 @@ set_mipsfpu_none_command (char *args, int from_tty) } static void -set_mipsfpu_auto_command (char *args, int from_tty) +set_mipsfpu_auto_command (const 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. */ static void -reinit_frame_cache_sfunc (char *args, int from_tty, +reinit_frame_cache_sfunc (const char *args, int from_tty, struct cmd_list_element *c) { reinit_frame_cache (); @@ -6773,7 +7005,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 @@ -6788,207 +7022,107 @@ gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info) memaddr &= (info->mach == bfd_mach_mips16 || info->mach == bfd_mach_mips_micromips) ? ~1 : ~3; - /* Set the disassembler options. */ - if (!info->disassembler_options) - /* This string is not recognized explicitly by the disassembler, - but it tells the disassembler to not try to guess the ABI from - the bfd elf headers, such that, if the user overrides the ABI - of a program linked as NewABI, the disassembly will follow the - register naming conventions specified by the user. */ - info->disassembler_options = "gpr-names=32"; - - /* Call the appropriate disassembler based on the target endian-ness. */ - if (info->endian == BFD_ENDIAN_BIG) - return print_insn_big_mips (memaddr, info); - else - return print_insn_little_mips (memaddr, info); + return default_print_insn (memaddr, info); } +/* Implement the breakpoint_kind_from_pc gdbarch method. */ + static int -gdb_print_insn_mips_n32 (bfd_vma memaddr, struct disassemble_info *info) +mips_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr) { - /* Set up the disassembler info, so that we get the right - register names from libopcodes. */ - info->disassembler_options = "gpr-names=n32"; - info->flavour = bfd_target_elf_flavour; + CORE_ADDR pc = *pcptr; - return gdb_print_insn_mips (memaddr, info); -} - -static int -gdb_print_insn_mips_n64 (bfd_vma memaddr, struct disassemble_info *info) -{ - /* Set up the disassembler info, so that we get the right - register names from libopcodes. */ - info->disassembler_options = "gpr-names=64"; - info->flavour = bfd_target_elf_flavour; - - return gdb_print_insn_mips (memaddr, info); -} - -/* 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. */ - -static const gdb_byte * -mips_breakpoint_from_pc (struct gdbarch *gdbarch, - CORE_ADDR *pcptr, int *lenptr) -{ - 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) { @@ -7028,93 +7162,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; + } + + return micromips_instruction_has_delay_slot (insn, mustbe32); +} - if (!mustbe32) - return (inst & 0xf89f) == 0xe800; /* JR/JALR (16-bit instruction) */ +/* 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. */ @@ -7206,12 +7388,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; @@ -7225,9 +7407,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; @@ -7236,12 +7418,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 @@ -7549,8 +7731,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 @@ -7635,9 +7817,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 + || msym.minsym->linkage_name () == NULL + || !startswith (msym.minsym->linkage_name (), ".pic.")) return 0; /* A two-instruction header. */ @@ -7686,27 +7868,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); @@ -7731,9 +7901,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; } @@ -7756,9 +7924,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; } @@ -7809,12 +7975,12 @@ static void mips_find_abi_section (bfd *abfd, asection *sect, void *obj) { enum mips_abi *abip = (enum mips_abi *) obj; - const char *name = bfd_get_section_name (abfd, sect); + const char *name = bfd_section_name (sect); if (*abip != MIPS_ABI_UNKNOWN) return; - if (strncmp (name, ".mdebug.", 8) != 0) + if (!startswith (name, ".mdebug.")) return; if (strcmp (name, ".mdebug.abi32") == 0) @@ -7837,13 +8003,13 @@ static void mips_find_long_section (bfd *abfd, asection *sect, void *obj) { int *lbp = (int *) obj; - const char *name = bfd_get_section_name (abfd, sect); + const char *name = bfd_section_name (sect); - if (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")); } @@ -7896,7 +8062,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); } @@ -7917,196 +8083,6 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int dspacc; 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) - { - mips_regnum.fp0 = 38; - mips_regnum.pc = 37; - mips_regnum.cause = 36; - mips_regnum.badvaddr = 35; - mips_regnum.hi = 34; - mips_regnum.lo = 33; - mips_regnum.fp_control_status = 70; - mips_regnum.fp_implementation_revision = 71; - mips_regnum.dspacc = -1; - mips_regnum.dspctl = -1; - dspacc = 72; - dspctl = 78; - num_regs = 79; - reg_names = mips_linux_reg_names; - } - else - { - mips_regnum.lo = MIPS_EMBED_LO_REGNUM; - mips_regnum.hi = MIPS_EMBED_HI_REGNUM; - mips_regnum.badvaddr = MIPS_EMBED_BADVADDR_REGNUM; - mips_regnum.cause = MIPS_EMBED_CAUSE_REGNUM; - mips_regnum.pc = MIPS_EMBED_PC_REGNUM; - mips_regnum.fp0 = MIPS_EMBED_FP0_REGNUM; - mips_regnum.fp_control_status = 70; - mips_regnum.fp_implementation_revision = 71; - mips_regnum.dspacc = dspacc = -1; - mips_regnum.dspctl = dspctl = -1; - num_regs = MIPS_LAST_EMBED_REGNUM + 1; - if (info.bfd_arch_info != NULL - && info.bfd_arch_info->mach == bfd_mach_mips3900) - reg_names = mips_tx39_reg_names; - else - reg_names = mips_generic_reg_names; - } - - /* Check any target description for validity. */ - if (tdesc_has_registers (info.target_desc)) - { - static const char *const mips_gprs[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", - "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" - }; - static const char *const mips_fprs[] = { - "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", - }; - - const struct tdesc_feature *feature; - int valid_p; - - feature = tdesc_find_feature (info.target_desc, - "org.gnu.gdb.mips.cpu"); - if (feature == NULL) - return NULL; - - tdesc_data = tdesc_data_alloc (); - - valid_p = 1; - for (i = MIPS_ZERO_REGNUM; i <= MIPS_RA_REGNUM; i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, i, - mips_gprs[i]); - - - valid_p &= tdesc_numbered_register (feature, tdesc_data, - mips_regnum.lo, "lo"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, - mips_regnum.hi, "hi"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, - mips_regnum.pc, "pc"); - - if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } - - feature = tdesc_find_feature (info.target_desc, - "org.gnu.gdb.mips.cp0"); - if (feature == NULL) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } - - valid_p = 1; - valid_p &= tdesc_numbered_register (feature, tdesc_data, - mips_regnum.badvaddr, "badvaddr"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, - MIPS_PS_REGNUM, "status"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, - mips_regnum.cause, "cause"); - - if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } - - /* FIXME drow/2007-05-17: The FPU should be optional. The MIPS - backend is not prepared for that, though. */ - feature = tdesc_find_feature (info.target_desc, - "org.gnu.gdb.mips.fpu"); - if (feature == NULL) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } - - valid_p = 1; - for (i = 0; i < 32; i++) - valid_p &= tdesc_numbered_register (feature, tdesc_data, - i + mips_regnum.fp0, mips_fprs[i]); - - valid_p &= tdesc_numbered_register (feature, tdesc_data, - mips_regnum.fp_control_status, - "fcsr"); - valid_p - &= tdesc_numbered_register (feature, tdesc_data, - mips_regnum.fp_implementation_revision, - "fir"); - - if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } - - if (dspacc >= 0) - { - feature = tdesc_find_feature (info.target_desc, - "org.gnu.gdb.mips.dsp"); - /* The DSP registers are optional; it's OK if they are absent. */ - if (feature != NULL) - { - i = 0; - valid_p = 1; - valid_p &= tdesc_numbered_register (feature, tdesc_data, - dspacc + i++, "hi1"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, - dspacc + i++, "lo1"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, - dspacc + i++, "hi2"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, - dspacc + i++, "lo2"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, - dspacc + i++, "hi3"); - valid_p &= tdesc_numbered_register (feature, tdesc_data, - dspacc + i++, "lo3"); - - valid_p &= tdesc_numbered_register (feature, tdesc_data, - dspctl, "dspctl"); - - if (!valid_p) - { - tdesc_data_cleanup (tdesc_data); - return NULL; - } - - mips_regnum.dspacc = dspacc; - mips_regnum.dspctl = dspctl; - } - } - - /* It would be nice to detect an attempt to use a 64-bit ABI - when only 32-bit registers are provided. */ - reg_names = NULL; - } - /* First of all, extract the elf_flags, if available. */ if (info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour) elf_flags = elf_elfheader (info.abfd)->e_flags; @@ -8169,7 +8145,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 @@ -8207,6 +8184,14 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) fprintf_unfiltered (gdb_stdlog, "mips_gdbarch_init: mips_abi = %d\n", mips_abi); + /* Make sure we don't use a 32-bit architecture with a 64-bit ABI. */ + if (mips_abi != MIPS_ABI_EABI32 + && mips_abi != MIPS_ABI_O32 + && info.bfd_arch_info != NULL + && info.bfd_arch_info->arch == bfd_arch_mips + && info.bfd_arch_info->bits_per_word < 64) + info.bfd_arch_info = bfd_lookup_arch (bfd_arch_mips, bfd_mach_mips4000); + /* Determine the default compressed ISA. */ if ((elf_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0 && (elf_flags & EF_MIPS_ARCH_ASE_M16) == 0) @@ -8270,7 +8255,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) break; } else if (arches != NULL) - fpu_type = gdbarch_tdep (arches->gdbarch)->mips_fpu_type; + fpu_type = MIPS_FPU_TYPE (arches->gdbarch); else fpu_type = MIPS_FPU_DOUBLE; if (gdbarch_debug) @@ -8285,10 +8270,185 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) && tdesc_property (info.target_desc, PROPERTY_GP32) != NULL && mips_abi != MIPS_ABI_EABI32 && mips_abi != MIPS_ABI_O32) + return NULL; + + /* Fill in the OS dependent register numbers and names. */ + if (info.osabi == GDB_OSABI_LINUX) { - if (tdesc_data != NULL) - tdesc_data_cleanup (tdesc_data); - return NULL; + mips_regnum.fp0 = 38; + mips_regnum.pc = 37; + mips_regnum.cause = 36; + mips_regnum.badvaddr = 35; + mips_regnum.hi = 34; + mips_regnum.lo = 33; + mips_regnum.fp_control_status = 70; + mips_regnum.fp_implementation_revision = 71; + mips_regnum.dspacc = -1; + mips_regnum.dspctl = -1; + dspacc = 72; + dspctl = 78; + num_regs = 90; + reg_names = mips_linux_reg_names; + } + else + { + mips_regnum.lo = MIPS_EMBED_LO_REGNUM; + mips_regnum.hi = MIPS_EMBED_HI_REGNUM; + mips_regnum.badvaddr = MIPS_EMBED_BADVADDR_REGNUM; + mips_regnum.cause = MIPS_EMBED_CAUSE_REGNUM; + mips_regnum.pc = MIPS_EMBED_PC_REGNUM; + mips_regnum.fp0 = MIPS_EMBED_FP0_REGNUM; + mips_regnum.fp_control_status = 70; + mips_regnum.fp_implementation_revision = 71; + mips_regnum.dspacc = dspacc = -1; + mips_regnum.dspctl = dspctl = -1; + num_regs = MIPS_LAST_EMBED_REGNUM + 1; + if (info.bfd_arch_info != NULL + && info.bfd_arch_info->mach == bfd_mach_mips3900) + reg_names = mips_tx39_reg_names; + else + reg_names = mips_generic_reg_names; + } + + /* Check any target description for validity. */ + if (tdesc_has_registers (info.target_desc)) + { + static const char *const mips_gprs[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" + }; + static const char *const mips_fprs[] = { + "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", + }; + + const struct tdesc_feature *feature; + int valid_p; + + feature = tdesc_find_feature (info.target_desc, + "org.gnu.gdb.mips.cpu"); + if (feature == NULL) + return NULL; + + tdesc_data = tdesc_data_alloc (); + + valid_p = 1; + for (i = MIPS_ZERO_REGNUM; i <= MIPS_RA_REGNUM; i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, i, + mips_gprs[i]); + + + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.lo, "lo"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.hi, "hi"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.pc, "pc"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + + feature = tdesc_find_feature (info.target_desc, + "org.gnu.gdb.mips.cp0"); + if (feature == NULL) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + + valid_p = 1; + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.badvaddr, "badvaddr"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + MIPS_PS_REGNUM, "status"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.cause, "cause"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + + /* FIXME drow/2007-05-17: The FPU should be optional. The MIPS + backend is not prepared for that, though. */ + feature = tdesc_find_feature (info.target_desc, + "org.gnu.gdb.mips.fpu"); + if (feature == NULL) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + + valid_p = 1; + for (i = 0; i < 32; i++) + valid_p &= tdesc_numbered_register (feature, tdesc_data, + i + mips_regnum.fp0, mips_fprs[i]); + + valid_p &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.fp_control_status, + "fcsr"); + valid_p + &= tdesc_numbered_register (feature, tdesc_data, + mips_regnum.fp_implementation_revision, + "fir"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + + num_regs = mips_regnum.fp_implementation_revision + 1; + + if (dspacc >= 0) + { + feature = tdesc_find_feature (info.target_desc, + "org.gnu.gdb.mips.dsp"); + /* The DSP registers are optional; it's OK if they are absent. */ + if (feature != NULL) + { + i = 0; + valid_p = 1; + valid_p &= tdesc_numbered_register (feature, tdesc_data, + dspacc + i++, "hi1"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + dspacc + i++, "lo1"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + dspacc + i++, "hi2"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + dspacc + i++, "lo2"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + dspacc + i++, "hi3"); + valid_p &= tdesc_numbered_register (feature, tdesc_data, + dspacc + i++, "lo3"); + + valid_p &= tdesc_numbered_register (feature, tdesc_data, + dspctl, "dspctl"); + + if (!valid_p) + { + tdesc_data_cleanup (tdesc_data); + return NULL; + } + + mips_regnum.dspacc = dspacc; + mips_regnum.dspctl = dspctl; + + num_regs = mips_regnum.dspctl + 1; + } + } + + /* It would be nice to detect an attempt to use a 64-bit ABI + when only 32-bit registers are provided. */ + reg_names = NULL; } /* Try to find a pre-existing architecture. */ @@ -8296,19 +8456,21 @@ 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 != mips64_transfers_32bit_regs_p) continue; /* Be pedantic about which FPU is selected. */ - if (gdbarch_tdep (arches->gdbarch)->mips_fpu_type != fpu_type) + if (MIPS_FPU_TYPE (arches->gdbarch) != fpu_type) continue; if (tdesc_data != NULL) @@ -8317,7 +8479,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 = XCNEW (struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); tdep->elf_flags = elf_flags; tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p; @@ -8327,10 +8489,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) { @@ -8364,6 +8522,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; @@ -8543,20 +8704,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); @@ -8566,12 +8728,19 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_print_registers_info (gdbarch, mips_print_registers_info); - if (mips_abi == MIPS_ABI_N32) - set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips_n32); - else if (mips_abi == MIPS_ABI_N64) - set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips_n64); + set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips); + if (mips_abi == MIPS_ABI_N64) + set_gdbarch_disassembler_options_implicit + (gdbarch, (const char *) mips_disassembler_options_n64); + else if (mips_abi == MIPS_ABI_N32) + set_gdbarch_disassembler_options_implicit + (gdbarch, (const char *) mips_disassembler_options_n32); else - set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips); + set_gdbarch_disassembler_options_implicit + (gdbarch, (const char *) mips_disassembler_options_o32); + set_gdbarch_disassembler_options (gdbarch, &mips_disassembler_options); + set_gdbarch_valid_disassembler_options (gdbarch, + disassembler_options_mips ()); /* FIXME: cagney/2003-08-29: The macros target_have_steppable_watchpoint, HAVE_NONSTEPPABLE_WATCHPOINT, and target_have_continuable_watchpoint @@ -8602,7 +8771,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.tdesc_data = tdesc_data; gdbarch_init_osabi (info, gdbarch); /* The hook may have adjusted num_regs, fetch the final value and @@ -8664,7 +8833,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) } static void -mips_abi_update (char *ignore_args, int from_tty, struct cmd_list_element *c) +mips_abi_update (const char *ignore_args, + int from_tty, struct cmd_list_element *c) { struct gdbarch_info info; @@ -8724,6 +8894,24 @@ show_mips_compression (struct ui_file *file, int from_tty, value); } +/* Return a textual name for MIPS FPU type FPU_TYPE. */ + +static const char * +mips_fpu_type_str (enum mips_fpu_type fpu_type) +{ + switch (fpu_type) + { + case MIPS_FPU_NONE: + return "none"; + case MIPS_FPU_SINGLE: + return "single"; + case MIPS_FPU_DOUBLE: + return "double"; + default: + return "???"; + } +} + static void mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) { @@ -8774,28 +8962,20 @@ mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) fprintf_unfiltered (file, "mips_dump_tdep: MIPS_DEFAULT_FPU_TYPE = %d (%s)\n", MIPS_DEFAULT_FPU_TYPE, - (MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_NONE ? "none" - : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_SINGLE ? "single" - : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_DOUBLE ? "double" - : "???")); + mips_fpu_type_str (MIPS_DEFAULT_FPU_TYPE)); fprintf_unfiltered (file, "mips_dump_tdep: MIPS_EABI = %d\n", MIPS_EABI (gdbarch)); fprintf_unfiltered (file, "mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n", MIPS_FPU_TYPE (gdbarch), - (MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_NONE ? "none" - : MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_SINGLE ? "single" - : MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_DOUBLE ? "double" - : "???")); + mips_fpu_type_str (MIPS_FPU_TYPE (gdbarch))); } -extern initialize_file_ftype _initialize_mips_tdep; /* -Wmissing-prototypes */ - +void _initialize_mips_tdep (); void -_initialize_mips_tdep (void) +_initialize_mips_tdep () { static struct cmd_list_element *mipsfpulist = NULL; - struct cmd_list_element *c; mips_abi_string = mips_abi_strings[MIPS_ABI_UNKNOWN]; if (MIPS_ABI_LAST + 1 @@ -8804,8 +8984,6 @@ _initialize_mips_tdep (void) gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep); - mips_pdr_data = register_objfile_data (); - /* Create feature sets with the appropriate properties. The values are not important. */ mips_tdesc_gp32 = allocate_target_description ();