2004-11-08 Andrew Cagney <cagney@gnu.org>
* sentinel-frame.c (sentinel_frame_prev_pc): New function. (sentinel_frame_unwinder): Add the prev_pc method. * frame.c (frame_pc_unwind): Use the per-frame pc unwinder when available. Do not handle the sentinel-frame case. * frame-unwind.h (frame_prev_register_ftype): Define. (struct frame_unwind): Add prev_pc;
This commit is contained in:
parent
a77a9021ea
commit
cbafadeb88
4 changed files with 40 additions and 12 deletions
|
@ -1,3 +1,12 @@
|
|||
2004-11-08 Andrew Cagney <cagney@gnu.org>
|
||||
|
||||
* sentinel-frame.c (sentinel_frame_prev_pc): New function.
|
||||
(sentinel_frame_unwinder): Add the prev_pc method.
|
||||
* frame.c (frame_pc_unwind): Use the per-frame pc unwinder when
|
||||
available. Do not handle the sentinel-frame case.
|
||||
* frame-unwind.h (frame_prev_register_ftype): Define.
|
||||
(struct frame_unwind): Add prev_pc;
|
||||
|
||||
2004-11-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
|
||||
|
||||
* configure.in: Check for ncurses/term.h.
|
||||
|
|
|
@ -118,6 +118,14 @@ typedef void (frame_prev_register_ftype) (struct frame_info *next_frame,
|
|||
CORE_ADDR *addrp,
|
||||
int *realnump, void *valuep);
|
||||
|
||||
/* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
|
||||
use the NEXT frame, and its register unwind method, to return the PREV
|
||||
frame's program-counter. */
|
||||
|
||||
typedef CORE_ADDR (frame_prev_pc_ftype) (struct frame_info *next_frame,
|
||||
void **this_prologue_cache);
|
||||
|
||||
|
||||
struct frame_unwind
|
||||
{
|
||||
/* The frame's type. Should this instead be a collection of
|
||||
|
@ -129,6 +137,7 @@ struct frame_unwind
|
|||
frame_prev_register_ftype *prev_register;
|
||||
const struct frame_data *unwind_data;
|
||||
frame_sniffer_ftype *sniffer;
|
||||
frame_prev_pc_ftype *prev_pc;
|
||||
};
|
||||
|
||||
/* Register a frame unwinder, _prepending_ it to the front of the
|
||||
|
|
21
gdb/frame.c
21
gdb/frame.c
|
@ -390,7 +390,15 @@ frame_pc_unwind (struct frame_info *this_frame)
|
|||
if (!this_frame->prev_pc.p)
|
||||
{
|
||||
CORE_ADDR pc;
|
||||
if (gdbarch_unwind_pc_p (current_gdbarch))
|
||||
if (this_frame->unwind == NULL)
|
||||
this_frame->unwind
|
||||
= frame_unwind_find_by_frame (this_frame->next,
|
||||
&this_frame->prologue_cache);
|
||||
if (this_frame->unwind->prev_pc != NULL)
|
||||
/* A per-frame unwinder, prefer it. */
|
||||
pc = this_frame->unwind->prev_pc (this_frame->next,
|
||||
&this_frame->prologue_cache);
|
||||
else if (gdbarch_unwind_pc_p (current_gdbarch))
|
||||
{
|
||||
/* The right way. The `pure' way. The one true way. This
|
||||
method depends solely on the register-unwind code to
|
||||
|
@ -410,17 +418,8 @@ frame_pc_unwind (struct frame_info *this_frame)
|
|||
different ways that a PC could be unwound. */
|
||||
pc = gdbarch_unwind_pc (current_gdbarch, this_frame);
|
||||
}
|
||||
else if (this_frame->level < 0)
|
||||
{
|
||||
/* FIXME: cagney/2003-03-06: Old code and a sentinel
|
||||
frame. Do like was always done. Fetch the PC's value
|
||||
directly from the global registers array (via read_pc).
|
||||
This assumes that this frame belongs to the current
|
||||
global register cache. The assumption is dangerous. */
|
||||
pc = read_pc ();
|
||||
}
|
||||
else
|
||||
internal_error (__FILE__, __LINE__, "No gdbarch_unwind_pc method");
|
||||
internal_error (__FILE__, __LINE__, "No unwind_pc method");
|
||||
this_frame->prev_pc.value = pc;
|
||||
this_frame->prev_pc.p = 1;
|
||||
if (frame_debug)
|
||||
|
|
|
@ -81,11 +81,22 @@ sentinel_frame_this_id (struct frame_info *next_frame,
|
|||
internal_error (__FILE__, __LINE__, "sentinel_frame_this_id called");
|
||||
}
|
||||
|
||||
static CORE_ADDR
|
||||
sentinel_frame_prev_pc (struct frame_info *next_frame,
|
||||
void **this_prologue_cache)
|
||||
{
|
||||
struct gdbarch *gdbarch = get_frame_arch (next_frame);
|
||||
return gdbarch_unwind_pc (gdbarch, next_frame);
|
||||
}
|
||||
|
||||
const struct frame_unwind sentinel_frame_unwinder =
|
||||
{
|
||||
SENTINEL_FRAME,
|
||||
sentinel_frame_this_id,
|
||||
sentinel_frame_prev_register
|
||||
sentinel_frame_prev_register,
|
||||
NULL, /* unwind_data */
|
||||
NULL, /* sniffer */
|
||||
sentinel_frame_prev_pc,
|
||||
};
|
||||
|
||||
const struct frame_unwind *const sentinel_frame_unwind = &sentinel_frame_unwinder;
|
||||
|
|
Loading…
Reference in a new issue