aboutsummaryrefslogtreecommitdiff
path: root/gdb/frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/frame.c')
-rw-r--r--gdb/frame.c146
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)
{