/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
- Copyright (C) 1988-2014 Free Software Foundation, Inc.
+ Copyright (C) 1988-2015 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.
static int mips16_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
CORE_ADDR addr, int mustbe32);
+static void mips_print_float_info (struct gdbarch *, struct ui_file *,
+ struct frame_info *, const char *);
+
/* A useful bit in the CP0 status register (MIPS_PS_REGNUM). */
/* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip. */
#define ST0_FR (1 << 26)
return ((addr) | (CORE_ADDR) 1);
}
+/* Extern version of unmake_compact_addr; we use a separate function
+ so that unmake_compact_addr can be inlined throughout this file. */
+
+CORE_ADDR
+mips_unmake_compact_addr (CORE_ADDR addr)
+{
+ return unmake_compact_addr (addr);
+}
+
/* Functions for setting and testing a bit in a minimal symbol that
marks it as MIPS16 or microMIPS function. The MSB of the minimal
symbol's "info" field is used for this purpose.
return;
if (ELF_ST_IS_MICROMIPS (st_other))
- MSYMBOL_TARGET_FLAG_2 (msym) = 1;
+ {
+ MSYMBOL_TARGET_FLAG_MICROMIPS (msym) = 1;
+ SET_MSYMBOL_VALUE_ADDRESS (msym, MSYMBOL_VALUE_RAW_ADDRESS (msym) | 1);
+ }
else if (ELF_ST_IS_MIPS16 (st_other))
- MSYMBOL_TARGET_FLAG_1 (msym) = 1;
+ {
+ MSYMBOL_TARGET_FLAG_MIPS16 (msym) = 1;
+ SET_MSYMBOL_VALUE_ADDRESS (msym, MSYMBOL_VALUE_RAW_ADDRESS (msym) | 1);
+ }
}
/* Return one iff MSYM refers to standard ISA code. */
static int
msymbol_is_mips (struct minimal_symbol *msym)
{
- return !(MSYMBOL_TARGET_FLAG_1 (msym) | MSYMBOL_TARGET_FLAG_2 (msym));
+ return !(MSYMBOL_TARGET_FLAG_MIPS16 (msym)
+ | MSYMBOL_TARGET_FLAG_MICROMIPS (msym));
}
/* Return one iff MSYM refers to MIPS16 code. */
static int
msymbol_is_mips16 (struct minimal_symbol *msym)
{
- return MSYMBOL_TARGET_FLAG_1 (msym);
+ return MSYMBOL_TARGET_FLAG_MIPS16 (msym);
}
/* Return one iff MSYM refers to microMIPS code. */
static int
msymbol_is_micromips (struct minimal_symbol *msym)
{
- return MSYMBOL_TARGET_FLAG_2 (msym);
+ return MSYMBOL_TARGET_FLAG_MICROMIPS (msym);
+}
+
+/* Set the ISA bit in the main symbol too, complementing the corresponding
+ minimal symbol setting and reflecting the run-time value of the symbol.
+ The need for comes from the ISA bit having been cleared as code in
+ `_bfd_mips_elf_symbol_processing' separated it into the ELF symbol's
+ `st_other' STO_MIPS16 or STO_MICROMIPS annotation, making the values
+ of symbols referring to compressed code different in GDB to the values
+ used by actual code. That in turn makes them evaluate incorrectly in
+ expressions, producing results different to what the same expressions
+ yield when compiled into the program being debugged. */
+
+static void
+mips_make_symbol_special (struct symbol *sym, struct objfile *objfile)
+{
+ if (SYMBOL_CLASS (sym) == LOC_BLOCK)
+ {
+ /* We are in symbol reading so it is OK to cast away constness. */
+ struct block *block = (struct block *) SYMBOL_BLOCK_VALUE (sym);
+ CORE_ADDR compact_block_start;
+ struct bound_minimal_symbol msym;
+
+ compact_block_start = BLOCK_START (block) | 1;
+ msym = lookup_minimal_symbol_by_pc (compact_block_start);
+ if (msym.minsym && !msymbol_is_mips (msym.minsym))
+ {
+ BLOCK_START (block) = compact_block_start;
+ }
+ }
}
/* XFER a value from the big/little/left end of the register.
stored by elfread.c in the high bit of the info field. Use this
to decide if the function is standard MIPS. Otherwise if bit 0
of the address is clear, then this is a standard MIPS function. */
- sym = lookup_minimal_symbol_by_pc (memaddr);
+ sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
if (sym.minsym)
return msymbol_is_mips (sym.minsym);
else
elfread.c in the high bit of the info field. Use this to decide
if the function is MIPS16. Otherwise if bit 0 of the address is
set, then ELF file flags will tell if this is a MIPS16 function. */
- sym = lookup_minimal_symbol_by_pc (memaddr);
+ sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
if (sym.minsym)
return msymbol_is_mips16 (sym.minsym);
else
if the function is microMIPS. Otherwise if bit 0 of the address
is set, then ELF file flags will tell if this is a microMIPS
function. */
- sym = lookup_minimal_symbol_by_pc (memaddr);
+ sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
if (sym.minsym)
return msymbol_is_micromips (sym.minsym);
else
this to decide if the function is MIPS16 or microMIPS or normal
MIPS. Otherwise if bit 0 of the address is set, then ELF file
flags will tell if this is a MIPS16 or a microMIPS function. */
- sym = lookup_minimal_symbol_by_pc (memaddr);
+ sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
if (sym.minsym)
{
if (msymbol_is_micromips (sym.minsym))
}
}
+/* Set the ISA bit correctly in the PC, used by DWARF-2 machinery.
+ The need for comes from the ISA bit having been cleared, making
+ addresses in FDE, range records, etc. referring to compressed code
+ different to those in line information, the symbol table and finally
+ the PC register. That in turn confuses many operations. */
+
+static CORE_ADDR
+mips_adjust_dwarf2_addr (CORE_ADDR pc)
+{
+ pc = unmake_compact_addr (pc);
+ return mips_pc_is_mips (pc) ? pc : make_compact_addr (pc);
+}
+
+/* Recalculate the line record requested so that the resulting PC has
+ the ISA bit set correctly, used by DWARF-2 machinery. The need for
+ this adjustment comes from some records associated with compressed
+ code having the ISA bit cleared, most notably at function prologue
+ ends. The ISA bit is in this context retrieved from the minimal
+ symbol covering the address requested, which in turn has been
+ constructed from the binary's symbol table rather than DWARF-2
+ information. The correct setting of the ISA bit is required for
+ breakpoint addresses to correctly match against the stop PC.
+
+ As line entries can specify relative address adjustments we need to
+ keep track of the absolute value of the last line address recorded
+ in line information, so that we can calculate the actual address to
+ apply the ISA bit adjustment to. We use PC for this tracking and
+ keep the original address there.
+
+ As such relative address adjustments can be odd within compressed
+ code we need to keep track of the last line address with the ISA
+ bit adjustment applied too, as the original address may or may not
+ have had the ISA bit set. We use ADJ_PC for this tracking and keep
+ the adjusted address there.
+
+ For relative address adjustments we then use these variables to
+ calculate the address intended by line information, which will be
+ PC-relative, and return an updated adjustment carrying ISA bit
+ information, which will be ADJ_PC-relative. For absolute address
+ adjustments we just return the same address that we store in ADJ_PC
+ too.
+
+ As the first line entry can be relative to an implied address value
+ of 0 we need to have the initial address set up that we store in PC
+ and ADJ_PC. This is arranged with a call from `dwarf_decode_lines_1'
+ that sets PC to 0 and ADJ_PC accordingly, usually 0 as well. */
+
+static CORE_ADDR
+mips_adjust_dwarf2_line (CORE_ADDR addr, int rel)
+{
+ static CORE_ADDR adj_pc;
+ static CORE_ADDR pc;
+ CORE_ADDR isa_pc;
+
+ pc = rel ? pc + addr : addr;
+ isa_pc = mips_adjust_dwarf2_addr (pc);
+ addr = rel ? isa_pc - adj_pc : isa_pc;
+ adj_pc = isa_pc;
+ return addr;
+}
+
/* Various MIPS16 thunk (aka stub or trampoline) names. */
static const char mips_str_mips16_call_stub[] = "__mips16_call_stub_";
return 0;
/* If the PC is in __mips16_call_stub_*, this is a call/return stub. */
- if (strncmp (name, mips_str_mips16_call_stub,
- strlen (mips_str_mips16_call_stub)) == 0)
+ if (startswith (name, mips_str_mips16_call_stub))
return 1;
/* If the PC is in __call_stub_*, this is a call/return or a call stub. */
- if (strncmp (name, mips_str_call_stub, strlen (mips_str_call_stub)) == 0)
+ if (startswith (name, mips_str_call_stub))
return 1;
/* If the PC is in __fn_stub_*, this is a call stub. */
- if (strncmp (name, mips_str_fn_stub, strlen (mips_str_fn_stub)) == 0)
+ if (startswith (name, mips_str_fn_stub))
return 1;
return 0; /* Not a stub. */
LONGEST pc;
regcache_cooked_read_signed (regcache, regnum, &pc);
- if (is_compact_addr (pc))
- pc = unmake_compact_addr (pc);
return pc;
}
CORE_ADDR pc;
pc = frame_unwind_register_signed (next_frame, gdbarch_pc_regnum (gdbarch));
- if (is_compact_addr (pc))
- pc = unmake_compact_addr (pc);
/* macro/2012-04-20: This hack skips over MIPS16 call thunks as
intermediate frames. In this case we can get the caller's address
from $ra, or if $ra contains an address within a thunk as well, then
{
pc = frame_unwind_register_signed
(next_frame, gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM);
- if (is_compact_addr (pc))
- pc = unmake_compact_addr (pc);
if (mips_in_frame_stub (pc))
- {
- pc = frame_unwind_register_signed
- (next_frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM);
- if (is_compact_addr (pc))
- pc = unmake_compact_addr (pc);
- }
+ pc = frame_unwind_register_signed
+ (next_frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM);
}
return pc;
}
{
int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache));
- if (mips_pc_is_mips (pc))
- regcache_cooked_write_unsigned (regcache, regnum, pc);
- else
- regcache_cooked_write_unsigned (regcache, regnum, make_compact_addr (pc));
+ regcache_cooked_write_unsigned (regcache, regnum, pc);
}
/* Fetch and return instruction from the specified location. Handle
}
+/* Calculate the destination of a branch whose 16-bit opcode word is at PC,
+ and having a signed 16-bit OFFSET. */
+
static CORE_ADDR
add_offset_16 (CORE_ADDR pc, int offset)
{
- return ((offset << 2) | ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)));
+ return pc + (offset << 1) + 2;
}
static CORE_ADDR
{
struct upk_mips16 upk;
unpack_mips16 (gdbarch, pc, extension, insn, itype, &upk);
- pc += (upk.offset << 1) + 2;
+ pc = add_offset_16 (pc, upk.offset);
break;
}
case 3: /* JAL , JALX - Watch out, these are 32 bit
{
struct upk_mips16 upk;
unpack_mips16 (gdbarch, pc, extension, insn, jalxtype, &upk);
- pc = add_offset_16 (pc, upk.offset);
+ pc = ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)) | (upk.offset << 2);
if ((insn >> 10) & 0x01) /* Exchange mode */
pc = pc & ~0x01; /* Clear low bit, indicate 32 bit mode. */
else
unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]);
if (reg == 0)
- pc += (upk.offset << 1) + 2;
+ pc = add_offset_16 (pc, upk.offset);
else
pc += 2;
break;
unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]);
if (reg != 0)
- pc += (upk.offset << 1) + 2;
+ pc = add_offset_16 (pc, upk.offset);
else
pc += 2;
break;
reg = get_frame_register_signed (frame, 24); /* Test register is 24 */
if (((upk.regx == 0) && (reg == 0)) /* BTEZ */
|| ((upk.regx == 1) && (reg != 0))) /* BTNEZ */
- /* pc = add_offset_16(pc,upk.offset) ; */
- pc += (upk.offset << 1) + 2;
+ pc = add_offset_16 (pc, upk.offset);
else
pc += 2;
break;
frame_offset = 0;
for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSN32_SIZE)
{
- unsigned long inst, high_word, low_word;
+ unsigned long inst, high_word;
+ long offset;
int reg;
this_non_prologue_insn = 0;
/* Save some code by pre-extracting some useful fields. */
high_word = (inst >> 16) & 0xffff;
- low_word = inst & 0xffff;
+ offset = ((inst & 0xffff) ^ 0x8000) - 0x8000;
reg = high_word & 0x1f;
if (high_word == 0x27bd /* addiu $sp,$sp,-i */
|| high_word == 0x23bd /* addi $sp,$sp,-i */
|| high_word == 0x67bd) /* daddiu $sp,$sp,-i */
{
- if (low_word & 0x8000) /* Negative stack adjustment? */
- frame_offset += 0x10000 - low_word;
+ if (offset < 0) /* Negative stack adjustment? */
+ frame_offset -= offset;
else
/* Exit loop if a positive stack adjustment is found, which
usually means that the stack cleanup code in the function
else if (((high_word & 0xFFE0) == 0xafa0) /* sw reg,offset($sp) */
&& !regsize_is_64_bits)
{
- set_reg_offset (gdbarch, this_cache, reg, sp + low_word);
+ set_reg_offset (gdbarch, this_cache, reg, sp + offset);
}
else if (((high_word & 0xFFE0) == 0xffa0) /* sd reg,offset($sp) */
&& regsize_is_64_bits)
{
/* Irix 6.2 N32 ABI uses sd instructions for saving $gp and $ra. */
- set_reg_offset (gdbarch, this_cache, reg, sp + low_word);
+ set_reg_offset (gdbarch, this_cache, reg, sp + offset);
}
else if (high_word == 0x27be) /* addiu $30,$sp,size */
{
/* Old gcc frame, r30 is virtual frame pointer. */
- if ((long) low_word != frame_offset)
- frame_addr = sp + low_word;
+ if (offset != frame_offset)
+ frame_addr = sp + offset;
else if (this_frame && frame_reg == MIPS_SP_REGNUM)
{
unsigned alloca_adjust;
(this_frame, gdbarch_num_regs (gdbarch) + 30);
frame_offset = 0;
- alloca_adjust = (unsigned) (frame_addr - (sp + low_word));
+ alloca_adjust = (unsigned) (frame_addr - (sp + offset));
if (alloca_adjust > 0)
{
/* FP > SP + frame_size. This may be because of
else if ((high_word & 0xFFE0) == 0xafc0 /* sw reg,offset($30) */
&& !regsize_is_64_bits)
{
- set_reg_offset (gdbarch, this_cache, reg, frame_addr + low_word);
+ set_reg_offset (gdbarch, this_cache, reg, frame_addr + offset);
}
else if ((high_word & 0xFFE0) == 0xE7A0 /* swc1 freg,n($sp) */
|| (high_word & 0xF3E0) == 0xA3C0 /* sx reg,n($s8) */
msym = lookup_minimal_symbol_by_pc (pc);
if (msym.minsym != NULL
&& MSYMBOL_LINKAGE_NAME (msym.minsym) != NULL
- && strncmp (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) == 0)
+ && startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic."))
return 1;
return 0;
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- if (is_compact_addr (addr))
- addr = unmake_compact_addr (addr);
-
if (mips_mask_address_p (tdep) && (((ULONGEST) addr) >> 32 == 0xffffffffUL))
/* This hack is a work-around for existing boards using PMON, the
simulator, and any other 64-bit targets that doesn't have true
"mips_eabi_push_dummy_call: %d len=%d type=%d",
argnum + 1, len, (int) typecode);
- /* Function pointer arguments to mips16 code need to be made into
- mips16 pointers. */
- if (typecode == TYPE_CODE_PTR
- && TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC)
- {
- CORE_ADDR addr = extract_signed_integer (value_contents (arg),
- len, byte_order);
- if (mips_pc_is_mips (addr))
- val = value_contents (arg);
- else
- {
- store_signed_integer (valbuf, len, byte_order,
- make_compact_addr (addr));
- val = valbuf;
- }
- }
/* The EABI passes structures that do not fit in a register by
reference. */
- else if (len > regsize
+ if (len > regsize
&& (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
{
store_unsigned_integer (valbuf, regsize, byte_order,
for (argnum = 0; argnum < nargs; argnum++)
{
const gdb_byte *val;
- gdb_byte valbuf[MAX_REGISTER_SIZE];
struct value *arg = args[argnum];
struct type *arg_type = check_typedef (value_type (arg));
int len = TYPE_LENGTH (arg_type);
val = value_contents (arg);
- /* Function pointer arguments to mips16 code need to be made into
- mips16 pointers. */
- if (typecode == TYPE_CODE_PTR
- && TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC)
- {
- CORE_ADDR addr = extract_signed_integer (value_contents (arg),
- len, byte_order);
- if (!mips_pc_is_mips (addr))
- {
- store_signed_integer (valbuf, len, byte_order,
- make_compact_addr (addr));
- val = valbuf;
- }
- }
-
/* Floating point arguments passed in registers have to be
treated specially. On 32-bit architectures, doubles are
passed in register pairs; the even FP register gets the
&opts, 0, file);
}
+/* Print IEEE exception condition bits in FLAGS. */
+
+static void
+print_fpu_flags (struct ui_file *file, int flags)
+{
+ if (flags & (1 << 0))
+ fputs_filtered (" inexact", file);
+ if (flags & (1 << 1))
+ fputs_filtered (" uflow", file);
+ if (flags & (1 << 2))
+ fputs_filtered (" oflow", file);
+ if (flags & (1 << 3))
+ fputs_filtered (" div0", file);
+ if (flags & (1 << 4))
+ fputs_filtered (" inval", file);
+ if (flags & (1 << 5))
+ fputs_filtered (" unimp", file);
+ fputc_filtered ('\n', file);
+}
+
+/* Print interesting information about the floating point processor
+ (if present) or emulator. */
+
+static void
+mips_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
+ struct frame_info *frame, const char *args)
+{
+ int fcsr = mips_regnum (gdbarch)->fp_control_status;
+ enum mips_fpu_type type = MIPS_FPU_TYPE (gdbarch);
+ ULONGEST fcs = 0;
+ int i;
+
+ if (fcsr == -1 || !read_frame_register_unsigned (frame, fcsr, &fcs))
+ type = MIPS_FPU_NONE;
+
+ fprintf_filtered (file, "fpu type: %s\n",
+ type == MIPS_FPU_DOUBLE ? "double-precision"
+ : type == MIPS_FPU_SINGLE ? "single-precision"
+ : "none / unused");
+
+ if (type == MIPS_FPU_NONE)
+ return;
+
+ fprintf_filtered (file, "reg size: %d bits\n",
+ register_size (gdbarch, mips_regnum (gdbarch)->fp0) * 8);
+
+ fputs_filtered ("cond :", file);
+ if (fcs & (1 << 23))
+ fputs_filtered (" 0", file);
+ for (i = 1; i <= 7; i++)
+ if (fcs & (1 << (24 + i)))
+ fprintf_filtered (file, " %d", i);
+ fputc_filtered ('\n', file);
+
+ fputs_filtered ("cause :", file);
+ print_fpu_flags (file, (fcs >> 12) & 0x3f);
+ fputs ("mask :", stdout);
+ print_fpu_flags (file, (fcs >> 7) & 0x1f);
+ fputs ("flags :", stdout);
+ print_fpu_flags (file, (fcs >> 2) & 0x1f);
+
+ fputs_filtered ("rounding: ", file);
+ switch (fcs & 3)
+ {
+ case 0: fputs_filtered ("nearest\n", file); break;
+ case 1: fputs_filtered ("zero\n", file); break;
+ case 2: fputs_filtered ("+inf\n", file); break;
+ case 3: fputs_filtered ("-inf\n", file); break;
+ }
+
+ fputs_filtered ("flush :", file);
+ if (fcs & (1 << 21))
+ fputs_filtered (" nearest", file);
+ if (fcs & (1 << 22))
+ fputs_filtered (" override", file);
+ if (fcs & (1 << 24))
+ fputs_filtered (" zero", file);
+ if ((fcs & (0xb << 21)) == 0)
+ fputs_filtered (" no", file);
+ fputc_filtered ('\n', file);
+
+ fprintf_filtered (file, "nan2008 : %s\n", fcs & (1 << 18) ? "yes" : "no");
+ fprintf_filtered (file, "abs2008 : %s\n", fcs & (1 << 19) ? "yes" : "no");
+ fputc_filtered ('\n', file);
+
+ default_print_float_info (gdbarch, file, frame, args);
+}
+
/* Replacement for generic do_registers_info.
Print regs in pretty columns. */
return mips32_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL);
}
-/* Check whether the PC is in a function epilogue (32-bit version).
- This is a helper function for mips_in_function_epilogue_p. */
+/* Implement the stack_frame_destroyed_p gdbarch method (32-bit version).
+ This is a helper function for mips_stack_frame_destroyed_p. */
+
static int
-mips32_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+mips32_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR func_addr = 0, func_end = 0;
return 0;
}
-/* Check whether the PC is in a function epilogue (microMIPS version).
- This is a helper function for mips_in_function_epilogue_p. */
+/* Implement the stack_frame_destroyed_p gdbarch method (microMIPS version).
+ This is a helper function for mips_stack_frame_destroyed_p. */
static int
-micromips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+micromips_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR func_addr = 0;
CORE_ADDR func_end = 0;
return 1;
}
-/* Check whether the PC is in a function epilogue (16-bit version).
- This is a helper function for mips_in_function_epilogue_p. */
+/* Implement the stack_frame_destroyed_p gdbarch method (16-bit version).
+ This is a helper function for mips_stack_frame_destroyed_p. */
+
static int
-mips16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+mips16_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR func_addr = 0, func_end = 0;
return 0;
}
-/* The epilogue is defined here as the area at the end of a function,
+/* Implement the stack_frame_destroyed_p gdbarch method.
+
+ The epilogue is defined here as the area at the end of a function,
after an instruction which destroys the function's stack frame. */
+
static int
-mips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+mips_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
if (mips_pc_is_mips16 (gdbarch, pc))
- return mips16_in_function_epilogue_p (gdbarch, pc);
+ return mips16_stack_frame_destroyed_p (gdbarch, pc);
else if (mips_pc_is_micromips (gdbarch, pc))
- return micromips_in_function_epilogue_p (gdbarch, pc);
+ return micromips_stack_frame_destroyed_p (gdbarch, pc);
else
- return mips32_in_function_epilogue_p (gdbarch, pc);
+ return mips32_stack_frame_destroyed_p (gdbarch, pc);
}
/* Root of all "set mips "/"show mips " commands. This will eventually be
/* If the PC is in __call_stub_* or __fn_stub*, this is one of the
compiler-generated call or call/return stubs. */
- if (strncmp (name, mips_str_fn_stub, strlen (mips_str_fn_stub)) == 0
- || strncmp (name, mips_str_call_stub, strlen (mips_str_call_stub)) == 0)
+ if (startswith (name, mips_str_fn_stub)
+ || startswith (name, mips_str_call_stub))
{
if (pc == start_addr)
/* This is the 'call' part of a call stub. Call this helper
if (msym.minsym == NULL
|| BMSYMBOL_VALUE_ADDRESS (msym) != pc
|| MSYMBOL_LINKAGE_NAME (msym.minsym) == NULL
- || strncmp (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) != 0)
+ || !startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic."))
return 0;
/* A two-instruction header. */
new_pc = mips_skip_mips16_trampoline_code (frame, pc);
if (new_pc)
- {
- pc = new_pc;
- if (is_compact_addr (pc))
- pc = unmake_compact_addr (pc);
- }
+ pc = new_pc;
new_pc = find_solib_trampoline_target (frame, pc);
if (new_pc)
- {
- pc = new_pc;
- if (is_compact_addr (pc))
- pc = unmake_compact_addr (pc);
- }
+ pc = new_pc;
new_pc = mips_skip_pic_trampoline_code (frame, pc);
if (new_pc)
- {
- pc = new_pc;
- if (is_compact_addr (pc))
- pc = unmake_compact_addr (pc);
- }
+ pc = new_pc;
}
while (pc != target_pc);
if (*abip != MIPS_ABI_UNKNOWN)
return;
- if (strncmp (name, ".mdebug.", 8) != 0)
+ if (!startswith (name, ".mdebug."))
return;
if (strcmp (name, ".mdebug.abi32") == 0)
int *lbp = (int *) obj;
const char *name = bfd_get_section_name (abfd, sect);
- if (strncmp (name, ".gcc_compiled_long32", 20) == 0)
+ if (startswith (name, ".gcc_compiled_long32"))
*lbp = 32;
- else if (strncmp (name, ".gcc_compiled_long64", 20) == 0)
+ else if (startswith (name, ".gcc_compiled_long64"))
*lbp = 64;
- else if (strncmp (name, ".gcc_compiled_long", 18) == 0)
+ else if (startswith (name, ".gcc_compiled_long"))
warning (_("unrecognized .gcc_compiled_longXX"));
}
}
/* Need a new architecture. Fill in a target specific vector. */
- tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+ tdep = XNEW (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
tdep->elf_flags = elf_flags;
tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p;
set_gdbarch_elf_make_msymbol_special (gdbarch,
mips_elf_make_msymbol_special);
+ set_gdbarch_make_symbol_special (gdbarch, mips_make_symbol_special);
+ set_gdbarch_adjust_dwarf2_addr (gdbarch, mips_adjust_dwarf2_addr);
+ set_gdbarch_adjust_dwarf2_line (gdbarch, mips_adjust_dwarf2_line);
regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct mips_regnum);
*regnum = mips_regnum;
set_gdbarch_push_dummy_code (gdbarch, mips_push_dummy_code);
set_gdbarch_frame_align (gdbarch, mips_frame_align);
+ set_gdbarch_print_float_info (gdbarch, mips_print_float_info);
+
set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p);
set_gdbarch_register_to_value (gdbarch, mips_register_to_value);
set_gdbarch_value_to_register (gdbarch, mips_value_to_register);
set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue);
- set_gdbarch_in_function_epilogue_p (gdbarch, mips_in_function_epilogue_p);
+ set_gdbarch_stack_frame_destroyed_p (gdbarch, mips_stack_frame_destroyed_p);
set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address);
set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer);