/* Target dependent code for CRIS, for GDB, the GNU debugger.
- Copyright (C) 2001-2012 Free Software Foundation, Inc.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
Contributed by Axis Communications AB.
Written by Hendrik Ruijter, Stefan Andersson, and Orjan Friberg.
#include "target.h"
#include "value.h"
#include "opcode/cris.h"
+#include "osabi.h"
#include "arch-utils.h"
#include "regcache.h"
-#include "gdb_assert.h"
#include "objfiles.h"
#include "solib.h" /* Support for shared libraries. */
#include "solib-svr4.h"
-#include "gdb_string.h"
#include "dis-asm.h"
+#include "cris-tdep.h"
+
enum cris_num_regs
{
/* There are no floating point registers. Used in gdbserver low-linux.c. */
/* CRIS version, set via the user command 'set cris-version'. Affects
register names and sizes. */
-static int usr_cmd_cris_version;
+static unsigned int usr_cmd_cris_version;
/* Indicates whether to trust the above variable. */
static int usr_cmd_cris_version_valid = 0;
/* Whether to make use of Dwarf-2 CFI (default on). */
static int usr_cmd_cris_dwarf2_cfi = 1;
-/* CRIS architecture specific information. */
-struct gdbarch_tdep
-{
- int cris_version;
- const char *cris_mode;
- int cris_dwarf2_cfi;
-};
-
/* Sigtramp identification code copied from i386-linux-tdep.c. */
#define SIGTRAMP_INSN0 0x9c5f /* movu.w 0xXX, $r9 */
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR pc;
CORE_ADDR sp;
- char buf[4];
+ gdb_byte buf[4];
get_frame_register (this_frame, gdbarch_sp_regnum (gdbarch), buf);
sp = extract_unsigned_integer (buf, 4, byte_order);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct cris_unwind_cache *info;
CORE_ADDR addr;
- char buf[4];
+ gdb_byte buf[4];
int i;
if ((*this_cache))
};
static struct stack_item *
-push_stack_item (struct stack_item *prev, void *contents, int len)
+push_stack_item (struct stack_item *prev, const gdb_byte *contents, int len)
{
struct stack_item *si;
si = xmalloc (sizeof (struct stack_item));
for (argnum = 0; argnum < nargs; argnum++)
{
int len;
- char *val;
+ const gdb_byte *val;
int reg_demand;
int i;
len = TYPE_LENGTH (value_type (args[argnum]));
- val = (char *) value_contents (args[argnum]);
+ val = value_contents (args[argnum]);
/* How may registers worth of storage do we need for this argument? */
reg_demand = (len / 4) + (len % 4 != 0 ? 1 : 0);
struct cris_spec_reg spec_reg)
{
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
- int version = tdep->cris_version;
+ unsigned int version = tdep->cris_version;
switch (spec_reg.applicable_version)
{
static void
cris_store_return_value (struct type *type, struct regcache *regcache,
- const void *valbuf)
+ const gdb_byte *valbuf)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST val;
+ int len = TYPE_LENGTH (type);
- if (TYPE_LENGTH (type) <= 4)
+ if (len <= 4)
{
/* Put the return value in R10. */
- val = extract_unsigned_integer (valbuf, TYPE_LENGTH (type), byte_order);
+ val = extract_unsigned_integer (valbuf, len, byte_order);
regcache_cooked_write_unsigned (regcache, ARG1_REGNUM, val);
}
- else if (TYPE_LENGTH (type) <= 8)
+ else if (len <= 8)
{
/* Put the return value in R10 and R11. */
val = extract_unsigned_integer (valbuf, 4, byte_order);
regcache_cooked_write_unsigned (regcache, ARG1_REGNUM, val);
- val = extract_unsigned_integer ((char *)valbuf + 4,
- TYPE_LENGTH (type) - 4, byte_order);
+ val = extract_unsigned_integer (valbuf + 4, len - 4, byte_order);
regcache_cooked_write_unsigned (regcache, ARG2_REGNUM, val);
}
else
static void
cris_extract_return_value (struct type *type, struct regcache *regcache,
- void *valbuf)
+ gdb_byte *valbuf)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST val;
+ int len = TYPE_LENGTH (type);
- if (TYPE_LENGTH (type) <= 4)
+ if (len <= 4)
{
/* Get the return value from R10. */
regcache_cooked_read_unsigned (regcache, ARG1_REGNUM, &val);
- store_unsigned_integer (valbuf, TYPE_LENGTH (type), byte_order, val);
+ store_unsigned_integer (valbuf, len, byte_order, val);
}
- else if (TYPE_LENGTH (type) <= 8)
+ else if (len <= 8)
{
/* Get the return value from R10 and R11. */
regcache_cooked_read_unsigned (regcache, ARG1_REGNUM, &val);
store_unsigned_integer (valbuf, 4, byte_order, val);
regcache_cooked_read_unsigned (regcache, ARG2_REGNUM, &val);
- store_unsigned_integer ((char *)valbuf + 4, TYPE_LENGTH (type) - 4,
- byte_order, val);
+ store_unsigned_integer (valbuf + 4, len - 4, byte_order, val);
}
else
error (_("cris_extract_return_value: type length too large"));
instruction. It stems from cris_constraint, found in cris-dis.c. */
static int
-constraint (unsigned int insn, const signed char *inst_args,
+constraint (unsigned int insn, const char *inst_args,
inst_env_type *inst_env)
{
int retval = 0;
int tmp, i;
- const char *s = inst_args;
+ const gdb_byte *s = (const gdb_byte *) inst_args;
for (; *s; s++)
switch (*s)
return print_insn (addr, info);
}
-/* Copied from <asm/elf.h>. */
-typedef unsigned long elf_greg_t;
+/* Originally from <asm/elf.h>. */
+typedef unsigned char cris_elf_greg_t[4];
/* Same as user_regs_struct struct in <asm/user.h>. */
#define CRISV10_ELF_NGREG 35
-typedef elf_greg_t elf_gregset_t[CRISV10_ELF_NGREG];
+typedef cris_elf_greg_t cris_elf_gregset_t[CRISV10_ELF_NGREG];
#define CRISV32_ELF_NGREG 32
-typedef elf_greg_t crisv32_elf_gregset_t[CRISV32_ELF_NGREG];
+typedef cris_elf_greg_t crisv32_elf_gregset_t[CRISV32_ELF_NGREG];
-/* Unpack an elf_gregset_t into GDB's register cache. */
+/* Unpack a cris_elf_gregset_t into GDB's register cache. */
static void
-cris_supply_gregset (struct regcache *regcache, elf_gregset_t *gregsetp)
+cris_supply_gregset (struct regcache *regcache, cris_elf_gregset_t *gregsetp)
{
struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
int i;
- elf_greg_t *regp = *gregsetp;
- static char zerobuf[4] = {0};
+ cris_elf_greg_t *regp = *gregsetp;
/* The kernel dumps all 32 registers as unsigned longs, but supply_register
knows about the actual size of each register so that's no problem. */
char *core_reg_sect, unsigned core_reg_size,
int which, CORE_ADDR reg_addr)
{
- elf_gregset_t gregset;
+ cris_elf_gregset_t gregset;
switch (which)
{
case 0:
- if (core_reg_size != sizeof (elf_gregset_t)
+ if (core_reg_size != sizeof (cris_elf_gregset_t)
&& core_reg_size != sizeof (crisv32_elf_gregset_t))
{
warning (_("wrong size gregset struct in core file"));
void
_initialize_cris_tdep (void)
{
- static struct cmd_list_element *cris_set_cmdlist;
- static struct cmd_list_element *cris_show_cmdlist;
-
struct cmd_list_element *c;
gdbarch_register (bfd_arch_cris, cris_gdbarch_init, cris_dump_tdep);
/* CRIS-specific user-commands. */
- add_setshow_uinteger_cmd ("cris-version", class_support,
- &usr_cmd_cris_version,
- _("Set the current CRIS version."),
- _("Show the current CRIS version."),
- _("\
+ add_setshow_zuinteger_cmd ("cris-version", class_support,
+ &usr_cmd_cris_version,
+ _("Set the current CRIS version."),
+ _("Show the current CRIS version."),
+ _("\
Set to 10 for CRISv10 or 32 for CRISv32 if autodetection fails.\n\
Defaults to 10. "),
- set_cris_version,
- NULL, /* FIXME: i18n: Current CRIS version
- is %s. */
- &setlist, &showlist);
+ set_cris_version,
+ NULL, /* FIXME: i18n: Current CRIS version
+ is %s. */
+ &setlist, &showlist);
add_setshow_enum_cmd ("cris-mode", class_support,
cris_modes, &usr_cmd_cris_mode,
{
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
- int cris_version;
+ unsigned int cris_version;
if (usr_cmd_cris_version_valid)
{
frame_unwind_append_unwinder (gdbarch, &cris_frame_unwind);
frame_base_set_default (gdbarch, &cris_frame_base);
- set_solib_svr4_fetch_link_map_offsets
- (gdbarch, svr4_ilp32_fetch_link_map_offsets);
-
+ /* Hook in ABI-specific overrides, if they have been registered. */
+ gdbarch_init_osabi (info, gdbarch);
+
/* FIXME: cagney/2003-08-27: It should be possible to select a CRIS
disassembler, even when there is no BFD. Does something like
"gdb; target remote; disassmeble *0x123" work? */