diff options
Diffstat (limited to 'gdb/frame.c')
-rw-r--r-- | gdb/frame.c | 146 |
1 files changed, 82 insertions, 64 deletions
diff --git a/gdb/frame.c b/gdb/frame.c index 267d484..002a306 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -247,9 +247,32 @@ frame_register_unwind (struct frame_info *frame, int regnum, detected the problem before calling here. */ gdb_assert (frame != NULL); - /* Ask this frame to unwind its register. */ - frame->unwind->reg (frame, &frame->unwind_cache, regnum, - optimizedp, lvalp, addrp, realnump, bufferp); +#if 0 + /* Save each register's value and location, as it is read in, in a + frame based cache. For moment leave this disabled. Plenty of + other things to worry about first. */ + if (regs == NULL) + { + int sizeof_cache = ((NUM_REGS + NUM_PSEUDO_REGS) + * sizeof (void *)); + regs = frame_obstack_zalloc (sizeof_cache); + (*this_prologue_cache) = regs; + } + if (regs[regnum] == NULL) + { + regs[regnum] + = frame_obstack_zalloc (REGISTER_RAW_SIZE (regnum)); + read_memory (get_frame_saved_regs (frame)[regnum], regs[regnum], + REGISTER_RAW_SIZE (regnum)); + } +#endif + + /* Ask this frame to unwind its register. See comment in + "frame-unwind.h" for why NEXT frame and this unwind cace are + passed in. */ + frame->unwind->prev_register (frame->next, &frame->prologue_cache, regnum, + optimizedp, lvalp, addrp, realnump, bufferp); + } void @@ -499,7 +522,7 @@ create_sentinel_frame (struct regcache *regcache) /* Explicitly initialize the sentinel frame's cache. Provide it with the underlying regcache. In the future additional information, such as the frame's thread will be added. */ - frame->unwind_cache = sentinel_frame_cache (regcache); + frame->prologue_cache = sentinel_frame_cache (regcache); /* For the moment there is only one sentinel frame implementation. */ frame->unwind = sentinel_frame_unwind; /* Link this frame back to itself. The frame is self referential @@ -656,27 +679,26 @@ select_frame (struct frame_info *fi) most frame. */ static void -frame_saved_regs_register_unwind (struct frame_info *frame, void **cache, - int regnum, int *optimizedp, - enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *bufferp) +legacy_saved_regs_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) { - /* There is always a frame at this point. And THIS is the frame - we're interested in. */ + /* HACK: New code is passed the next frame and this cache. + Unfortunatly, old code expects this frame. Since this is a + backward compatibility hack, cheat by walking one level along the + prologue chain to the frame the old code expects. + + Do not try this at home. Professional driver, closed course. */ + struct frame_info *frame = next_frame->prev; + + /* There is always a frame. */ gdb_assert (frame != NULL); - /* 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))); - - /* Only (older) architectures that implement the - DEPRECATED_FRAME_INIT_SAVED_REGS method should be using this - function. */ - gdb_assert (DEPRECATED_FRAME_INIT_SAVED_REGS_P ()); /* Load the saved_regs register cache. */ - if (get_frame_saved_regs (frame) == NULL) + if (get_frame_saved_regs (frame) == NULL + && DEPRECATED_FRAME_INIT_SAVED_REGS_P ()) DEPRECATED_FRAME_INIT_SAVED_REGS (frame); if (get_frame_saved_regs (frame) != NULL @@ -703,46 +725,25 @@ frame_saved_regs_register_unwind (struct frame_info *frame, void **cache, *realnump = -1; if (bufferp != NULL) { -#if 1 - /* Save each register value, as it is read in, in a - frame based cache. */ - void **regs = (*cache); - if (regs == NULL) - { - int sizeof_cache = ((NUM_REGS + NUM_PSEUDO_REGS) - * sizeof (void *)); - regs = frame_obstack_zalloc (sizeof_cache); - (*cache) = regs; - } - if (regs[regnum] == NULL) - { - regs[regnum] - = frame_obstack_zalloc (REGISTER_RAW_SIZE (regnum)); - read_memory (get_frame_saved_regs (frame)[regnum], regs[regnum], - REGISTER_RAW_SIZE (regnum)); - } - memcpy (bufferp, regs[regnum], REGISTER_RAW_SIZE (regnum)); -#else /* Read the value in from memory. */ read_memory (get_frame_saved_regs (frame)[regnum], bufferp, REGISTER_RAW_SIZE (regnum)); -#endif } } return; } - /* No luck, assume this and the next frame have the same register - value. Pass the request down the frame chain to the next frame. - Hopefully that will find the register's location, either in a - register or in memory. */ - frame_register (frame, regnum, optimizedp, lvalp, addrp, realnump, - bufferp); + /* No luck. Assume this and the next frame have the same register + value. Pass the unwind request down the frame chain to the next + frame. Hopefully that frame will find the register's location. */ + frame_register_unwind (next_frame, regnum, optimizedp, lvalp, addrp, + realnump, bufferp); } static void -frame_saved_regs_id_unwind (struct frame_info *next_frame, void **cache, - struct frame_id *id) +legacy_saved_regs_this_id (struct frame_info *next_frame, + void **this_prologue_cache, + struct frame_id *id) { int fromleaf; CORE_ADDR base; @@ -801,11 +802,11 @@ frame_saved_regs_id_unwind (struct frame_info *next_frame, void **cache, id->base = base; } -const struct frame_unwind trad_frame_unwinder = { - frame_saved_regs_id_unwind, - frame_saved_regs_register_unwind +const struct frame_unwind legacy_saved_regs_unwinder = { + legacy_saved_regs_this_id, + legacy_saved_regs_prev_register }; -const struct frame_unwind *trad_frame_unwind = &trad_frame_unwinder; +const struct frame_unwind *legacy_saved_regs_unwind = &legacy_saved_regs_unwinder; /* Function: get_saved_register @@ -1327,10 +1328,7 @@ get_prev_frame (struct frame_info *this_frame) the legacy get_prev_frame method. Just don't try to unwind a sentinel frame using that method - it doesn't work. All sentinal frames use the new unwind code. */ - if ((DEPRECATED_INIT_FRAME_PC_P () - || DEPRECATED_INIT_FRAME_PC_FIRST_P () - || DEPRECATED_INIT_EXTRA_FRAME_INFO_P () - || FRAME_CHAIN_P ()) + if (legacy_frame_p (current_gdbarch) && this_frame->level >= 0) { prev_frame = legacy_get_prev_frame (this_frame); @@ -1434,12 +1432,23 @@ get_prev_frame (struct frame_info *this_frame) break; case NORMAL_FRAME: case SIGTRAMP_FRAME: - /* FIXME: cagney/2003-03-04: The below call isn't right. It - should instead be doing something like "prev_frame -> unwind - -> id (this_frame, & prev_frame -> unwind_cache, & prev_frame - -> id)" but that requires more extensive (pending) changes. */ - this_frame->unwind->id (this_frame, &this_frame->unwind_cache, - &prev_frame->id); + /* The callee expects to be invoked with: + + this->unwind->this_id (this->next, &this->cache, &this->id); + + The below is carefully shifted one frame `to the left' so + that both the unwind->this_id and unwind->prev_register + methods are consistently invoked with NEXT_FRAME and + THIS_PROLOGUE_CACHE. + + Also note that, while the PC for this new previous frame was + unwound first (see above), the below is the first call that + [potentially] requires analysis of the new previous frame's + prologue. Consequently, it is this call, that typically ends + up initializing the previous frame's prologue cache. */ + prev_frame->unwind->this_id (this_frame, + &prev_frame->prologue_cache, + &prev_frame->id); /* Check that the unwound ID is valid. */ if (!frame_id_p (prev_frame->id)) { @@ -1696,6 +1705,15 @@ deprecated_frame_xmalloc_with_cleanup (long sizeof_saved_regs, return frame; } +int +legacy_frame_p (struct gdbarch *current_gdbarch) +{ + return (DEPRECATED_INIT_FRAME_PC_P () + || DEPRECATED_INIT_FRAME_PC_FIRST_P () + || DEPRECATED_INIT_EXTRA_FRAME_INFO_P () + || FRAME_CHAIN_P ()); +} + void _initialize_frame (void) { |