2003-03-12 Andrew Cagney <cagney@redhat.com>
Eliminate the need for POP_FRAME. * frame.c (do_frame_unwind_register): New function. (frame_pop): When no POP_FRAME, pop the frame using register unwind and a scratch regcache. (frame_saved_regs_pop): Delete function. (trad_frame_unwinder): Update. * d10v-tdep.c (d10v_frame_pop): Delete function. (d10v_frame_unwind): Update. * sentinel-frame.c (sentinel_frame_pop): Delete function. (sentinel_frame_unwinder): Update. * dummy-frame.c (dummy_frame_pop): Delete function. (dummy_frame_unwind): Update. * frame-unwind.h (frame_unwind_pop_ftype): Delete definition. (struct frame_unwind): Update.
This commit is contained in:
parent
c4d8feb262
commit
7a25a7c1cc
6 changed files with 54 additions and 113 deletions
|
@ -1,3 +1,20 @@
|
|||
2003-03-12 Andrew Cagney <cagney@redhat.com>
|
||||
|
||||
Eliminate the need for POP_FRAME.
|
||||
* frame.c (do_frame_unwind_register): New function.
|
||||
(frame_pop): When no POP_FRAME, pop the frame using register
|
||||
unwind and a scratch regcache.
|
||||
(frame_saved_regs_pop): Delete function.
|
||||
(trad_frame_unwinder): Update.
|
||||
* d10v-tdep.c (d10v_frame_pop): Delete function.
|
||||
(d10v_frame_unwind): Update.
|
||||
* sentinel-frame.c (sentinel_frame_pop): Delete function.
|
||||
(sentinel_frame_unwinder): Update.
|
||||
* dummy-frame.c (dummy_frame_pop): Delete function.
|
||||
(dummy_frame_unwind): Update.
|
||||
* frame-unwind.h (frame_unwind_pop_ftype): Delete definition.
|
||||
(struct frame_unwind): Update.
|
||||
|
||||
2003-03-11 Kevin Buettner <kevinb@redhat.com>
|
||||
|
||||
* mips-tdep.c (mips_ecoff_reg_to_regnum): Rename to
|
||||
|
|
|
@ -1572,45 +1572,7 @@ d10v_frame_register_unwind (struct frame_info *frame,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
d10v_frame_pop (struct frame_info *fi, void **unwind_cache,
|
||||
struct regcache *regcache)
|
||||
{
|
||||
struct d10v_unwind_cache *info = d10v_frame_unwind_cache (fi, unwind_cache);
|
||||
CORE_ADDR fp;
|
||||
int regnum;
|
||||
char raw_buffer[8];
|
||||
|
||||
fp = get_frame_base (fi);
|
||||
|
||||
/* now update the current registers with the old values */
|
||||
for (regnum = A0_REGNUM; regnum < A0_REGNUM + NR_A_REGS; regnum++)
|
||||
{
|
||||
frame_unwind_register (fi, regnum, raw_buffer);
|
||||
regcache_cooked_write (regcache, regnum, raw_buffer);
|
||||
}
|
||||
for (regnum = 0; regnum < SP_REGNUM; regnum++)
|
||||
{
|
||||
frame_unwind_register (fi, regnum, raw_buffer);
|
||||
regcache_cooked_write (regcache, regnum, raw_buffer);
|
||||
}
|
||||
frame_unwind_register (fi, PSW_REGNUM, raw_buffer);
|
||||
regcache_cooked_write (regcache, PSW_REGNUM, raw_buffer);
|
||||
|
||||
frame_unwind_register (fi, PC_REGNUM, raw_buffer);
|
||||
regcache_cooked_write (regcache, PC_REGNUM, raw_buffer);
|
||||
|
||||
store_unsigned_integer (raw_buffer,
|
||||
register_size (current_gdbarch, SP_REGNUM),
|
||||
fp + info->size);
|
||||
regcache_cooked_write (regcache, SP_REGNUM, raw_buffer);
|
||||
|
||||
target_store_registers (-1);
|
||||
flush_cached_frames ();
|
||||
}
|
||||
|
||||
static struct frame_unwind d10v_frame_unwind = {
|
||||
d10v_frame_pop,
|
||||
d10v_frame_id_unwind,
|
||||
d10v_frame_register_unwind
|
||||
};
|
||||
|
|
|
@ -282,37 +282,6 @@ discard_innermost_dummy (struct dummy_frame **stack)
|
|||
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)
|
||||
{
|
||||
|
@ -390,7 +359,6 @@ dummy_frame_id_unwind (struct frame_info *frame,
|
|||
|
||||
static struct frame_unwind dummy_frame_unwind =
|
||||
{
|
||||
dummy_frame_pop,
|
||||
dummy_frame_id_unwind,
|
||||
dummy_frame_register_unwind
|
||||
};
|
||||
|
|
|
@ -76,27 +76,11 @@ 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_id_ftype *id;
|
||||
frame_unwind_reg_ftype *reg;
|
||||
};
|
||||
|
|
55
gdb/frame.c
55
gdb/frame.c
|
@ -185,16 +185,44 @@ frame_pc_unwind (struct frame_info *this_frame)
|
|||
return this_frame->pc_unwind_cache;
|
||||
}
|
||||
|
||||
void
|
||||
frame_pop (struct frame_info *frame)
|
||||
static int
|
||||
do_frame_unwind_register (void *src, int regnum, void *buf)
|
||||
{
|
||||
/* 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);
|
||||
frame_unwind_register (src, regnum, buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
frame_pop (struct frame_info *this_frame)
|
||||
{
|
||||
struct regcache *scratch_regcache;
|
||||
struct cleanup *cleanups;
|
||||
|
||||
if (POP_FRAME_P ())
|
||||
{
|
||||
/* A legacy architecture that has implemented a custom pop
|
||||
function. All new architectures should instead be using the
|
||||
generic code below. */
|
||||
POP_FRAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make a copy of all the register values unwound from this
|
||||
frame. Save them in a scratch buffer so that there isn't a
|
||||
race betweening trying to extract the old values from the
|
||||
current_regcache while, at the same time writing new values
|
||||
into that same cache. */
|
||||
struct regcache *scratch = regcache_xmalloc (current_gdbarch);
|
||||
struct cleanup *cleanups = make_cleanup_regcache_xfree (scratch);
|
||||
regcache_save (scratch, do_frame_unwind_register, this_frame);
|
||||
/* Now copy those saved registers into the current regcache.
|
||||
Here, regcache_cpy() calls regcache_restore(). */
|
||||
regcache_cpy (current_regcache, scratch);
|
||||
do_cleanups (cleanups);
|
||||
}
|
||||
/* We've made right mess of GDB's local state, just discard
|
||||
everything. */
|
||||
target_store_registers (-1);
|
||||
flush_cached_frames ();
|
||||
}
|
||||
|
||||
|
@ -768,16 +796,7 @@ 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)
|
||||
{
|
||||
gdb_assert (POP_FRAME_P ());
|
||||
POP_FRAME;
|
||||
}
|
||||
|
||||
const struct frame_unwind trad_frame_unwinder = {
|
||||
frame_saved_regs_pop,
|
||||
frame_saved_regs_id_unwind,
|
||||
frame_saved_regs_register_unwind
|
||||
};
|
||||
|
|
|
@ -83,17 +83,8 @@ sentinel_frame_id_unwind (struct frame_info *frame,
|
|||
id->pc = read_pc ();
|
||||
}
|
||||
|
||||
static void
|
||||
sentinel_frame_pop (struct frame_info *frame,
|
||||
void **cache,
|
||||
struct regcache *regcache)
|
||||
{
|
||||
internal_error (__FILE__, __LINE__, "Function sentinal_frame_pop called");
|
||||
}
|
||||
|
||||
const struct frame_unwind sentinel_frame_unwinder =
|
||||
{
|
||||
sentinel_frame_pop,
|
||||
sentinel_frame_id_unwind,
|
||||
sentinel_frame_register_unwind
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue