return 0;
}
-static unsigned long
-xtensa_read_register (int regnum)
-{
- ULONGEST value;
-
- regcache_raw_read_unsigned (get_current_regcache (), regnum, &value);
- return (unsigned long) value;
-}
-
/* Return the type of a register. Create a new type, if necessary. */
static struct ctype_cache
+ gdbarch_tdep (gdbarch)->num_aregs)
|| (regnum >= gdbarch_tdep (gdbarch)->a0_base
&& regnum < gdbarch_tdep (gdbarch)->a0_base + 16))
- return builtin_type_int;
+ return builtin_type (gdbarch)->builtin_int;
if (regnum == gdbarch_pc_regnum (gdbarch)
|| regnum == gdbarch_tdep (gdbarch)->a0_base + 1)
- return lookup_pointer_type (builtin_type_void);
+ return builtin_type (gdbarch)->builtin_data_ptr;
/* Return the stored type for all other registers. */
else if (regnum >= 0 && regnum < gdbarch_num_regs (gdbarch)
CORE_ADDR base; /* Stack pointer of this frame. */
CORE_ADDR pc; /* PC at the entry point to the function. */
CORE_ADDR ra; /* The raw return address (without CALLINC). */
- CORE_ADDR ps; /* The PS register of the previous frame. */
+ CORE_ADDR ps; /* The PS register of this frame. */
CORE_ADDR prev_sp; /* Stack Pointer of the previous frame. */
int call0; /* It's a call0 framework (else windowed). */
union
xtensa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
gdb_byte buf[8];
+ CORE_ADDR pc;
DEBUGTRACE ("xtensa_unwind_pc (next_frame = %p)\n", next_frame);
frame_unwind_register (next_frame, gdbarch_pc_regnum (gdbarch), buf);
+ pc = extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
- DEBUGINFO ("[xtensa_unwind_pc] pc = 0x%08x\n", (unsigned int)
- extract_typed_address (buf, builtin_type_void_func_ptr));
+ DEBUGINFO ("[xtensa_unwind_pc] pc = 0x%08x\n", (unsigned int) pc);
- return extract_typed_address (buf, builtin_type_void_func_ptr);
+ return pc;
}
static struct frame_id
-xtensa_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
+xtensa_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
CORE_ADDR pc, fp;
- /* next_frame->prev is a dummy frame. Return a frame ID of that frame. */
-
- DEBUGTRACE ("xtensa_unwind_dummy_id ()\n");
+ /* THIS-FRAME is a dummy frame. Return a frame ID of that frame. */
- pc = frame_pc_unwind (next_frame);
- fp = frame_unwind_register_unsigned
- (next_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
+ pc = get_frame_pc (this_frame);
+ fp = get_frame_register_unsigned
+ (this_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
/* Make dummy frame ID unique by adding a constant. */
return frame_id_build (fp + SP_ALIGNMENT, pc);
*/
static void
-call0_frame_cache (struct frame_info *next_frame,
+call0_frame_cache (struct frame_info *this_frame,
xtensa_frame_cache_t *cache,
- CORE_ADDR pc);
+ CORE_ADDR pc, CORE_ADDR litbase);
static struct xtensa_frame_cache *
-xtensa_frame_cache (struct frame_info *next_frame, void **this_cache)
+xtensa_frame_cache (struct frame_info *this_frame, void **this_cache)
{
xtensa_frame_cache_t *cache;
CORE_ADDR ra, wb, ws, pc, sp, ps;
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
- unsigned int ps_regnum = gdbarch_ps_regnum (gdbarch);
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
unsigned int fp_regnum;
char op1;
int windowed;
- DEBUGTRACE ("xtensa_frame_cache (next_frame %p, *this_cache %p)\n",
- next_frame, this_cache ? *this_cache : (void*)0xdeadbeef);
-
if (*this_cache)
return *this_cache;
- windowed = windowing_enabled (xtensa_read_register (ps_regnum));
+ ps = get_frame_register_unsigned (this_frame, gdbarch_ps_regnum (gdbarch));
+ windowed = windowing_enabled (ps);
/* Get pristine xtensa-frame. */
cache = xtensa_alloc_frame_cache (windowed);
*this_cache = cache;
- pc = frame_unwind_register_unsigned (next_frame,
- gdbarch_pc_regnum (gdbarch));
+ pc = get_frame_register_unsigned (this_frame, gdbarch_pc_regnum (gdbarch));
if (windowed)
{
/* Get WINDOWBASE, WINDOWSTART, and PS registers. */
- wb = frame_unwind_register_unsigned
- (next_frame, gdbarch_tdep (gdbarch)->wb_regnum);
- ws = frame_unwind_register_unsigned
- (next_frame, gdbarch_tdep (gdbarch)->ws_regnum);
- ps = frame_unwind_register_unsigned (next_frame, ps_regnum);
+ wb = get_frame_register_unsigned (this_frame,
+ gdbarch_tdep (gdbarch)->wb_regnum);
+ ws = get_frame_register_unsigned (this_frame,
+ gdbarch_tdep (gdbarch)->ws_regnum);
op1 = read_memory_integer (pc, 1);
if (XTENSA_IS_ENTRY (gdbarch, op1))
{
int callinc = CALLINC (ps);
- ra = frame_unwind_register_unsigned
- (next_frame, gdbarch_tdep (gdbarch)->a0_base + callinc * 4);
-
- DEBUGINFO("[xtensa_frame_cache] 'entry' at 0x%08x\n (callinc = %d)",
- (int)pc, callinc);
+ ra = get_frame_register_unsigned
+ (this_frame, gdbarch_tdep (gdbarch)->a0_base + callinc * 4);
/* ENTRY hasn't been executed yet, therefore callsize is still 0. */
cache->wd.callsize = 0;
cache->wd.wb = wb;
cache->wd.ws = ws;
- cache->prev_sp = frame_unwind_register_unsigned
- (next_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
+ cache->prev_sp = get_frame_register_unsigned
+ (this_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
/* This only can be the outermost frame since we are
just about to execute ENTRY. SP hasn't been set yet.
else
{
fp_regnum = xtensa_scan_prologue (gdbarch, pc);
- ra = frame_unwind_register_unsigned
- (next_frame, gdbarch_tdep (gdbarch)->a0_base);
+ ra = get_frame_register_unsigned (this_frame,
+ gdbarch_tdep (gdbarch)->a0_base);
cache->wd.callsize = WINSIZE (ra);
cache->wd.wb = (wb - cache->wd.callsize / 4)
& (gdbarch_tdep (gdbarch)->num_aregs / 4 - 1);
cache->wd.ws = ws & ~(1 << wb);
- cache->pc = frame_func_unwind (next_frame, NORMAL_FRAME);
+ cache->pc = get_frame_func (this_frame);
cache->ra = (cache->pc & 0xc0000000) | (ra & 0x3fffffff);
cache->ps = (ps & ~PS_CALLINC_MASK)
| ((WINSIZE(ra)/4) << PS_CALLINC_SHIFT);
int i;
/* Set A0...A3. */
- sp = frame_unwind_register_unsigned
- (next_frame, gdbarch_tdep (gdbarch)->a0_base + 1) - 16;
+ sp = get_frame_register_unsigned
+ (this_frame, gdbarch_tdep (gdbarch)->a0_base + 1) - 16;
for (i = 0; i < 4; i++, sp += 4)
{
{
/* Register window overflow already happened.
We can read caller's SP from the proper spill loction. */
- sp = frame_unwind_register_unsigned (next_frame,
- gdbarch_tdep (gdbarch)->a0_base + 1);
+ sp = get_frame_register_unsigned
+ (this_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
cache->prev_sp = read_memory_integer (sp - 12, 4);
}
else
(gdbarch, gdbarch_tdep (gdbarch)->a0_base + 1,
cache->wd.wb);
- cache->prev_sp = xtensa_read_register (regnum);
+ cache->prev_sp = get_frame_register_unsigned (this_frame, regnum);
}
}
}
else /* Call0 framework. */
{
- call0_frame_cache (next_frame, cache, pc);
+ unsigned int litbase_regnum = gdbarch_tdep (gdbarch)->litbase_regnum;
+ CORE_ADDR litbase = (litbase_regnum == -1)
+ ? 0 : get_frame_register_unsigned (this_frame, litbase_regnum);
+
+ call0_frame_cache (this_frame, cache, pc, litbase);
fp_regnum = cache->c0.fp_regnum;
}
- cache->base = frame_unwind_register_unsigned (next_frame, fp_regnum);
+ cache->base = get_frame_register_unsigned (this_frame, fp_regnum);
return cache;
}
static void
-xtensa_frame_this_id (struct frame_info *next_frame,
+xtensa_frame_this_id (struct frame_info *this_frame,
void **this_cache,
struct frame_id *this_id)
{
struct xtensa_frame_cache *cache =
- xtensa_frame_cache (next_frame, this_cache);
- struct frame_id id;
-
- DEBUGTRACE ("xtensa_frame_this_id (next 0x%lx, *this 0x%lx)\n",
- (unsigned long) next_frame, (unsigned long) *this_cache);
+ xtensa_frame_cache (this_frame, this_cache);
if (cache->prev_sp == 0)
return;
- id = frame_id_build (cache->prev_sp, cache->pc);
- if (frame_id_eq (id, get_frame_id(next_frame)))
- {
- warning(_("\
-Frame stack is corrupted. That could happen because of \
-setting register(s) from GDB or stopping execution \
-inside exception handler. Frame backtracing has stopped. \
-It can make some GDB commands work inappropriately.\n"));
- cache->prev_sp = 0;
- return;
- }
- (*this_id) = id;
+ (*this_id) = frame_id_build (cache->prev_sp, cache->pc);
}
-static int
-call0_frame_get_reg_at_entry (struct frame_info *next_frame,
- struct xtensa_frame_cache *cache,
- int regnum,
- CORE_ADDR *addrp,
- enum lval_type *lval,
- gdb_byte *valuep)
-{
- CORE_ADDR fp, spe;
- int stkofs;
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
- int reg = (regnum >= gdbarch_tdep (gdbarch)->ar_base
- && regnum <= (gdbarch_tdep (gdbarch)->ar_base + C0_NREGS))
- ? regnum - gdbarch_tdep (gdbarch)->ar_base : regnum;
-
- /* Determine stack pointer on entry to this function, based on FP. */
- spe = cache->c0.c0_fp - cache->c0.c0_rt[cache->c0.fp_regnum].fr_ofs;
-
- /* If register was saved to the stack frame in the prologue, retrieve it. */
- stkofs = cache->c0.c0_rt[reg].to_stk;
- if (stkofs != C0_NOSTK)
- {
- *lval = lval_memory;
- *addrp = spe + stkofs;
-
- if (valuep)
- read_memory (*addrp, valuep, register_size (gdbarch, regnum));
-
- return 1;
- }
-
- /* If not callee-saved or if known to have been overwritten, give up. */
- if (reg < C0_CLESV
- || cache->c0.c0_rt[reg].fr_reg != reg
- || cache->c0.c0_rt[reg].fr_ofs != 0)
- return 0;
-
- if (get_frame_type (next_frame) != NORMAL_FRAME)
- /* TODO: Do we need a special case for DUMMY_FRAME here? */
- return 0;
-
- return call0_frame_get_reg_at_entry (get_next_frame(next_frame),
- cache, regnum, addrp, lval, valuep);
-}
-
-static void
-xtensa_frame_prev_register (struct frame_info *next_frame,
+static struct value *
+xtensa_frame_prev_register (struct frame_info *this_frame,
void **this_cache,
- int regnum,
- int *optimizedp,
- enum lval_type *lvalp,
- CORE_ADDR *addrp,
- int *realnump,
- gdb_byte *valuep)
+ int regnum)
{
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
- struct xtensa_frame_cache *cache =
- xtensa_frame_cache (next_frame, this_cache);
- CORE_ADDR saved_reg = 0;
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct xtensa_frame_cache *cache;
+ ULONGEST saved_reg = 0;
int done = 1;
- DEBUGTRACE ("xtensa_frame_prev_register (next 0x%lx, "
- "*this 0x%lx, regnum %d (%s), ...)\n",
- (unsigned long) next_frame,
- *this_cache ? (unsigned long) *this_cache : 0, regnum,
- xtensa_register_name (gdbarch, regnum));
+ if (*this_cache == NULL)
+ *this_cache = xtensa_frame_cache (this_frame, this_cache);
+ cache = *this_cache;
if (regnum ==gdbarch_pc_regnum (gdbarch))
saved_reg = cache->ra;
done = 0;
if (done)
- {
- *optimizedp = 0;
- *lvalp = not_lval;
- *addrp = 0;
- *realnump = -1;
- if (valuep)
- store_unsigned_integer (valuep, 4, saved_reg);
-
- return;
- }
+ return frame_unwind_got_constant (this_frame, regnum, saved_reg);
if (!cache->call0) /* Windowed ABI. */
{
if (areg >= 0
&& areg < XTENSA_NUM_SAVED_AREGS
&& cache->wd.aregs[areg] != -1)
- {
- *optimizedp = 0;
- *lvalp = lval_memory;
- *addrp = cache->wd.aregs[areg];
- *realnump = -1;
-
- if (valuep)
- read_memory (*addrp, valuep,
- register_size (gdbarch, regnum));
-
- DEBUGINFO ("[xtensa_frame_prev_register] register on stack\n");
- return;
- }
+ return frame_unwind_got_memory (this_frame, regnum,
+ cache->wd.aregs[areg]);
}
}
else /* Call0 ABI. */
/* Determine SP on entry based on FP. */
spe = cache->c0.c0_fp
- cache->c0.c0_rt[cache->c0.fp_regnum].fr_ofs;
- *optimizedp = 0;
- *lvalp = lval_memory;
- *addrp = spe + stkofs;
- *realnump = -1;
-
- if (valuep)
- read_memory (*addrp, valuep,
- register_size (gdbarch, regnum));
-
- DEBUGINFO ("[xtensa_frame_prev_register] register on stack\n");
- return;
+
+ return frame_unwind_got_memory (this_frame, regnum, spe + stkofs);
}
}
}
/* All other registers have been either saved to
the stack or are still alive in the processor. */
- *optimizedp = 0;
- *lvalp = lval_register;
- *addrp = 0;
- *realnump = regnum;
- if (valuep)
- frame_unwind_register (next_frame, (*realnump), valuep);
+ return frame_unwind_got_register (this_frame, regnum, regnum);
}
static const struct frame_unwind
-xtensa_frame_unwind =
+xtensa_unwind =
{
NORMAL_FRAME,
xtensa_frame_this_id,
- xtensa_frame_prev_register
+ xtensa_frame_prev_register,
+ NULL,
+ default_frame_sniffer
};
-static const struct frame_unwind *
-xtensa_frame_sniffer (struct frame_info *next_frame)
-{
- return &xtensa_frame_unwind;
-}
-
static CORE_ADDR
-xtensa_frame_base_address (struct frame_info *next_frame, void **this_cache)
+xtensa_frame_base_address (struct frame_info *this_frame, void **this_cache)
{
struct xtensa_frame_cache *cache =
- xtensa_frame_cache (next_frame, this_cache);
+ xtensa_frame_cache (this_frame, this_cache);
return cache->base;
}
static const struct frame_base
xtensa_frame_base =
{
- &xtensa_frame_unwind,
+ &xtensa_unwind,
xtensa_frame_base_address,
xtensa_frame_base_address,
xtensa_frame_base_address
case TYPE_CODE_ENUM:
/* Cast argument to long if necessary as the mask does it too. */
- if (TYPE_LENGTH (arg_type) < TYPE_LENGTH (builtin_type_long))
+ if (TYPE_LENGTH (arg_type)
+ < TYPE_LENGTH (builtin_type (gdbarch)->builtin_long))
{
- arg_type = builtin_type_long;
+ arg_type = builtin_type (gdbarch)->builtin_long;
arg = value_cast (arg_type, arg);
}
/* Aligment is equal to the type length for the basic types. */
case TYPE_CODE_FLT:
/* Align doubles correctly. */
- if (TYPE_LENGTH (arg_type) == TYPE_LENGTH (builtin_type_double))
- info->align = TYPE_LENGTH (builtin_type_double);
+ if (TYPE_LENGTH (arg_type)
+ == TYPE_LENGTH (builtin_type (gdbarch)->builtin_double))
+ info->align = TYPE_LENGTH (builtin_type (gdbarch)->builtin_double);
else
- info->align = TYPE_LENGTH (builtin_type_long);
+ info->align = TYPE_LENGTH (builtin_type (gdbarch)->builtin_long);
break;
case TYPE_CODE_STRUCT:
default:
- info->align = TYPE_LENGTH (builtin_type_long);
+ info->align = TYPE_LENGTH (builtin_type (gdbarch)->builtin_long);
break;
}
info->length = TYPE_LENGTH (arg_type);
static void
call0_track_op (xtensa_c0reg_t dst[], xtensa_c0reg_t src[],
xtensa_insn_kind opclass, int nods, unsigned odv[],
- CORE_ADDR pc, int spreg)
+ CORE_ADDR pc, CORE_ADDR litbase, int spreg)
{
- unsigned litbase, litaddr, litval;
+ unsigned litaddr, litval;
switch (opclass)
{
case c0opc_l32r:
/* 2 operands: dst, literal offset. */
gdb_assert (nods == 2);
- /* litbase = xtensa_get_litbase (pc); can be also used. */
- litbase = (gdbarch_tdep (current_gdbarch)->litbase_regnum == -1)
- ? 0 : xtensa_read_register
- (gdbarch_tdep (current_gdbarch)->litbase_regnum);
litaddr = litbase & 1
? (litbase & ~1) + (signed)odv[1]
: (pc + 3 + (signed)odv[1]) & ~3;
because they begin with default assumptions that analysis may change. */
static CORE_ADDR
-call0_analyze_prologue (CORE_ADDR start, CORE_ADDR pc,
+call0_analyze_prologue (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. */
}
/* Track register movement and modification for this operation. */
- call0_track_op (rt, rtmp, opclass, nods, odv, ia, 1);
+ call0_track_op (rt, rtmp, opclass, nods, odv, ia, litbase, 1);
}
}
done:
return fail ? 0 : ia;
}
-/* Initialize frame cache for the current frame. The "next_frame" is the next
- one relative to current frame. "cache" is the pointer to the data structure
- we have to initialize. "pc" is curretnt PC. */
+/* Initialize frame cache for the current frame in CALL0 ABI. */
static void
-call0_frame_cache (struct frame_info *next_frame,
- xtensa_frame_cache_t *cache, CORE_ADDR pc)
+call0_frame_cache (struct frame_info *this_frame,
+ xtensa_frame_cache_t *cache, CORE_ADDR pc, CORE_ADDR litbase)
{
- struct gdbarch *gdbarch = get_frame_arch (next_frame);
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
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, C0_NREGS,
+ body_pc = call0_analyze_prologue (start_pc, pc, litbase, C0_NREGS,
&cache->c0.c0_rt[0],
&cache->call0);
}
- sp = frame_unwind_register_unsigned
- (next_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
+ sp = get_frame_register_unsigned
+ (this_frame, gdbarch_tdep (gdbarch)->a0_base + 1);
fp = sp; /* Assume FP == SP until proven otherwise. */
/* Get the frame information and FP (if used) at the current PC.
alloca() and other dynamic allocations. Adjust frame size by FP - SP. */
if (c0_hasfp)
{
- fp = frame_unwind_register_unsigned (next_frame, fp_regnum);
+ fp = get_frame_register_unsigned (this_frame, fp_regnum);
/* Recalculate previous SP. */
prev_sp = fp + c0_frmsz;
++i);
if (i >= C0_NREGS && cache->c0.c0_rt[C0_RA].fr_reg == C0_RA)
i = C0_RA;
- if (i < C0_NREGS) /* Read from the next_frame. */
+ if (i < C0_NREGS)
{
- ra = frame_unwind_register_unsigned
- (next_frame,
- gdbarch_tdep (gdbarch)->a0_base + cache->c0.c0_rt[i].fr_reg);
+ ra = get_frame_register_unsigned
+ (this_frame,
+ gdbarch_tdep (gdbarch)->a0_base + cache->c0.c0_rt[i].fr_reg);
}
else ra = 0;
}
}
/* No debug line info. Analyze prologue for Call0 or simply skip ENTRY. */
- body_pc = call0_analyze_prologue(start_pc, 0, 0, NULL, NULL);
+ body_pc = call0_analyze_prologue(start_pc, 0, 0, 0, NULL, NULL);
return body_pc != 0 ? body_pc : start_pc;
}
set_gdbarch_pc_regnum (gdbarch, tdep->pc_regnum);
set_gdbarch_ps_regnum (gdbarch, tdep->ps_regnum);
- /* Renumber registers for known formats (stab, dwarf, and dwarf2). */
+ /* Renumber registers for known formats (stabs and dwarf2). */
set_gdbarch_stab_reg_to_regnum (gdbarch, xtensa_reg_to_regnum);
- set_gdbarch_dwarf_reg_to_regnum (gdbarch, xtensa_reg_to_regnum);
set_gdbarch_dwarf2_reg_to_regnum (gdbarch, xtensa_reg_to_regnum);
/* We provide our own function to get register information. */
set_gdbarch_frame_align (gdbarch, xtensa_frame_align);
- set_gdbarch_unwind_dummy_id (gdbarch, xtensa_unwind_dummy_id);
+ set_gdbarch_dummy_id (gdbarch, xtensa_dummy_id);
/* Frame handling. */
frame_base_set_default (gdbarch, &xtensa_frame_base);
- frame_unwind_append_sniffer (gdbarch, xtensa_frame_sniffer);
+ frame_unwind_append_unwinder (gdbarch, &xtensa_unwind);
+ dwarf2_append_unwinders (gdbarch);
set_gdbarch_print_insn (gdbarch, print_insn_xtensa);