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:
Andrew Cagney 2004-11-09 01:16:42 +00:00
parent a77a9021ea
commit cbafadeb88
4 changed files with 40 additions and 12 deletions

View file

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

View file

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

View file

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

View file

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