/* Target-dependent code for the Xtensa port of GDB, the GNU debugger.
- Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009
+ Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GDB.
#include "regset.h"
#include "dummy-frame.h"
-#include "elf/dwarf2.h"
+#include "dwarf2.h"
#include "dwarf2-frame.h"
#include "dwarf2loc.h"
#include "frame.h"
#define PS_WOE (1<<18)
#define PS_EXC (1<<4)
-/* Convert a live A-register number to the corresponding AR-register number. */
+/* Convert a live A-register number to the corresponding AR-register
+ number. */
static int
arreg_number (struct gdbarch *gdbarch, int a_regnum, ULONGEST wb)
{
static int
extract_call_winsize (struct gdbarch *gdbarch, CORE_ADDR pc)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int winsize = 4;
int insn;
gdb_byte buf[4];
/* Read the previous instruction (should be a call[x]{4|8|12}. */
read_memory (pc-3, buf, 3);
- insn = extract_unsigned_integer (buf, 3);
+ insn = extract_unsigned_integer (buf, 3, byte_order);
/* Decode call instruction:
Little Endian
call{0,4,8,12} 0101 || {00,01,10,11} || OFFSET
callx{0,4,8,12} 0000 || {00,01,10,11} || 11 || OFFSET. */
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE)
+ if (byte_order == BFD_ENDIAN_LITTLE)
{
if (((insn & 0xf) == 0x5) || ((insn & 0xcf) == 0xc0))
winsize = (insn & 0x30) >> 2; /* 0, 4, 8, 12. */
tp->size = size;
sprintf (name, "int%d", size * 8);
- tp->virtual_type = init_type (TYPE_CODE_INT, size,
- TYPE_FLAG_UNSIGNED, name,
- NULL);
+ tp->virtual_type
+ = arch_integer_type (gdbarch, size * 8, 1, xstrdup (name));
}
reg->ctype = tp->virtual_type;
int regnum,
gdb_byte *buffer)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
DEBUGTRACE ("xtensa_pseudo_register_read (... regnum = %d (%s) ...)\n",
regnum, xtensa_register_name (gdbarch, regnum));
regcache_raw_read (regcache, gdbarch_tdep (gdbarch)->wb_regnum, buf);
regnum = arreg_number (gdbarch, regnum,
- extract_unsigned_integer (buf, 4));
+ extract_unsigned_integer (buf, 4, byte_order));
}
/* We can always read non-pseudo registers. */
int regnum,
const gdb_byte *buffer)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
DEBUGTRACE ("xtensa_pseudo_register_write (... regnum = %d (%s) ...)\n",
regnum, xtensa_register_name (gdbarch, regnum));
regcache_raw_read (regcache,
gdbarch_tdep (gdbarch)->wb_regnum, buf);
regnum = arreg_number (gdbarch, regnum,
- extract_unsigned_integer (buf, 4));
+ extract_unsigned_integer (buf, 4, byte_order));
}
/* We can always write 'core' registers.
struct gdbarch *gdbarch = get_regcache_arch (rc);
int i;
- DEBUGTRACE ("xtensa_supply_gregset (..., regnum==%d, ...) \n", regnum);
+ DEBUGTRACE ("xtensa_supply_gregset (..., regnum==%d, ...)\n", regnum);
if (regnum == gdbarch_pc_regnum (gdbarch) || regnum == -1)
regcache_raw_supply (rc, gdbarch_pc_regnum (gdbarch), (char *) ®s->pc);
size_t sect_size)
{
DEBUGTRACE ("xtensa_regset_from_core_section "
- "(..., sect_name==\"%s\", sect_size==%x) \n",
+ "(..., sect_name==\"%s\", sect_size==%x)\n",
sect_name, (unsigned int) sect_size);
if (strcmp (sect_name, ".reg") == 0
{
int wb; /* WINDOWBASE of the previous frame. */
int callsize; /* Call size of this frame. */
- int ws; /* WINDOWSTART of the previous frame. It keeps track of
- life windows only. If there is no bit set for the
- window, that means it had been already spilled
- because of window overflow. */
+ int ws; /* WINDOWSTART of the previous frame. It
+ keeps track of life windows only. If there
+ is no bit set for the window, that means it
+ had been already spilled because of window
+ overflow. */
/* Spilled A-registers from the previous frame.
AREGS[i] == -1, if corresponding AR is alive. */
/* Call0 ABI Definitions. */
-#define C0_MAXOPDS 3 /* Maximum number of operands for prologue analysis. */
+#define C0_MAXOPDS 3 /* Maximum number of operands for prologue
+ analysis. */
#define C0_NREGS 16 /* Number of A-registers to track. */
#define C0_CLESV 12 /* Callee-saved registers are here and up. */
#define C0_SP 1 /* Register used as SP. */
int fr_reg; /* original register from which register content
is derived, or C0_CONST, or C0_INEXP. */
int fr_ofs; /* constant offset from reg, or immediate value. */
- int to_stk; /* offset from original SP to register (4-byte aligned),
- or C0_NOSTK if register has not been saved. */
+ int to_stk; /* offset from original SP to register (4-byte
+ aligned), or C0_NOSTK if register has not
+ been saved. */
} xtensa_c0reg_t;
typedef struct xtensa_call0_frame_cache
{
int c0_frmsz; /* Stack frame size. */
- int c0_hasfp; /* Current frame uses frame pointer. */
+ int c0_hasfp; /* Current frame uses frame
+ pointer. */
int fp_regnum; /* A-register used as FP. */
int c0_fp; /* Actual value of frame pointer. */
xtensa_c0reg_t c0_rt[C0_NREGS]; /* Register tracking information. */
/* Returns the best guess about which register is a frame pointer
for the function containing CURRENT_PC. */
-#define XTENSA_ISA_BSZ 32 /* Instruction buffer size. */
+#define XTENSA_ISA_BSZ 32 /* Instruction buffer size. */
+#define XTENSA_ISA_BADPC ((CORE_ADDR)0) /* Bad PC value. */
static unsigned int
xtensa_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR current_pc)
ba = ia;
bt = (ba + XTENSA_ISA_BSZ) < current_pc
? ba + XTENSA_ISA_BSZ : current_pc;
- read_memory (ba, ibuf, bt - ba);
+ if (target_read_memory (ba, ibuf, bt - ba) != 0)
+ RETURN_FP;
}
xtensa_insnbuf_from_chars (isa, ins, &ibuf[ia-ba], 0);
unsigned int register_operand;
/* Possible candidate for setting frame pointer
- from A1. This is what we are looking for. */
+ from A1. This is what we are looking for. */
if (xtensa_operand_get_field (isa, opc, 1, ifmt,
is, slot, ®ister_operand) != 0)
®ister_operand) != 0)
RETURN_FP;
- fp_regnum = gdbarch_tdep (gdbarch)->a0_base + register_operand;
+ fp_regnum
+ = gdbarch_tdep (gdbarch)->a0_base + register_operand;
RETURN_FP;
}
}
cache->base = SP (or best guess about FP) of this frame;
cache->pc = entry-PC (entry point of the frame function);
- cache->prev_sp = SP of the previous frame.
-*/
+ cache->prev_sp = SP of the previous frame. */
static void
call0_frame_cache (struct frame_info *this_frame,
xtensa_frame_cache_t *cache;
CORE_ADDR ra, wb, ws, pc, sp, ps;
struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned int fp_regnum;
char op1;
int windowed;
ws = get_frame_register_unsigned (this_frame,
gdbarch_tdep (gdbarch)->ws_regnum);
- op1 = read_memory_integer (pc, 1);
+ op1 = read_memory_integer (pc, 1, byte_order);
if (XTENSA_IS_ENTRY (gdbarch, op1))
{
int callinc = CALLINC (ps);
/* Set A4...A7/A11. */
/* Get the SP of the frame previous to the previous one.
To achieve this, we have to dereference SP twice. */
- sp = (CORE_ADDR) read_memory_integer (sp - 12, 4);
- sp = (CORE_ADDR) read_memory_integer (sp - 12, 4);
+ sp = (CORE_ADDR) read_memory_integer (sp - 12, 4, byte_order);
+ sp = (CORE_ADDR) read_memory_integer (sp - 12, 4, byte_order);
sp -= cache->wd.callsize * 4;
for ( i = 4; i < cache->wd.callsize; i++, sp += 4)
}
if ((cache->prev_sp == 0) && ( ra != 0 ))
- /* If RA is equal to 0 this frame is an outermost frame. Leave
- cache->prev_sp unchanged marking the boundary of the frame stack. */
+ /* If RA is equal to 0 this frame is an outermost frame.
+ Leave cache->prev_sp unchanged marking the boundary of the
+ frame stack. */
{
if ((cache->wd.ws & (1 << cache->wd.wb)) == 0)
{
We can read caller's SP from the proper spill loction. */
sp = get_frame_register_unsigned
(this_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
- cache->prev_sp = read_memory_integer (sp - 12, 4);
+ cache->prev_sp = read_memory_integer (sp - 12, 4, byte_order);
}
else
{
(gdbarch, gdbarch_tdep (gdbarch)->a0_base + 1,
cache->wd.wb);
- cache->prev_sp = get_frame_register_unsigned (this_frame, regnum);
+ cache->prev_sp = get_frame_register_unsigned (this_frame,
+ regnum);
}
}
}
spe = cache->c0.c0_fp
- cache->c0.c0_rt[cache->c0.fp_regnum].fr_ofs;
- return frame_unwind_got_memory (this_frame, regnum, spe + stkofs);
+ return frame_unwind_got_memory (this_frame, regnum,
+ spe + stkofs);
}
}
}
/* On Xtensa, we can return up to 4 words (or 2 for call12). */
if (len > (callsize > 8 ? 8 : 16))
internal_error (__FILE__, __LINE__,
- _("cannot extract return value of %d bytes long"), len);
+ _("cannot extract return value of %d bytes long"),
+ len);
/* Get the register offset of the return
register (A2) in the caller window. */
int struct_return,
CORE_ADDR struct_addr)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int i;
int size, onstack_size;
gdb_byte *buf = (gdb_byte *) alloca (16);
int align; /* alignment */
union
{
- int offset; /* stack offset if on stack */
- int regno; /* regno if in register */
+ int offset; /* stack offset if on stack. */
+ int regno; /* regno if in register. */
} u;
};
{
struct value *arg = args[i];
struct type *arg_type = check_typedef (value_type (arg));
- fprintf_unfiltered (gdb_stdlog, "%2d: 0x%lx %3d ",
- i, (unsigned long) arg, TYPE_LENGTH (arg_type));
+ fprintf_unfiltered (gdb_stdlog, "%2d: %s %3d ", i,
+ host_address_to_string (arg),
+ TYPE_LENGTH (arg_type));
switch (TYPE_CODE (arg_type))
{
case TYPE_CODE_INT:
fprintf_unfiltered (gdb_stdlog, "%3d", TYPE_CODE (arg_type));
break;
}
- fprintf_unfiltered (gdb_stdlog, " 0x%lx\n",
- (unsigned long) value_contents (arg));
+ fprintf_unfiltered (gdb_stdlog, " %s\n",
+ host_address_to_string (value_contents (arg)));
}
}
if (struct_return)
{
- store_unsigned_integer (buf, REGISTER_SIZE, struct_addr);
+ store_unsigned_integer (buf, REGISTER_SIZE, byte_order, struct_addr);
regcache_cooked_write (regcache, ARG_1ST (gdbarch), buf);
}
than REGISTER_SIZE; for larger odd-sized structures the excess
will be left-aligned in the register on both endiannesses. */
- if (n < REGISTER_SIZE
- && gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+ if (n < REGISTER_SIZE && byte_order == BFD_ENDIAN_BIG)
{
- ULONGEST v = extract_unsigned_integer (cp, REGISTER_SIZE);
+ ULONGEST v;
+ v = extract_unsigned_integer (cp, REGISTER_SIZE, byte_order);
v = v >> ((REGISTER_SIZE - n) * TARGET_CHAR_BIT);
- store_unsigned_integer (buf, REGISTER_SIZE, v);
+ store_unsigned_integer (buf, REGISTER_SIZE, byte_order, v);
regcache_cooked_write (regcache, r, buf);
cp += REGISTER_SIZE;
{
ra = (bp_addr & 0x3fffffff) | 0x40000000;
regcache_raw_read (regcache, gdbarch_ps_regnum (gdbarch), buf);
- ps = extract_unsigned_integer (buf, 4) & ~0x00030000;
+ ps = extract_unsigned_integer (buf, 4, byte_order) & ~0x00030000;
regcache_cooked_write_unsigned
(regcache, gdbarch_tdep (gdbarch)->a0_base + 4, ra);
regcache_cooked_write_unsigned (regcache,
is only one register window corresponding to WINDOWEBASE. */
regcache_raw_read (regcache, gdbarch_tdep (gdbarch)->wb_regnum, buf);
- regcache_cooked_write_unsigned (regcache,
- gdbarch_tdep (gdbarch)->ws_regnum,
- 1 << extract_unsigned_integer (buf, 4));
+ regcache_cooked_write_unsigned
+ (regcache, gdbarch_tdep (gdbarch)->ws_regnum,
+ 1 << extract_unsigned_integer (buf, 4, byte_order));
}
else
{
c0opc_mov, /* Moving a register to a register. */
c0opc_movi, /* Moving an immediate to a register. */
c0opc_l32r, /* Loading a literal. */
- c0opc_s32i, /* Storing word at fixed offset from a base register. */
+ c0opc_s32i, /* Storing word at fixed offset from a base
+ register. */
c0opc_NrOf /* Number of opcode classifications. */
} xtensa_insn_kind;
the stack frame. */
static void
-call0_track_op (xtensa_c0reg_t dst[], xtensa_c0reg_t src[],
+call0_track_op (struct gdbarch *gdbarch,
+ xtensa_c0reg_t dst[], xtensa_c0reg_t src[],
xtensa_insn_kind opclass, int nods, unsigned odv[],
CORE_ADDR pc, CORE_ADDR litbase, int spreg)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
unsigned litaddr, litval;
switch (opclass)
litaddr = litbase & 1
? (litbase & ~1) + (signed)odv[1]
: (pc + 3 + (signed)odv[1]) & ~3;
- litval = read_memory_integer(litaddr, 4);
+ litval = read_memory_integer (litaddr, 4, byte_order);
dst[odv[0]].fr_reg = C0_CONST;
dst[odv[0]].fr_ofs = litval;
break;
}
break;
default:
- gdb_assert (0);
+ gdb_assert_not_reached ("unexpected instruction kind");
}
}
because they begin with default assumptions that analysis may change. */
static CORE_ADDR
-call0_analyze_prologue (CORE_ADDR start, CORE_ADDR pc, CORE_ADDR litbase,
+call0_analyze_prologue (struct gdbarch *gdbarch,
+ CORE_ADDR start, CORE_ADDR pc, CORE_ADDR litbase,
int nregs, xtensa_c0reg_t rt[], int *call0)
{
CORE_ADDR ia; /* Current insn address in prologue. */
Assume we may be in the prologue until we hit a flow control instr. */
rtmp = NULL;
- body_pc = INT_MAX;
+ body_pc = UINT_MAX;
end_pc = 0;
/* Find out, if we have an information about the prologue from DWARF. */
ba = ia;
bt = (ba + XTENSA_ISA_BSZ) < body_pc ? ba + XTENSA_ISA_BSZ : body_pc;
read_memory (ba, ibuf, bt - ba);
+ /* If there is a memory reading error read_memory () will report it
+ and then throw an exception, stopping command execution. */
}
/* Decode format information. */
goto done;
opc = xtensa_opcode_decode (isa, ifmt, is, slot);
- DEBUGVERB ("[call0_analyze_prologue] instr addr = 0x%08x, opc = %d\n",
+ DEBUGVERB ("[call0_analyze_prologue] instr "
+ "addr = 0x%08x, opc = %d\n",
(unsigned)ia, opc);
if (opc == XTENSA_UNDEFINED)
opclass = c0opc_illegal;
}
/* Track register movement and modification for this operation. */
- call0_track_op (rt, rtmp, opclass, nods, odv, ia, litbase, 1);
+ call0_track_op (gdbarch, rt, rtmp, opclass,
+ nods, odv, ia, litbase, 1);
}
}
done:
(unsigned)ia, fail ? "failed" : "succeeded");
xtensa_insnbuf_free(isa, slot);
xtensa_insnbuf_free(isa, ins);
- return fail ? 0 : ia;
+ return fail ? XTENSA_ISA_BADPC : ia;
}
/* Initialize frame cache for the current frame in CALL0 ABI. */
static void
call0_frame_cache (struct frame_info *this_frame,
- xtensa_frame_cache_t *cache, CORE_ADDR pc, CORE_ADDR litbase)
+ xtensa_frame_cache_t *cache,
+ CORE_ADDR pc, CORE_ADDR litbase)
{
struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR start_pc; /* The beginning of the function. */
CORE_ADDR body_pc=UINT_MAX; /* PC, where prologue analysis stopped. */
CORE_ADDR sp, fp, ra;
if (find_pc_partial_function (pc, NULL, &start_pc, NULL))
{
- body_pc = call0_analyze_prologue (start_pc, pc, litbase, C0_NREGS,
+ body_pc = call0_analyze_prologue (gdbarch, start_pc, pc, litbase,
+ C0_NREGS,
&cache->c0.c0_rt[0],
&cache->call0);
+
+ if (body_pc == XTENSA_ISA_BADPC)
+ error (_("Xtensa-specific internal error: CALL0 prologue \
+analysis failed in this frame. GDB command execution stopped."));
}
sp = get_frame_register_unsigned
to_stk = cache->c0.c0_rt[C0_RA].to_stk;
if (to_stk != C0_NOSTK)
ra = (CORE_ADDR)
- read_memory_integer (sp + c0_frmsz + cache->c0.c0_rt[C0_RA].to_stk, 4);
+ read_memory_integer (sp + c0_frmsz + cache->c0.c0_rt[C0_RA].to_stk,
+ 4, byte_order);
else if (cache->c0.c0_rt[C0_RA].fr_reg == C0_CONST
&& cache->c0.c0_rt[C0_RA].fr_ofs == 0)
{
- /* Special case for terminating backtrace at a function that wants to
- be seen as the outermost. Such a function will clear it's RA (A0)
- register to 0 in the prologue instead of saving its original value. */
+ /* Special case for terminating backtrace at a function that
+ wants to be seen as the outermost. Such a function will
+ clear it's RA (A0) register to 0 in the prologue instead of
+ saving its original value. */
ra = 0;
}
else
{
- /* RA was copied to another register or (before any function call) may
- still be in the original RA register. This is not always reliable:
- even in a leaf function, register tracking stops after prologue, and
- even in prologue, non-prologue instructions (not tracked) may overwrite
- RA or any register it was copied to. If likely in prologue or before
- any call, use retracking info and hope for the best (compiler should
- have saved RA in stack if not in a leaf function). If not in prologue,
- too bad. */
+ /* RA was copied to another register or (before any function
+ call) may still be in the original RA register. This is not
+ always reliable: even in a leaf function, register tracking
+ stops after prologue, and even in prologue, non-prologue
+ instructions (not tracked) may overwrite RA or any register
+ it was copied to. If likely in prologue or before any call,
+ use retracking info and hope for the best (compiler should
+ have saved RA in stack if not in a leaf function). If not in
+ prologue, too bad. */
int i;
for (i = 0;
}
/* No debug line info. Analyze prologue for Call0 or simply skip ENTRY. */
- body_pc = call0_analyze_prologue(start_pc, 0, 0, 0, NULL, NULL);
+ body_pc = call0_analyze_prologue (gdbarch, start_pc, 0, 0, 0, NULL, NULL);
return body_pc != 0 ? body_pc : start_pc;
}
struct ui_file *log;
struct cleanup *cleanups;
struct gdbarch_tdep *tdep;
- long dummy;
+ long length;
char *buf;
tdep = gdbarch_tdep (gdbarch);
if (tdep->a0_base == -1)
fprintf_unfiltered (log, _("\n\ta0_base: No Ax registers"));
- buf = ui_file_xstrdup (log, &dummy);
+ buf = ui_file_xstrdup (log, &length);
make_cleanup (xfree, buf);
- if (strlen (buf) > 0)
+ if (length > 0)
internal_error (__FILE__, __LINE__,
_("the following are invalid: %s"), buf);
do_cleanups (cleanups);
set_gdbarch_register_name (gdbarch, xtensa_register_name);
set_gdbarch_register_type (gdbarch, xtensa_register_type);
- /* To call functions from GDB using dummy frame */
+ /* To call functions from GDB using dummy frame. */
set_gdbarch_push_dummy_call (gdbarch, xtensa_push_dummy_call);
set_gdbarch_believe_pcc_promotion (gdbarch, 1);
add_setshow_zinteger_cmd ("xtensa",
class_maintenance,
- &xtensa_debug_level, _("\
-Set Xtensa debugging."), _("\
-Show Xtensa debugging."), _("\
+ &xtensa_debug_level,
+ _("Set Xtensa debugging."),
+ _("Show Xtensa debugging."), _("\
When non-zero, Xtensa-specific debugging is enabled. \
Can be 1, 2, 3, or 4 indicating the level of debugging."),
NULL,