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:
parent
e5fbc737f6
commit
82417da5f0
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
20
gdb/frame.c
20
gdb/frame.c
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user