2003-07-15 Andrew Cagney <cagney@redhat.com>

* frame.c (get_frame_id): Use frame_unwind_find_by_frame.
	(frame_register_unwind, create_new_frame): Ditto.
	(legacy_get_prev_frame, get_frame_type): Ditto.
	(get_frame_base_address): Use frame_base_find_by_frame.
	(get_frame_locals_address): Use frame_base_find_by_frame.
	(get_frame_args_address): Use frame_base_find_by_frame.
	* frame-base.h (frame_base_sniffer_ftype): Declare.
	(frame_base_append_sniffer): Declare.
	(frame_base_find_by_frame): Replace frame_base_find_by_pc.
	* frame-base.c (append_predicate): Add a "sniffer" parameter.
	(frame_base_append_sniffer): New function.
	(frame_base_append_predicate): Add a NULL sniffer.
	(frame_base_find_by_frame): Replace "frame_base_find_by_pc".
	(struct frame_base_table): Add "sniffer".
	(frame_base_free): Free the "sniffer" table.
	* frame-unwind.h (frame_unwind_sniffer_ftype): Define.
	(frame_unwind_append_sniffer): Declare.
	(frame_unwind_find_by_frame): Replace frame_unwind_find_by_pc.
	* frame-unwind.c (frame_unwind_free): Free the "sniffer" table.
	(struct frame_unwind_table): Add "sniffer", delete "middle".
	(append_predicate): Add "sniffer" parameter, append the sniffer.
	(frame_unwind_init): Update append_predicate call.
	(frame_unwind_append_sniffer): New function.
	(frame_unwind_append_predicate): Update append_predicate call.
	(frame_unwind_find_by_frame): Replace frame_unwind_find_by_pc.
This commit is contained in:
Andrew Cagney 2003-07-15 17:35:00 +00:00
parent 0714963c79
commit e8a89fe278
6 changed files with 142 additions and 63 deletions

View File

@ -1,3 +1,31 @@
2003-07-15 Andrew Cagney <cagney@redhat.com>
* frame.c (get_frame_id): Use frame_unwind_find_by_frame.
(frame_register_unwind, create_new_frame): Ditto.
(legacy_get_prev_frame, get_frame_type): Ditto.
(get_frame_base_address): Use frame_base_find_by_frame.
(get_frame_locals_address): Use frame_base_find_by_frame.
(get_frame_args_address): Use frame_base_find_by_frame.
* frame-base.h (frame_base_sniffer_ftype): Declare.
(frame_base_append_sniffer): Declare.
(frame_base_find_by_frame): Replace frame_base_find_by_pc.
* frame-base.c (append_predicate): Add a "sniffer" parameter.
(frame_base_append_sniffer): New function.
(frame_base_append_predicate): Add a NULL sniffer.
(frame_base_find_by_frame): Replace "frame_base_find_by_pc".
(struct frame_base_table): Add "sniffer".
(frame_base_free): Free the "sniffer" table.
* frame-unwind.h (frame_unwind_sniffer_ftype): Define.
(frame_unwind_append_sniffer): Declare.
(frame_unwind_find_by_frame): Replace frame_unwind_find_by_pc.
* frame-unwind.c (frame_unwind_free): Free the "sniffer" table.
(struct frame_unwind_table): Add "sniffer", delete "middle".
(append_predicate): Add "sniffer" parameter, append the sniffer.
(frame_unwind_init): Update append_predicate call.
(frame_unwind_append_sniffer): New function.
(frame_unwind_append_predicate): Update append_predicate call.
(frame_unwind_find_by_frame): Replace frame_unwind_find_by_pc.
2003-07-15 Andrew Cagney <cagney@redhat.com>
* frame.c (get_prev_frame): Move disabled inside_entry_func to

View File

@ -71,6 +71,7 @@ static struct gdbarch_data *frame_base_data;
struct frame_base_table
{
frame_base_p_ftype **p;
frame_base_sniffer_ftype **sniffer;
const struct frame_base *default_base;
int nr;
};
@ -89,6 +90,7 @@ frame_base_free (struct gdbarch *gdbarch, void *data)
struct frame_base_table *table =
gdbarch_data (gdbarch, frame_base_data);
xfree (table->p);
xfree (table->sniffer);
xfree (table);
}
@ -108,11 +110,16 @@ frame_base_table (struct gdbarch *gdbarch)
/* Append a predicate to the end of the table. */
static void
append_predicate (struct frame_base_table *table, frame_base_p_ftype *p)
append_predicate (struct frame_base_table *table, frame_base_p_ftype *p,
frame_base_sniffer_ftype *sniffer)
{
table->p = xrealloc (table->p, ((table->nr + 1)
* sizeof (frame_base_p_ftype *)));
table->sniffer = xrealloc (table->sniffer,
((table->nr + 1)
* sizeof (frame_base_sniffer_ftype *)));
table->p[table->nr] = p;
table->sniffer[table->nr] = sniffer;
table->nr++;
}
@ -121,7 +128,15 @@ frame_base_append_predicate (struct gdbarch *gdbarch,
frame_base_p_ftype *p)
{
struct frame_base_table *table = frame_base_table (gdbarch);
append_predicate (table, p);
append_predicate (table, p, NULL);
}
void
frame_base_append_sniffer (struct gdbarch *gdbarch,
frame_base_sniffer_ftype *sniffer)
{
struct frame_base_table *table = frame_base_table (gdbarch);
append_predicate (table, NULL, sniffer);
}
void
@ -133,13 +148,18 @@ frame_base_set_default (struct gdbarch *gdbarch,
}
const struct frame_base *
frame_base_find_by_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
frame_base_find_by_frame (struct frame_info *next_frame)
{
int i;
struct gdbarch *gdbarch = get_frame_arch (next_frame);
struct frame_base_table *table = frame_base_table (gdbarch);
int i;
for (i = 0; i < table->nr; i++)
{
const struct frame_base *desc = table->p[i] (pc);
const struct frame_base *desc = NULL;
if (table->p[i] != NULL)
desc = table->p[i] (frame_pc_unwind (next_frame));
else if (table->sniffer[i] != NULL)
desc = table->sniffer[i] (next_frame);
if (desc != NULL)
return desc;
}

View File

@ -29,30 +29,12 @@ struct frame_base;
struct gdbarch;
struct regcache;
/* Return the frame base methods for the function that contains PC, or
NULL if it can't handle this frame. */
/* For compatibility. */
typedef const struct frame_base *(frame_base_p_ftype) (CORE_ADDR pc);
/* Add a frame base handler to the list. The predicates are polled in
the order that they are appended. */
extern void frame_base_append_predicate (struct gdbarch *gdbarch,
frame_base_p_ftype *p);
/* Set the default frame base. If all else fails, this one is
returned. If this isn't set, the default is to use legacy code
that uses things like the frame ID's base (ulgh!). */
extern void frame_base_set_default (struct gdbarch *gdbarch,
const struct frame_base *def);
/* Iterate through the list of frame base handlers until one returns
an implementation. */
extern const struct frame_base *frame_base_find_by_pc (struct gdbarch *gdbarch,
CORE_ADDR pc);
/* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
and that this is a `normal frame'; use the NEXT frame, and its
register unwind method, to determine the address of THIS frame's
@ -91,4 +73,27 @@ struct frame_base
frame_this_args_ftype *this_args;
};
/* Given the NEXT frame, return the frame base methods for THIS frame,
or NULL if it can't handle THIS frame. */
typedef const struct frame_base *(frame_base_sniffer_ftype) (struct frame_info *next_frame);
/* Append a frame base sniffer to the list. The sniffers are polled
in the order that they are appended. */
extern void frame_base_append_sniffer (struct gdbarch *gdbarch,
frame_base_sniffer_ftype *sniffer);
/* Set the default frame base. If all else fails, this one is
returned. If this isn't set, the default is to use legacy code
that uses things like the frame ID's base (ulgh!). */
extern void frame_base_set_default (struct gdbarch *gdbarch,
const struct frame_base *def);
/* Iterate through the list of frame base handlers until one returns
an implementation. */
extern const struct frame_base *frame_base_find_by_frame (struct frame_info *next_frame);
#endif

View File

@ -30,17 +30,21 @@ static struct gdbarch_data *frame_unwind_data;
struct frame_unwind_table
{
frame_unwind_p_ftype **p;
int middle;
frame_unwind_sniffer_ftype **sniffer;
int nr;
};
/* Append a predicate to the end of the table. */
static void
append_predicate (struct frame_unwind_table *table, frame_unwind_p_ftype *p)
append_predicate (struct frame_unwind_table *table, frame_unwind_p_ftype *p,
frame_unwind_sniffer_ftype *sniffer)
{
table->p = xrealloc (table->p, ((table->nr + 1)
* sizeof (frame_unwind_p_ftype *)));
table->sniffer = xrealloc (table->sniffer, ((table->nr + 1)
* sizeof (frame_unwind_sniffer_ftype *)));
table->p[table->nr] = p;
table->sniffer[table->nr] = sniffer;
table->nr++;
}
@ -48,7 +52,7 @@ static void *
frame_unwind_init (struct gdbarch *gdbarch)
{
struct frame_unwind_table *table = XCALLOC (1, struct frame_unwind_table);
append_predicate (table, dummy_frame_p);
append_predicate (table, dummy_frame_p, NULL);
return table;
}
@ -58,6 +62,7 @@ frame_unwind_free (struct gdbarch *gdbarch, void *data)
struct frame_unwind_table *table =
gdbarch_data (gdbarch, frame_unwind_data);
xfree (table->p);
xfree (table->sniffer);
xfree (table);
}
@ -74,15 +79,31 @@ frame_unwind_append_predicate (struct gdbarch *gdbarch,
table = frame_unwind_init (gdbarch);
set_gdbarch_data (gdbarch, frame_unwind_data, table);
}
append_predicate (table, p);
append_predicate (table, p, NULL);
}
void
frame_unwind_append_sniffer (struct gdbarch *gdbarch,
frame_unwind_sniffer_ftype *sniffer)
{
struct frame_unwind_table *table =
gdbarch_data (gdbarch, frame_unwind_data);
if (table == NULL)
{
/* ULGH, called during architecture initialization. Patch
things up. */
table = frame_unwind_init (gdbarch);
set_gdbarch_data (gdbarch, frame_unwind_data, table);
}
append_predicate (table, NULL, sniffer);
}
const struct frame_unwind *
frame_unwind_find_by_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
frame_unwind_find_by_frame (struct frame_info *next_frame)
{
int i;
struct frame_unwind_table *table =
gdbarch_data (gdbarch, frame_unwind_data);
struct gdbarch *gdbarch = get_frame_arch (next_frame);
struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
if (!DEPRECATED_USE_GENERIC_DUMMY_FRAMES)
/* Seriously old code. Don't even try to use this new mechanism.
(Note: The variable USE_GENERIC_DUMMY_FRAMES is deprecated, not
@ -91,7 +112,13 @@ frame_unwind_find_by_pc (struct gdbarch *gdbarch, CORE_ADDR pc)
return legacy_saved_regs_unwind;
for (i = 0; i < table->nr; i++)
{
const struct frame_unwind *desc = table->p[i] (pc);
const struct frame_unwind *desc;
if (table->p[i] != NULL)
desc = table->p[i] (frame_pc_unwind (next_frame));
else if (table->sniffer[i] != NULL)
desc = table->sniffer[i] (next_frame);
else
internal_error (__FILE__, __LINE__, "Missing sniffer?");
if (desc != NULL)
return desc;
}

View File

@ -30,25 +30,12 @@ struct regcache;
#include "frame.h" /* For enum frame_type. */
/* Return the frame unwind methods for the function that contains PC,
or NULL if this this unwinder can't handle this frame. */
/* For compatibility with the old frame code. See end of header for
new methods. */
typedef const struct frame_unwind *(frame_unwind_p_ftype) (CORE_ADDR pc);
/* Add a frame unwinder to the list. The predicates are polled in the
order that they are appended. The initial list contains the dummy
frame's predicate. */
extern void frame_unwind_append_predicate (struct gdbarch *gdbarch,
frame_unwind_p_ftype *p);
/* Iterate through the list of frame unwinders until one returns an
implementation. */
extern const struct frame_unwind *frame_unwind_find_by_pc (struct gdbarch
*gdbarch,
CORE_ADDR pc);
/* The following unwind functions assume a chain of frames forming the
sequence: (outer) prev <-> this <-> next (inner). All the
functions are called with called with the next frame's `struct
@ -139,4 +126,22 @@ struct frame_unwind
frame_prev_register_ftype *prev_register;
};
/* 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. */
typedef const struct frame_unwind *(frame_unwind_sniffer_ftype) (struct frame_info *next_frame);
/* Add a frame sniffer to the list. The predicates are polled in the
order that they are appended. The initial list contains the dummy
frame sniffer. */
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. */
extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame);
#endif

View File

@ -229,8 +229,7 @@ get_frame_id (struct frame_info *fi)
/* Find the unwinder. */
if (fi->unwind == NULL)
{
fi->unwind = frame_unwind_find_by_pc (current_gdbarch,
get_frame_pc (fi));
fi->unwind = frame_unwind_find_by_frame (fi->next);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunatly, legacy code, called by
@ -517,8 +516,7 @@ frame_register_unwind (struct frame_info *frame, int regnum,
/* Find the unwinder. */
if (frame->unwind == NULL)
{
frame->unwind = frame_unwind_find_by_pc (current_gdbarch,
get_frame_pc (frame));
frame->unwind = frame_unwind_find_by_frame (frame->next);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunatly, legacy code, called by
@ -1206,7 +1204,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_pc (current_gdbarch, pc);
fi->unwind = frame_unwind_find_by_frame (fi->next);
if (fi->unwind->type != UNKNOWN_FRAME)
fi->type = fi->unwind->type;
else
@ -1365,8 +1363,7 @@ 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_pc (current_gdbarch,
get_frame_pc (prev));
prev->unwind = frame_unwind_find_by_frame (prev->next);
if (prev->unwind->type == UNKNOWN_FRAME)
prev->type = frame_type_from_pc (get_frame_pc (prev));
else
@ -1514,8 +1511,7 @@ 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_pc (current_gdbarch,
frame_pc_unwind (this_frame));
prev->unwind = frame_unwind_find_by_frame (this_frame->next);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunatly, legacy code, called by
@ -1676,8 +1672,7 @@ 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_pc (current_gdbarch,
get_frame_pc (prev));
prev->unwind = frame_unwind_find_by_frame (prev->next);
/* If the unwinder provides a frame type, use it. Otherwize
continue on to that heuristic mess. */
@ -2090,7 +2085,7 @@ get_frame_base_address (struct frame_info *fi)
if (get_frame_type (fi) != NORMAL_FRAME)
return 0;
if (fi->base == NULL)
fi->base = frame_base_find_by_pc (current_gdbarch, get_frame_pc (fi));
fi->base = frame_base_find_by_frame (fi->next);
/* Sneaky: If the low-level unwind and high-level base code share a
common unwinder, let them share the prologue cache. */
if (fi->base->unwind == fi->unwind)
@ -2106,7 +2101,7 @@ get_frame_locals_address (struct frame_info *fi)
return 0;
/* If there isn't a frame address method, find it. */
if (fi->base == NULL)
fi->base = frame_base_find_by_pc (current_gdbarch, get_frame_pc (fi));
fi->base = frame_base_find_by_frame (fi->next);
/* Sneaky: If the low-level unwind and high-level base code share a
common unwinder, let them share the prologue cache. */
if (fi->base->unwind == fi->unwind)
@ -2124,7 +2119,7 @@ get_frame_args_address (struct frame_info *fi)
return 0;
/* If there isn't a frame address method, find it. */
if (fi->base == NULL)
fi->base = frame_base_find_by_pc (current_gdbarch, get_frame_pc (fi));
fi->base = frame_base_find_by_frame (fi->next);
/* Sneaky: If the low-level unwind and high-level base code share a
common unwinder, let them share the prologue cache. */
if (fi->base->unwind == fi->unwind)
@ -2163,8 +2158,7 @@ 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_pc (current_gdbarch,
get_frame_pc (frame));
frame->unwind = frame_unwind_find_by_frame (frame->next);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunatly, legacy code, called by