diff options
Diffstat (limited to 'gdb/d10v-tdep.c')
-rw-r--r-- | gdb/d10v-tdep.c | 60 |
1 files changed, 17 insertions, 43 deletions
diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c index 5f334e6a7ab..b60ce7fad3a 100644 --- a/gdb/d10v-tdep.c +++ b/gdb/d10v-tdep.c @@ -1445,13 +1445,12 @@ display_trace (int low, int high) } } - static CORE_ADDR -d10v_frame_pc_unwind (struct frame_info *frame, - void **cache) +d10v_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) { - struct d10v_unwind_cache *info = d10v_frame_unwind_cache (frame, cache); - return info->return_pc; + ULONGEST pc; + frame_unwind_unsigned_register (next_frame, PC_REGNUM, &pc); + return d10v_make_iaddr (pc); } /* Given a GDB frame, determine the address of the calling function's @@ -1557,51 +1556,23 @@ d10v_frame_register_unwind (struct frame_info *frame, int *realnump, void *bufferp) { struct d10v_unwind_cache *info = d10v_frame_unwind_cache (frame, cache); - saved_regs_unwinder (frame, info->saved_regs, regnum, optimizedp, - lvalp, addrp, realnump, bufferp); -} - - -static void -d10v_frame_pop (struct frame_info *fi, void **unwind_cache, - struct regcache *regcache) -{ - struct d10v_unwind_cache *info = d10v_frame_unwind_cache (fi, unwind_cache); - CORE_ADDR fp; - int regnum; - char raw_buffer[8]; - - fp = get_frame_base (fi); - - /* now update the current registers with the old values */ - for (regnum = A0_REGNUM; regnum < A0_REGNUM + NR_A_REGS; regnum++) + if (regnum == PC_REGNUM) { - frame_unwind_register (fi, regnum, raw_buffer); - regcache_cooked_write (regcache, regnum, raw_buffer); + /* The call instruction saves the caller's PC in LR. The + function prologue of the callee may then save the LR on the + stack. Find that possibly saved LR value and return it. */ + saved_regs_unwinder (frame, info->saved_regs, LR_REGNUM, optimizedp, + lvalp, addrp, realnump, bufferp); } - for (regnum = 0; regnum < SP_REGNUM; regnum++) + else { - frame_unwind_register (fi, regnum, raw_buffer); - regcache_cooked_write (regcache, regnum, raw_buffer); + saved_regs_unwinder (frame, info->saved_regs, regnum, optimizedp, + lvalp, addrp, realnump, bufferp); } - frame_unwind_register (fi, PSW_REGNUM, raw_buffer); - regcache_cooked_write (regcache, PSW_REGNUM, raw_buffer); - - frame_unwind_register (fi, LR_REGNUM, raw_buffer); - regcache_cooked_write (regcache, PC_REGNUM, raw_buffer); - - store_unsigned_integer (raw_buffer, - register_size (current_gdbarch, SP_REGNUM), - fp + info->size); - regcache_cooked_write (regcache, SP_REGNUM, raw_buffer); - - target_store_registers (-1); - flush_cached_frames (); } + static struct frame_unwind d10v_frame_unwind = { - d10v_frame_pop, - d10v_frame_pc_unwind, d10v_frame_id_unwind, d10v_frame_register_unwind }; @@ -1769,6 +1740,9 @@ d10v_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_unwind_dummy_id (gdbarch, d10v_unwind_dummy_id); set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); + /* Return the unwound PC value. */ + set_gdbarch_unwind_pc (gdbarch, d10v_unwind_pc); + return gdbarch; } |