/* Target dependent code for CRIS, for GDB, the GNU debugger.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
- Free Software Foundation, Inc.
+ Copyright (C) 2001-2015 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"
-/* To get entry_point_address. */
#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. */
ARG1_REGNUM Contains the first parameter to a function.
ARG2_REGNUM Contains the second parameter to a function.
ARG3_REGNUM Contains the third parameter to a function.
- ARG4_REGNUM Contains the fourth parameter to a function. Rest on stack.
+ ARG4_REGNUM Contains the fourth parameter to a function. Rest on stack.
gdbarch_sp_regnum Contains address of top of stack.
gdbarch_pc_regnum Contains address of next instruction.
SRP_REGNUM Subroutine return pointer register.
MOF_REGNUM = 23,
SRP_REGNUM = 27,
- /* CRISv10 et. al. specific registers. */
+ /* CRISv10 et al. specific registers. */
P0_REGNUM = 16,
P4_REGNUM = 20,
CCR_REGNUM = 21,
/* 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;
static const char cris_mode_normal[] = "normal";
static const char cris_mode_guru[] = "guru";
-static const char *cris_modes[] = {
+static const char *const cris_modes[] = {
cris_mode_normal,
cris_mode_guru,
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;
-};
-
-/* Functions for accessing target dependent data. */
-
-static int
-cris_version (void)
-{
- return (gdbarch_tdep (current_gdbarch)->cris_version);
-}
-
-static const char *
-cris_mode (void)
-{
- return (gdbarch_tdep (current_gdbarch)->cris_mode);
-}
-
/* Sigtramp identification code copied from i386-linux-tdep.c. */
#define SIGTRAMP_INSN0 0x9c5f /* movu.w 0xXX, $r9 */
static CORE_ADDR
cris_sigcontext_addr (struct frame_info *this_frame)
{
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ 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 (get_frame_arch (this_frame)), buf);
- sp = extract_unsigned_integer (buf, 4);
+ get_frame_register (this_frame, gdbarch_sp_regnum (gdbarch), buf);
+ sp = extract_unsigned_integer (buf, 4, byte_order);
/* Look for normal sigtramp frame first. */
pc = cris_sigtramp_start (this_frame);
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct cris_unwind_cache *info;
- CORE_ADDR pc;
- CORE_ADDR sp;
CORE_ADDR addr;
- char buf[4];
+ gdb_byte buf[4];
int i;
if ((*this_cache))
- return (*this_cache);
+ return (struct cris_unwind_cache *) (*this_cache);
info = FRAME_OBSTACK_ZALLOC (struct cris_unwind_cache);
(*this_cache) = info;
info->leaf_function = 0;
get_frame_register (this_frame, gdbarch_sp_regnum (gdbarch), buf);
- info->base = extract_unsigned_integer (buf, 4);
+ info->base = extract_unsigned_integer (buf, 4, byte_order);
addr = cris_sigcontext_addr (this_frame);
/* FIXME: If ERP is in a delay slot at this point then the PC will
be wrong at this point. This problem manifests itself in the
sigaltstack.exp test case, which occasionally generates FAILs when
- the signal is received while in a delay slot.
+ the signal is received while in a delay slot.
This could be solved by a couple of read_memory_unsigned_integer and a
trad_frame_set_value. */
static const struct frame_unwind cris_sigtramp_frame_unwind =
{
SIGTRAMP_FRAME,
+ default_frame_unwind_stop_reason,
cris_sigtramp_frame_this_id,
cris_sigtramp_frame_prev_register,
NULL,
cris_sigtramp_frame_sniffer
};
-int
+static int
crisv32_single_step_through_delay (struct gdbarch *gdbarch,
struct frame_info *this_frame)
{
ULONGEST erp;
int ret = 0;
- if (cris_mode () == cris_mode_guru)
+ if (tdep->cris_mode == cris_mode_guru)
erp = get_frame_register_unsigned (this_frame, NRP_REGNUM);
else
erp = get_frame_register_unsigned (this_frame, ERP_REGNUM);
{
/* In delay slot - check if there's a breakpoint at the preceding
instruction. */
- if (breakpoint_here_p (erp & ~0x1))
+ if (breakpoint_here_p (get_frame_address_space (this_frame), erp & ~0x1))
ret = 1;
}
return ret;
}
-/* Hardware watchpoint support. */
-
-/* We support 6 hardware data watchpoints, but cannot trigger on execute
- (any combination of read/write is fine). */
-
-int
-cris_can_use_hardware_watchpoint (int type, int count, int other)
-{
- struct gdbarch_tdep *tdep = gdbarch_tdep (target_gdbarch);
-
- /* No bookkeeping is done here; it is handled by the remote debug agent. */
-
- if (tdep->cris_version != 32)
- return 0;
- else
- /* CRISv32: Six data watchpoints, one for instructions. */
- return (((type == bp_read_watchpoint || type == bp_access_watchpoint
- || type == bp_hardware_watchpoint) && count <= 6)
- || (type == bp_hardware_breakpoint && count <= 1));
-}
-
-/* The CRISv32 hardware data watchpoints work by specifying ranges,
- which have no alignment or length restrictions. */
-
-int
-cris_region_ok_for_watchpoint (CORE_ADDR addr, int len)
-{
- return 1;
-}
-
-/* If the inferior has some watchpoint that triggered, return the
- address associated with that watchpoint. Otherwise, return
- zero. */
-
-CORE_ADDR
-cris_stopped_data_address (void)
-{
- CORE_ADDR eda;
- eda = get_frame_register_unsigned (get_current_frame (), EDA_REGNUM);
- return eda;
-}
-
/* The instruction environment needed to find single-step breakpoints. */
typedef
int delay_slot_pc_active;
int xflag_found;
int disable_interrupt;
+ int byte_order;
} inst_env_type;
/* Machine-dependencies in CRIS for opcodes. */
struct frame_info *next_frame);
/* When arguments must be pushed onto the stack, they go on in reverse
- order. The below implements a FILO (stack) to do this.
+ order. The below implements a FILO (stack) to do this.
Copied from d10v-tdep.c. */
struct stack_item
};
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));
+ struct stack_item *si = XNEW (struct stack_item);
si->data = xmalloc (len);
si->len = len;
si->prev = prev;
in the stack frame. sp is even more special: the address we return
for it IS the sp for the next frame. */
-struct cris_unwind_cache *
+static struct cris_unwind_cache *
cris_frame_unwind_cache (struct frame_info *this_frame,
void **this_prologue_cache)
{
- CORE_ADDR pc;
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
struct cris_unwind_cache *info;
- int i;
if ((*this_prologue_cache))
- return (*this_prologue_cache);
+ return (struct cris_unwind_cache *) (*this_prologue_cache);
info = FRAME_OBSTACK_ZALLOC (struct cris_unwind_cache);
(*this_prologue_cache) = info;
info->leaf_function = 0;
/* Prologue analysis does the rest... */
- if (cris_version () == 32)
+ if (tdep->cris_version == 32)
crisv32_scan_prologue (get_frame_func (this_frame), this_frame, info);
else
cris_scan_prologue (get_frame_func (this_frame), this_frame, info);
int nargs, struct value **args, CORE_ADDR sp,
int struct_return, CORE_ADDR struct_addr)
{
- int stack_alloc;
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int stack_offset;
int argreg;
int argnum;
- CORE_ADDR regval;
-
/* The function's arguments and memory allocated by gdb for the arguments to
point at reside in separate areas on the stack.
Both frame pointers grow toward higher addresses. */
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);
else
{
gdb_byte buf[4];
- store_unsigned_integer (buf, 4, sp);
+ store_unsigned_integer (buf, 4, byte_order, sp);
si = push_stack_item (si, buf, 4);
}
}
static const struct frame_unwind cris_frame_unwind =
{
NORMAL_FRAME,
+ default_frame_unwind_stop_reason,
cris_frame_this_id,
cris_frame_prev_register,
NULL,
the subq-instruction will be present with X as the number of bytes
needed for storage. The reshuffle with respect to r8 may be performed
with any size S (b, w, d) and any of the general registers Z={0..13}.
- The offset U should be representable by a signed 8-bit value in all cases.
+ The offset U should be representable by a signed 8-bit value in all cases.
Thus, the prefix word is assumed to be immediate byte offset mode followed
by another word containing the instruction.
move.d r13,rV ; P3
move.S [r8+U],rZ ; P4
- if any of the call parameters are stored. The host expects these
+ if any of the call parameters are stored. The host expects these
instructions to be executed in order to get the call parameters right. */
/* Examine the prologue of a function. The variable ip is the address of
struct cris_unwind_cache *info)
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
/* Present instruction. */
unsigned short insn;
/* Find the prologue instructions. */
while (pc > 0 && pc < limit)
{
- insn = read_memory_unsigned_integer (pc, 2);
+ insn = read_memory_unsigned_integer (pc, 2, byte_order);
pc += 2;
if (insn == 0xE1FC)
{
- /* push <reg> 32 bit instruction */
- insn_next = read_memory_unsigned_integer (pc, 2);
+ /* push <reg> 32 bit instruction. */
+ insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
pc += 2;
regno = cris_get_operand2 (insn_next);
if (info)
{
info->sp_offset += -cris_get_signed_offset (insn);
}
- insn_next = read_memory_unsigned_integer (pc, 2);
+ insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
pc += 2;
if (cris_get_mode (insn_next) == PREFIX_ASSIGN_MODE
&& cris_get_opcode (insn_next) == 0x000F
&& (cris_get_signed_offset (insn) < 0))
{
/* move.S rZ,[r8-U] (?) */
- insn_next = read_memory_unsigned_integer (pc, 2);
+ insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
pc += 2;
regno = cris_get_operand2 (insn_next);
if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch))
&& (cris_get_signed_offset (insn) > 0))
{
/* move.S [r8+U],rZ (?) */
- insn_next = read_memory_unsigned_integer (pc, 2);
+ insn_next = read_memory_unsigned_integer (pc, 2, byte_order);
pc += 2;
regno = cris_get_operand2 (insn_next);
if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch))
static CORE_ADDR
cris_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
CORE_ADDR func_addr, func_end;
struct symtab_and_line sal;
CORE_ADDR pc_after_prologue;
return sal.end;
}
- if (cris_version () == 32)
+ if (tdep->cris_version == 32)
pc_after_prologue = crisv32_scan_prologue (pc, NULL, NULL);
else
pc_after_prologue = cris_scan_prologue (pc, NULL, NULL);
the breakpoint should be inserted. */
static const unsigned char *
-cris_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr, int *lenptr)
+cris_breakpoint_from_pc (struct gdbarch *gdbarch,
+ CORE_ADDR *pcptr, int *lenptr)
{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
static unsigned char break8_insn[] = {0x38, 0xe9};
static unsigned char break15_insn[] = {0x3f, 0xe9};
*lenptr = 2;
- if (cris_mode () == cris_mode_guru)
+ if (tdep->cris_mode == cris_mode_guru)
return break15_insn;
else
return break8_insn;
0 otherwise. */
static int
-cris_spec_reg_applicable (struct cris_spec_reg spec_reg)
+cris_spec_reg_applicable (struct gdbarch *gdbarch,
+ struct cris_spec_reg spec_reg)
{
- int version = cris_version ();
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ unsigned int version = tdep->cris_version;
switch (spec_reg.applicable_version)
{
for (i = 0; cris_spec_regs[i].name != NULL; i++)
{
if (cris_spec_regs[i].number == spec_regno
- && cris_spec_reg_applicable (cris_spec_regs[i]))
+ && cris_spec_reg_applicable (gdbarch, cris_spec_regs[i]))
/* Go with the first applicable register. */
return cris_spec_regs[i].reg_size;
}
/* There are three kinds of registers we refuse to write to.
1. Those that not implemented.
2. Those that are read-only (depends on the processor mode).
- 3. Those registers to which a write has no effect.
- */
+ 3. Those registers to which a write has no effect. */
if (regno < 0
|| regno >= gdbarch_num_regs (gdbarch)
/* There are three kinds of registers we refuse to write to.
1. Those that not implemented.
2. Those that are read-only (depends on the processor mode).
- 3. Those registers to which a write has no effect.
- */
+ 3. Those registers to which a write has no effect. */
if (regno < 0
|| regno >= gdbarch_num_regs (gdbarch)
cris_register_type (struct gdbarch *gdbarch, int regno)
{
if (regno == gdbarch_pc_regnum (gdbarch))
- return builtin_type_void_func_ptr;
+ return builtin_type (gdbarch)->builtin_func_ptr;
else if (regno == gdbarch_sp_regnum (gdbarch)
|| regno == CRIS_FP_REGNUM)
- return builtin_type_void_data_ptr;
+ return builtin_type (gdbarch)->builtin_data_ptr;
else if ((regno >= 0 && regno < gdbarch_sp_regnum (gdbarch))
|| (regno >= MOF_REGNUM && regno <= USP_REGNUM))
/* Note: R8 taken care of previous clause. */
- return builtin_type_uint32;
+ return builtin_type (gdbarch)->builtin_uint32;
else if (regno >= P4_REGNUM && regno <= CCR_REGNUM)
- return builtin_type_uint16;
+ return builtin_type (gdbarch)->builtin_uint16;
else if (regno >= P0_REGNUM && regno <= VR_REGNUM)
- return builtin_type_uint8;
+ return builtin_type (gdbarch)->builtin_uint8;
else
/* Invalid (unimplemented) register. */
- return builtin_type_int0;
+ return builtin_type (gdbarch)->builtin_int0;
}
static struct type *
crisv32_register_type (struct gdbarch *gdbarch, int regno)
{
if (regno == gdbarch_pc_regnum (gdbarch))
- return builtin_type_void_func_ptr;
+ return builtin_type (gdbarch)->builtin_func_ptr;
else if (regno == gdbarch_sp_regnum (gdbarch)
|| regno == CRIS_FP_REGNUM)
- return builtin_type_void_data_ptr;
+ return builtin_type (gdbarch)->builtin_data_ptr;
else if ((regno >= 0 && regno <= ACR_REGNUM)
|| (regno >= EXS_REGNUM && regno <= SPC_REGNUM)
|| (regno == PID_REGNUM)
|| (regno >= S0_REGNUM && regno <= S15_REGNUM))
/* Note: R8 and SP taken care of by previous clause. */
- return builtin_type_uint32;
+ return builtin_type (gdbarch)->builtin_uint32;
else if (regno == WZ_REGNUM)
- return builtin_type_uint16;
+ return builtin_type (gdbarch)->builtin_uint16;
else if (regno == BZ_REGNUM || regno == VR_REGNUM || regno == SRS_REGNUM)
- return builtin_type_uint8;
+ return builtin_type (gdbarch)->builtin_uint8;
else
{
/* Invalid (unimplemented) register. Should not happen as there are
no unimplemented CRISv32 registers. */
warning (_("crisv32_register_type: unknown regno %d"), regno);
- return builtin_type_int0;
+ return builtin_type (gdbarch)->builtin_int0;
}
}
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 (len <= 4)
{
/* Put the return value in R10. */
- val = extract_unsigned_integer (valbuf, len);
+ val = extract_unsigned_integer (valbuf, len, byte_order);
regcache_cooked_write_unsigned (regcache, ARG1_REGNUM, val);
}
else if (len <= 8)
{
/* Put the return value in R10 and R11. */
- val = extract_unsigned_integer (valbuf, 4);
+ val = extract_unsigned_integer (valbuf, 4, byte_order);
regcache_cooked_write_unsigned (regcache, ARG1_REGNUM, val);
- val = extract_unsigned_integer ((char *)valbuf + 4, len - 4);
+ val = extract_unsigned_integer (valbuf + 4, len - 4, byte_order);
regcache_cooked_write_unsigned (regcache, ARG2_REGNUM, val);
}
else
error (_("cris_store_return_value: type length too large."));
}
-/* Return the name of register regno as a string. Return NULL for an invalid or
- unimplemented register. */
+/* Return the name of register regno as a string. Return NULL for an
+ invalid or unimplemented register. */
static const char *
-cris_special_register_name (int regno)
+cris_special_register_name (struct gdbarch *gdbarch, int regno)
{
int spec_regno;
int i;
for (i = 0; cris_spec_regs[i].name != NULL; i++)
{
if (cris_spec_regs[i].number == spec_regno
- && cris_spec_reg_applicable (cris_spec_regs[i]))
+ && cris_spec_reg_applicable (gdbarch, cris_spec_regs[i]))
/* Go with the first applicable register. */
return cris_spec_regs[i].name;
}
}
else if (regno >= NUM_GENREGS && regno < gdbarch_num_regs (gdbarch))
{
- return cris_special_register_name (regno);
+ return cris_special_register_name (gdbarch, regno);
}
else
{
}
else if (regno >= NUM_GENREGS && regno < (NUM_GENREGS + NUM_SPECREGS))
{
- return cris_special_register_name (regno);
+ return cris_special_register_name (gdbarch, regno);
}
else if (regno == gdbarch_pc_regnum (gdbarch))
{
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);
{
/* Get the return value from R10. */
regcache_cooked_read_unsigned (regcache, ARG1_REGNUM, &val);
- store_unsigned_integer (valbuf, len, val);
+ store_unsigned_integer (valbuf, len, byte_order, val);
}
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, val);
+ store_unsigned_integer (valbuf, 4, byte_order, val);
regcache_cooked_read_unsigned (regcache, ARG2_REGNUM, &val);
- store_unsigned_integer ((char *)valbuf + 4, len - 4, val);
+ store_unsigned_integer (valbuf + 4, len - 4, byte_order, val);
}
else
error (_("cris_extract_return_value: type length too large"));
/* Handle the CRIS return value convention. */
static enum return_value_convention
-cris_return_value (struct gdbarch *gdbarch, struct type *func_type,
+cris_return_value (struct gdbarch *gdbarch, struct value *function,
struct type *type, struct regcache *regcache,
gdb_byte *readbuf, const gdb_byte *writebuf)
{
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)
int offset;
unsigned short insn;
struct gdbarch *gdbarch = get_frame_arch (frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
/* Create a local register image and set the initial state. */
for (i = 0; i < NUM_GENREGS; i++)
inst_env->invalid = 0;
inst_env->xflag_found = 0;
inst_env->disable_interrupt = 0;
+ inst_env->byte_order = byte_order;
/* Look for a step target. */
do
{
/* Read an instruction from the client. */
insn = read_memory_unsigned_integer
- (inst_env->reg[gdbarch_pc_regnum (gdbarch)], 2);
+ (inst_env->reg[gdbarch_pc_regnum (gdbarch)], 2, byte_order);
/* If the instruction is not in a delay slot the new content of the
PC is [PC] + 2. If the instruction is in a delay slot it is not
}
/* There is no hardware single-step support. The function find_step_target
- digs through the opcodes in order to find all possible targets.
+ digs through the opcodes in order to find all possible targets.
Either one ordinary target or two targets for branches may be found. */
static int
cris_software_single_step (struct frame_info *frame)
{
+ struct gdbarch *gdbarch = get_frame_arch (frame);
+ struct address_space *aspace = get_frame_address_space (frame);
inst_env_type inst_env;
/* Analyse the present instruction environment and insert
{
/* Insert at most two breakpoints. One for the next PC content
and possibly another one for a branch, jump, etc. */
- CORE_ADDR next_pc =
- (CORE_ADDR) inst_env.reg[gdbarch_pc_regnum (get_frame_arch (frame))];
- insert_single_step_breakpoint (next_pc);
+ CORE_ADDR next_pc
+ = (CORE_ADDR) inst_env.reg[gdbarch_pc_regnum (gdbarch)];
+ insert_single_step_breakpoint (gdbarch, aspace, next_pc);
if (inst_env.branch_found
&& (CORE_ADDR) inst_env.branch_break_address != next_pc)
{
CORE_ADDR branch_target_address
= (CORE_ADDR) inst_env.branch_break_address;
- insert_single_step_breakpoint (branch_target_address);
+ insert_single_step_breakpoint (gdbarch,
+ aspace, branch_target_address);
}
}
/* Just a forward declaration. */
static unsigned long get_data_from_address (unsigned short *inst,
- CORE_ADDR address);
+ CORE_ADDR address,
+ enum bfd_endian byte_order);
/* Calculates the prefix value for the general case of offset addressing
mode. */
static void
bdap_prefix (unsigned short inst, inst_env_type *inst_env)
{
-
- long offset;
-
/* It's invalid to be in a delay slot. */
if (inst_env->slot_needed || inst_env->prefix_found)
{
/* The offset is an indirection of the contents of the operand1 register. */
inst_env->prefix_value +=
- get_data_from_address (&inst, inst_env->reg[cris_get_operand1 (inst)]);
+ get_data_from_address (&inst, inst_env->reg[cris_get_operand1 (inst)],
+ inst_env->byte_order);
if (cris_get_mode (inst) == AUTOINC_MODE)
{
/* The prefix value is one dereference of the contents of the operand1
register. */
address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)];
- inst_env->prefix_value = read_memory_unsigned_integer (address, 4);
+ inst_env->prefix_value
+ = read_memory_unsigned_integer (address, 4, inst_env->byte_order);
/* Check if the mode is autoincrement. */
if (cris_get_mode (inst) == AUTOINC_MODE)
}
/* We have a branch, find out the offset for the branch. */
- offset = read_memory_integer (inst_env->reg[REG_PC], 2);
+ offset = read_memory_integer (inst_env->reg[REG_PC], 2,
+ inst_env->byte_order);
/* The instruction is one word longer than normal, so add one word
to the PC. */
return;
}
/* Get the number of bits to shift. */
- shift_steps = cris_get_asr_shift_steps (inst_env->reg[cris_get_operand1 (inst)]);
+ shift_steps
+ = cris_get_asr_shift_steps (inst_env->reg[cris_get_operand1 (inst)]);
value = inst_env->reg[REG_PC];
/* Find out how many bits the operation should apply to. */
return;
}
/* The shift size is given as a 5 bit quick value, i.e. we don't
- want the the sign bit of the quick value. */
+ want the sign bit of the quick value. */
shift_steps = cris_get_asr_shift_steps (inst);
value = inst_env->reg[REG_PC];
if (value & SIGNED_DWORD_MASK)
{
check_assign (inst, inst_env);
- /* Get the new value for the the PC. */
+ /* Get the new value for the PC. */
newpc =
read_memory_unsigned_integer ((CORE_ADDR) inst_env->prefix_value,
- 4);
+ 4, inst_env->byte_order);
}
else
{
/* Get the new value for the PC. */
address = (CORE_ADDR) inst_env->reg[cris_get_operand1 (inst)];
- newpc = read_memory_unsigned_integer (address, 4);
+ newpc = read_memory_unsigned_integer (address,
+ 4, inst_env->byte_order);
/* Check if we should increment a register. */
if (cris_get_mode (inst) == AUTOINC_MODE)
if (cris_get_operand2 (inst) >= REG_PC)
{
inst_env->reg[REG_PC] =
- read_memory_unsigned_integer (inst_env->prefix_value, 4);
+ read_memory_unsigned_integer (inst_env->prefix_value,
+ 4, inst_env->byte_order);
}
/* The assign value is the value after the increment. Normally, the
assign value is the value before the increment. */
}
inst_env->reg[REG_PC] =
read_memory_unsigned_integer (inst_env->reg[cris_get_operand1 (inst)],
- 4);
+ 4, inst_env->byte_order);
}
/* The increment is not depending on the size, instead it's depending
on the number of registers loaded from memory. */
- if ((cris_get_operand1 (inst) == REG_PC) && (cris_get_mode (inst) == AUTOINC_MODE))
+ if ((cris_get_operand1 (inst) == REG_PC)
+ && (cris_get_mode (inst) == AUTOINC_MODE))
{
/* It's invalid to change the PC in a delay slot. */
if (inst_env->slot_needed)
{
/* The assign value is the value after the increment. Normally, the
assign value is the value before the increment. */
- if ((cris_get_operand1 (inst) == REG_PC) &&
- (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
+ if ((cris_get_operand1 (inst) == REG_PC)
+ && (cris_get_mode (inst) == PREFIX_ASSIGN_MODE))
{
/* The prefix handles the problem if we are in a delay slot. */
inst_env->reg[REG_PC] = inst_env->prefix_value;
{
/* The increment is not depending on the size, instead it's depending
on the number of registers loaded to memory. */
- if ((cris_get_operand1 (inst) == REG_PC) && (cris_get_mode (inst) == AUTOINC_MODE))
+ if ((cris_get_operand1 (inst) == REG_PC)
+ && (cris_get_mode (inst) == AUTOINC_MODE))
{
/* It's invalid to change the PC in a delay slot. */
if (inst_env->slot_needed)
inst_env->disable_interrupt = 0;
}
-/* Calculate the result of the instruction for ADD, SUB, CMP AND, OR and MOVE.
+/* Calculate the result of the instruction for ADD, SUB, CMP AND, OR and MOVE.
The MOVE instruction is the move from source to register. */
static void
extend instruction, the size field is changed in instruction. */
static unsigned long
-get_data_from_address (unsigned short *inst, CORE_ADDR address)
+get_data_from_address (unsigned short *inst, CORE_ADDR address,
+ enum bfd_endian byte_order)
{
int size = cris_get_size (*inst);
unsigned long value;
/* Is there a need for checking the size? Size should contain the number of
bytes to read. */
size = 1 << size;
- value = read_memory_unsigned_integer (address, size);
+ value = read_memory_unsigned_integer (address, size, byte_order);
/* Check if it's an extend, signed or zero instruction. */
if (cris_get_opcode (*inst) < 4)
operand2 = inst_env->reg[REG_PC];
/* Get the value of the third operand. */
- operand3 = get_data_from_address (&inst, inst_env->prefix_value);
+ operand3 = get_data_from_address (&inst, inst_env->prefix_value,
+ inst_env->byte_order);
/* Calculate the PC value after the instruction, i.e. where the
breakpoint should be. The order of the udw_operands is vital. */
operand2 = inst_env->reg[cris_get_operand2 (inst)];
/* Get the value of the third operand. */
- operand3 = get_data_from_address (&inst, inst_env->prefix_value);
+ operand3 = get_data_from_address (&inst, inst_env->prefix_value,
+ inst_env->byte_order);
/* Calculate the PC value after the instruction, i.e. where the
breakpoint should be. */
unsigned long operand3;
int size;
- /* The instruction is either an indirect or autoincrement addressing mode.
+ /* The instruction is either an indirect or autoincrement addressing mode.
Check if the destination register is the PC. */
if (cris_get_operand2 (inst) == REG_PC)
{
/* Get the value of the third operand, i.e. the indirect operand. */
operand1 = inst_env->reg[cris_get_operand1 (inst)];
- operand3 = get_data_from_address (&inst, operand1);
+ operand3 = get_data_from_address (&inst, operand1, inst_env->byte_order);
/* Calculate the PC value after the instruction, i.e. where the
breakpoint should be. The order of the udw_operands is vital. */
}
/* If this is an autoincrement addressing mode, check if the increment
changes the PC. */
- if ((cris_get_operand1 (inst) == REG_PC) && (cris_get_mode (inst) == AUTOINC_MODE))
+ if ((cris_get_operand1 (inst) == REG_PC)
+ && (cris_get_mode (inst) == AUTOINC_MODE))
{
/* Get the size field. */
size = cris_get_size (inst);
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,
_("Show the usage of Dwarf-2 CFI for CRIS."),
_("Set this to \"off\" if using gcc-cris < R59."),
set_cris_dwarf2_cfi,
- NULL, /* FIXME: i18n: Usage of Dwarf-2 CFI for CRIS is %d. */
+ NULL, /* FIXME: i18n: Usage of Dwarf-2 CFI
+ for CRIS is %d. */
&setlist, &showlist);
deprecated_add_core_fns (&cris_elf_core_fns);
{
struct gdbarch *gdbarch;
struct gdbarch_tdep *tdep;
- int cris_version;
+ unsigned int cris_version;
if (usr_cmd_cris_version_valid)
{
}
/* No matching architecture was found. Create a new one. */
- tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+ tdep = XNEW (struct gdbarch_tdep);
gdbarch = gdbarch_alloc (&info, tdep);
tdep->cris_version = usr_cmd_cris_version;
break;
case BFD_ENDIAN_BIG:
- internal_error (__FILE__, __LINE__, _("cris_gdbarch_init: big endian byte order in info"));
+ internal_error (__FILE__, __LINE__,
+ _("cris_gdbarch_init: big endian byte order in info"));
break;
default:
- internal_error (__FILE__, __LINE__, _("cris_gdbarch_init: unknown byte order in info"));
+ internal_error (__FILE__, __LINE__,
+ _("cris_gdbarch_init: unknown byte order in info"));
}
set_gdbarch_return_value (gdbarch, cris_return_value);
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? */