/* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
- 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software
- Foundation, Inc.
+ 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+ 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 void
mips_xfer_register (struct regcache *regcache, int reg_num, int length,
- enum bfd_endian endian, bfd_byte * in,
- const bfd_byte * out, int buf_offset)
+ enum bfd_endian endian, gdb_byte *in,
+ const gdb_byte *out, int buf_offset)
{
int reg_offset = 0;
gdb_assert (reg_num >= NUM_REGS);
static void
mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
- int cookednum, void *buf)
+ int cookednum, gdb_byte *buf)
{
int rawnum = cookednum % NUM_REGS;
gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
static void
mips_pseudo_register_write (struct gdbarch *gdbarch,
struct regcache *regcache, int cookednum,
- const void *buf)
+ const gdb_byte *buf)
{
int rawnum = cookednum % NUM_REGS;
gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
static void
mips_register_to_value (struct frame_info *frame, int regnum,
- struct type *type, void *to)
+ struct type *type, gdb_byte *to)
{
- get_frame_register (frame, regnum + 0, (char *) to + 4);
- get_frame_register (frame, regnum + 1, (char *) to + 0);
+ get_frame_register (frame, regnum + 0, to + 4);
+ get_frame_register (frame, regnum + 1, to + 0);
}
static void
mips_value_to_register (struct frame_info *frame, int regnum,
- struct type *type, const void *from)
+ struct type *type, const gdb_byte *from)
{
- put_frame_register (frame, regnum + 0, (const char *) from + 4);
- put_frame_register (frame, regnum + 1, (const char *) from + 0);
+ put_frame_register (frame, regnum + 0, from + 4);
+ put_frame_register (frame, regnum + 1, from + 0);
}
/* Return the GDB type object for the "standard" data type of data in
}
static void
-show_mask_address (char *cmd, int from_tty, struct cmd_list_element *c)
+show_mask_address (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+ deprecated_show_value_hack (file, from_tty, c, value);
switch (mask_address_var)
{
case AUTO_BOOLEAN_TRUE:
static ULONGEST
mips_fetch_instruction (CORE_ADDR addr)
{
- char buf[MIPS_INSN32_SIZE];
+ gdb_byte buf[MIPS_INSN32_SIZE];
int instlen;
int status;
static unsigned int
fetch_mips_16 (CORE_ADDR pc)
{
- char buf[8];
+ gdb_byte buf[8];
pc &= 0xfffffffe; /* clear the low order bit */
target_read_memory (pc, buf, 2);
return extract_unsigned_integer (buf, 2);
void **this_cache,
int regnum, int *optimizedp,
enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, void *valuep)
+ int *realnump, gdb_byte *valuep)
{
struct mips_frame_cache *info = mips_insn16_frame_cache (next_frame,
this_cache);
void **this_cache,
int regnum, int *optimizedp,
enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, void *valuep)
+ int *realnump, gdb_byte *valuep)
{
struct mips_frame_cache *info = mips_insn32_frame_cache (next_frame,
this_cache);
void **this_cache,
int regnum, int *optimizedp,
enum lval_type *lvalp, CORE_ADDR *addrp,
- int *realnump, void *valuep)
+ int *realnump, gdb_byte *valuep)
{
struct trad_frame_cache *this_trad_cache
= mips_stub_frame_cache (next_frame, this_cache);
static const struct frame_unwind *
mips_stub_frame_sniffer (struct frame_info *next_frame)
{
+ struct obj_section *s;
CORE_ADDR pc = frame_pc_unwind (next_frame);
+
if (in_plt_section (pc, NULL))
return &mips_stub_frame_unwind;
- else
- return NULL;
+
+ /* Binutils for MIPS puts lazy resolution stubs into .MIPS.stubs. */
+ s = find_pc_section (pc);
+
+ if (s != NULL
+ && strcmp (bfd_get_section_name (s->objfile->obfd, s->the_bfd_section),
+ ".MIPS.stubs") == 0)
+ return &mips_stub_frame_unwind;
+
+ return NULL;
}
static CORE_ADDR
from first to last. */
for (argnum = 0; argnum < nargs; argnum++)
{
- char *val;
- char valbuf[MAX_REGISTER_SIZE];
+ 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);
fprintf_unfiltered (gdb_stdlog, " push");
}
else
- val = (char *) value_contents (arg);
+ val = value_contents (arg);
/* 32-bit ABIs always start floating point arguments in an
even-numbered floating point register. Round the FP register
static enum return_value_convention
mips_eabi_return_value (struct gdbarch *gdbarch,
struct type *type, struct regcache *regcache,
- void *readbuf, const void *writebuf)
+ gdb_byte *readbuf, const gdb_byte *writebuf)
{
if (TYPE_LENGTH (type) > 2 * mips_abi_regsize (gdbarch))
return RETURN_VALUE_STRUCT_CONVENTION;
from first to last. */
for (argnum = 0; argnum < nargs; argnum++)
{
- char *val;
+ const gdb_byte *val;
struct value *arg = args[argnum];
struct type *arg_type = check_typedef (value_type (arg));
int len = TYPE_LENGTH (arg_type);
"mips_n32n64_push_dummy_call: %d len=%d type=%d",
argnum + 1, len, (int) typecode);
- val = (char *) value_contents (arg);
+ val = value_contents (arg);
if (fp_register_arg_p (typecode, arg_type)
&& float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
static enum return_value_convention
mips_n32n64_return_value (struct gdbarch *gdbarch,
struct type *type, struct regcache *regcache,
- void *readbuf, const void *writebuf)
+ gdb_byte *readbuf, const gdb_byte *writebuf)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
if (TYPE_CODE (type) == TYPE_CODE_STRUCT
from first to last. */
for (argnum = 0; argnum < nargs; argnum++)
{
- char *val;
+ const gdb_byte *val;
struct value *arg = args[argnum];
struct type *arg_type = check_typedef (value_type (arg));
int len = TYPE_LENGTH (arg_type);
"mips_o32_push_dummy_call: %d len=%d type=%d",
argnum + 1, len, (int) typecode);
- val = (char *) value_contents (arg);
+ val = value_contents (arg);
/* 32-bit ABIs always start floating point arguments in an
even-numbered floating point register. Round the FP register
static enum return_value_convention
mips_o32_return_value (struct gdbarch *gdbarch, struct type *type,
struct regcache *regcache,
- void *readbuf, const void *writebuf)
+ gdb_byte *readbuf, const gdb_byte *writebuf)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
/* A struct that contains one or two floats. Each value is part
in the least significant part of their floating point
register.. */
- bfd_byte reg[MAX_REGISTER_SIZE];
+ gdb_byte reg[MAX_REGISTER_SIZE];
int regnum;
int field;
for (field = 0, regnum = mips_regnum (current_gdbarch)->fp0;
from first to last. */
for (argnum = 0; argnum < nargs; argnum++)
{
- char *val;
+ const gdb_byte *val;
struct value *arg = args[argnum];
struct type *arg_type = check_typedef (value_type (arg));
int len = TYPE_LENGTH (arg_type);
"mips_o64_push_dummy_call: %d len=%d type=%d",
argnum + 1, len, (int) typecode);
- val = (char *) value_contents (arg);
+ val = value_contents (arg);
/* 32-bit ABIs always start floating point arguments in an
even-numbered floating point register. Round the FP register
static enum return_value_convention
mips_o64_return_value (struct gdbarch *gdbarch,
struct type *type, struct regcache *regcache,
- void *readbuf, const void *writebuf)
+ gdb_byte *readbuf, const gdb_byte *writebuf)
{
return RETURN_VALUE_STRUCT_CONVENTION;
}
static void
mips_read_fp_register_single (struct frame_info *frame, int regno,
- char *rare_buffer)
+ gdb_byte *rare_buffer)
{
int raw_size = register_size (current_gdbarch, regno);
- char *raw_buffer = alloca (raw_size);
+ gdb_byte *raw_buffer = alloca (raw_size);
if (!frame_register_read (frame, regno, raw_buffer))
error (_("can't read register %d (%s)"), regno, REGISTER_NAME (regno));
static void
mips_read_fp_register_double (struct frame_info *frame, int regno,
- char *rare_buffer)
+ gdb_byte *rare_buffer)
{
int raw_size = register_size (current_gdbarch, regno);
mips_print_fp_register (struct ui_file *file, struct frame_info *frame,
int regnum)
{ /* do values for FP (float) regs */
- char *raw_buffer;
+ gdb_byte *raw_buffer;
double doub, flt1; /* doubles extracted from raw hex data */
int inv1, inv2;
- raw_buffer =
- (char *) alloca (2 *
- register_size (current_gdbarch,
- mips_regnum (current_gdbarch)->fp0));
+ raw_buffer = alloca (2 * register_size (current_gdbarch,
+ mips_regnum (current_gdbarch)->fp0));
fprintf_filtered (file, "%s:", REGISTER_NAME (regnum));
fprintf_filtered (file, "%*s", 4 - (int) strlen (REGISTER_NAME (regnum)),
int regnum, int all)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
- char raw_buffer[MAX_REGISTER_SIZE];
+ gdb_byte raw_buffer[MAX_REGISTER_SIZE];
int offset;
if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
/* do values for GP (int) regs */
- char raw_buffer[MAX_REGISTER_SIZE];
+ gdb_byte raw_buffer[MAX_REGISTER_SIZE];
int ncols = (mips_abi_regsize (gdbarch) == 8 ? 4 : 8); /* display cols per row */
int col, byte;
int regnum;
register_size (current_gdbarch,
regnum) - register_size (current_gdbarch, regnum);
byte < register_size (current_gdbarch, regnum); byte++)
- fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]);
+ fprintf_filtered (file, "%02x", raw_buffer[byte]);
else
for (byte = register_size (current_gdbarch, regnum) - 1;
byte >= 0; byte--)
- fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]);
+ fprintf_filtered (file, "%02x", raw_buffer[byte]);
fprintf_filtered (file, " ");
col++;
}
struct frame_info *frame)
{
CORE_ADDR pc = get_frame_pc (frame);
- char buf[MIPS_INSN32_SIZE];
+ gdb_byte buf[MIPS_INSN32_SIZE];
/* There is no branch delay slot on MIPS16. */
if (mips_pc_is_mips16 (pc))
return 0;
+ if (!breakpoint_here_p (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. */
(if necessary) to point to the actual memory location where the
breakpoint should be inserted. */
-static const unsigned char *
+static const gdb_byte *
mips_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
{
if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
{
if (mips_pc_is_mips16 (*pcptr))
{
- static unsigned char mips16_big_breakpoint[] = { 0xe8, 0xa5 };
+ static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 };
*pcptr = unmake_mips16_addr (*pcptr);
*lenptr = sizeof (mips16_big_breakpoint);
return mips16_big_breakpoint;
/* The IDT board uses an unusual breakpoint value, and
sometimes gets confused when it sees the usual MIPS
breakpoint instruction. */
- static unsigned char big_breakpoint[] = { 0, 0x5, 0, 0xd };
- static unsigned char pmon_big_breakpoint[] = { 0, 0, 0, 0xd };
- static unsigned char idt_big_breakpoint[] = { 0, 0, 0x0a, 0xd };
+ 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 };
*lenptr = sizeof (big_breakpoint);
{
if (mips_pc_is_mips16 (*pcptr))
{
- static unsigned char mips16_little_breakpoint[] = { 0xa5, 0xe8 };
+ static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 };
*pcptr = unmake_mips16_addr (*pcptr);
*lenptr = sizeof (mips16_little_breakpoint);
return mips16_little_breakpoint;
}
else
{
- static unsigned char little_breakpoint[] = { 0xd, 0, 0x5, 0 };
- static unsigned char pmon_little_breakpoint[] = { 0xd, 0, 0, 0 };
- static unsigned char idt_little_breakpoint[] = { 0xd, 0x0a, 0, 0 };
+ 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);
static CORE_ADDR
mips_integer_to_address (struct gdbarch *gdbarch,
- struct type *type, const bfd_byte *buf)
+ struct type *type, const gdb_byte *buf)
{
- char *tmp = alloca (TYPE_LENGTH (builtin_type_void_data_ptr));
+ gdb_byte *tmp = alloca (TYPE_LENGTH (builtin_type_void_data_ptr));
LONGEST val = unpack_long (type, buf);
store_signed_integer (tmp, TYPE_LENGTH (builtin_type_void_data_ptr), val);
return extract_signed_integer (tmp,
/* Print out which MIPS ABI is in use. */
static void
-show_mips_abi (char *ignore_args, int from_tty)
+show_mips_abi (struct ui_file *file,
+ int from_tty,
+ struct cmd_list_element *ignored_cmd,
+ const char *ignored_value)
{
if (gdbarch_bfd_arch_info (current_gdbarch)->arch != bfd_arch_mips)
- printf_filtered
- ("The MIPS ABI is unknown because the current architecture is not MIPS.\n");
+ fprintf_filtered
+ (file,
+ "The MIPS ABI is unknown because the current architecture "
+ "is not MIPS.\n");
else
{
enum mips_abi global_abi = global_mips_abi ();
const char *actual_abi_str = mips_abi_strings[actual_abi];
if (global_abi == MIPS_ABI_UNKNOWN)
- printf_filtered
- ("The MIPS ABI is set automatically (currently \"%s\").\n",
+ fprintf_filtered
+ (file,
+ "The MIPS ABI is set automatically (currently \"%s\").\n",
actual_abi_str);
else if (global_abi == actual_abi)
- printf_filtered
- ("The MIPS ABI is assumed to be \"%s\" (due to user setting).\n",
+ fprintf_filtered
+ (file,
+ "The MIPS ABI is assumed to be \"%s\" (due to user setting).\n",
actual_abi_str);
else
{
/* Probably shouldn't happen... */
- printf_filtered
- ("The (auto detected) MIPS ABI \"%s\" is in use even though the user setting was \"%s\".\n",
+ fprintf_filtered
+ (file,
+ "The (auto detected) MIPS ABI \"%s\" is in use even though the user setting was \"%s\".\n",
actual_abi_str, mips_abi_strings[global_abi]);
}
}
auto - Allow GDB to use the target's default setting or autodetect the\n\
saved GP register size from information contained in the\n\
executable (default)."),
+ NULL,
NULL, /* FIXME: i18n: Size of general purpose registers saved on the stack is %s. */
- NULL, NULL, &setmipscmdlist, &showmipscmdlist);
+ &setmipscmdlist, &showmipscmdlist);
/* Allow the user to override the argument stack size. */
add_setshow_enum_cmd ("stack-arg-size", class_obscure,
64 - Force GDB to allocate 64-bit chunks per argument\n\
auto - Allow GDB to determine the correct setting from the current\n\
target and executable (default)"),
+ NULL,
NULL, /* FIXME: i18n: The amount of stack space reserved for each argument is %s. */
- NULL, NULL, &setmipscmdlist, &showmipscmdlist);
+ &setmipscmdlist, &showmipscmdlist);
/* Allow the user to override the ABI. */
- c = add_set_enum_cmd
- ("abi", class_obscure, mips_abi_strings, &mips_abi_string,
- "Set the ABI used by this program.\n"
- "This option can be set to one of:\n"
- " auto - the default ABI associated with the current binary\n"
- " o32\n"
- " o64\n" " n32\n" " n64\n" " eabi32\n" " eabi64", &setmipscmdlist);
- set_cmd_sfunc (c, mips_abi_update);
- add_cmd ("abi", class_obscure, show_mips_abi,
- _("Show ABI in use by MIPS target"), &showmipscmdlist);
+ add_setshow_enum_cmd ("abi", class_obscure, mips_abi_strings,
+ &mips_abi_string, _("\
+Set the MIPS ABI used by this program."), _("\
+Show the MIPS ABI used by this program."), _("\
+This option can be set to one of:\n\
+ auto - the default ABI associated with the current binary\n\
+ o32\n\
+ o64\n\
+ n32\n\
+ n64\n\
+ eabi32\n\
+ eabi64"),
+ mips_abi_update,
+ show_mips_abi,
+ &setmipscmdlist, &showmipscmdlist);
/* Let the user turn off floating point and set the fence post for
heuristic_proc_start. */
If you are debugging a stripped executable, GDB needs to search through the\n\
program for the start of a function. This command sets the distance of the\n\
search. The only need to set it is when debugging a stripped executable."),
+ reinit_frame_cache_sfunc,
NULL, /* FIXME: i18n: The distance searched for the start of a function is %s. */
- reinit_frame_cache_sfunc, NULL,
&setlist, &showlist);
/* Allow the user to control whether the upper bits of 64-bit
Show zeroing of upper 32 bits of 64-bit addresses."), _("\
Use \"on\" to enable the masking, \"off\" to disable it and \"auto\" to \n\
allow GDB to determine the correct value."),
- NULL, /* FIXME: i18n: Zerroing of upper 32 bits of 64-bit address is %s. */
- NULL, show_mask_address, &setmipscmdlist, &showmipscmdlist);
+ NULL, show_mask_address,
+ &setmipscmdlist, &showmipscmdlist);
/* Allow the user to control the size of 32 bit registers within the
raw remote packet. */
Use \"on\" to enable backward compatibility with older MIPS 64 GDB+target\n\
that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
64 bits for others. Use \"off\" to disable compatibility mode"),
+ set_mips64_transfers_32bit_regs,
NULL, /* FIXME: i18n: Compatibility with 64-bit MIPS target that transfers 32-bit quantities is %s. */
- set_mips64_transfers_32bit_regs, NULL,
&setlist, &showlist);
/* Debug this files internals. */
Set mips debugging."), _("\
Show mips debugging."), _("\
When non-zero, mips specific debugging is enabled."),
+ NULL,
NULL, /* FIXME: i18n: Mips debugging is currently %s. */
- NULL, NULL,
&setdebuglist, &showdebuglist);
}