diff options
author | Andrew Cagney <cagney@redhat.com> | 2003-03-17 14:23:50 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2003-03-17 14:23:50 +0000 |
commit | 6dc42492b62e85e892cb3a0ec4732d4b81f79b87 (patch) | |
tree | c6532c44bc4acf08219f101ad924c4e6cb2092b7 /gdb/d10v-tdep.c | |
parent | 112290abe5a8587193c29b2f9b4671fd10d260df (diff) | |
download | gdb-6dc42492b62e85e892cb3a0ec4732d4b81f79b87.zip gdb-6dc42492b62e85e892cb3a0ec4732d4b81f79b87.tar.gz gdb-6dc42492b62e85e892cb3a0ec4732d4b81f79b87.tar.bz2 |
2003-03-17 Andrew Cagney <cagney@redhat.com>
Fix frame off-by-one bug.
* frame-unwind.h (frame_this_id_ftype): Replace
frame_unwind_id_ftype.
(frame_prev_register_ftype): Replace frame_unwind_reg_ftype.
(struct frame_unwind): Replace "id" with "this_id". Replace "reg"
with "prev_register".
* frame-unwind.c (frame_unwind_find_by_pc): Return
legacy_saved_regs_unwind instead of trad_frame_unwind. Update
comment.
* dummy-frame.c (cached_find_dummy_frame): Delete function.
(dummy_frame_this_id): Replace dummy_frame_id_unwind.
(dummy_frame_prev_register): Replace dummy_frame_register_unwind.
(dummy_frame_unwind): Update.
* sentinel-frame.c (sentinel_frame_prev_register): Replace
sentinel_frame_register_unwind.
(sentinel_frame_this_id): Replace sentinel_frame_id_unwind.
(sentinel_frame_unwinder): Update.
* frame.h (legacy_saved_regs_unwind): Replace trad_frame_unwind.
(struct frame_info): Rename "unwind_cache" to "prologue_cache".
* frame.c (create_sentinel_frame): Update. Initialize
"prologue_cache" instead of "unwind_cache".
(frame_register_unwind): Call this frame's prev_register with the
next frame and this frame's prologue cache.
(get_prev_frame): Simplify. Always call prev frame's this_id with
this frame and prev frame's prologue cache. Document that this
call is shifted one to the left when compared to the
frame_register_unwind call.
(legacy_saved_regs_prev_register): Replace
frame_saved_regs_register_unwind.
(legacy_saved_regs_this_id): Replace frame_saved_regs_id_unwind.
(legacy_saved_regs_unwinder): Replace trad_frame_unwinder.
(legacy_saved_regs_unwind): Replace trad_frame_unwind.
* d10v-tdep.c (d10v_frame_this_id): Replace d10v_frame_id_unwind.
(d10v_frame_unwind): Update.
(d10v_frame_prev_register): Replace d10v_frame_register_unwind.
(d10v_frame_unwind_cache): Replace this "fi" with "next_frame".
(saved_regs_unwinder): Replace this "frame" with "next_frame", and
"saved_regs" with "this_saved_regs".
Diffstat (limited to 'gdb/d10v-tdep.c')
-rw-r--r-- | gdb/d10v-tdep.c | 120 |
1 files changed, 59 insertions, 61 deletions
diff --git a/gdb/d10v-tdep.c b/gdb/d10v-tdep.c index b60ce7f..f443cef 100644 --- a/gdb/d10v-tdep.c +++ b/gdb/d10v-tdep.c @@ -705,8 +705,8 @@ prologue_find_regs (struct d10v_unwind_cache *info, unsigned short op, for it IS the sp for the next frame. */ struct d10v_unwind_cache * -d10v_frame_unwind_cache (struct frame_info *fi, - void **cache) +d10v_frame_unwind_cache (struct frame_info *next_frame, + void **this_prologue_cache) { CORE_ADDR pc; ULONGEST prev_sp; @@ -716,18 +716,18 @@ d10v_frame_unwind_cache (struct frame_info *fi, int i; struct d10v_unwind_cache *info; - if ((*cache)) - return (*cache); + if ((*this_prologue_cache)) + return (*this_prologue_cache); info = FRAME_OBSTACK_ZALLOC (struct d10v_unwind_cache); - (*cache) = info; + (*this_prologue_cache) = info; info->saved_regs = frame_obstack_zalloc (SIZEOF_FRAME_SAVED_REGS); info->size = 0; info->return_pc = 0; info->sp_offset = 0; - pc = get_pc_function_start (get_frame_pc (fi)); + pc = get_pc_function_start (frame_pc_unwind (next_frame)); info->uses_frame = 0; while (1) @@ -788,7 +788,7 @@ d10v_frame_unwind_cache (struct frame_info *fi, /* The SP was moved to the FP. This indicates that a new frame was created. Get THIS frame's FP value by unwinding it from the next frame. */ - frame_read_unsigned_register (fi, FP_REGNUM, &this_base); + frame_unwind_unsigned_register (next_frame, FP_REGNUM, &this_base); /* The FP points at the last saved register. Adjust the FP back to before the first saved register giving the SP. */ prev_sp = this_base + info->size; @@ -806,7 +806,7 @@ d10v_frame_unwind_cache (struct frame_info *fi, { /* Assume that the FP is this frame's SP but with that pushed stack space added back. */ - frame_read_unsigned_register (fi, SP_REGNUM, &this_base); + frame_unwind_unsigned_register (next_frame, SP_REGNUM, &this_base); prev_sp = this_base + info->size; } @@ -831,7 +831,7 @@ d10v_frame_unwind_cache (struct frame_info *fi, else { ULONGEST return_pc; - frame_read_unsigned_register (fi, LR_REGNUM, &return_pc); + frame_unwind_unsigned_register (next_frame, LR_REGNUM, &return_pc); info->return_pc = d10v_make_iaddr (return_pc); } @@ -1457,58 +1457,55 @@ d10v_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) frame. This will be used to create a new GDB frame struct. */ static void -d10v_frame_id_unwind (struct frame_info *frame, - void **cache, - struct frame_id *id) +d10v_frame_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *this_id) { - struct d10v_unwind_cache *info = d10v_frame_unwind_cache (frame, cache); - CORE_ADDR addr; + struct d10v_unwind_cache *info + = d10v_frame_unwind_cache (next_frame, this_prologue_cache); + CORE_ADDR base; + CORE_ADDR pc; /* Start with a NULL frame ID. */ - (*id) = null_frame_id; + (*this_id) = null_frame_id; - if (info->return_pc == IMEM_START - || info->return_pc <= IMEM_START - || inside_entry_file (info->return_pc)) - { - /* This is meant to halt the backtrace at "_start". - Make sure we don't halt it at a generic dummy frame. */ - return; - } + /* The PC is easy. */ + pc = frame_pc_unwind (next_frame); - if (!info->saved_regs[FP_REGNUM]) - { - if (!info->saved_regs[SP_REGNUM] - || info->saved_regs[SP_REGNUM] == STACK_START) - return; + /* This is meant to halt the backtrace at "_start". Make sure we + don't halt it at a generic dummy frame. */ + if (pc == IMEM_START || pc <= IMEM_START || inside_entry_file (pc)) + return; - id->base = info->saved_regs[SP_REGNUM]; - id->pc = info->return_pc; - } + /* Hopefully the prologue analysis either correctly determined the + frame's base (which is the SP from the previous frame), or set + that base to "NULL". */ + base = info->base; + if (base == STACK_START || base == 0) + return; - addr = read_memory_unsigned_integer (info->saved_regs[FP_REGNUM], - register_size (current_gdbarch, FP_REGNUM)); - if (addr == 0) + /* Check that we're not going round in circles with the same frame + ID (but avoid applying the test to sentinel frames which do go + round in circles). Can't use frame_id_eq() as that doesn't yet + compare the frame's PC value. */ + if (frame_relative_level (next_frame) >= 0 + && get_frame_type (next_frame) != DUMMY_FRAME + && get_frame_id (next_frame).pc == pc + && get_frame_id (next_frame).base == base) return; - id->base = d10v_make_daddr (addr); - id->pc = info->return_pc; + this_id->base = base; + this_id->pc = pc; } static void -saved_regs_unwinder (struct frame_info *frame, - CORE_ADDR *saved_regs, +saved_regs_unwinder (struct frame_info *next_frame, + CORE_ADDR *this_saved_regs, int regnum, int *optimizedp, enum lval_type *lvalp, CORE_ADDR *addrp, int *realnump, void *bufferp) { - /* If we're using generic dummy frames, we'd better not be in a call - dummy. (generic_call_dummy_register_unwind ought to have been called - instead.) */ - gdb_assert (!(DEPRECATED_USE_GENERIC_DUMMY_FRAMES - && (get_frame_type (frame) == DUMMY_FRAME))); - - if (saved_regs[regnum] != 0) + if (this_saved_regs[regnum] != 0) { if (regnum == SP_REGNUM) { @@ -1519,7 +1516,7 @@ saved_regs_unwinder (struct frame_info *frame, *realnump = -1; if (bufferp != NULL) store_address (bufferp, register_size (current_gdbarch, regnum), - saved_regs[regnum]); + this_saved_regs[regnum]); } else { @@ -1527,12 +1524,12 @@ saved_regs_unwinder (struct frame_info *frame, a local copy of its value. */ *optimizedp = 0; *lvalp = lval_memory; - *addrp = saved_regs[regnum]; + *addrp = this_saved_regs[regnum]; *realnump = -1; if (bufferp != NULL) { /* Read the value in from memory. */ - read_memory (saved_regs[regnum], bufferp, + read_memory (this_saved_regs[regnum], bufferp, register_size (current_gdbarch, regnum)); } } @@ -1543,38 +1540,39 @@ saved_regs_unwinder (struct frame_info *frame, value. If a value is needed, pass the request on down the chain; otherwise just return an indication that the value is in the same register as the next frame. */ - frame_register (frame, regnum, optimizedp, lvalp, addrp, - realnump, bufferp); + frame_register_unwind (next_frame, regnum, optimizedp, lvalp, addrp, + realnump, bufferp); } static void -d10v_frame_register_unwind (struct frame_info *frame, - void **cache, - int regnum, int *optimizedp, - enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *bufferp) -{ - struct d10v_unwind_cache *info = d10v_frame_unwind_cache (frame, cache); +d10v_frame_prev_register (struct frame_info *next_frame, + void **this_prologue_cache, + int regnum, int *optimizedp, + enum lval_type *lvalp, CORE_ADDR *addrp, + int *realnump, void *bufferp) +{ + struct d10v_unwind_cache *info + = d10v_frame_unwind_cache (next_frame, this_prologue_cache); if (regnum == PC_REGNUM) { /* 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, + saved_regs_unwinder (next_frame, info->saved_regs, LR_REGNUM, optimizedp, lvalp, addrp, realnump, bufferp); } else { - saved_regs_unwinder (frame, info->saved_regs, regnum, optimizedp, + saved_regs_unwinder (next_frame, info->saved_regs, regnum, optimizedp, lvalp, addrp, realnump, bufferp); } } static struct frame_unwind d10v_frame_unwind = { - d10v_frame_id_unwind, - d10v_frame_register_unwind + d10v_frame_this_id, + d10v_frame_prev_register }; const struct frame_unwind * |