aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2004-04-08 20:03:52 +0000
committerAndrew Cagney <cagney@redhat.com>2004-04-08 20:03:52 +0000
commitfb2be677dcb440b001df7739bda229295910a7c8 (patch)
tree343dee28c6245e56eabcebd5fb77ac965c7ab071
parent67faf007637dbb56ab9efb68af7a800a29bf3141 (diff)
downloadgdb-fb2be677dcb440b001df7739bda229295910a7c8.zip
gdb-fb2be677dcb440b001df7739bda229295910a7c8.tar.gz
gdb-fb2be677dcb440b001df7739bda229295910a7c8.tar.bz2
2004-04-08 Andrew Cagney <cagney@redhat.com>
* frame-unwind.c (struct frame_unwind_table, frame_unwind_init) (frame_unwind_prepend_unwinder, frame_unwind_append_sniffer) (frame_unwind_find_by_frame): Re-implement the unwind code so that it can both prepend and append sniffers. Replace frame_unwind_register_unwinder with frame_unwind_prepend_unwinder. * tramp-frame.c (tramp_frame_append): Use frame_unwind_prepend_unwinder. * frame-unwind.h (frame_unwind_prepend_unwinder): Replace frame_unwind_register_unwinder. * tramp-frame.h (tramp_frame_prepend_unwinder): Rename tramp_frame_append. * tramp-frame.c (tramp_frame_prepend_unwinder): Update. * mips-linux-tdep.c (mips_linux_init_abi, mips_linux_init_abi) (mips_linux_init_abi): Update.
-rw-r--r--gdb/ChangeLog17
-rw-r--r--gdb/frame-unwind.c38
-rw-r--r--gdb/frame-unwind.h13
-rw-r--r--gdb/mips-linux-tdep.c8
-rw-r--r--gdb/tramp-frame.c6
-rw-r--r--gdb/tramp-frame.h4
6 files changed, 58 insertions, 28 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 9a78c86..09e800a 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,20 @@
+2004-04-08 Andrew Cagney <cagney@redhat.com>
+
+ * frame-unwind.c (struct frame_unwind_table, frame_unwind_init)
+ (frame_unwind_prepend_unwinder, frame_unwind_append_sniffer)
+ (frame_unwind_find_by_frame): Re-implement the unwind code so
+ that it can both prepend and append sniffers. Replace
+ frame_unwind_register_unwinder with frame_unwind_prepend_unwinder.
+ * tramp-frame.c (tramp_frame_append): Use
+ frame_unwind_prepend_unwinder.
+ * frame-unwind.h (frame_unwind_prepend_unwinder): Replace
+ frame_unwind_register_unwinder.
+ * tramp-frame.h (tramp_frame_prepend_unwinder): Rename
+ tramp_frame_append.
+ * tramp-frame.c (tramp_frame_prepend_unwinder): Update.
+ * mips-linux-tdep.c (mips_linux_init_abi, mips_linux_init_abi)
+ (mips_linux_init_abi): Update.
+
2004-04-08 Kevin Buettner <kevinb@redhat.com>
* ppc-linux-tdep.c (ELF_NREG, ELF_NFPREG, ELF_NVRREG)
diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index ac26a64..71c8def 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -37,8 +37,9 @@ struct frame_unwind_table_entry
struct frame_unwind_table
{
- struct frame_unwind_table_entry *head;
- struct frame_unwind_table_entry **tail;
+ struct frame_unwind_table_entry *list;
+ /* The head of the OSABI part of the search list. */
+ struct frame_unwind_table_entry **osabi_head;
};
static void *
@@ -46,9 +47,12 @@ frame_unwind_init (struct obstack *obstack)
{
struct frame_unwind_table *table
= OBSTACK_ZALLOC (obstack, struct frame_unwind_table);
- table->head = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry);
- table->head->sniffer = dummy_frame_sniffer;
- table->tail = &table->head->next;
+ /* Start the table out with a few default sniffers. OSABI code
+ can't override this. */
+ table->list = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry);
+ table->list->sniffer = dummy_frame_sniffer;
+ /* The insertion point for OSABI sniffers. */
+ table->osabi_head = &table->list->next;
return table;
}
@@ -57,20 +61,26 @@ frame_unwind_append_sniffer (struct gdbarch *gdbarch,
frame_unwind_sniffer_ftype *sniffer)
{
struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
- (*table->tail) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
- (*table->tail)->sniffer = sniffer;
- table->tail = &((*table->tail)->next);
+ struct frame_unwind_table_entry **ip;
+
+ /* Find the end of the list and insert the new entry there. */
+ for (ip = table->osabi_head; (*ip) != NULL; ip = &(*ip)->next);
+ (*ip) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
+ (*ip)->sniffer = sniffer;
}
void
-frame_unwind_register_unwinder (struct gdbarch *gdbarch,
+frame_unwind_prepend_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);
+ struct frame_unwind_table_entry *entry;
+
+ /* Insert the new entry at the start of the list. */
+ entry = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
+ entry->unwinder = unwinder;
+ entry->next = (*table->osabi_head);
+ (*table->osabi_head) = entry;
}
const struct frame_unwind *
@@ -80,7 +90,7 @@ frame_unwind_find_by_frame (struct frame_info *next_frame, void **this_cache)
struct gdbarch *gdbarch = get_frame_arch (next_frame);
struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
struct frame_unwind_table_entry *entry;
- for (entry = table->head; entry != NULL; entry = entry->next)
+ for (entry = table->list; entry != NULL; entry = entry->next)
{
if (entry->sniffer != NULL)
{
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index 49f2889..12d6dd2 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -131,11 +131,14 @@ struct frame_unwind
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);
-
+/* Register a frame unwinder, _prepending_ it to the front of the
+ search list (so it is sniffed before previously registered
+ unwinders). By using a prepend, later calls can install unwinders
+ that override earlier calls. This allows, for instance, an OSABI
+ to install a a more specific sigtramp unwinder that overrides the
+ traditional brute-force unwinder. */
+extern void frame_unwind_prepend_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
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index 48a82f7..d512446 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -1119,8 +1119,8 @@ mips_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_solib_svr4_fetch_link_map_offsets
(gdbarch, mips_linux_svr4_fetch_link_map_offsets);
set_mips_linux_register_addr (gdbarch, mips_linux_register_addr);
- tramp_frame_append (gdbarch, &mips_linux_o32_sigframe);
- tramp_frame_append (gdbarch, &mips_linux_o32_rt_sigframe);
+ tramp_frame_prepend_unwinder (gdbarch, &mips_linux_o32_sigframe);
+ tramp_frame_prepend_unwinder (gdbarch, &mips_linux_o32_rt_sigframe);
break;
case MIPS_ABI_N32:
set_gdbarch_get_longjmp_target (gdbarch,
@@ -1128,7 +1128,7 @@ mips_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_solib_svr4_fetch_link_map_offsets
(gdbarch, mips_linux_svr4_fetch_link_map_offsets);
set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr);
- tramp_frame_append (gdbarch, &mips_linux_n32_rt_sigframe);
+ tramp_frame_prepend_unwinder (gdbarch, &mips_linux_n32_rt_sigframe);
break;
case MIPS_ABI_N64:
set_gdbarch_get_longjmp_target (gdbarch,
@@ -1136,7 +1136,7 @@ mips_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_solib_svr4_fetch_link_map_offsets
(gdbarch, mips64_linux_svr4_fetch_link_map_offsets);
set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr);
- tramp_frame_append (gdbarch, &mips_linux_n64_rt_sigframe);
+ tramp_frame_prepend_unwinder (gdbarch, &mips_linux_n64_rt_sigframe);
break;
default:
internal_error (__FILE__, __LINE__, "can't handle ABI");
diff --git a/gdb/tramp-frame.c b/gdb/tramp-frame.c
index 528603c..6ea2e3f 100644
--- a/gdb/tramp-frame.c
+++ b/gdb/tramp-frame.c
@@ -146,8 +146,8 @@ tramp_frame_sniffer (const struct frame_unwind *self,
}
void
-tramp_frame_append (struct gdbarch *gdbarch,
- const struct tramp_frame *tramp_frame)
+tramp_frame_prepend_unwinder (struct gdbarch *gdbarch,
+ const struct tramp_frame *tramp_frame)
{
struct frame_data *data;
struct frame_unwind *unwinder;
@@ -171,5 +171,5 @@ tramp_frame_append (struct gdbarch *gdbarch,
unwinder->sniffer = tramp_frame_sniffer;
unwinder->this_id = tramp_frame_this_id;
unwinder->prev_register = tramp_frame_prev_register;
- frame_unwind_register_unwinder (gdbarch, unwinder);
+ frame_unwind_prepend_unwinder (gdbarch, unwinder);
}
diff --git a/gdb/tramp-frame.h b/gdb/tramp-frame.h
index 54f29bb..26d4178 100644
--- a/gdb/tramp-frame.h
+++ b/gdb/tramp-frame.h
@@ -63,7 +63,7 @@ struct tramp_frame
CORE_ADDR func);
};
-void tramp_frame_append (struct gdbarch *gdbarch,
- const struct tramp_frame *tramp);
+void tramp_frame_prepend_unwinder (struct gdbarch *gdbarch,
+ const struct tramp_frame *tramp);
#endif