/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
- Free Software Foundation, Inc.
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+ 2010 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.
#include "dwarf2-frame.h"
#include "user-regs.h"
#include "valprint.h"
+#include "ax.h"
static const struct objfile_data *mips_pdr_data;
return ((addr) & ~(CORE_ADDR) 1);
}
+static CORE_ADDR
+make_mips16_addr (CORE_ADDR addr)
+{
+ return ((addr) | (CORE_ADDR) 1);
+}
+
/* Return the MIPS ABI associated with GDBARCH. */
enum mips_abi
mips_abi (struct gdbarch *gdbarch)
if (((elf_symbol_type *) (sym))->internal_elf_sym.st_other == STO_MIPS16)
{
MSYMBOL_TARGET_FLAG_1 (msym) = 1;
- SYMBOL_VALUE_ADDRESS (msym) |= 1;
}
}
static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
-static struct type *mips_float_register_type (void);
-static struct type *mips_double_register_type (void);
-
/* The list of available "set mips " and "show mips " commands */
static struct cmd_list_element *setmipscmdlist = NULL;
enum mips_abi abi = mips_abi (gdbarch);
/* Map [gdbarch_num_regs .. 2*gdbarch_num_regs) onto the raw registers,
- but then don't make the raw register names visible. */
+ but then don't make the raw register names visible. This (upper)
+ range of user visible register numbers are the pseudo-registers.
+
+ This approach was adopted accommodate the following scenario:
+ It is possible to debug a 64-bit device using a 32-bit
+ programming model. In such instances, the raw registers are
+ configured to be 64-bits wide, while the pseudo registers are
+ configured to be 32-bits wide. The registers that the user
+ sees - the pseudo registers - match the users expectations
+ given the programming model being used. */
int rawnum = regno % gdbarch_num_regs (gdbarch);
if (regno < gdbarch_num_regs (gdbarch))
return "";
else if (register_size (gdbarch, rawnum) >
register_size (gdbarch, cookednum))
{
- if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
- || gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+ if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p)
regcache_raw_read_part (regcache, rawnum, 0, 4, buf);
else
- regcache_raw_read_part (regcache, rawnum, 4, 4, buf);
+ {
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ LONGEST regval;
+ regcache_raw_read_signed (regcache, rawnum, ®val);
+ store_signed_integer (buf, 4, byte_order, regval);
+ }
}
else
internal_error (__FILE__, __LINE__, _("bad register size"));
else if (register_size (gdbarch, rawnum) >
register_size (gdbarch, cookednum))
{
- if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
- || gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+ if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p)
regcache_raw_write_part (regcache, rawnum, 0, 4, buf);
else
- regcache_raw_write_part (regcache, rawnum, 4, 4, buf);
+ {
+ /* Sign extend the shortened version of the register prior
+ to placing it in the raw register. This is required for
+ some mips64 parts in order to avoid unpredictable behavior. */
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ LONGEST regval = extract_signed_integer (buf, 4, byte_order);
+ regcache_raw_write_signed (regcache, rawnum, regval);
+ }
+ }
+ else
+ internal_error (__FILE__, __LINE__, _("bad register size"));
+}
+
+static int
+mips_ax_pseudo_register_collect (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg)
+{
+ int rawnum = reg % gdbarch_num_regs (gdbarch);
+ gdb_assert (reg >= gdbarch_num_regs (gdbarch)
+ && reg < 2 * gdbarch_num_regs (gdbarch));
+
+ ax_reg_mask (ax, rawnum);
+
+ return 0;
+}
+
+static int
+mips_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
+ struct agent_expr *ax, int reg)
+{
+ int rawnum = reg % gdbarch_num_regs (gdbarch);
+ gdb_assert (reg >= gdbarch_num_regs (gdbarch)
+ && reg < 2 * gdbarch_num_regs (gdbarch));
+ if (register_size (gdbarch, rawnum) >= register_size (gdbarch, reg))
+ {
+ ax_reg (ax, rawnum);
+
+ if (register_size (gdbarch, rawnum) > register_size (gdbarch, reg))
+ {
+ if (!gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
+ || gdbarch_byte_order (gdbarch) != BFD_ENDIAN_BIG)
+ {
+ ax_const_l (ax, 32);
+ ax_simple (ax, aop_lsh);
+ }
+ ax_const_l (ax, 32);
+ ax_simple (ax, aop_rsh_signed);
+ }
}
else
internal_error (__FILE__, __LINE__, _("bad register size"));
+
+ return 0;
}
/* Table to translate MIPS16 register field to actual register number. */
/* Convert to/from a register and the corresponding memory value. */
+/* This predicate tests for the case of an 8 byte floating point
+ value that is being transferred to or from a pair of floating point
+ registers each of which are (or are considered to be) only 4 bytes
+ wide. */
static int
-mips_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
+mips_convert_register_float_case_p (struct gdbarch *gdbarch, int regnum,
+ struct type *type)
{
return (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG
&& register_size (gdbarch, regnum) == 4
&& TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8);
}
+/* This predicate tests for the case of a value of less than 8
+ bytes in width that is being transfered to or from an 8 byte
+ general purpose register. */
+static int
+mips_convert_register_gpreg_case_p (struct gdbarch *gdbarch, int regnum,
+ struct type *type)
+{
+ int num_regs = gdbarch_num_regs (gdbarch);
+
+ return (register_size (gdbarch, regnum) == 8
+ && regnum % num_regs > 0 && regnum % num_regs < 32
+ && TYPE_LENGTH (type) < 8);
+}
+
+static int
+mips_convert_register_p (struct gdbarch *gdbarch, int regnum, struct type *type)
+{
+ return mips_convert_register_float_case_p (gdbarch, regnum, type)
+ || mips_convert_register_gpreg_case_p (gdbarch, regnum, type);
+}
+
static void
mips_register_to_value (struct frame_info *frame, int regnum,
struct type *type, gdb_byte *to)
{
- get_frame_register (frame, regnum + 0, to + 4);
- get_frame_register (frame, regnum + 1, to + 0);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+
+ if (mips_convert_register_float_case_p (gdbarch, regnum, type))
+ {
+ get_frame_register (frame, regnum + 0, to + 4);
+ get_frame_register (frame, regnum + 1, to + 0);
+ }
+ else if (mips_convert_register_gpreg_case_p (gdbarch, regnum, type))
+ {
+ int len = TYPE_LENGTH (type);
+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ get_frame_register_bytes (frame, regnum, 8 - len, len, to);
+ else
+ get_frame_register_bytes (frame, regnum, 0, len, to);
+ }
+ else
+ {
+ internal_error (__FILE__, __LINE__,
+ _("mips_register_to_value: unrecognized case"));
+ }
}
static void
mips_value_to_register (struct frame_info *frame, int regnum,
struct type *type, const gdb_byte *from)
{
- put_frame_register (frame, regnum + 0, from + 4);
- put_frame_register (frame, regnum + 1, from + 0);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+
+ if (mips_convert_register_float_case_p (gdbarch, regnum, type))
+ {
+ put_frame_register (frame, regnum + 0, from + 4);
+ put_frame_register (frame, regnum + 1, from + 0);
+ }
+ else if (mips_convert_register_gpreg_case_p (gdbarch, regnum, type))
+ {
+ gdb_byte fill[8];
+ int len = TYPE_LENGTH (type);
+
+ /* Sign extend values, irrespective of type, that are stored to
+ a 64-bit general purpose register. (32-bit unsigned values
+ are stored as signed quantities within a 64-bit register.
+ When performing an operation, in compiled code, that combines
+ a 32-bit unsigned value with a signed 64-bit value, a type
+ conversion is first performed that zeroes out the high 32 bits.) */
+ if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ {
+ if (from[0] & 0x80)
+ store_signed_integer (fill, 8, BFD_ENDIAN_BIG, -1);
+ else
+ store_signed_integer (fill, 8, BFD_ENDIAN_BIG, 0);
+ put_frame_register_bytes (frame, regnum, 0, 8 - len, fill);
+ put_frame_register_bytes (frame, regnum, 8 - len, len, from);
+ }
+ else
+ {
+ if (from[len-1] & 0x80)
+ store_signed_integer (fill, 8, BFD_ENDIAN_LITTLE, -1);
+ else
+ store_signed_integer (fill, 8, BFD_ENDIAN_LITTLE, 0);
+ put_frame_register_bytes (frame, regnum, 0, len, from);
+ put_frame_register_bytes (frame, regnum, len, 8 - len, fill);
+ }
+ }
+ else
+ {
+ internal_error (__FILE__, __LINE__,
+ _("mips_value_to_register: unrecognized case"));
+ }
}
/* Return the GDB type object for the "standard" data type of data in
/* The floating-point registers raw, or cooked, always match
mips_isa_regsize(), and also map 1:1, byte for byte. */
if (mips_isa_regsize (gdbarch) == 4)
- return builtin_type_ieee_single;
+ return builtin_type (gdbarch)->builtin_float;
else
- return builtin_type_ieee_double;
+ return builtin_type (gdbarch)->builtin_double;
}
else if (regnum < gdbarch_num_regs (gdbarch))
{
/* The raw or ISA registers. These are all sized according to
the ISA regsize. */
if (mips_isa_regsize (gdbarch) == 4)
- return builtin_type_int32;
+ return builtin_type (gdbarch)->builtin_int32;
else
- return builtin_type_int64;
+ return builtin_type (gdbarch)->builtin_int64;
}
else
{
&& regnum <= gdbarch_num_regs (gdbarch) + MIPS_LAST_EMBED_REGNUM)
/* The pseudo/cooked view of the embedded registers is always
32-bit. The raw view is handled below. */
- return builtin_type_int32;
+ return builtin_type (gdbarch)->builtin_int32;
else if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p)
/* The target, while possibly using a 64-bit register buffer,
is only transfering 32-bits of each integer register.
Reflect this in the cooked/pseudo (ABI) register value. */
- return builtin_type_int32;
+ return builtin_type (gdbarch)->builtin_int32;
else if (mips_abi_regsize (gdbarch) == 4)
/* The ABI is restricted to 32-bit registers (the ISA could be
32- or 64-bit). */
- return builtin_type_int32;
+ return builtin_type (gdbarch)->builtin_int32;
else
/* 64-bit ABI. */
- return builtin_type_int64;
+ return builtin_type (gdbarch)->builtin_int64;
}
}
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_int32;
+ return builtin_type (gdbarch)->builtin_int32;
}
/* Use pointer types for registers if we can. For n32 we can not,
if (mips_abi_regsize (gdbarch) == 4 && TYPE_LENGTH (rawtype) == 8
&& rawnum >= MIPS_ZERO_REGNUM && rawnum <= MIPS_EMBED_PC_REGNUM)
- return builtin_type_int32;
+ return builtin_type (gdbarch)->builtin_int32;
/* For all other registers, pass through the hardware type. */
return rawtype;
ULONGEST pc;
int regnum = mips_regnum (get_regcache_arch (regcache))->pc;
regcache_cooked_read_signed (regcache, regnum, &pc);
+ if (is_mips16_addr (pc))
+ pc = unmake_mips16_addr (pc);
return pc;
}
static CORE_ADDR
mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
- return frame_unwind_register_signed
- (next_frame, gdbarch_num_regs (gdbarch) + mips_regnum (gdbarch)->pc);
+ ULONGEST pc;
+
+ pc = frame_unwind_register_signed
+ (next_frame, gdbarch_num_regs (gdbarch) + mips_regnum (gdbarch)->pc);
+ if (is_mips16_addr (pc))
+ pc = unmake_mips16_addr (pc);
+ return pc;
}
static CORE_ADDR
mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
int regnum = mips_regnum (get_regcache_arch (regcache))->pc;
- regcache_cooked_write_unsigned (regcache, regnum, pc);
+ if (mips_pc_is_mips16 (pc))
+ regcache_cooked_write_unsigned (regcache, regnum, make_mips16_addr (pc));
+ else
+ regcache_cooked_write_unsigned (regcache, regnum, pc);
}
/* Fetch and return instruction from the specified location. If the PC
is odd, assume it's a MIPS16 instruction; otherwise MIPS32. */
static ULONGEST
-mips_fetch_instruction (CORE_ADDR addr)
+mips_fetch_instruction (struct gdbarch *gdbarch, CORE_ADDR addr)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[MIPS_INSN32_SIZE];
int instlen;
int status;
status = target_read_memory (addr, buf, instlen);
if (status)
memory_error (status, addr);
- return extract_unsigned_integer (buf, instlen);
+ return extract_unsigned_integer (buf, instlen, byte_order);
}
/* These the fields of 32 bit mips instructions */
static CORE_ADDR
mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
unsigned long inst;
int op;
- inst = mips_fetch_instruction (pc);
+ inst = mips_fetch_instruction (gdbarch, pc);
if ((inst & 0xe0000000) != 0) /* Not a special, jump or branch instruction */
{
if (itype_op (inst) >> 2 == 5)
when the offset is to be used in relative addressing. */
static unsigned int
-fetch_mips_16 (CORE_ADDR pc)
+fetch_mips_16 (struct gdbarch *gdbarch, CORE_ADDR pc)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
gdb_byte buf[8];
pc &= 0xfffffffe; /* clear the low order bit */
target_read_memory (pc, buf, 2);
- return extract_unsigned_integer (buf, 2);
+ return extract_unsigned_integer (buf, 2, byte_order);
}
static void
-unpack_mips16 (CORE_ADDR pc,
+unpack_mips16 (struct gdbarch *gdbarch, CORE_ADDR pc,
unsigned int extension,
unsigned int inst,
enum mips16_inst_fmts insn_format, struct upk_mips16 *upk)
unsigned int nexthalf;
value = ((inst & 0x1f) << 5) | ((inst >> 5) & 0x1f);
value = value << 16;
- nexthalf = mips_fetch_instruction (pc + 2); /* low bit still set */
+ nexthalf = mips_fetch_instruction (gdbarch, pc + 2); /* low bit still set */
value |= nexthalf;
offset = value;
regx = -1;
extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
unsigned int extension, unsigned int insn)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
int op = (insn >> 11);
switch (op)
{
{
CORE_ADDR offset;
struct upk_mips16 upk;
- unpack_mips16 (pc, extension, insn, itype, &upk);
+ unpack_mips16 (gdbarch, pc, extension, insn, itype, &upk);
offset = upk.offset;
if (offset & 0x800)
{
case 3: /* JAL , JALX - Watch out, these are 32 bit instruction */
{
struct upk_mips16 upk;
- unpack_mips16 (pc, extension, insn, jalxtype, &upk);
+ unpack_mips16 (gdbarch, pc, extension, insn, jalxtype, &upk);
pc = add_offset_16 (pc, upk.offset);
if ((insn >> 10) & 0x01) /* Exchange mode */
pc = pc & ~0x01; /* Clear low bit, indicate 32 bit mode */
{
struct upk_mips16 upk;
int reg;
- unpack_mips16 (pc, extension, insn, ritype, &upk);
+ unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
reg = get_frame_register_signed (frame, upk.regx);
if (reg == 0)
pc += (upk.offset << 1) + 2;
{
struct upk_mips16 upk;
int reg;
- unpack_mips16 (pc, extension, insn, ritype, &upk);
+ unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
reg = get_frame_register_signed (frame, upk.regx);
if (reg != 0)
pc += (upk.offset << 1) + 2;
{
struct upk_mips16 upk;
int reg;
- unpack_mips16 (pc, extension, insn, i8type, &upk);
+ unpack_mips16 (gdbarch, pc, extension, insn, i8type, &upk);
/* upk.regx contains the opcode */
reg = get_frame_register_signed (frame, 24); /* Test register is 24 */
if (((upk.regx == 0) && (reg == 0)) /* BTEZ */
that. */
{
pc += 2;
- pc = extended_mips16_next_pc (frame, pc, insn, fetch_mips_16 (pc));
+ pc = extended_mips16_next_pc (frame, pc, insn,
+ fetch_mips_16 (gdbarch, pc));
break;
}
default:
static CORE_ADDR
mips16_next_pc (struct frame_info *frame, CORE_ADDR pc)
{
- unsigned int insn = fetch_mips_16 (pc);
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ unsigned int insn = fetch_mips_16 (gdbarch, pc);
return extended_mips16_next_pc (frame, pc, 0, insn);
}
Return the address of the first instruction past the prologue. */
static CORE_ADDR
-mips16_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
+mips16_scan_prologue (struct gdbarch *gdbarch,
+ CORE_ADDR start_pc, CORE_ADDR limit_pc,
struct frame_info *this_frame,
struct mips_frame_cache *this_cache)
{
int extend_bytes = 0;
int prev_extend_bytes;
CORE_ADDR end_prologue_addr = 0;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
/* Can be called when there's no process, and hence when there's no
THIS_FRAME. */
prev_inst = inst;
/* Fetch and decode the instruction. */
- inst = (unsigned short) mips_fetch_instruction (cur_pc);
+ inst = (unsigned short) mips_fetch_instruction (gdbarch, cur_pc);
/* Normally we ignore extend instructions. However, if it is
not followed by a valid prologue instruction, then this
static struct mips_frame_cache *
mips_insn16_frame_cache (struct frame_info *this_frame, void **this_cache)
{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct mips_frame_cache *cache;
if ((*this_cache) != NULL)
find_pc_partial_function (pc, NULL, &start_addr, NULL);
if (start_addr == 0)
- start_addr = heuristic_proc_start (get_frame_arch (this_frame), pc);
+ start_addr = heuristic_proc_start (gdbarch, pc);
/* We can't analyze the prologue if we couldn't find the begining
of the function. */
if (start_addr == 0)
return cache;
- mips16_scan_prologue (start_addr, pc, this_frame, *this_cache);
+ mips16_scan_prologue (gdbarch, start_addr, pc, this_frame, *this_cache);
}
/* gdbarch_sp_regnum contains the value and not the address. */
trad_frame_set_value (cache->saved_regs,
- gdbarch_num_regs (get_frame_arch (this_frame))
- + MIPS_SP_REGNUM,
+ gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM,
cache->base);
return (*this_cache);
{
struct mips_frame_cache *info = mips_insn16_frame_cache (this_frame,
this_cache);
+ /* This marks the outermost frame. */
+ if (info->base == 0)
+ return;
(*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
}
Return the address of the first instruction past the prologue. */
static CORE_ADDR
-mips32_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
+mips32_scan_prologue (struct gdbarch *gdbarch,
+ CORE_ADDR start_pc, CORE_ADDR limit_pc,
struct frame_info *this_frame,
struct mips_frame_cache *this_cache)
{
int seen_sp_adjust = 0;
int load_immediate_bytes = 0;
int in_delay_slot = 0;
- struct gdbarch *gdbarch = get_frame_arch (this_frame);
int regsize_is_64_bits = (mips_abi_regsize (gdbarch) == 8);
/* Can be called when there's no process, and hence when there's no
int reg;
/* Fetch the instruction. */
- inst = (unsigned long) mips_fetch_instruction (cur_pc);
+ inst = (unsigned long) mips_fetch_instruction (gdbarch, cur_pc);
/* Save some code by pre-extracting some useful fields. */
high_word = (inst >> 16) & 0xffff;
static struct mips_frame_cache *
mips_insn32_frame_cache (struct frame_info *this_frame, void **this_cache)
{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct mips_frame_cache *cache;
if ((*this_cache) != NULL)
find_pc_partial_function (pc, NULL, &start_addr, NULL);
if (start_addr == 0)
- start_addr = heuristic_proc_start (get_frame_arch (this_frame), pc);
+ start_addr = heuristic_proc_start (gdbarch, pc);
/* We can't analyze the prologue if we couldn't find the begining
of the function. */
if (start_addr == 0)
return cache;
- mips32_scan_prologue (start_addr, pc, this_frame, *this_cache);
+ mips32_scan_prologue (gdbarch, start_addr, pc, this_frame, *this_cache);
}
/* gdbarch_sp_regnum contains the value and not the address. */
trad_frame_set_value (cache->saved_regs,
- gdbarch_num_regs (get_frame_arch (this_frame))
- + MIPS_SP_REGNUM,
+ gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM,
cache->base);
return (*this_cache);
{
struct mips_frame_cache *info = mips_insn32_frame_cache (this_frame,
this_cache);
+ /* This marks the outermost frame. */
+ if (info->base == 0)
+ return;
(*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
}
mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ if (is_mips16_addr (addr))
+ addr = unmake_mips16_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
the sequence. */
static int
-deal_with_atomic_sequence (CORE_ADDR pc)
+deal_with_atomic_sequence (struct gdbarch *gdbarch,
+ struct address_space *aspace, CORE_ADDR pc)
{
CORE_ADDR breaks[2] = {-1, -1};
CORE_ADDR loc = pc;
if (pc & 0x01)
return 0;
- insn = mips_fetch_instruction (loc);
+ insn = mips_fetch_instruction (gdbarch, loc);
/* Assume all atomic sequences start with a ll/lld instruction. */
if (itype_op (insn) != LL_OPCODE && itype_op (insn) != LLD_OPCODE)
return 0;
{
int is_branch = 0;
loc += MIPS_INSN32_SIZE;
- insn = mips_fetch_instruction (loc);
+ insn = mips_fetch_instruction (gdbarch, loc);
/* Assume that there is at most one branch in the atomic
sequence. If a branch is found, put a breakpoint in its
/* Effectively inserts the breakpoints. */
for (index = 0; index <= last_breakpoint; index++)
- insert_single_step_breakpoint (breaks[index]);
+ insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
return 1;
}
int
mips_software_single_step (struct frame_info *frame)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct address_space *aspace = get_frame_address_space (frame);
CORE_ADDR pc, next_pc;
pc = get_frame_pc (frame);
- if (deal_with_atomic_sequence (pc))
+ if (deal_with_atomic_sequence (gdbarch, aspace, pc))
return 1;
next_pc = mips_next_pc (frame, pc);
- insert_single_step_breakpoint (next_pc);
+ insert_single_step_breakpoint (gdbarch, aspace, next_pc);
return 1;
}
end of a function. */
static int
-mips_about_to_return (CORE_ADDR pc)
+mips_about_to_return (struct gdbarch *gdbarch, CORE_ADDR pc)
{
if (mips_pc_is_mips16 (pc))
/* This mips16 case isn't necessarily reliable. Sometimes the compiler
as $a3), then a "jr" using that register. This second case
is almost impossible to distinguish from an indirect jump
used for switch statements, so we don't even try. */
- return mips_fetch_instruction (pc) == 0xe820; /* jr $ra */
+ return mips_fetch_instruction (gdbarch, pc) == 0xe820; /* jr $ra */
else
- return mips_fetch_instruction (pc) == 0x3e00008; /* jr $ra */
+ return mips_fetch_instruction (gdbarch, pc) == 0x3e00008; /* jr $ra */
}
stop_soon, but with this test, at least we
don't print out warnings for every child forked (eg, on
decstation). 22apr93 rich@cygnus.com. */
- if (inf->stop_soon == NO_STOP_QUIETLY)
+ if (inf->control.stop_soon == NO_STOP_QUIETLY)
{
static int blurb_printed = 0;
- warning (_("GDB can't find the start of the function at 0x%s."),
- paddr_nz (pc));
+ warning (_("GDB can't find the start of the function at %s."),
+ paddress (gdbarch, pc));
if (!blurb_printed)
{
in that situation enough information to
determine that it's no big deal. */
printf_filtered ("\n\
- GDB is unable to find the start of the function at 0x%s\n\
+ GDB is unable to find the start of the function at %s\n\
and thus can't determine the size of that function's stack frame.\n\
This means that GDB may be unable to access that stack frame, or\n\
the frames below it.\n\
This problem is most likely caused by an invalid program counter or\n\
stack pointer.\n\
However, if you think GDB should simply search farther back\n\
-from 0x%s for code which looks like the beginning of a\n\
+from %s for code which looks like the beginning of a\n\
function, you can increase the range of the search using the `set\n\
-heuristic-fence-post' command.\n", paddr_nz (pc), paddr_nz (pc));
+heuristic-fence-post' command.\n",
+ paddress (gdbarch, pc), paddress (gdbarch, pc));
blurb_printed = 1;
}
}
addiu sp,-n
daddiu sp,-n
extend -n followed by 'addiu sp,+n' or 'daddiu sp,+n' */
- inst = mips_fetch_instruction (start_pc);
+ inst = mips_fetch_instruction (gdbarch, start_pc);
if ((inst & 0xff80) == 0x6480) /* save */
{
if (start_pc - instlen >= fence)
{
- inst = mips_fetch_instruction (start_pc - instlen);
+ inst = mips_fetch_instruction (gdbarch, start_pc - instlen);
if ((inst & 0xf800) == 0xf000) /* extend */
start_pc -= instlen;
}
else
seen_adjsp = 0;
}
- else if (mips_about_to_return (start_pc))
+ else if (mips_about_to_return (gdbarch, start_pc))
{
/* Skip return and its delay slot. */
start_pc += 2 * MIPS_INSN32_SIZE;
int len = 0;
int stack_offset = 0;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = find_function_addr (function, NULL);
int regsize = mips_abi_regsize (gdbarch);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_eabi_push_dummy_call: sp=0x%s allocated %ld\n",
- paddr_nz (sp), (long) align_up (len, 16));
+ "mips_eabi_push_dummy_call: sp=%s allocated %ld\n",
+ paddress (gdbarch, sp), (long) align_up (len, 16));
/* Initialize the integer and float register pointers. */
argreg = MIPS_A0_REGNUM;
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_eabi_push_dummy_call: struct_return reg=%d 0x%s\n",
- argreg, paddr_nz (struct_addr));
+ "mips_eabi_push_dummy_call: struct_return reg=%d %s\n",
+ argreg, paddress (gdbarch, struct_addr));
regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
}
"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_mips16 (addr))
+ {
+ store_signed_integer (valbuf, len, byte_order,
+ make_mips16_addr (addr));
+ val = valbuf;
+ }
+ else
+ val = value_contents (arg);
+ }
/* The EABI passes structures that do not fit in a register by
reference. */
- if (len > regsize
+ else if (len > regsize
&& (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
{
- store_unsigned_integer (valbuf, regsize, VALUE_ADDRESS (arg));
+ store_unsigned_integer (valbuf, regsize, byte_order,
+ value_address (arg));
typecode = TYPE_CODE_PTR;
len = regsize;
val = valbuf;
{
int low_offset = gdbarch_byte_order (gdbarch)
== BFD_ENDIAN_BIG ? 4 : 0;
- unsigned long regval;
+ long regval;
/* Write the low word of the double to the even register(s). */
- regval = extract_unsigned_integer (val + low_offset, 4);
+ regval = extract_signed_integer (val + low_offset,
+ 4, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
- regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+ regcache_cooked_write_signed (regcache, float_argreg++, regval);
/* Write the high word of the double to the odd register(s). */
- regval = extract_unsigned_integer (val + 4 - low_offset, 4);
+ regval = extract_signed_integer (val + 4 - low_offset,
+ 4, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
- regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+ regcache_cooked_write_signed (regcache, float_argreg++, regval);
}
else
{
in a single register. */
/* On 32 bit ABI's the float_argreg is further adjusted
above to ensure that it is even register aligned. */
- LONGEST regval = extract_unsigned_integer (val, len);
+ LONGEST regval = extract_signed_integer (val, len, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
- regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+ regcache_cooked_write_signed (regcache, float_argreg++, regval);
}
}
else
if (mips_debug)
{
- fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s",
- paddr_nz (stack_offset));
- fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s",
- paddr_nz (longword_offset));
+ fprintf_unfiltered (gdb_stdlog, " - stack_offset=%s",
+ paddress (gdbarch, stack_offset));
+ fprintf_unfiltered (gdb_stdlog, " longword_offset=%s",
+ paddress (gdbarch, longword_offset));
}
addr = sp + stack_offset + longword_offset;
if (mips_debug)
{
int i;
- fprintf_unfiltered (gdb_stdlog, " @0x%s ",
- paddr_nz (addr));
+ fprintf_unfiltered (gdb_stdlog, " @%s ",
+ paddress (gdbarch, addr));
for (i = 0; i < partial_len; i++)
{
fprintf_unfiltered (gdb_stdlog, "%02x",
&& !fp_register_arg_p (gdbarch, typecode, arg_type))
{
LONGEST regval =
- extract_unsigned_integer (val, partial_len);
+ extract_signed_integer (val, partial_len, byte_order);
if (mips_debug)
fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
argreg,
phex (regval, regsize));
- regcache_cooked_write_unsigned (regcache, argreg, regval);
+ regcache_cooked_write_signed (regcache, argreg, regval);
argreg++;
}
int len = 0;
int stack_offset = 0;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = find_function_addr (function, NULL);
/* For shared libraries, "t9" needs to point at the function
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_n32n64_push_dummy_call: sp=0x%s allocated %ld\n",
- paddr_nz (sp), (long) align_up (len, 16));
+ "mips_n32n64_push_dummy_call: sp=%s allocated %ld\n",
+ paddress (gdbarch, sp), (long) align_up (len, 16));
/* Initialize the integer and float register pointers. */
argreg = MIPS_A0_REGNUM;
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_n32n64_push_dummy_call: struct_return reg=%d 0x%s\n",
- argreg, paddr_nz (struct_addr));
+ "mips_n32n64_push_dummy_call: struct_return reg=%d %s\n",
+ argreg, paddress (gdbarch, struct_addr));
regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
}
/* This is a floating point value that fits entirely
in a single register or a pair of registers. */
int reglen = (len <= MIPS64_REGSIZE ? len : MIPS64_REGSIZE);
- LONGEST regval = extract_unsigned_integer (val, reglen);
+ LONGEST regval = extract_unsigned_integer (val, reglen, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, reglen));
argreg++;
if (len == 16)
{
- regval = extract_unsigned_integer (val + reglen, reglen);
+ regval = extract_unsigned_integer (val + reglen,
+ reglen, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, reglen));
if (mips_debug)
{
- fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s",
- paddr_nz (stack_offset));
- fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s",
- paddr_nz (longword_offset));
+ fprintf_unfiltered (gdb_stdlog, " - stack_offset=%s",
+ paddress (gdbarch, stack_offset));
+ fprintf_unfiltered (gdb_stdlog, " longword_offset=%s",
+ paddress (gdbarch, longword_offset));
}
addr = sp + stack_offset + longword_offset;
if (mips_debug)
{
int i;
- fprintf_unfiltered (gdb_stdlog, " @0x%s ",
- paddr_nz (addr));
+ fprintf_unfiltered (gdb_stdlog, " @%s ",
+ paddress (gdbarch, addr));
for (i = 0; i < partial_len; i++)
{
fprintf_unfiltered (gdb_stdlog, "%02x",
|| (partial_len < 4
&& typecode == TYPE_CODE_INT
&& !TYPE_UNSIGNED (arg_type)))
- regval = extract_signed_integer (val, partial_len);
+ regval = extract_signed_integer (val, partial_len,
+ byte_order);
else
- regval = extract_unsigned_integer (val, partial_len);
+ regval = extract_unsigned_integer (val, partial_len,
+ byte_order);
/* A non-floating-point argument being passed in a
general register. If a struct or union, and if
(and $f2 if necessary). This is a generalization of the Fortran COMPLEX
case.
- * Any other struct or union results of at most 128 bits are returned in
+ * Any other composite results of at most 128 bits are returned in
$2 (first 64 bits) and $3 (remainder, if necessary).
* Larger composite results are handled by converting the function to a
specific exception to return COMPLEX results in the floating point
registers.] */
- if (TYPE_CODE (type) == TYPE_CODE_ARRAY
- || TYPE_LENGTH (type) > 2 * MIPS64_REGSIZE)
+ if (TYPE_LENGTH (type) > 2 * MIPS64_REGSIZE)
return RETURN_VALUE_STRUCT_CONVENTION;
else if (TYPE_CODE (type) == TYPE_CODE_FLT
&& TYPE_LENGTH (type) == 16
return RETURN_VALUE_REGISTER_CONVENTION;
}
else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_UNION)
+ || TYPE_CODE (type) == TYPE_CODE_UNION
+ || TYPE_CODE (type) == TYPE_CODE_ARRAY)
{
- /* A structure or union. Extract the left justified value,
+ /* A composite type. Extract the left justified value,
regardless of the byte order. I.e. DO NOT USE
mips_xfer_lower. */
int offset;
int len = 0;
int stack_offset = 0;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = find_function_addr (function, NULL);
/* For shared libraries, "t9" needs to point at the function
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_o32_push_dummy_call: sp=0x%s allocated %ld\n",
- paddr_nz (sp), (long) align_up (len, 16));
+ "mips_o32_push_dummy_call: sp=%s allocated %ld\n",
+ paddress (gdbarch, sp), (long) align_up (len, 16));
/* Initialize the integer and float register pointers. */
argreg = MIPS_A0_REGNUM;
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_o32_push_dummy_call: struct_return reg=%d 0x%s\n",
- argreg, paddr_nz (struct_addr));
+ "mips_o32_push_dummy_call: struct_return reg=%d %s\n",
+ argreg, paddress (gdbarch, struct_addr));
regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
stack_offset += MIPS32_REGSIZE;
}
unsigned long regval;
/* Write the low word of the double to the even register(s). */
- regval = extract_unsigned_integer (val + low_offset, 4);
+ regval = extract_unsigned_integer (val + low_offset,
+ 4, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
regcache_cooked_write_unsigned (regcache, argreg++, regval);
/* Write the high word of the double to the odd register(s). */
- regval = extract_unsigned_integer (val + 4 - low_offset, 4);
+ regval = extract_unsigned_integer (val + 4 - low_offset,
+ 4, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, 4));
in a single register. */
/* On 32 bit ABI's the float_argreg is further adjusted
above to ensure that it is even register aligned. */
- LONGEST regval = extract_unsigned_integer (val, len);
+ LONGEST regval = extract_unsigned_integer (val, len, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
if (mips_debug)
{
- fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s",
- paddr_nz (stack_offset));
- fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s",
- paddr_nz (longword_offset));
+ fprintf_unfiltered (gdb_stdlog, " - stack_offset=%s",
+ paddress (gdbarch, stack_offset));
+ fprintf_unfiltered (gdb_stdlog, " longword_offset=%s",
+ paddress (gdbarch, longword_offset));
}
addr = sp + stack_offset + longword_offset;
if (mips_debug)
{
int i;
- fprintf_unfiltered (gdb_stdlog, " @0x%s ",
- paddr_nz (addr));
+ fprintf_unfiltered (gdb_stdlog, " @%s ",
+ paddress (gdbarch, addr));
for (i = 0; i < partial_len; i++)
{
fprintf_unfiltered (gdb_stdlog, "%02x",
purpose register. */
if (argreg <= MIPS_LAST_ARG_REGNUM (gdbarch))
{
- LONGEST regval = extract_signed_integer (val, partial_len);
+ LONGEST regval = extract_signed_integer (val, partial_len,
+ byte_order);
/* Value may need to be sign extended, because
mips_isa_regsize() != mips_abi_regsize(). */
int len = 0;
int stack_offset = 0;
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR func_addr = find_function_addr (function, NULL);
/* For shared libraries, "t9" needs to point at the function
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_o64_push_dummy_call: sp=0x%s allocated %ld\n",
- paddr_nz (sp), (long) align_up (len, 16));
+ "mips_o64_push_dummy_call: sp=%s allocated %ld\n",
+ paddress (gdbarch, sp), (long) align_up (len, 16));
/* Initialize the integer and float register pointers. */
argreg = MIPS_A0_REGNUM;
{
if (mips_debug)
fprintf_unfiltered (gdb_stdlog,
- "mips_o64_push_dummy_call: struct_return reg=%d 0x%s\n",
- argreg, paddr_nz (struct_addr));
+ "mips_o64_push_dummy_call: struct_return reg=%d %s\n",
+ argreg, paddress (gdbarch, struct_addr));
regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
stack_offset += MIPS64_REGSIZE;
}
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_mips16 (addr))
+ {
+ store_signed_integer (valbuf, len, byte_order,
+ make_mips16_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 register gets
if (fp_register_arg_p (gdbarch, typecode, arg_type)
&& float_argreg <= MIPS_LAST_FP_ARG_REGNUM (gdbarch))
{
- LONGEST regval = extract_unsigned_integer (val, len);
+ LONGEST regval = extract_unsigned_integer (val, len, byte_order);
if (mips_debug)
fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
float_argreg, phex (regval, len));
if (mips_debug)
{
- fprintf_unfiltered (gdb_stdlog, " - stack_offset=0x%s",
- paddr_nz (stack_offset));
- fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%s",
- paddr_nz (longword_offset));
+ fprintf_unfiltered (gdb_stdlog, " - stack_offset=%s",
+ paddress (gdbarch, stack_offset));
+ fprintf_unfiltered (gdb_stdlog, " longword_offset=%s",
+ paddress (gdbarch, longword_offset));
}
addr = sp + stack_offset + longword_offset;
if (mips_debug)
{
int i;
- fprintf_unfiltered (gdb_stdlog, " @0x%s ",
- paddr_nz (addr));
+ fprintf_unfiltered (gdb_stdlog, " @%s ",
+ paddress (gdbarch, addr));
for (i = 0; i < partial_len; i++)
{
fprintf_unfiltered (gdb_stdlog, "%02x",
purpose register. */
if (argreg <= MIPS_LAST_ARG_REGNUM (gdbarch))
{
- LONGEST regval = extract_signed_integer (val, partial_len);
+ LONGEST regval = extract_signed_integer (val, partial_len,
+ byte_order);
/* Value may need to be sign extended, because
mips_isa_regsize() != mips_abi_regsize(). */
regs could be 32 bits wide in one frame and 64 on the frame above
and below). */
-static struct type *
-mips_float_register_type (void)
-{
- return builtin_type_ieee_single;
-}
-
-static struct type *
-mips_double_register_type (void)
-{
- return builtin_type_ieee_double;
-}
-
/* Copy a 32-bit single-precision value from the current frame
into rare_buffer. */
/* 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 (mips_float_register_type (), raw_buffer, &inv1);
+ flt1 = unpack_double (builtin_type (gdbarch)->builtin_float, raw_buffer, &inv1);
get_formatted_print_options (&opts, 'x');
- print_scalar_formatted (raw_buffer, builtin_type_uint32, &opts, 'w',
- file);
+ print_scalar_formatted (raw_buffer,
+ builtin_type (gdbarch)->builtin_uint32,
+ &opts, 'w', file);
fprintf_filtered (file, " flt: ");
if (inv1)
if ((regnum - gdbarch_num_regs (gdbarch)) % 2 == 0)
{
mips_read_fp_register_double (frame, regnum, raw_buffer);
- doub = unpack_double (mips_double_register_type (), raw_buffer,
- &inv2);
+ doub = unpack_double (builtin_type (gdbarch)->builtin_double,
+ raw_buffer, &inv2);
fprintf_filtered (file, " dbl: ");
if (inv2)
/* Eight byte registers: print each one as hex, float and double. */
mips_read_fp_register_single (frame, regnum, raw_buffer);
- flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1);
+ flt1 = unpack_double (builtin_type (gdbarch)->builtin_float,
+ raw_buffer, &inv1);
mips_read_fp_register_double (frame, regnum, raw_buffer);
- doub = unpack_double (mips_double_register_type (), raw_buffer, &inv2);
+ doub = unpack_double (builtin_type (gdbarch)->builtin_double,
+ raw_buffer, &inv2);
get_formatted_print_options (&opts, 'x');
- print_scalar_formatted (raw_buffer, builtin_type_uint64, &opts, 'g',
- file);
+ print_scalar_formatted (raw_buffer,
+ builtin_type (gdbarch)->builtin_uint64,
+ &opts, 'g', file);
fprintf_filtered (file, " flt: ");
if (inv1)
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);
gdb_byte buf[MIPS_INSN32_SIZE];
if (mips_pc_is_mips16 (pc))
return 0;
- if (!breakpoint_here_p (pc + 4))
+ if (!breakpoint_here_p (get_frame_address_space (frame), pc + 4))
return 0;
if (!safe_frame_unwind_memory (frame, pc, buf, sizeof buf))
/* If error reading memory, guess that it is not a delayed
branch. */
return 0;
- return is_delayed (extract_unsigned_integer (buf, sizeof buf));
+ return is_delayed (extract_unsigned_integer (buf, sizeof buf, byte_order));
}
/* To skip prologues, I use this predicate. Returns either PC itself
is greater. */
if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
{
- CORE_ADDR post_prologue_pc = skip_prologue_using_sal (func_addr);
+ CORE_ADDR post_prologue_pc
+ = skip_prologue_using_sal (gdbarch, func_addr);
if (post_prologue_pc != 0)
return max (pc, post_prologue_pc);
}
/* Find an upper limit on the function prologue using the debug
information. If the debug information could not be used to provide
that bound, then use an arbitrary large number as the upper bound. */
- limit_pc = skip_prologue_using_sal (pc);
+ limit_pc = skip_prologue_using_sal (gdbarch, pc);
if (limit_pc == 0)
limit_pc = pc + 100; /* Magic. */
if (mips_pc_is_mips16 (pc))
- return mips16_scan_prologue (pc, limit_pc, NULL, NULL);
+ return mips16_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL);
else
- return mips32_scan_prologue (pc, limit_pc, NULL, NULL);
+ 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. */
static int
-mips32_in_function_epilogue_p (CORE_ADDR pc)
+mips32_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR func_addr = 0, func_end = 0;
unsigned long high_word;
unsigned long inst;
- inst = mips_fetch_instruction (pc);
+ inst = mips_fetch_instruction (gdbarch, pc);
high_word = (inst >> 16) & 0xffff;
if (high_word != 0x27bd /* addiu $sp,$sp,offset */
/* Check whether the PC is in a function epilogue (16-bit version).
This is a helper function for mips_in_function_epilogue_p. */
static int
-mips16_in_function_epilogue_p (CORE_ADDR pc)
+mips16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR func_addr = 0, func_end = 0;
{
unsigned short inst;
- inst = mips_fetch_instruction (pc);
+ inst = mips_fetch_instruction (gdbarch, pc);
if ((inst & 0xf800) == 0xf000) /* extend */
continue;
mips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
if (mips_pc_is_mips16 (pc))
- return mips16_in_function_epilogue_p (pc);
+ return mips16_in_function_epilogue_p (gdbarch, pc);
else
- return mips32_in_function_epilogue_p (pc);
+ return mips32_in_function_epilogue_p (gdbarch, pc);
}
/* Root of all "set mips "/"show mips " commands. This will eventually be
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);
|| 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;
}
static CORE_ADDR
mips_skip_mips16_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
char *name;
CORE_ADDR start_addr;
instructions. FIXME. */
for (i = 0, pc = 0; i < 20; i++, target_pc += MIPS_INSN32_SIZE)
{
- inst = mips_fetch_instruction (target_pc);
+ inst = mips_fetch_instruction (gdbarch, target_pc);
if ((inst & 0xffff0000) == 0x3c010000) /* lui $at */
pc = (inst << 16) & 0xffff0000; /* high word */
else if ((inst & 0xffff0000) == 0x24210000) /* addiu $at */
static CORE_ADDR
mips_skip_pic_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct minimal_symbol *msym;
int i;
gdb_byte stub_code[16];
if (target_read_memory (pc, stub_code, 16) != 0)
return 0;
for (i = 0; i < 4; i++)
- stub_words[i] = extract_unsigned_integer (stub_code + i * 4, 4);
+ stub_words[i] = extract_unsigned_integer (stub_code + i * 4,
+ 4, byte_order);
/* A stub contains these instructions:
lui t9, %hi(target)
mips_integer_to_address (struct gdbarch *gdbarch,
struct type *type, const gdb_byte *buf)
{
- return (CORE_ADDR) extract_signed_integer (buf, TYPE_LENGTH (type));
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+ return extract_signed_integer (buf, TYPE_LENGTH (type), byte_order);
}
/* Dummy virtual frame pointer method. This is no more or less accurate
tdep->mips_fpu_type = fpu_type;
tdep->register_size_valid_p = 0;
tdep->register_size = 0;
+ tdep->gregset = NULL;
+ tdep->gregset64 = NULL;
+ tdep->fpregset = NULL;
+ tdep->fpregset64 = NULL;
if (info.target_desc)
{
set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read);
set_gdbarch_pseudo_register_write (gdbarch, mips_pseudo_register_write);
+ set_gdbarch_ax_pseudo_register_collect (gdbarch,
+ mips_ax_pseudo_register_collect);
+ set_gdbarch_ax_pseudo_register_push_stack
+ (gdbarch, mips_ax_pseudo_register_push_stack);
+
set_gdbarch_elf_make_msymbol_special (gdbarch,
mips_elf_make_msymbol_special);
else
set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips);
- /* FIXME: cagney/2003-08-29: The macros HAVE_STEPPABLE_WATCHPOINT,
- HAVE_NONSTEPPABLE_WATCHPOINT, and HAVE_CONTINUABLE_WATCHPOINT
+ /* FIXME: cagney/2003-08-29: The macros target_have_steppable_watchpoint,
+ HAVE_NONSTEPPABLE_WATCHPOINT, and target_have_continuable_watchpoint
need to all be folded into the target vector. Since they are
- being used as guards for STOPPED_BY_WATCHPOINT, why not have
- STOPPED_BY_WATCHPOINT return the type of watchpoint that the code
+ being used as guards for target_stopped_by_watchpoint, why not have
+ target_stopped_by_watchpoint return the type of watchpoint that the code
is sitting on? */
set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
&mask_address_var, _("\
Set zeroing of upper 32 bits of 64-bit addresses."), _("\
Show zeroing of upper 32 bits of 64-bit addresses."), _("\
-Use \"on\" to enable the masking, \"off\" to disable it and \"auto\" to \n\
+Use \"on\" to enable the masking, \"off\" to disable it and \"auto\" to\n\
allow GDB to determine the correct value."),
NULL, show_mask_address,
&setmipscmdlist, &showmipscmdlist);