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.
This commit is contained in:
Andrew Cagney
2004-04-08 20:03:52 +00:00
parent 67faf00763
commit fb2be677dc
6 changed files with 58 additions and 28 deletions

View File

@ -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> 2004-04-08 Kevin Buettner <kevinb@redhat.com>
* ppc-linux-tdep.c (ELF_NREG, ELF_NFPREG, ELF_NVRREG) * ppc-linux-tdep.c (ELF_NREG, ELF_NFPREG, ELF_NVRREG)

View File

@ -37,8 +37,9 @@ struct frame_unwind_table_entry
struct frame_unwind_table struct frame_unwind_table
{ {
struct frame_unwind_table_entry *head; struct frame_unwind_table_entry *list;
struct frame_unwind_table_entry **tail; /* The head of the OSABI part of the search list. */
struct frame_unwind_table_entry **osabi_head;
}; };
static void * static void *
@ -46,9 +47,12 @@ frame_unwind_init (struct obstack *obstack)
{ {
struct frame_unwind_table *table struct frame_unwind_table *table
= OBSTACK_ZALLOC (obstack, struct frame_unwind_table); = OBSTACK_ZALLOC (obstack, struct frame_unwind_table);
table->head = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry); /* Start the table out with a few default sniffers. OSABI code
table->head->sniffer = dummy_frame_sniffer; can't override this. */
table->tail = &table->head->next; 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; return table;
} }
@ -57,20 +61,26 @@ frame_unwind_append_sniffer (struct gdbarch *gdbarch,
frame_unwind_sniffer_ftype *sniffer) frame_unwind_sniffer_ftype *sniffer)
{ {
struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data); struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
(*table->tail) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry); struct frame_unwind_table_entry **ip;
(*table->tail)->sniffer = sniffer;
table->tail = &((*table->tail)->next); /* 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 void
frame_unwind_register_unwinder (struct gdbarch *gdbarch, frame_unwind_prepend_unwinder (struct gdbarch *gdbarch,
const struct frame_unwind *unwinder) const struct frame_unwind *unwinder)
{ {
struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data); struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
(*table->tail) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry *entry;
struct frame_unwind_table_entry);
(*table->tail)->unwinder = unwinder; /* Insert the new entry at the start of the list. */
table->tail = &((*table->tail)->next); 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 * 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 gdbarch *gdbarch = get_frame_arch (next_frame);
struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data); struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
struct frame_unwind_table_entry *entry; 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) if (entry->sniffer != NULL)
{ {

View File

@ -131,11 +131,14 @@ struct frame_unwind
frame_sniffer_ftype *sniffer; frame_sniffer_ftype *sniffer;
}; };
/* Register a frame unwinder, _appending_ it to the end of the search /* Register a frame unwinder, _prepending_ it to the front of the
list. */ search list (so it is sniffed before previously registered
extern void frame_unwind_register_unwinder (struct gdbarch *gdbarch, unwinders). By using a prepend, later calls can install unwinders
const struct frame_unwind *unwinder); 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 /* 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 PC and attributes) and if it is the applicable unwinder return

View File

@ -1119,8 +1119,8 @@ mips_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_solib_svr4_fetch_link_map_offsets set_solib_svr4_fetch_link_map_offsets
(gdbarch, mips_linux_svr4_fetch_link_map_offsets); (gdbarch, mips_linux_svr4_fetch_link_map_offsets);
set_mips_linux_register_addr (gdbarch, mips_linux_register_addr); set_mips_linux_register_addr (gdbarch, mips_linux_register_addr);
tramp_frame_append (gdbarch, &mips_linux_o32_sigframe); tramp_frame_prepend_unwinder (gdbarch, &mips_linux_o32_sigframe);
tramp_frame_append (gdbarch, &mips_linux_o32_rt_sigframe); tramp_frame_prepend_unwinder (gdbarch, &mips_linux_o32_rt_sigframe);
break; break;
case MIPS_ABI_N32: case MIPS_ABI_N32:
set_gdbarch_get_longjmp_target (gdbarch, 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 set_solib_svr4_fetch_link_map_offsets
(gdbarch, mips_linux_svr4_fetch_link_map_offsets); (gdbarch, mips_linux_svr4_fetch_link_map_offsets);
set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr); 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; break;
case MIPS_ABI_N64: case MIPS_ABI_N64:
set_gdbarch_get_longjmp_target (gdbarch, 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 set_solib_svr4_fetch_link_map_offsets
(gdbarch, mips64_linux_svr4_fetch_link_map_offsets); (gdbarch, mips64_linux_svr4_fetch_link_map_offsets);
set_mips_linux_register_addr (gdbarch, mips64_linux_register_addr); 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; break;
default: default:
internal_error (__FILE__, __LINE__, "can't handle ABI"); internal_error (__FILE__, __LINE__, "can't handle ABI");

View File

@ -146,8 +146,8 @@ tramp_frame_sniffer (const struct frame_unwind *self,
} }
void void
tramp_frame_append (struct gdbarch *gdbarch, tramp_frame_prepend_unwinder (struct gdbarch *gdbarch,
const struct tramp_frame *tramp_frame) const struct tramp_frame *tramp_frame)
{ {
struct frame_data *data; struct frame_data *data;
struct frame_unwind *unwinder; struct frame_unwind *unwinder;
@ -171,5 +171,5 @@ tramp_frame_append (struct gdbarch *gdbarch,
unwinder->sniffer = tramp_frame_sniffer; unwinder->sniffer = tramp_frame_sniffer;
unwinder->this_id = tramp_frame_this_id; unwinder->this_id = tramp_frame_this_id;
unwinder->prev_register = tramp_frame_prev_register; unwinder->prev_register = tramp_frame_prev_register;
frame_unwind_register_unwinder (gdbarch, unwinder); frame_unwind_prepend_unwinder (gdbarch, unwinder);
} }

View File

@ -63,7 +63,7 @@ struct tramp_frame
CORE_ADDR func); CORE_ADDR func);
}; };
void tramp_frame_append (struct gdbarch *gdbarch, void tramp_frame_prepend_unwinder (struct gdbarch *gdbarch,
const struct tramp_frame *tramp); const struct tramp_frame *tramp);
#endif #endif