From 5142f611ca2556cb8e1510a69b9d240785a7db48 Mon Sep 17 00:00:00 2001 From: Maxim Grigoriev Date: Mon, 5 May 2008 20:49:44 +0000 Subject: [PATCH] 2008-05-05 Maxim Grigoriev * xtensa-tdep.c: Update for unwinder changes. --- gdb/ChangeLog | 4 + gdb/xtensa-tdep.c | 247 +++++++++++++--------------------------------- 2 files changed, 70 insertions(+), 181 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6075efa7340..46041a465d1 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,7 @@ +2008-05-05 Maxim Grigoriev + + * xtensa-tdep.c: Update for unwinder changes. + 2008-05-05 Andreas Schwab Update m68k port for unwinder changes. diff --git a/gdb/xtensa-tdep.c b/gdb/xtensa-tdep.c index 200ad2665a3..a6181dad27e 100644 --- a/gdb/xtensa-tdep.c +++ b/gdb/xtensa-tdep.c @@ -1037,17 +1037,15 @@ xtensa_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) 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. */ + /* THIS-FRAME is a dummy frame. Return a frame ID of that frame. */ - DEBUGTRACE ("xtensa_unwind_dummy_id ()\n"); - - 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); @@ -1178,24 +1176,21 @@ done: */ 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); 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); + struct gdbarch *gdbarch = get_frame_arch (this_frame); unsigned int ps_regnum = gdbarch_ps_regnum (gdbarch); 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; @@ -1205,34 +1200,31 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache) 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); + ps = get_frame_register_unsigned (this_frame, ps_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. @@ -1250,14 +1242,14 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache) 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); @@ -1268,8 +1260,8 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache) 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) { @@ -1300,8 +1292,8 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache) { /* 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 @@ -1317,110 +1309,42 @@ xtensa_frame_cache (struct frame_info *next_frame, void **this_cache) } else /* Call0 framework. */ { - call0_frame_cache (next_frame, cache, pc); + call0_frame_cache (this_frame, cache, pc); 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; -} - -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); + (*this_id) = frame_id_build (cache->prev_sp, cache->pc); } -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; @@ -1441,16 +1365,7 @@ xtensa_frame_prev_register (struct frame_info *next_frame, 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. */ { @@ -1470,19 +1385,8 @@ xtensa_frame_prev_register (struct frame_info *next_frame, 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. */ @@ -1504,17 +1408,8 @@ xtensa_frame_prev_register (struct frame_info *next_frame, /* 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); } } } @@ -1522,34 +1417,25 @@ xtensa_frame_prev_register (struct frame_info *next_frame, /* 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; } @@ -1557,7 +1443,7 @@ xtensa_frame_base_address (struct frame_info *next_frame, void **this_cache) 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 @@ -2410,15 +2296,13 @@ 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, +call0_frame_cache (struct frame_info *this_frame, xtensa_frame_cache_t *cache, CORE_ADDR pc) { - 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; @@ -2434,8 +2318,8 @@ call0_frame_cache (struct frame_info *next_frame, &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. @@ -2470,7 +2354,7 @@ call0_frame_cache (struct frame_info *next_frame, 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; @@ -2512,11 +2396,11 @@ call0_frame_cache (struct frame_info *next_frame, ++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; } @@ -2802,11 +2686,12 @@ xtensa_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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); -- 2.30.2