diff options
author | Andrew Cagney <cagney@redhat.com> | 2004-04-08 20:03:52 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 2004-04-08 20:03:52 +0000 |
commit | fb2be677dcb440b001df7739bda229295910a7c8 (patch) | |
tree | 343dee28c6245e56eabcebd5fb77ac965c7ab071 /gdb | |
parent | 67faf007637dbb56ab9efb68af7a800a29bf3141 (diff) | |
download | gdb-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.
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 17 | ||||
-rw-r--r-- | gdb/frame-unwind.c | 38 | ||||
-rw-r--r-- | gdb/frame-unwind.h | 13 | ||||
-rw-r--r-- | gdb/mips-linux-tdep.c | 8 | ||||
-rw-r--r-- | gdb/tramp-frame.c | 6 | ||||
-rw-r--r-- | gdb/tramp-frame.h | 4 |
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 |