aboutsummaryrefslogtreecommitdiff
path: root/gdb/dummy-frame.c
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2003-01-19 17:39:16 +0000
committerAndrew Cagney <cagney@redhat.com>2003-01-19 17:39:16 +0000
commitdbe9fe588fc696a5d74b3a5c3208f2568b9fb7aa (patch)
tree2d995d5a3e6b2d1b7fc8ccda1b5cf3b523c8c83e /gdb/dummy-frame.c
parentb4fc4eff63f50b61e744a5ad0bdac77e40441739 (diff)
downloadgdb-dbe9fe588fc696a5d74b3a5c3208f2568b9fb7aa.zip
gdb-dbe9fe588fc696a5d74b3a5c3208f2568b9fb7aa.tar.gz
gdb-dbe9fe588fc696a5d74b3a5c3208f2568b9fb7aa.tar.bz2
2003-01-19 Andrew Cagney <ac131313@redhat.com>
* frame-unwind.h (frame_unwind_pop_ftype): Declare. (struct frame_unwind): Add field pop. * frame.h (frame_pop): Declare. * frame.c (frame_saved_regs_pop): New function. (trad_frame_unwinder): Add frame_saved_regs_pop. (frame_pop): New function. * dummy-frame.c (dummy_frame_pop): New function. (discard_innermost_dummy): New function. (generic_pop_dummy_frame): Use discard_innermost_dummy. (dummy_frame_unwind): Add dummy_frame_pop. * infrun.c (normal_stop): Call frame_pop instead of POP_FRAME. * valops.c (hand_function_call): Ditto. * stack.c (return_command): Ditto.
Diffstat (limited to 'gdb/dummy-frame.c')
-rw-r--r--gdb/dummy-frame.c49
1 files changed, 44 insertions, 5 deletions
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c
index 0a3e35e..5b63830 100644
--- a/gdb/dummy-frame.c
+++ b/gdb/dummy-frame.c
@@ -270,8 +270,48 @@ generic_pop_current_frame (void (*popper) (struct frame_info * frame))
(*popper) (frame);
}
-/* Function: pop_dummy_frame
- Restore the machine state from a saved dummy stack frame. */
+/* Discard the innermost dummy frame from the dummy frame stack
+ (passed in as a parameter). */
+
+static void
+discard_innermost_dummy (struct dummy_frame **stack)
+{
+ struct dummy_frame *tbd = (*stack);
+ (*stack) = (*stack)->next;
+ regcache_xfree (tbd->regcache);
+ xfree (tbd);
+}
+
+/* Function: dummy_frame_pop. Restore the machine state from a saved
+ dummy stack frame. */
+
+static void
+dummy_frame_pop (struct frame_info *fi, void **cache,
+ struct regcache *regcache)
+{
+ struct dummy_frame *dummy = cached_find_dummy_frame (fi, cache);
+
+ /* If it isn't, what are we even doing here? */
+ gdb_assert (get_frame_type (fi) == DUMMY_FRAME);
+
+ if (dummy == NULL)
+ error ("Can't pop dummy frame!");
+
+ /* Discard all dummy frames up-to but not including this one. */
+ while (dummy_frame_stack != dummy)
+ discard_innermost_dummy (&dummy_frame_stack);
+
+ /* Restore this one. */
+ regcache_cpy (regcache, dummy->regcache);
+ flush_cached_frames ();
+
+ /* Now discard it. */
+ discard_innermost_dummy (&dummy_frame_stack);
+
+ /* Note: target changed would be better. Registers, memory and
+ frame are all invalid. */
+ flush_cached_frames ();
+}
void
generic_pop_dummy_frame (void)
@@ -283,12 +323,10 @@ generic_pop_dummy_frame (void)
if (!dummy_frame)
error ("Can't pop dummy frame!");
- dummy_frame_stack = dummy_frame->next;
regcache_cpy (current_regcache, dummy_frame->regcache);
flush_cached_frames ();
- regcache_xfree (dummy_frame->regcache);
- xfree (dummy_frame);
+ discard_innermost_dummy (&dummy_frame_stack);
}
/* Function: fix_call_dummy
@@ -369,6 +407,7 @@ dummy_frame_id_unwind (struct frame_info *frame,
static struct frame_unwind dummy_frame_unwind =
{
+ dummy_frame_pop,
dummy_frame_pc_unwind,
dummy_frame_id_unwind,
dummy_frame_register_unwind