diff options
author | David Carlton <carlton@bactrian.org> | 2003-02-07 19:18:06 +0000 |
---|---|---|
committer | David Carlton <carlton@bactrian.org> | 2003-02-07 19:18:06 +0000 |
commit | 9ec3c59b028a60cb6ab45f53f06cba1a24395875 (patch) | |
tree | 660b3ce9f1b465c31b507dcbdd2dc5fed7bbc0a9 /gdb/dummy-frame.c | |
parent | f79355f07b5ace625d507e1f6308728bcdc757de (diff) | |
download | gdb-9ec3c59b028a60cb6ab45f53f06cba1a24395875.zip gdb-9ec3c59b028a60cb6ab45f53f06cba1a24395875.tar.gz gdb-9ec3c59b028a60cb6ab45f53f06cba1a24395875.tar.bz2 |
2003-02-07 David Carlton <carlton@math.stanford.edu>
* Merge with mainline; tag is carlton_dictionary-20030207-merge.
Diffstat (limited to 'gdb/dummy-frame.c')
-rw-r--r-- | gdb/dummy-frame.c | 87 |
1 files changed, 76 insertions, 11 deletions
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c index fab10c0..5b63830 100644 --- a/gdb/dummy-frame.c +++ b/gdb/dummy-frame.c @@ -28,6 +28,7 @@ #include "frame.h" #include "inferior.h" #include "gdb_assert.h" +#include "frame-unwind.h" /* Dummy frame. This saves the processor state just prior to setting up the inferior function call. Older targets save the registers @@ -269,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) @@ -282,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 @@ -304,7 +343,7 @@ generic_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, /* Given a call-dummy dummy-frame, return the registers. Here the register value is taken from the local copy of the register buffer. */ -void +static void dummy_frame_register_unwind (struct frame_info *frame, void **cache, int regnum, int *optimized, enum lval_type *lvalp, CORE_ADDR *addrp, @@ -331,7 +370,10 @@ dummy_frame_register_unwind (struct frame_info *frame, void **cache, } } -CORE_ADDR +/* Assuming that FRAME is a dummy, return the resume address for the + previous frame. */ + +static CORE_ADDR dummy_frame_pc_unwind (struct frame_info *frame, void **cache) { @@ -345,16 +387,39 @@ dummy_frame_pc_unwind (struct frame_info *frame, } -struct frame_id +/* Assuming that FRAME is a dummy, return the ID of the calling frame + (the frame that the dummy has the saved state of). */ + +static void dummy_frame_id_unwind (struct frame_info *frame, - void **cache) + void **cache, + struct frame_id *id) { struct dummy_frame *dummy = cached_find_dummy_frame (frame, cache); /* Oops! In a dummy-frame but can't find the stack dummy. Pretend that the frame doesn't unwind. Should this function instead return a has-no-caller indication? */ if (dummy == NULL) - return null_frame_id; - return dummy->id; + (*id) = null_frame_id; + else + (*id) = dummy->id; } +static struct frame_unwind dummy_frame_unwind = +{ + dummy_frame_pop, + dummy_frame_pc_unwind, + dummy_frame_id_unwind, + dummy_frame_register_unwind +}; + +const struct frame_unwind * +dummy_frame_p (CORE_ADDR pc) +{ + if (DEPRECATED_PC_IN_CALL_DUMMY_P () + ? DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0) + : pc_in_dummy_frame (pc)) + return &dummy_frame_unwind; + else + return NULL; +} |