X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmips-tdep.c;h=0852851595f0eac5008283d992379415cda61831;hb=c6cbf900d42cf8f2ebbcf33d799c52c54b9aa9f0;hp=89ccea88d4d0122df259d52d60ff73bce4d6300e;hpb=8d7493201cf01c9836403695f67f7e157341bfd5;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 89ccea88d4..0852851595 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -1,6 +1,6 @@ /* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger. - Copyright (C) 1988-2015 Free Software Foundation, Inc. + Copyright (C) 1988-2019 Free Software Foundation, Inc. Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin. @@ -44,19 +44,19 @@ #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 "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); @@ -107,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. */ @@ -195,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) { @@ -252,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 @@ -488,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; @@ -534,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; @@ -559,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] = { @@ -585,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", @@ -611,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", @@ -619,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", @@ -739,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; @@ -777,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 @@ -852,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; @@ -1032,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 @@ -1073,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) @@ -1102,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) @@ -1361,12 +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); + regcache->cooked_read (regnum, &pc); return pc; } @@ -1419,7 +1428,7 @@ 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 ()); regcache_cooked_write_unsigned (regcache, regnum, pc); } @@ -1429,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) { @@ -1450,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); @@ -1518,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; @@ -1547,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; @@ -1561,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) @@ -1605,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); @@ -1634,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. */ @@ -1664,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 @@ -1688,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; } @@ -1716,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 */ @@ -1725,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 */ @@ -1742,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; @@ -1766,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; @@ -1789,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; @@ -1843,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; @@ -1857,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) @@ -1872,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; @@ -1895,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 */ @@ -1909,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); @@ -1919,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; @@ -1971,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); @@ -1984,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; @@ -2003,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); @@ -2031,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); @@ -2052,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); @@ -2231,10 +2250,10 @@ add_offset_16 (CORE_ADDR pc, int offset) } 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) { @@ -2262,7 +2281,7 @@ 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 = add_offset_16 (pc, upk.offset); else @@ -2274,7 +2293,7 @@ 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 = add_offset_16 (pc, upk.offset); else @@ -2287,7 +2306,8 @@ 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); @@ -2309,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; @@ -2321,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; } @@ -2335,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 @@ -2348,16 +2368,16 @@ 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 @@ -2818,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); @@ -2836,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. */ @@ -2844,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 @@ -2946,7 +2967,6 @@ micromips_scan_prologue (struct gdbarch *gdbarch, 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; @@ -2992,13 +3012,6 @@ micromips_scan_prologue (struct gdbarch *gdbarch, 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; @@ -3054,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++) @@ -3082,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; } @@ -3158,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; @@ -3263,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; @@ -3282,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. */ @@ -3290,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 @@ -3640,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; @@ -3659,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. */ @@ -3667,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 @@ -3749,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; @@ -3796,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; @@ -3811,8 +3821,8 @@ mips_stub_frame_sniffer (const struct frame_unwind *self, stub. The stub for foo is named ".pic.foo". */ msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym != NULL - && MSYMBOL_LINKAGE_NAME (msym.minsym) != NULL - && startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.")) + && msym.minsym->linkage_name () != NULL + && startswith (msym.minsym->linkage_name (), ".pic.")) return 1; return 0; @@ -3895,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; @@ -3911,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. */ @@ -3928,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* */ @@ -3937,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 */ @@ -3963,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++; } @@ -3975,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; @@ -3987,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; @@ -4013,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 @@ -4038,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)) @@ -4093,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) @@ -4120,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; @@ -4147,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 @@ -4171,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 @@ -4487,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. */ @@ -4519,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, @@ -4548,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); @@ -4561,14 +4571,15 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* The EABI passes structures that do not fit in a register by reference. */ - 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"); } @@ -4580,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++; @@ -4646,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. */ @@ -4659,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", @@ -4677,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) @@ -4726,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++; } @@ -4741,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) @@ -4878,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); @@ -4907,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, @@ -5334,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); @@ -5368,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, @@ -5519,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) @@ -5535,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) { @@ -5782,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; @@ -5862,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); @@ -5895,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, @@ -5977,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) @@ -5993,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 @@ -6097,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; @@ -6205,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)"), @@ -6278,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", @@ -6296,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 @@ -6329,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 ()); } } @@ -6384,7 +6374,6 @@ 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); @@ -6500,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; @@ -6508,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') @@ -6547,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') @@ -6559,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 = @@ -6605,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)) { @@ -6625,12 +6621,9 @@ 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) @@ -6645,7 +6638,9 @@ mips_single_step_through_delay (struct gdbarch *gdbarch, /* _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; } @@ -6672,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 @@ -6765,11 +6760,6 @@ micromips_stack_frame_destroyed_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; @@ -6894,13 +6884,13 @@ mips_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) 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"); @@ -6910,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) { @@ -6947,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"); @@ -6955,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); @@ -6969,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); @@ -6983,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); @@ -6997,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 (); @@ -7034,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 @@ -7049,188 +7022,94 @@ 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); } -static int -gdb_print_insn_mips_n32 (bfd_vma memaddr, struct disassemble_info *info) -{ - /* Set up the disassembler info, so that we get the right - register names from libopcodes. */ - info->disassembler_options = "gpr-names=n32"; - info->flavour = bfd_target_elf_flavour; - - return gdb_print_insn_mips (memaddr, info); -} +/* Implement the breakpoint_kind_from_pc gdbarch method. */ 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) +mips_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr) { CORE_ADDR pc = *pcptr; - if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) + if (mips_pc_is_mips16 (gdbarch, pc)) { - if (mips_pc_is_mips16 (gdbarch, pc)) - { - static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 }; - *pcptr = unmake_compact_addr (pc); - *lenptr = sizeof (mips16_big_breakpoint); - return mips16_big_breakpoint; - } - else if (mips_pc_is_micromips (gdbarch, pc)) - { - static gdb_byte micromips16_big_breakpoint[] = { 0x46, 0x85 }; - static gdb_byte micromips32_big_breakpoint[] = { 0, 0x5, 0, 0x7 }; - ULONGEST insn; - int status; - int size; - - insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status); - size = status ? 2 - : mips_insn_size (ISA_MICROMIPS, insn) == 2 ? 2 : 4; - *pcptr = unmake_compact_addr (pc); - *lenptr = size; - return (size == 2) ? micromips16_big_breakpoint - : micromips32_big_breakpoint; - } - else - { - /* The IDT board uses an unusual breakpoint value, and - sometimes gets confused when it sees the usual MIPS - breakpoint instruction. */ - static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd }; - static gdb_byte pmon_big_breakpoint[] = { 0, 0, 0, 0xd }; - static gdb_byte idt_big_breakpoint[] = { 0, 0, 0x0a, 0xd }; - /* Likewise, IRIX appears to expect a different breakpoint, - although this is not apparent until you try to use pthreads. */ - static gdb_byte irix_big_breakpoint[] = { 0, 0, 0, 0xd }; - - *lenptr = sizeof (big_breakpoint); - - if (strcmp (target_shortname, "mips") == 0) - return idt_big_breakpoint; - else if (strcmp (target_shortname, "ddb") == 0 - || strcmp (target_shortname, "pmon") == 0 - || strcmp (target_shortname, "lsi") == 0) - return pmon_big_breakpoint; - else if (gdbarch_osabi (gdbarch) == GDB_OSABI_IRIX) - return irix_big_breakpoint; - else - return big_breakpoint; - } + *pcptr = unmake_compact_addr (pc); + return MIPS_BP_KIND_MIPS16; } - else + else if (mips_pc_is_micromips (gdbarch, pc)) { - if (mips_pc_is_mips16 (gdbarch, pc)) - { - static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 }; - *pcptr = unmake_compact_addr (pc); - *lenptr = sizeof (mips16_little_breakpoint); - return mips16_little_breakpoint; - } - else if (mips_pc_is_micromips (gdbarch, pc)) - { - static gdb_byte micromips16_little_breakpoint[] = { 0x85, 0x46 }; - static gdb_byte micromips32_little_breakpoint[] = { 0x5, 0, 0x7, 0 }; - ULONGEST insn; - int status; - int size; - - insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status); - size = status ? 2 - : mips_insn_size (ISA_MICROMIPS, insn) == 2 ? 2 : 4; - *pcptr = unmake_compact_addr (pc); - *lenptr = size; - return (size == 2) ? micromips16_little_breakpoint - : micromips32_little_breakpoint; - } + ULONGEST insn; + int status; + + *pcptr = unmake_compact_addr (pc); + insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status); + if (status || (mips_insn_size (ISA_MICROMIPS, insn) == 2)) + return MIPS_BP_KIND_MICROMIPS16; else - { - static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 }; - static gdb_byte pmon_little_breakpoint[] = { 0xd, 0, 0, 0 }; - static gdb_byte idt_little_breakpoint[] = { 0xd, 0x0a, 0, 0 }; - - *lenptr = sizeof (little_breakpoint); - - if (strcmp (target_shortname, "mips") == 0) - return idt_little_breakpoint; - else if (strcmp (target_shortname, "ddb") == 0 - || strcmp (target_shortname, "pmon") == 0 - || strcmp (target_shortname, "lsi") == 0) - return pmon_little_breakpoint; - else - return little_breakpoint; - } + return MIPS_BP_KIND_MICROMIPS32; } + else + return MIPS_BP_KIND_MIPS32; } -/* Determine the remote breakpoint kind suitable for the PC. The following - kinds are used: +/* Implement the sw_breakpoint_from_kind gdbarch method. */ - * 2 -- 16-bit MIPS16 mode breakpoint, +static const gdb_byte * +mips_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size) +{ + enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); - * 3 -- 16-bit microMIPS mode breakpoint, + switch (kind) + { + case MIPS_BP_KIND_MIPS16: + { + static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 }; + static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 }; - * 4 -- 32-bit standard MIPS mode breakpoint, + *size = 2; + if (byte_order_for_code == BFD_ENDIAN_BIG) + return mips16_big_breakpoint; + else + return mips16_little_breakpoint; + } + case MIPS_BP_KIND_MICROMIPS16: + { + static gdb_byte micromips16_big_breakpoint[] = { 0x46, 0x85 }; + static gdb_byte micromips16_little_breakpoint[] = { 0x85, 0x46 }; - * 5 -- 32-bit microMIPS mode breakpoint. */ + *size = 2; -static void -mips_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, - int *kindptr) -{ - CORE_ADDR pc = *pcptr; + if (byte_order_for_code == BFD_ENDIAN_BIG) + return micromips16_big_breakpoint; + else + return micromips16_little_breakpoint; + } + case MIPS_BP_KIND_MICROMIPS32: + { + static gdb_byte micromips32_big_breakpoint[] = { 0, 0x5, 0, 0x7 }; + static gdb_byte micromips32_little_breakpoint[] = { 0x5, 0, 0x7, 0 }; - if (mips_pc_is_mips16 (gdbarch, pc)) - { - *pcptr = unmake_compact_addr (pc); - *kindptr = 2; - } - else if (mips_pc_is_micromips (gdbarch, pc)) - { - ULONGEST insn; - int status; - int size; + *size = 4; + if (byte_order_for_code == BFD_ENDIAN_BIG) + return micromips32_big_breakpoint; + else + return micromips32_little_breakpoint; + } + case MIPS_BP_KIND_MIPS32: + { + static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd }; + static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 }; - insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status); - size = status ? 2 : mips_insn_size (ISA_MICROMIPS, insn) == 2 ? 2 : 4; - *pcptr = unmake_compact_addr (pc); - *kindptr = size | 1; - } - else - *kindptr = 4; + *size = 4; + if (byte_order_for_code == BFD_ENDIAN_BIG) + return big_breakpoint; + else + return little_breakpoint; + } + default: + gdb_assert_not_reached ("unexpected mips breakpoint kind"); + }; } /* Return non-zero if the standard MIPS instruction INST has a branch @@ -7370,12 +7249,14 @@ micromips_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, { ULONGEST insn; int status; + int size; insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status); if (status) return 0; + size = mips_insn_size (ISA_MICROMIPS, insn); insn <<= 16; - if (mips_insn_size (ISA_MICROMIPS, insn) == 2 * MIPS_INSN16_SIZE) + if (size == 2 * MIPS_INSN16_SIZE) { insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status); if (status) @@ -7937,8 +7818,8 @@ mips_skip_pic_trampoline_code (struct frame_info *frame, CORE_ADDR pc) msym = lookup_minimal_symbol_by_pc (pc); if (msym.minsym == NULL || BMSYMBOL_VALUE_ADDRESS (msym) != pc - || MSYMBOL_LINKAGE_NAME (msym.minsym) == NULL - || !startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.")) + || msym.minsym->linkage_name () == NULL + || !startswith (msym.minsym->linkage_name (), ".pic.")) return 0; /* A two-instruction header. */ @@ -8020,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; } @@ -8045,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; } @@ -8098,7 +7975,7 @@ static void mips_find_abi_section (bfd *abfd, asection *sect, void *obj) { enum mips_abi *abip = (enum mips_abi *) obj; - const char *name = bfd_get_section_name (abfd, sect); + const char *name = bfd_section_name (sect); if (*abip != MIPS_ABI_UNKNOWN) return; @@ -8126,7 +8003,7 @@ static void mips_find_long_section (bfd *abfd, asection *sect, void *obj) { int *lbp = (int *) obj; - const char *name = bfd_get_section_name (abfd, sect); + const char *name = bfd_section_name (sect); if (startswith (name, ".gcc_compiled_long32")) *lbp = 32; @@ -8185,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); } @@ -8206,228 +8083,38 @@ 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; - } + /* 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; + else if (arches != NULL) + elf_flags = gdbarch_tdep (arches->gdbarch)->elf_flags; else + elf_flags = 0; + if (gdbarch_debug) + fprintf_unfiltered (gdb_stdlog, + "mips_gdbarch_init: elf_flags = 0x%08x\n", elf_flags); + + /* Check ELF_FLAGS to see if it specifies the ABI being used. */ + switch ((elf_flags & EF_MIPS_ABI)) { - 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; + case E_MIPS_ABI_O32: + found_abi = MIPS_ABI_O32; + break; + case E_MIPS_ABI_O64: + found_abi = MIPS_ABI_O64; + break; + case E_MIPS_ABI_EABI32: + found_abi = MIPS_ABI_EABI32; + break; + case E_MIPS_ABI_EABI64: + found_abi = MIPS_ABI_EABI64; + break; + default: + if ((elf_flags & EF_MIPS_ABI2)) + found_abi = MIPS_ABI_N32; 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; - else if (arches != NULL) - elf_flags = gdbarch_tdep (arches->gdbarch)->elf_flags; - else - elf_flags = 0; - if (gdbarch_debug) - fprintf_unfiltered (gdb_stdlog, - "mips_gdbarch_init: elf_flags = 0x%08x\n", elf_flags); - - /* Check ELF_FLAGS to see if it specifies the ABI being used. */ - switch ((elf_flags & EF_MIPS_ABI)) - { - case E_MIPS_ABI_O32: - found_abi = MIPS_ABI_O32; - break; - case E_MIPS_ABI_O64: - found_abi = MIPS_ABI_O64; - break; - case E_MIPS_ABI_EABI32: - found_abi = MIPS_ABI_EABI32; - break; - case E_MIPS_ABI_EABI64: - found_abi = MIPS_ABI_EABI64; - break; - default: - if ((elf_flags & EF_MIPS_ABI2)) - found_abi = MIPS_ABI_N32; - else - found_abi = MIPS_ABI_UNKNOWN; - break; + found_abi = MIPS_ABI_UNKNOWN; + break; } /* GCC creates a pseudo-section whose name describes the ABI. */ @@ -8458,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 @@ -8496,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) @@ -8559,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) @@ -8574,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. */ @@ -8599,7 +8470,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) != 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) @@ -8608,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 = XNEW (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; @@ -8840,9 +8711,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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); @@ -8858,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 @@ -8894,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 @@ -8956,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; @@ -9016,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) { @@ -9066,28 +8962,19 @@ 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) { 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 @@ -9096,8 +8983,6 @@ _initialize_mips_tdep (void) gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep); - mips_pdr_data = register_objfile_data (); - /* Create feature sets with the appropriate properties. The values are not important. */ mips_tdesc_gp32 = allocate_target_description ();