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.
This commit is contained in:
Andrew Cagney 2003-01-19 17:39:16 +00:00
parent b4fc4eff63
commit dbe9fe588f
8 changed files with 118 additions and 14 deletions

View File

@ -1,3 +1,19 @@
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.
2003-01-18 Andrew Cagney <ac131313@redhat.com>
* cris-tdep.c: Fix function declaration indentation.

View File

@ -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

View File

@ -82,12 +82,27 @@ typedef void (frame_unwind_id_ftype) (struct frame_info * frame,
void **unwind_cache,
struct frame_id * id);
/* Discard the frame by restoring the registers (in regcache) back to
that of the caller. */
/* NOTE: cagney/2003-01-19: While at present the callers all pop each
frame in turn, the implementor should try to code things so that
any frame can be popped directly. */
/* FIXME: cagney/2003-01-19: Since both FRAME and REGCACHE refer to a
common register cache, care must be taken when restoring the
registers. The `correct fix' is to first first save the registers
in a scratch cache, and second write that scratch cache back to to
the real register cache. */
typedef void (frame_unwind_pop_ftype) (struct frame_info *frame,
void **unwind_cache,
struct regcache *regcache);
struct frame_unwind
{
/* Should the frame's type go here? */
/* Should an attribute indicating the frame's address-in-block go
here? */
frame_unwind_pop_ftype *pop;
frame_unwind_pc_ftype *pc;
frame_unwind_id_ftype *id;
frame_unwind_reg_ftype *reg;

View File

@ -145,6 +145,18 @@ frame_id_unwind (struct frame_info *frame)
return frame->id_unwind_cache;
}
void
frame_pop (struct frame_info *frame)
{
/* FIXME: cagney/2003-01-18: There is probably a chicken-egg problem
with passing in current_regcache. The pop function needs to be
written carefully so as to not overwrite registers whose [old]
values are needed to restore other registers. Instead, this code
should pass in a scratch cache and, as a second step, restore the
registers using that. */
frame->unwind->pop (frame, &frame->unwind_cache, current_regcache);
flush_cached_frames ();
}
void
frame_register_unwind (struct frame_info *frame, int regnum,
@ -715,7 +727,15 @@ frame_saved_regs_id_unwind (struct frame_info *next_frame, void **cache,
id->base = base;
}
static void
frame_saved_regs_pop (struct frame_info *fi, void **cache,
struct regcache *regcache)
{
POP_FRAME;
}
const struct frame_unwind trad_frame_unwinder = {
frame_saved_regs_pop,
frame_saved_regs_pc_unwind,
frame_saved_regs_id_unwind,
frame_saved_regs_register_unwind

View File

@ -306,6 +306,10 @@ extern CORE_ADDR frame_pc_unwind (struct frame_info *frame);
caller's frame. */
extern struct frame_id frame_id_unwind (struct frame_info *frame);
/* Discard the specified frame. Restoring the registers to the state
of the caller. */
extern void frame_pop (struct frame_info *frame);
/* Describe the saved registers of a frame. */
#if defined (EXTRA_FRAME_INFO) || defined (FRAME_FIND_SAVED_REGS)

View File

@ -3109,10 +3109,10 @@ normal_stop (void)
if (stop_stack_dummy)
{
/* Pop the empty frame that contains the stack dummy.
POP_FRAME ends with a setting of the current frame, so we
can use that next. */
POP_FRAME;
/* Pop the empty frame that contains the stack dummy. POP_FRAME
ends with a setting of the current frame, so we can use that
next. */
frame_pop (get_current_frame ());
/* Set stop_pc to what it was before we called the function.
Can't rely on restore_inferior_status because that only gets
called if we don't stop in the called function. */

View File

@ -1625,6 +1625,10 @@ return_command (char *retval_exp, int from_tty)
error ("Not confirmed.");
}
/* FIXME: cagney/2003-01-18: Rather than pop each frame in turn,
this code should just go straight to the relevant frame and pop
that. */
/* Do the real work. Pop until the specified frame is current. We
use this method because the deprecated_selected_frame is not valid after
a POP_FRAME. The pc comparison makes this work even if the
@ -1632,11 +1636,11 @@ return_command (char *retval_exp, int from_tty)
while (selected_frame_addr != get_frame_base (frame = get_current_frame ())
|| selected_frame_pc != get_frame_pc (frame))
POP_FRAME;
frame_pop (get_current_frame ());
/* Then pop that frame. */
POP_FRAME;
frame_pop (get_current_frame ());
/* Compute the return value (if any) and store in the place
for return values. */
@ -1646,9 +1650,14 @@ return_command (char *retval_exp, int from_tty)
/* If we are at the end of a call dummy now, pop the dummy frame too. */
/* FIXME: cagney/2003-01-18: This is silly. Instead of popping all
the frames except the dummy, and then, as an afterthought,
popping the dummy frame, this code should just pop through to the
dummy frame. */
if (CALL_DUMMY_HAS_COMPLETED (read_pc(), read_sp (),
get_frame_base (get_current_frame ())))
POP_FRAME;
frame_pop (get_current_frame ());
/* If interactive, print the frame that is now current. */

View File

@ -1711,8 +1711,9 @@ You must use a pointer to function type variable. Command ignored.", arg_name);
{
/* The user wants the context restored. */
/* We must get back to the frame we were before the dummy call. */
POP_FRAME;
/* We must get back to the frame we were before the dummy
call. */
frame_pop (get_current_frame ());
/* FIXME: Insert a bunch of wrap_here; name can be very long if it's
a C++ name with arguments and stuff. */