diff options
author | Andrew Cagney <cagney@redhat.com> | 2003-01-19 17:39:16 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2003-01-19 17:39:16 +0000 |
commit | dbe9fe588fc696a5d74b3a5c3208f2568b9fb7aa (patch) | |
tree | 2d995d5a3e6b2d1b7fc8ccda1b5cf3b523c8c83e /gdb/dummy-frame.c | |
parent | b4fc4eff63f50b61e744a5ad0bdac77e40441739 (diff) | |
download | gdb-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.c | 49 |
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 |