summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2004-03-21 22:28:52 +0000
committerAndrew Cagney <cagney@redhat.com>2004-03-21 22:28:52 +0000
commit3d0e5d44322383b9989cbaaa8c8f644ffeffbbd3 (patch)
treee02e71c97cbc54a8be6bd19a4ec1f44838feeb9a
parent4c73f0a0679827d838a68c7db3c55cb5542396ee (diff)
downloadgdb-3d0e5d44322383b9989cbaaa8c8f644ffeffbbd3.tar.gz
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.
-rw-r--r--gdb/ChangeLog17
-rw-r--r--gdb/frame-unwind.c31
-rw-r--r--gdb/frame-unwind.h24
-rw-r--r--gdb/frame.c20
4 files changed, 77 insertions, 15 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 53824f1d941..6bbe41593dd 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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
diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index 1d340912dac..cacb2ed4160 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -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;
}
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index 8d17280fc9a..49f28896ffe 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -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
diff --git a/gdb/frame.c b/gdb/frame.c
index 1af200fe60b..7df7c43e296 100644
--- a/gdb/frame.c
+++ b/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