summaryrefslogtreecommitdiff
path: root/gdb/d10v-tdep.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/d10v-tdep.c')
-rw-r--r--gdb/d10v-tdep.c60
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;
}