2004-04-08 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Thu, 8 Apr 2004 20:03:52 +0000 (20:03 +0000)
committerAndrew Cagney <cagney@redhat.com>
Thu, 8 Apr 2004 20:03:52 +0000 (20:03 +0000)
* 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.

gdb/ChangeLog
gdb/frame-unwind.c
gdb/frame-unwind.h
gdb/mips-linux-tdep.c
gdb/tramp-frame.c
gdb/tramp-frame.h

index 9a78c86d93d647cb863e421ae98be4c6a4c5650f..09e800a1abacb9a9d47fce183790e95535d6d407 100644 (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>
 
        * ppc-linux-tdep.c (ELF_NREG, ELF_NFPREG, ELF_NVRREG)
index ac26a643a840fa791493f48c4d65bc7ca598b119..71c8def0c21c1200e3dcad85f6347b223c10998d 100644 (file)
@@ -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)
        {
index 49f28896ffe602c4103eaaee2e08d60123dcbb43..12d6dd240ed85d3fdfed3ea5c550306069e89987 100644 (file)
@@ -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
index 48a82f7cf36c57ae4f099d2911a141f1613f8d6d..d512446d04c3c372e36b0a832699bee12a9ba1eb 100644 (file)
@@ -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");
index 528603c745257387232baa24cf4db3cd2620be41..6ea2e3f1ebe1f46da32f6320e74fabdb0e6ec3c3 100644 (file)
@@ -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);
 }
index 54f29bbca54ab8e27cf5e7e303111f42f4421844..26d4178e7be2e84a1ea18b7646c3b5359792d80a 100644 (file)
@@ -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