From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4985 invoked by alias); 3 Apr 2004 19:33:33 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 4978 invoked from network); 3 Apr 2004 19:33:32 -0000 Received: from unknown (HELO localhost.redhat.com) (24.157.170.238) by sources.redhat.com with SMTP; 3 Apr 2004 19:33:32 -0000 Received: from gnu.org (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id 55C812B92; Sat, 3 Apr 2004 14:33:24 -0500 (EST) Message-ID: <406F1184.5040106@gnu.org> Date: Sat, 03 Apr 2004 19:33:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-GB; rv:1.4.1) Gecko/20040217 MIME-Version: 1.0 To: gdb-patches@sources.redhat.com Subject: [patch/rfc] frame_unwind_register_unwinder -> frame_unwind_prepend_unwinder Content-Type: multipart/mixed; boundary="------------070207000106070407060106" X-SW-Source: 2004-04/txt/msg00100.txt.bz2 This is a multi-part message in MIME format. --------------070207000106070407060106 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 903 Hello, At present unwind sniffers are appeneded to the search list. Consequently to ensure that the more specific OSABI unwinders override the more generic architecture unwinders, the architecture code has to append the sniffers in reverse order. This is contrary to how the rest of the architecture vector is constructed - for other architecture entries, the OSABI does its initialization last, overriding earlier more generic architecture entries. The attached replaces the recently added, and hardly called, rame_unwind_register_unwinder (which does an append) with frame_unwind_prepend_unwinder (which does a prepend). By using this new method, OSABI code can ensure that their methods are always at the front of the unwind sniffer search list, and hence ensure that their methods always override the more generic architecture methods. Comments? I'll leave this for a few days. Andrew --------------070207000106070407060106 Content-Type: text/plain; name="diffs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diffs" Content-length: 7804 2004-04-03 Andrew Cagney * 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 sniffer so that it can both prepend and append sniffers. Replace frame_unwind_register_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. Index: frame-unwind.c =================================================================== RCS file: /cvs/src/src/gdb/frame-unwind.c,v retrieving revision 1.11 diff -u -r1.11 frame-unwind.c --- frame-unwind.c 21 Mar 2004 22:28:52 -0000 1.11 +++ frame-unwind.c 3 Apr 2004 19:23:38 -0000 @@ -37,8 +37,9 @@ 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 @@ { 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_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 * @@ -86,7 +96,7 @@ the dummy frame mechanism. All architectures should be using generic dummy frames). */ return legacy_saved_regs_unwind; - for (entry = table->head; entry != NULL; entry = entry->next) + for (entry = table->list; entry != NULL; entry = entry->next) { if (entry->sniffer != NULL) { Index: frame-unwind.h =================================================================== RCS file: /cvs/src/src/gdb/frame-unwind.h,v retrieving revision 1.10 diff -u -r1.10 frame-unwind.h --- frame-unwind.h 21 Mar 2004 22:28:52 -0000 1.10 +++ frame-unwind.h 3 Apr 2004 19:23:38 -0000 @@ -131,11 +131,14 @@ 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 Index: mips-linux-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/mips-linux-tdep.c,v retrieving revision 1.21 diff -u -r1.21 mips-linux-tdep.c --- mips-linux-tdep.c 25 Mar 2004 01:27:26 -0000 1.21 +++ mips-linux-tdep.c 3 Apr 2004 19:23:40 -0000 @@ -1119,8 +1119,8 @@ 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 @@ 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 @@ 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"); Index: tramp-frame.c =================================================================== RCS file: /cvs/src/src/gdb/tramp-frame.c,v retrieving revision 1.4 diff -u -r1.4 tramp-frame.c --- tramp-frame.c 2 Apr 2004 19:44:25 -0000 1.4 +++ tramp-frame.c 3 Apr 2004 19:23:40 -0000 @@ -146,8 +146,8 @@ } 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 @@ 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); } Index: tramp-frame.h =================================================================== RCS file: /cvs/src/src/gdb/tramp-frame.h,v retrieving revision 1.3 diff -u -r1.3 tramp-frame.h --- tramp-frame.h 24 Mar 2004 23:14:39 -0000 1.3 +++ tramp-frame.h 3 Apr 2004 19:23:40 -0000 @@ -63,7 +63,7 @@ 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 --------------070207000106070407060106--