2004-03-21 Andrew Cagney <cagney@redhat.com>

* frame-unwind.h: Update copyright.
	(struct frame_data): Add opaque declaration.
	(frame_sniffer_ftype): Declare.
	(struct frame_unwind): Add "unwind_data" and "sniffer".
	(frame_unwind_register_unwinder): Declare.
	(frame_unwind_find_by_frame): Add parameter "this_cache".
	* frame.c (get_frame_id, create_new_frame, legacy_get_prev_frame)
	(legacy_get_prev_frame, legacy_get_prev_frame)
	(get_frame_type): Pass the prologue_cache to
	frame_unwind_find_by_frame.
	* frame-unwind.c (struct frame_unwind_table_entry): Add field
	"unwinder".
	(frame_unwind_register_unwinder): New function.
	(frame_unwind_find_by_frame): Handle an unwind sniffer.
This commit is contained in:
Andrew Cagney 2004-03-21 22:28:52 +00:00
parent e5fbc737f6
commit 82417da5f0
4 changed files with 77 additions and 15 deletions

View File

@ -1,3 +1,20 @@
2004-03-21 Andrew Cagney <cagney@redhat.com>
* frame-unwind.h: Update copyright.
(struct frame_data): Add opaque declaration.
(frame_sniffer_ftype): Declare.
(struct frame_unwind): Add "unwind_data" and "sniffer".
(frame_unwind_register_unwinder): Declare.
(frame_unwind_find_by_frame): Add parameter "this_cache".
* frame.c (get_frame_id, create_new_frame, legacy_get_prev_frame)
(legacy_get_prev_frame, legacy_get_prev_frame)
(get_frame_type): Pass the prologue_cache to
frame_unwind_find_by_frame.
* frame-unwind.c (struct frame_unwind_table_entry): Add field
"unwinder".
(frame_unwind_register_unwinder): New function.
(frame_unwind_find_by_frame): Handle an unwind sniffer.
2004-03-20 Paul Hilfinger <hilfingr@nile.gnat.com>
* bcache.c (print_percentage): Use floating point to avoid

View File

@ -31,6 +31,7 @@ static struct gdbarch_data *frame_unwind_data;
struct frame_unwind_table_entry
{
frame_unwind_sniffer_ftype *sniffer;
const struct frame_unwind *unwinder;
struct frame_unwind_table_entry *next;
};
@ -61,8 +62,19 @@ frame_unwind_append_sniffer (struct gdbarch *gdbarch,
table->tail = &((*table->tail)->next);
}
void
frame_unwind_register_unwinder (struct gdbarch *gdbarch,
const struct frame_unwind *unwinder)
{
struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
(*table->tail) = GDBARCH_OBSTACK_ZALLOC (gdbarch,
struct frame_unwind_table_entry);
(*table->tail)->unwinder = unwinder;
table->tail = &((*table->tail)->next);
}
const struct frame_unwind *
frame_unwind_find_by_frame (struct frame_info *next_frame)
frame_unwind_find_by_frame (struct frame_info *next_frame, void **this_cache)
{
int i;
struct gdbarch *gdbarch = get_frame_arch (next_frame);
@ -76,10 +88,19 @@ frame_unwind_find_by_frame (struct frame_info *next_frame)
return legacy_saved_regs_unwind;
for (entry = table->head; entry != NULL; entry = entry->next)
{
const struct frame_unwind *desc;
desc = entry->sniffer (next_frame);
if (desc != NULL)
return desc;
if (entry->sniffer != NULL)
{
const struct frame_unwind *desc = NULL;
desc = entry->sniffer (next_frame);
if (desc != NULL)
return desc;
}
if (entry->unwinder != NULL)
{
if (entry->unwinder->sniffer (entry->unwinder, next_frame,
this_cache))
return entry->unwinder;
}
}
return legacy_saved_regs_unwind;
}

View File

@ -1,6 +1,6 @@
/* Definitions for a frame unwinder, for GDB, the GNU debugger.
Copyright 2003 Free Software Foundation, Inc.
Copyright 2003, 2004 Free Software Foundation, Inc.
This file is part of GDB.
@ -22,6 +22,7 @@
#if !defined (FRAME_UNWIND_H)
#define FRAME_UNWIND_H 1
struct frame_data;
struct frame_info;
struct frame_id;
struct frame_unwind;
@ -42,6 +43,14 @@ struct regcache;
as where this frame's prologue stores the previous frame's
registers. */
/* Given the NEXT frame, take a wiff of THIS frame's registers (namely
the PC and attributes) and if SELF is the applicable unwinder,
return non-zero. Possibly also initialize THIS_PROLOGUE_CACHE. */
typedef int (frame_sniffer_ftype) (const struct frame_unwind *self,
struct frame_info *next_frame,
void **this_prologue_cache);
/* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
use the NEXT frame, and its register unwind method, to determine
the frame ID of THIS frame.
@ -118,8 +127,16 @@ struct frame_unwind
here? */
frame_this_id_ftype *this_id;
frame_prev_register_ftype *prev_register;
const struct frame_data *unwind_data;
frame_sniffer_ftype *sniffer;
};
/* Register a frame unwinder, _appending_ it to the end of the search
list. */
extern void frame_unwind_register_unwinder (struct gdbarch *gdbarch,
const struct frame_unwind *unwinder);
/* Given the NEXT frame, take a wiff of THIS frame's registers (namely
the PC and attributes) and if it is the applicable unwinder return
the unwind methods, or NULL if it is not. */
@ -134,8 +151,9 @@ extern void frame_unwind_append_sniffer (struct gdbarch *gdbarch,
frame_unwind_sniffer_ftype *sniffer);
/* Iterate through the next frame's sniffers until one returns with an
unwinder implementation. */
unwinder implementation. Possibly initialize THIS_CACHE. */
extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame);
extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame,
void **this_cache);
#endif

View File

@ -228,7 +228,8 @@ get_frame_id (struct frame_info *fi)
/* Find the unwinder. */
if (fi->unwind == NULL)
{
fi->unwind = frame_unwind_find_by_frame (fi->next);
fi->unwind = frame_unwind_find_by_frame (fi->next,
&fi->prologue_cache);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunately, legacy code, called by
@ -532,7 +533,8 @@ frame_register_unwind (struct frame_info *frame, int regnum,
/* Find the unwinder. */
if (frame->unwind == NULL)
{
frame->unwind = frame_unwind_find_by_frame (frame->next);
frame->unwind = frame_unwind_find_by_frame (frame->next,
&frame->prologue_cache);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunately, legacy code, called by
@ -1191,7 +1193,7 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
/* Select/initialize both the unwind function and the frame's type
based on the PC. */
fi->unwind = frame_unwind_find_by_frame (fi->next);
fi->unwind = frame_unwind_find_by_frame (fi->next, &fi->prologue_cache);
if (fi->unwind->type != UNKNOWN_FRAME)
fi->type = fi->unwind->type;
else
@ -1344,7 +1346,8 @@ legacy_get_prev_frame (struct frame_info *this_frame)
/* Set the unwind functions based on that identified PC. Ditto
for the "type" but strongly prefer the unwinder's frame type. */
prev->unwind = frame_unwind_find_by_frame (prev->next);
prev->unwind = frame_unwind_find_by_frame (prev->next,
&prev->prologue_cache);
if (prev->unwind->type == UNKNOWN_FRAME)
prev->type = frame_type_from_pc (get_frame_pc (prev));
else
@ -1493,7 +1496,8 @@ legacy_get_prev_frame (struct frame_info *this_frame)
to the new frame code. Implement FRAME_CHAIN the way the
new frame will. */
/* Find PREV frame's unwinder. */
prev->unwind = frame_unwind_find_by_frame (this_frame);
prev->unwind = frame_unwind_find_by_frame (this_frame,
&prev->prologue_cache);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunately, legacy code, called by
@ -1654,7 +1658,8 @@ legacy_get_prev_frame (struct frame_info *this_frame)
If there isn't a FRAME_CHAIN, the code above will have already
done this. */
if (prev->unwind == NULL)
prev->unwind = frame_unwind_find_by_frame (prev->next);
prev->unwind = frame_unwind_find_by_frame (prev->next,
&prev->prologue_cache);
/* If the unwinder provides a frame type, use it. Otherwize
continue on to that heuristic mess. */
@ -2124,7 +2129,8 @@ get_frame_type (struct frame_info *frame)
{
/* Initialize the frame's unwinder because it is that which
provides the frame's type. */
frame->unwind = frame_unwind_find_by_frame (frame->next);
frame->unwind = frame_unwind_find_by_frame (frame->next,
&frame->prologue_cache);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunately, legacy code, called by