This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch/rfc] frame_unwind_register_unwinder -> frame_unwind_prepend_unwinder


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
2004-04-03  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 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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]