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]

[commit/tramp branch] The real tramp-frame patch


Hello,

I've committed the attached to the tramp branch.

It contains today's earlier post (the interesting bits), all the house keeping needed to make it work, and the import of recent gdbarch init changes.

Andrew
Index: dummy-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dummy-frame.c,v
retrieving revision 1.27.12.1
diff -u -r1.27.12.1 dummy-frame.c
--- dummy-frame.c	9 Mar 2004 22:58:58 -0000	1.27.12.1
+++ dummy-frame.c	16 Mar 2004 16:01:39 -0000
@@ -403,7 +403,7 @@
 					     (*this_id).stack_addr);
 }
 
-static const struct frame_unwind dummy_frame_unwind =
+static struct frame_unwind dummy_frame_unwind =
 {
   DUMMY_FRAME,
   dummy_frame_this_id,
@@ -411,8 +411,7 @@
 };
 
 const struct frame_unwind *
-dummy_frame_sniffer (const struct frame_unwind_sniffer *self,
-		     struct frame_info *next_frame)
+dummy_frame_sniffer (struct frame_info *next_frame)
 {
   CORE_ADDR pc = frame_pc_unwind (next_frame);
   if (DEPRECATED_PC_IN_CALL_DUMMY_P ()
Index: dummy-frame.h
===================================================================
RCS file: /cvs/src/src/gdb/dummy-frame.h,v
retrieving revision 1.12.18.1
diff -u -r1.12.18.1 dummy-frame.h
--- dummy-frame.h	9 Mar 2004 22:58:58 -0000	1.12.18.1
+++ dummy-frame.h	16 Mar 2004 16:01:39 -0000
@@ -26,7 +26,6 @@
 struct regcache;
 struct frame_unwind;
 struct frame_id;
-struct frame_unwind_sniffer;
 
 /* GENERIC DUMMY FRAMES
   
@@ -49,8 +48,7 @@
 /* If the PC falls in a dummy frame, return a dummy frame
    unwinder.  */
 
-const struct frame_unwind *dummy_frame_sniffer (const struct frame_unwind_sniffer *self,
-						struct frame_info *next_frame);
+extern const struct frame_unwind *dummy_frame_sniffer (struct frame_info *next_frame);
 
 /* Does the PC fall in a dummy frame?
 
Index: dwarf2-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v
retrieving revision 1.31.6.1
diff -u -r1.31.6.1 dwarf2-frame.c
--- dwarf2-frame.c	9 Mar 2004 22:58:58 -0000	1.31.6.1
+++ dwarf2-frame.c	16 Mar 2004 16:01:40 -0000
@@ -509,29 +509,15 @@
 /* Return a default for the architecture-specific operations.  */
 
 static void *
-dwarf2_frame_init (struct gdbarch *gdbarch)
+dwarf2_frame_init (struct obstack *obstack)
 {
   struct dwarf2_frame_ops *ops;
   
-  ops = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct dwarf2_frame_ops);
+  ops = OBSTACK_ZALLOC (obstack, struct dwarf2_frame_ops);
   ops->init_reg = dwarf2_frame_default_init_reg;
   return ops;
 }
 
-static struct dwarf2_frame_ops *
-dwarf2_frame_ops (struct gdbarch *gdbarch)
-{
-  struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
-  if (ops == NULL)
-    {
-      /* ULGH, called during architecture initialization.  Patch
-         things up.  */
-      ops = dwarf2_frame_init (gdbarch);
-      set_gdbarch_data (gdbarch, dwarf2_frame_data, ops);
-    }
-  return ops;
-}
-
 /* Set the architecture-specific register state initialization
    function for GDBARCH to INIT_REG.  */
 
@@ -540,9 +526,8 @@
 			   void (*init_reg) (struct gdbarch *, int,
 					     struct dwarf2_frame_state_reg *))
 {
-  struct dwarf2_frame_ops *ops;
+  struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
 
-  ops = dwarf2_frame_ops (gdbarch);
   ops->init_reg = init_reg;
 }
 
@@ -552,9 +537,8 @@
 dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
 		       struct dwarf2_frame_state_reg *reg)
 {
-  struct dwarf2_frame_ops *ops;
+  struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
 
-  ops = dwarf2_frame_ops (gdbarch);
   ops->init_reg (gdbarch, regnum, reg);
 }
 
@@ -1611,6 +1595,6 @@
 void
 _initialize_dwarf2_frame (void)
 {
-  dwarf2_frame_data = register_gdbarch_data (NULL, dwarf2_frame_init);
+  dwarf2_frame_data = gdbarch_data_register_pre_init (dwarf2_frame_init);
   dwarf2_frame_objfile_data = register_objfile_data ();
 }
Index: frame-base.c
===================================================================
RCS file: /cvs/src/src/gdb/frame-base.c,v
retrieving revision 1.8.18.1
diff -u -r1.8.18.1 frame-base.c
--- frame-base.c	9 Mar 2004 22:58:58 -0000	1.8.18.1
+++ frame-base.c	16 Mar 2004 16:01:40 -0000
@@ -152,5 +152,5 @@
 void
 _initialize_frame_base (void)
 {
-  frame_base_data = register_gdbarch_data (frame_base_init, NULL);
+  frame_base_data = gdbarch_data_register_pre_init (frame_base_init);
 }
Index: frame-unwind.c
===================================================================
RCS file: /cvs/src/src/gdb/frame-unwind.c,v
retrieving revision 1.8.4.1
diff -u -r1.8.4.1 frame-unwind.c
--- frame-unwind.c	9 Mar 2004 22:58:58 -0000	1.8.4.1
+++ frame-unwind.c	16 Mar 2004 16:01:40 -0000
@@ -1,6 +1,6 @@
 /* Definitions for frame unwinder, for GDB, the GNU debugger.
 
-   Copyright 2003 Free Software Foundation, Inc.
+   Copyright 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -30,57 +30,50 @@
 
 struct frame_unwind_table_entry
 {
-  const struct frame_unwind_sniffer *sniffer;
+  frame_unwind_sniffer_ftype *sniffer;
+  const struct frame_unwind *unwinder;
   struct frame_unwind_table_entry *next;
 };
 
 struct frame_unwind_table
 {
-  struct frame_unwind_table_entry *first;
+  struct frame_unwind_table_entry *head;
+  struct frame_unwind_table_entry **tail;
 };
 
 static void *
 frame_unwind_init (struct obstack *obstack)
 {
-  struct frame_unwind_table *table;
-  struct frame_unwind_sniffer *dummy_sniffer;
-
-  dummy_sniffer = OBSTACK_ZALLOC (obstack, struct frame_unwind_sniffer);
-  dummy_sniffer->sniffer = dummy_frame_sniffer;
-
-  table = OBSTACK_ZALLOC (obstack, struct frame_unwind_table);
-  table->first = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry);
-  table->first->sniffer = dummy_sniffer;
-
+  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;
   return table;
 }
 
-/* Append a predicate to the end of the table.  */
-
 void
-frame_unwind_sniffer_append (struct gdbarch *gdbarch,
-			     const struct frame_unwind_sniffer *sniffer)
+frame_unwind_append_sniffer (struct gdbarch *gdbarch,
+			     frame_unwind_sniffer_ftype *sniffer)
 {
   struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
-  struct frame_unwind_table_entry **entry;
-  for (entry = &table->first; (*entry) != NULL; entry = &(*entry)->next);
-  (*entry) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
-  (*entry)->sniffer = sniffer;
+  (*table->tail) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
+  (*table->tail)->sniffer = sniffer;
+  table->tail = &((*table->tail)->next);
 }
 
 void
-frame_unwind_append_sniffer (struct gdbarch *gdbarch,
-			     frame_unwind_sniffer_ftype *sniffer)
+frame_unwind_append (struct gdbarch *gdbarch,
+		     const struct frame_unwind *unwinder)
 {
-  struct frame_unwind_sniffer *unwind_sniffer;
-
-  unwind_sniffer = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_sniffer);
-  unwind_sniffer->sniffer = sniffer;
-  frame_unwind_sniffer_append (gdbarch, unwind_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)->unwinder = unwinder;
+  table->tail = &((*table->tail)->next);
 }
 
 const struct frame_unwind *
-frame_unwind_find_by_frame (struct frame_info *next_frame)
+frame_unwind_find_by_frame (struct frame_info *next_frame, void **this_cache)
 {
   int i;
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
@@ -92,13 +85,28 @@
        the dummy frame mechanism.  All architectures should be using
        generic dummy frames).  */
     return legacy_saved_regs_unwind;
-  for (entry = table->first; entry != NULL; entry = entry->next)
+  for (entry = table->head; entry != NULL; entry = entry->next)
     {
-      const struct frame_unwind *desc;
-      gdb_assert (entry->sniffer->sniffer != NULL);
-      desc = entry->sniffer->sniffer (entry->sniffer, next_frame);
-      if (desc != NULL)
-	return desc;
+      if (entry->sniffer != NULL)
+	{
+	  const struct frame_unwind *desc = NULL;
+	  desc = entry->sniffer (next_frame);
+	  if (desc != NULL)
+	    {
+	      (*this_cache) = NULL;
+	      return desc;
+	    }
+	}
+      if (entry->unwinder != NULL)
+	{
+	  void *cache = NULL;
+	  cache = entry->unwinder->sniffer (entry->unwinder, next_frame);
+	  if (cache != NULL)
+	    {
+	      (*this_cache) = cache;
+	      return entry->unwinder;
+	    }
+	}
     }
   return legacy_saved_regs_unwind;
 }
@@ -108,5 +116,5 @@
 void
 _initialize_frame_unwind (void)
 {
-  frame_unwind_data = register_gdbarch_data (frame_unwind_init, NULL);
+  frame_unwind_data = gdbarch_data_register_pre_init (frame_unwind_init);
 }
Index: frame-unwind.h
===================================================================
RCS file: /cvs/src/src/gdb/frame-unwind.h,v
retrieving revision 1.9.18.1
diff -u -r1.9.18.1 frame-unwind.h
--- frame-unwind.h	9 Mar 2004 22:58:58 -0000	1.9.18.1
+++ frame-unwind.h	16 Mar 2004 16:01:40 -0000
@@ -1,6 +1,6 @@
 /* Definitions for a frame unwinder, for GDB, the GNU debugger.
 
-   Copyright 2003 Free Software Foundation, Inc.
+   Copyright 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -22,6 +22,7 @@
 #if !defined (FRAME_UNWIND_H)
 #define FRAME_UNWIND_H 1
 
+struct frame_data;
 struct frame_info;
 struct frame_id;
 struct frame_unwind;
@@ -30,6 +31,13 @@
 
 #include "frame.h"		/* For enum frame_type.  */
 
+/* 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
+   an unwind cache (allocated using frame_obstack_zalloc).  */
+
+typedef void *(frame_sniffer_ftype) (const struct frame_unwind *self,
+				     struct frame_info *next_frame);
+
 /* The following unwind functions assume a chain of frames forming the
    sequence: (outer) prev <-> this <-> next (inner).  All the
    functions are called with called with the next frame's `struct
@@ -102,15 +110,14 @@
    with the other unwind methods.  Memory for that cache should be
    allocated using frame_obstack_zalloc().  */
 
-typedef void (frame_prev_register_ftype)
-     (const struct frame_unwind *self,
-      struct frame_info *next_frame,
-      void **this_prologue_cache,
-      int prev_regnum,
-      int *optimized,
-      enum lval_type * lvalp,
-      CORE_ADDR *addrp,
-      int *realnump, void *valuep);
+typedef void (frame_prev_register_ftype) (const struct frame_unwind *self,
+					  struct frame_info *next_frame,
+					  void **this_prologue_cache,
+					  int prev_regnum,
+					  int *optimized,
+					  enum lval_type * lvalp,
+					  CORE_ADDR *addrp,
+					  int *realnump, void *valuep);
 
 struct frame_unwind
 {
@@ -122,36 +129,32 @@
   frame_this_id_ftype *this_id;
   frame_prev_register_ftype *prev_register;
   const struct frame_data *unwind_data;
+  frame_sniffer_ftype *sniffer;
 };
 
+/* Register a frame unwinder, appending it to the end of the search
+   list.  */
+extern void frame_unwind_append (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
    the unwind methods, or NULL if it is not.  */
 
-struct frame_unwind_sniffer;
-
-typedef const struct frame_unwind *(frame_unwind_sniffer_ftype)
-     (const struct frame_unwind_sniffer *self,
-      struct frame_info *next_frame);
-
-struct frame_unwind_sniffer
-{
-  frame_unwind_sniffer_ftype *sniffer;
-  const struct frame_data *sniffer_data;
-};
+typedef const struct frame_unwind *(frame_unwind_sniffer_ftype) (struct frame_info *next_frame);
 
 /* Add a frame sniffer to the list.  The predicates are polled in the
    order that they are appended.  The initial list contains the dummy
    frame sniffer.  */
 
-void frame_unwind_append_sniffer (struct gdbarch *gdbarch,
-				  frame_unwind_sniffer_ftype *sniffer);
-void frame_unwind_sniffer_append (struct gdbarch *gdbarch,
-				  const struct frame_unwind_sniffer *sniffer);
+extern void frame_unwind_append_sniffer (struct gdbarch *gdbarch,
+					 frame_unwind_sniffer_ftype *sniffer);
 
 /* Iterate through the next frame's sniffers until one returns with an
-   unwinder implementation.  */
+   unwinder implementation.  Possibly initialize THIS_CACHE.  */
 
-extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame);
+extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame,
+							      void **this_cache);
 
 #endif
Index: frame.c
===================================================================
RCS file: /cvs/src/src/gdb/frame.c,v
retrieving revision 1.162.6.1
diff -u -r1.162.6.1 frame.c
--- frame.c	9 Mar 2004 22:58:58 -0000	1.162.6.1
+++ frame.c	16 Mar 2004 16:01:41 -0000
@@ -228,7 +228,8 @@
       /* Find the unwinder.  */
       if (fi->unwind == NULL)
 	{
-	  fi->unwind = frame_unwind_find_by_frame (fi->next);
+	  fi->unwind = frame_unwind_find_by_frame (fi->next,
+						   &fi->prologue_cache);
 	  /* FIXME: cagney/2003-04-02: Rather than storing the frame's
 	     type in the frame, the unwinder's type should be returned
 	     directly.  Unfortunately, legacy code, called by
@@ -430,7 +431,7 @@
 }
 
 CORE_ADDR
-frame_unwind_func_by_symtab (struct frame_info *fi)
+frame_func_unwind (struct frame_info *fi)
 {
   if (!fi->prev_func.p)
     {
@@ -448,12 +449,6 @@
 }
 
 CORE_ADDR
-frame_func_unwind (struct frame_info *fi)
-{
-  return frame_unwind_func_by_symtab (fi);
-}
-
-CORE_ADDR
 get_frame_func (struct frame_info *fi)
 {
   return frame_func_unwind (fi->next);
@@ -539,7 +534,8 @@
   /* Find the unwinder.  */
   if (frame->unwind == NULL)
     {
-      frame->unwind = frame_unwind_find_by_frame (frame->next);
+      frame->unwind = frame_unwind_find_by_frame (frame->next,
+						  &frame->prologue_cache);
       /* FIXME: cagney/2003-04-02: Rather than storing the frame's
 	 type in the frame, the unwinder's type should be returned
 	 directly.  Unfortunately, legacy code, called by
@@ -1201,7 +1197,7 @@
 
   /* Select/initialize both the unwind function and the frame's type
      based on the PC.  */
-  fi->unwind = frame_unwind_find_by_frame (fi->next);
+  fi->unwind = frame_unwind_find_by_frame (fi->next, &fi->prologue_cache);
   if (fi->unwind->type != UNKNOWN_FRAME)
     fi->type = fi->unwind->type;
   else
@@ -1354,7 +1350,8 @@
 
       /* Set the unwind functions based on that identified PC.  Ditto
          for the "type" but strongly prefer the unwinder's frame type.  */
-      prev->unwind = frame_unwind_find_by_frame (prev->next);
+      prev->unwind = frame_unwind_find_by_frame (prev->next,
+						 &prev->prologue_cache);
       if (prev->unwind->type == UNKNOWN_FRAME)
 	prev->type = frame_type_from_pc (get_frame_pc (prev));
       else
@@ -1454,8 +1451,7 @@
   /* Still don't want to worry about this except on the innermost
      frame.  This macro will set FROMLEAF if THIS_FRAME is a frameless
      function invocation.  */
-  if (this_frame->level == 0
-      && this_frame->unwind->type == UNKNOWN_FRAME)
+  if (this_frame->level == 0)
     /* FIXME: 2002-11-09: Frameless functions can occure anywhere in
        the frame chain, not just the inner most frame!  The generic,
        per-architecture, frame code should handle this and the below
@@ -1496,8 +1492,7 @@
          this to after the ffi test; I'd rather have backtraces from
          start go curfluy than have an abort called from main not show
          main.  */
-      if (DEPRECATED_FRAME_CHAIN_P ()
-	  && this_frame->unwind->type == UNKNOWN_FRAME)
+      if (DEPRECATED_FRAME_CHAIN_P ())
 	address = DEPRECATED_FRAME_CHAIN (this_frame);
       else
 	{
@@ -1505,7 +1500,8 @@
              to the new frame code.  Implement FRAME_CHAIN the way the
              new frame will.  */
 	  /* Find PREV frame's unwinder.  */
-	  prev->unwind = frame_unwind_find_by_frame (this_frame->next);
+	  prev->unwind = frame_unwind_find_by_frame (this_frame->next,
+						     &prev->prologue_cache);
 	  /* FIXME: cagney/2003-04-02: Rather than storing the frame's
 	     type in the frame, the unwinder's type should be returned
 	     directly.  Unfortunately, legacy code, called by
@@ -1666,27 +1662,13 @@
      If there isn't a FRAME_CHAIN, the code above will have already
      done this.  */
   if (prev->unwind == NULL)
-    prev->unwind = frame_unwind_find_by_frame (prev->next);
+    prev->unwind = frame_unwind_find_by_frame (prev->next,
+					       &prev->prologue_cache);
 
-  /* If the unwinder provides a frame type (i.e., is a new style
-     unwinder), use it.  Otherwize continue on to that heuristic
-     mess.  */
-  switch (prev->unwind->type)
+  /* If the unwinder provides a frame type, use it.  Otherwize
+     continue on to that heuristic mess.  */
+  if (prev->unwind->type != UNKNOWN_FRAME)
     {
-    case SIGTRAMP_FRAME:
-      prev->type = prev->unwind->type;
-      prev->unwind->this_id (prev->unwind, prev->next,
-			     &prev->prologue_cache,
-			     &prev->this_id.value);
-      if (frame_debug)
-	{
-	  fprintf_unfiltered (gdb_stdlog, "-> ");
-	  fprint_frame (gdb_stdlog, prev);
-	  fprintf_unfiltered (gdb_stdlog, " } // legacy with sigtramp type\n");
-	}
-      return prev;
-    case DUMMY_FRAME:
-    case NORMAL_FRAME:
       prev->type = prev->unwind->type;
       if (prev->type == NORMAL_FRAME)
 	/* FIXME: cagney/2003-06-16: would get_frame_pc() be better?  */
@@ -1699,10 +1681,6 @@
 	  fprintf_unfiltered (gdb_stdlog, " } // legacy with unwound type\n");
 	}
       return prev;
-    case UNKNOWN_FRAME:
-      break;
-    default:
-      internal_error (__FILE__, __LINE__, "bad switch");
     }
 
   /* NOTE: cagney/2002-11-18: The code segments, found in
@@ -2155,7 +2133,8 @@
     {
       /* Initialize the frame's unwinder because it is that which
          provides the frame's type.  */
-      frame->unwind = frame_unwind_find_by_frame (frame->next);
+      frame->unwind = frame_unwind_find_by_frame (frame->next,
+						  &frame->prologue_cache);
       /* FIXME: cagney/2003-04-02: Rather than storing the frame's
 	 type in the frame, the unwinder's type should be returned
 	 directly.  Unfortunately, legacy code, called by
Index: frame.h
===================================================================
RCS file: /cvs/src/src/gdb/frame.h,v
retrieving revision 1.119.6.1
diff -u -r1.119.6.1 frame.h
--- frame.h	9 Mar 2004 22:58:58 -0000	1.119.6.1
+++ frame.h	16 Mar 2004 16:01:41 -0000
@@ -260,7 +260,6 @@
 /* Following on from the `resume' address.  Return the entry point
    address of the function containing that resume address, or zero if
    that function isn't known.  */
-extern CORE_ADDR frame_unwind_func_by_symtab (struct frame_info *fi);
 extern CORE_ADDR frame_func_unwind (struct frame_info *fi);
 extern CORE_ADDR get_frame_func (struct frame_info *fi);
 
Index: gdbarch.c
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.c,v
retrieving revision 1.275.6.1
diff -u -r1.275.6.1 gdbarch.c
--- gdbarch.c	9 Mar 2004 22:58:58 -0000	1.275.6.1
+++ gdbarch.c	16 Mar 2004 16:01:42 -0000
@@ -5403,13 +5403,12 @@
   0, NULL,
 };
 
-struct gdbarch_data *
-register_gdbarch_data (gdbarch_data_pre_init_ftype *pre_init,
+static struct gdbarch_data *
+gdbarch_data_register (gdbarch_data_pre_init_ftype *pre_init,
 		       gdbarch_data_post_init_ftype *post_init)
 {
   struct gdbarch_data_registration **curr;
   /* Append the new registraration.  */
-  gdb_assert ((pre_init != NULL) != (post_init != NULL));
   for (curr = &gdbarch_data_registry.registrations;
        (*curr) != NULL;
        curr = &(*curr)->next);
@@ -5423,6 +5422,17 @@
   return (*curr)->data;
 }
 
+struct gdbarch_data *
+gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *pre_init)
+{
+  return gdbarch_data_register (pre_init, NULL);
+}
+
+struct gdbarch_data *
+gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *post_init)
+{
+  return gdbarch_data_register (NULL, post_init);
+}
 
 /* Create/delete the gdbarch data vector. */
 
@@ -5438,12 +5448,13 @@
    data-pointer. */
 
 void
-set_gdbarch_data (struct gdbarch *gdbarch,
-                  struct gdbarch_data *data,
-                  void *pointer)
+deprecated_set_gdbarch_data (struct gdbarch *gdbarch,
+			     struct gdbarch_data *data,
+			     void *pointer)
 {
   gdb_assert (data->index < gdbarch->nr_data);
   gdb_assert (gdbarch->data[data->index] == NULL);
+  gdb_assert (data->pre_init == NULL);
   gdbarch->data[data->index] = pointer;
 }
 
@@ -5456,21 +5467,36 @@
   gdb_assert (data->index < gdbarch->nr_data);
   if (gdbarch->data[data->index] == NULL)
     {
-      /* Be careful to detect an initialization cycle.  */
-      gdb_assert (data->init_p);
-      data->init_p = 0;
+      /* The data-pointer isn't initialized, call init() to get a
+	 value.  */
       if (data->pre_init != NULL)
+	/* Mid architecture creation: pass just the obstack, and not
+	   the entire architecture, as that way it isn't possible for
+	   pre-init code to refer to undefined architecture
+	   fields.  */
 	gdbarch->data[data->index] = data->pre_init (gdbarch->obstack);
       else if (gdbarch->initialized_p
 	       && data->post_init != NULL)
-	gdbarch->data[data->index] = data->post_init (gdbarch);
+	/* Post architecture creation: pass the entire architecture
+	   (as all fields are valid), but be careful to also detect
+	   recursive references.  */
+	{
+	  gdb_assert (data->init_p);
+	  data->init_p = 0;
+	  gdbarch->data[data->index] = data->post_init (gdbarch);
+	  data->init_p = 1;
+	}
       else
-	internal_error (__FILE__, __LINE__, "Bad initialization method");
-      data->init_p = 1;
+	/* The architecture initialization hasn't completed - punt -
+	 hope that the caller knows what they are doing.  Once
+	 deprecated_set_gdbarch_data has been initialized, this can be
+	 changed to an internal error.  */
+	return NULL;
       gdb_assert (gdbarch->data[data->index] != NULL);
     }
   return gdbarch->data[data->index];
 }
+
 
 
 /* Keep a registry of swapped data required by GDB modules. */
Index: gdbarch.h
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.h,v
retrieving revision 1.238.6.1
diff -u -r1.238.6.1 gdbarch.h
--- gdbarch.h	9 Mar 2004 22:58:58 -0000	1.238.6.1
+++ gdbarch.h	16 Mar 2004 16:01:43 -0000
@@ -2518,10 +2518,6 @@
    for the reserved data-pointer is returned.  That identifer should
    be saved in a local static variable.
 
-   The per-architecture data-pointer is either initialized explicitly
-   (set_gdbarch_data()) or implicitly (by INIT() via a call to
-   gdbarch_data()).
-
    Memory for the per-architecture data shall be allocated using
    gdbarch_obstack_zalloc.  That memory will be deleted when the
    corresponding architecture object is deleted.
@@ -2536,12 +2532,12 @@
 struct gdbarch_data;
 
 typedef void *(gdbarch_data_pre_init_ftype) (struct obstack *obstack);
+extern struct gdbarch_data *gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *init);
 typedef void *(gdbarch_data_post_init_ftype) (struct gdbarch *gdbarch);
-extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_pre_init_ftype *pre,
-                                                   gdbarch_data_post_init_ftype *post);
-extern void set_gdbarch_data (struct gdbarch *gdbarch,
-                              struct gdbarch_data *data,
-                              void *pointer);
+extern struct gdbarch_data *gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *init);
+extern void deprecated_set_gdbarch_data (struct gdbarch *gdbarch,
+                                         struct gdbarch_data *data,
+			                 void *pointer);
 
 extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *);
 
@@ -2557,7 +2553,7 @@
    Memory regions are swapped / initialized in the order that they are
    registered.  NULL DATA and/or INIT values can be specified.
 
-   New code should use register_gdbarch_data(). */
+   New code should use gdbarch_data_register_*(). */
 
 typedef void (gdbarch_swap_ftype) (void);
 extern void deprecated_register_gdbarch_swap (void *data, unsigned long size, gdbarch_swap_ftype *init);
Index: gdbarch.sh
===================================================================
RCS file: /cvs/src/src/gdb/gdbarch.sh,v
retrieving revision 1.301.6.1
diff -u -r1.301.6.1 gdbarch.sh
--- gdbarch.sh	9 Mar 2004 22:59:00 -0000	1.301.6.1
+++ gdbarch.sh	16 Mar 2004 16:01:43 -0000
@@ -1202,10 +1202,6 @@
    for the reserved data-pointer is returned.  That identifer should
    be saved in a local static variable.
 
-   The per-architecture data-pointer is either initialized explicitly
-   (set_gdbarch_data()) or implicitly (by INIT() via a call to
-   gdbarch_data()).
-
    Memory for the per-architecture data shall be allocated using
    gdbarch_obstack_zalloc.  That memory will be deleted when the
    corresponding architecture object is deleted.
@@ -1220,12 +1216,12 @@
 struct gdbarch_data;
 
 typedef void *(gdbarch_data_pre_init_ftype) (struct obstack *obstack);
+extern struct gdbarch_data *gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *init);
 typedef void *(gdbarch_data_post_init_ftype) (struct gdbarch *gdbarch);
-extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_pre_init_ftype *pre,
-                                                   gdbarch_data_post_init_ftype *post);
-extern void set_gdbarch_data (struct gdbarch *gdbarch,
-                              struct gdbarch_data *data,
-                              void *pointer);
+extern struct gdbarch_data *gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *init);
+extern void deprecated_set_gdbarch_data (struct gdbarch *gdbarch,
+                                         struct gdbarch_data *data,
+			                 void *pointer);
 
 extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *);
 
@@ -1241,7 +1237,7 @@
    Memory regions are swapped / initialized in the order that they are
    registered.  NULL DATA and/or INIT values can be specified.
 
-   New code should use register_gdbarch_data(). */
+   New code should use gdbarch_data_register_*(). */
 
 typedef void (gdbarch_swap_ftype) (void);
 extern void deprecated_register_gdbarch_swap (void *data, unsigned long size, gdbarch_swap_ftype *init);
@@ -1814,7 +1810,8 @@
 {
   unsigned index;
   int init_p;
-  gdbarch_data_init_ftype *init;
+  gdbarch_data_pre_init_ftype *pre_init;
+  gdbarch_data_post_init_ftype *post_init;
 };
 
 struct gdbarch_data_registration
@@ -1834,8 +1831,9 @@
   0, NULL,
 };
 
-struct gdbarch_data *
-register_gdbarch_data (gdbarch_data_init_ftype *init)
+static struct gdbarch_data *
+gdbarch_data_register (gdbarch_data_pre_init_ftype *pre_init,
+		       gdbarch_data_post_init_ftype *post_init)
 {
   struct gdbarch_data_registration **curr;
   /* Append the new registraration.  */
@@ -1846,11 +1844,23 @@
   (*curr)->next = NULL;
   (*curr)->data = XMALLOC (struct gdbarch_data);
   (*curr)->data->index = gdbarch_data_registry.nr++;
-  (*curr)->data->init = init;
+  (*curr)->data->pre_init = pre_init;
+  (*curr)->data->post_init = post_init;
   (*curr)->data->init_p = 1;
   return (*curr)->data;
 }
 
+struct gdbarch_data *
+gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *pre_init)
+{
+  return gdbarch_data_register (pre_init, NULL);
+}
+
+struct gdbarch_data *
+gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *post_init)
+{
+  return gdbarch_data_register (NULL, post_init);
+}
 
 /* Create/delete the gdbarch data vector. */
 
@@ -1866,12 +1876,13 @@
    data-pointer. */
 
 void
-set_gdbarch_data (struct gdbarch *gdbarch,
-                  struct gdbarch_data *data,
-                  void *pointer)
+deprecated_set_gdbarch_data (struct gdbarch *gdbarch,
+			     struct gdbarch_data *data,
+			     void *pointer)
 {
   gdb_assert (data->index < gdbarch->nr_data);
   gdb_assert (gdbarch->data[data->index] == NULL);
+  gdb_assert (data->pre_init == NULL);
   gdbarch->data[data->index] = pointer;
 }
 
@@ -1882,18 +1893,33 @@
 gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data)
 {
   gdb_assert (data->index < gdbarch->nr_data);
-  /* The data-pointer isn't initialized, call init() to get a value but
-     only if the architecture initializaiton has completed.  Otherwise
-     punt - hope that the caller knows what they are doing.  */
-  if (gdbarch->data[data->index] == NULL
-      && gdbarch->initialized_p)
+  if (gdbarch->data[data->index] == NULL)
     {
-      /* Be careful to detect an initialization cycle.  */
-      gdb_assert (data->init_p);
-      data->init_p = 0;
-      gdb_assert (data->init != NULL);
-      gdbarch->data[data->index] = data->init (gdbarch);
-      data->init_p = 1;
+      /* The data-pointer isn't initialized, call init() to get a
+	 value.  */
+      if (data->pre_init != NULL)
+	/* Mid architecture creation: pass just the obstack, and not
+	   the entire architecture, as that way it isn't possible for
+	   pre-init code to refer to undefined architecture
+	   fields.  */
+	gdbarch->data[data->index] = data->pre_init (gdbarch->obstack);
+      else if (gdbarch->initialized_p
+	       && data->post_init != NULL)
+	/* Post architecture creation: pass the entire architecture
+	   (as all fields are valid), but be careful to also detect
+	   recursive references.  */
+	{
+	  gdb_assert (data->init_p);
+	  data->init_p = 0;
+	  gdbarch->data[data->index] = data->post_init (gdbarch);
+	  data->init_p = 1;
+	}
+      else
+	/* The architecture initialization hasn't completed - punt -
+	 hope that the caller knows what they are doing.  Once
+	 deprecated_set_gdbarch_data has been initialized, this can be
+	 changed to an internal error.  */
+	return NULL;
       gdb_assert (gdbarch->data[data->index] != NULL);
     }
   return gdbarch->data[data->index];
Index: gnu-v3-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-v3-abi.c,v
retrieving revision 1.20.10.1
diff -u -r1.20.10.1 gnu-v3-abi.c
--- gnu-v3-abi.c	9 Mar 2004 22:59:00 -0000	1.20.10.1
+++ gnu-v3-abi.c	16 Mar 2004 16:01:44 -0000
@@ -422,7 +422,7 @@
 static void
 init_gnuv3_ops (void)
 {
-  vtable_type_gdbarch_data = register_gdbarch_data (NULL, build_gdb_vtable_type);
+  vtable_type_gdbarch_data = gdbarch_data_register_post_init (build_gdb_vtable_type);
 
   gnu_v3_abi_ops.shortname = "gnu-v3";
   gnu_v3_abi_ops.longname = "GNU G++ Version 3 ABI";
Index: ppc-linux-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/ppc-linux-tdep.c,v
retrieving revision 1.50
diff -u -r1.50 ppc-linux-tdep.c
--- ppc-linux-tdep.c	16 Feb 2004 21:49:22 -0000	1.50
+++ ppc-linux-tdep.c	16 Mar 2004 16:01:44 -0000
@@ -32,7 +32,8 @@
 #include "regcache.h"
 #include "value.h"
 #include "osabi.h"
-
+#include "trad-frame.h"
+#include "tramp-frame.h"
 #include "solib-svr4.h"
 #include "ppc-tdep.h"
 
@@ -1035,6 +1036,144 @@
 };
 
 static void
+ppc_linux_sigtramp_cache (struct frame_info *next_frame,
+			  struct trad_frame_cache *this_cache,
+			  CORE_ADDR func, LONGEST offset,
+			  int bias)
+{
+  CORE_ADDR base;
+  CORE_ADDR regs;
+  CORE_ADDR gpregs;
+  CORE_ADDR fpregs;
+  int i;
+  struct gdbarch *gdbarch = get_frame_arch (next_frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
+  if (bias > 0 && frame_pc_unwind (next_frame) != func)
+    /* See below, some signal trampolines increment the stack as their
+       first instruction, need to compensate for that.  */
+    base -= bias;
+
+  /* Find the address of the register buffer pointer.  */
+  regs = base + offset;
+  /* Use that to find the address of the corresponding register
+     buffers.  */
+  gpregs = read_memory_unsigned_integer (regs, tdep->wordsize);
+  fpregs = gpregs + 48 * tdep->wordsize;
+
+  /* General purpose.  */
+  for (i = 0; i < 32; i++)
+    {
+      int regnum = i + tdep->ppc_gp0_regnum;
+      trad_frame_set_addr (this_cache, regnum, gpregs + i * tdep->wordsize);
+    }
+  trad_frame_set_addr (this_cache, PC_REGNUM, gpregs + 32 * tdep->wordsize);
+  trad_frame_set_addr (this_cache, tdep->ppc_ctr_regnum,
+		       gpregs + 35 * tdep->wordsize);
+  trad_frame_set_addr (this_cache, tdep->ppc_lr_regnum,
+		       gpregs + 36 * tdep->wordsize);
+  trad_frame_set_addr (this_cache, tdep->ppc_xer_regnum,
+		       gpregs + 37 * tdep->wordsize);
+  trad_frame_set_addr (this_cache, tdep->ppc_cr_regnum,
+		       gpregs + 38 * tdep->wordsize);
+
+  /* Floating point registers.  */
+  for (i = 0; i < 32; i++)
+    {
+      int regnum = i + FP0_REGNUM;
+      trad_frame_set_addr (this_cache, regnum, fpregs + i * tdep->wordsize);
+    }
+  trad_frame_set_addr (this_cache, tdep->ppc_fpscr_regnum,
+		       fpregs + 32 * tdep->wordsize);
+
+  this_cache->this_id = frame_id_build (base, func);
+}
+
+static void
+ppc32_linux_sigaction_cache_init (const struct tramp_frame *self,
+				  struct frame_info *next_frame,
+				  struct trad_frame_cache *this_cache,
+				  CORE_ADDR func)
+{
+  ppc_linux_sigtramp_cache (next_frame, this_cache, func,
+			    0xd0 /* Offset to ucontext_t.  */
+			    + 0x30 /* Offset to .reg.  */,
+			    0);
+}
+
+static void
+ppc64_linux_sigaction_cache_init (const struct tramp_frame *self,
+				  struct frame_info *next_frame,
+				  struct trad_frame_cache *this_cache,
+				  CORE_ADDR func)
+{
+  ppc_linux_sigtramp_cache (next_frame, this_cache, func,
+			    0x80 /* Offset to ucontext_t.  */
+			    + 0xe0 /* Offset to .reg.  */,
+			    128);
+}
+
+static void
+ppc32_linux_sighandler_cache_init (const struct tramp_frame *self,
+				   struct frame_info *next_frame,
+				   struct trad_frame_cache *this_cache,
+				   CORE_ADDR func)
+{
+  ppc_linux_sigtramp_cache (next_frame, this_cache, func,
+			    0x40 /* Offset to ucontext_t.  */
+			    + 0x1c /* Offset to .reg.  */,
+			    0);
+}
+
+static void
+ppc64_linux_sighandler_cache_init (const struct tramp_frame *self,
+				   struct frame_info *next_frame,
+				   struct trad_frame_cache *this_cache,
+				   CORE_ADDR func)
+{
+  ppc_linux_sigtramp_cache (next_frame, this_cache, func,
+			    0x80 /* Offset to struct sigcontext.  */
+			    + 0x38 /* Offset to .reg.  */,
+			    128);
+}
+
+static struct tramp_frame ppc32_linux_sigaction_tramp_frame = {
+  4,
+  { 0x380000ac, /* li r0, 172 */
+    0x44000002, /* sc */
+    0
+  },
+  ppc32_linux_sigaction_cache_init
+};
+static struct tramp_frame ppc64_linux_sigaction_tramp_frame = {
+  4,
+  { 0x38210080, /* addi r1,r1,128 */
+    0x380000ac, /* li r0, 172 */
+    0x44000002, /* sc */
+    0
+  },
+  ppc64_linux_sigaction_cache_init
+};
+static struct tramp_frame ppc32_linux_sighandler_tramp_frame = {
+  4,
+  { 0x38000077, /* li r0,119 */
+    0x44000002, /* sc */
+    0
+  },
+  ppc32_linux_sighandler_cache_init
+};
+static struct tramp_frame ppc64_linux_sighandler_tramp_frame = {
+  4,
+  { 0x38210080, /* addi r1,r1,128 */
+    0x38000077, /* li r0,119 */
+    0x44000002, /* sc */
+    0
+  },
+  ppc64_linux_sighandler_cache_init
+};
+
+static void
 ppc_linux_init_abi (struct gdbarch_info info,
                     struct gdbarch *gdbarch)
 {
@@ -1070,6 +1209,10 @@
                                         ppc_linux_skip_trampoline_code);
       set_solib_svr4_fetch_link_map_offsets
         (gdbarch, ppc_linux_svr4_fetch_link_map_offsets);
+
+      /* Trampolines.  */
+      tramp_frame_append (gdbarch, &ppc32_linux_sigaction_tramp_frame);
+      tramp_frame_append (gdbarch, &ppc32_linux_sighandler_tramp_frame);
     }
   
   if (tdep->wordsize == 8)
@@ -1085,6 +1228,9 @@
 
       /* PPC64 malloc's entry-point is called ".malloc".  */
       set_gdbarch_name_of_malloc (gdbarch, ".malloc");
+
+      tramp_frame_append (gdbarch, &ppc64_linux_sigaction_tramp_frame);
+      tramp_frame_append (gdbarch, &ppc64_linux_sighandler_tramp_frame);
     }
 }
 
Index: regcache.c
===================================================================
RCS file: /cvs/src/src/gdb/regcache.c,v
retrieving revision 1.109.4.1
diff -u -r1.109.4.1 regcache.c
--- regcache.c	9 Mar 2004 22:59:00 -0000	1.109.4.1
+++ regcache.c	16 Mar 2004 16:01:45 -0000
@@ -1705,7 +1705,7 @@
 void
 _initialize_regcache (void)
 {
-  regcache_descr_handle = register_gdbarch_data (NULL, init_regcache_descr);
+  regcache_descr_handle = gdbarch_data_register_post_init (init_regcache_descr);
   DEPRECATED_REGISTER_GDBARCH_SWAP (current_regcache);
   DEPRECATED_REGISTER_GDBARCH_SWAP (deprecated_registers);
   DEPRECATED_REGISTER_GDBARCH_SWAP (deprecated_register_valid);
Index: reggroups.c
===================================================================
RCS file: /cvs/src/src/gdb/reggroups.c,v
retrieving revision 1.8.16.1
diff -u -r1.8.16.1 reggroups.c
--- reggroups.c	9 Mar 2004 22:59:00 -0000	1.8.16.1
+++ reggroups.c	16 Mar 2004 16:01:45 -0000
@@ -109,7 +109,7 @@
       /* ULGH, called during architecture initialization.  Patch
          things up.  */
       groups = reggroups_init (gdbarch);
-      set_gdbarch_data (gdbarch, reggroups_data, groups);
+      deprecated_set_gdbarch_data (gdbarch, reggroups_data, groups);
     }
   add_group (groups, group,
 	     GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el));
@@ -268,7 +268,7 @@
 void
 _initialize_reggroup (void)
 {
-  reggroups_data = register_gdbarch_data (NULL, reggroups_init);
+  reggroups_data = gdbarch_data_register_post_init (reggroups_init);
 
   /* The pre-defined list of groups.  */
   add_group (&default_groups, general_reggroup, XMALLOC (struct reggroup_el));
Index: remote.c
===================================================================
RCS file: /cvs/src/src/gdb/remote.c,v
retrieving revision 1.130.4.1
diff -u -r1.130.4.1 remote.c
--- remote.c	9 Mar 2004 22:59:00 -0000	1.130.4.1
+++ remote.c	16 Mar 2004 16:01:46 -0000
@@ -5456,7 +5456,7 @@
   struct cmd_list_element *tmpcmd;
 
   /* architecture specific data */
-  remote_gdbarch_data_handle = register_gdbarch_data (NULL, init_remote_state);
+  remote_gdbarch_data_handle = gdbarch_data_register_post_init (init_remote_state);
 
   /* Old tacky stuff.  NOTE: This comes after the remote protocol so
      that the remote protocol has been initialized.  */
Index: rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.183.2.1
diff -u -r1.183.2.1 rs6000-tdep.c
--- rs6000-tdep.c	9 Mar 2004 22:59:01 -0000	1.183.2.1
+++ rs6000-tdep.c	16 Mar 2004 16:01:47 -0000
@@ -69,7 +69,6 @@
 
 struct rs6000_framedata
   {
-    CORE_ADDR func_start;	/* true function start */
     int offset;			/* total size of frame --- the distance
 				   by which we decrement sp to allocate
 				   the frame */
@@ -507,7 +506,6 @@
   int minimal_toc_loaded = 0;
   int prev_insn_was_prologue_insn = 1;
   int num_skip_non_prologue_insns = 0;
-  int num_skip_syscall_insn = 0;
   const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch);
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   
@@ -527,7 +525,6 @@
     lim_pc = refine_prologue_limit (pc, lim_pc);
 
   memset (fdata, 0, sizeof (struct rs6000_framedata));
-  fdata->func_start = pc;
   fdata->saved_gpr = -1;
   fdata->saved_fpr = -1;
   fdata->saved_vr = -1;
@@ -556,65 +553,9 @@
 	break;
       op = extract_signed_integer (buf, 4);
 
-      /* A PPC64 GNU/Linux system call function starts with a
-	 non-threaded fast-path, only when that fails is a stack frame
-	 created, treat it as several functions:
-
-	 *INDENT-OFF*
-	 NAME:
-	 	SINGLE_THREAD_P
-	 	bne- .Lpseudo_cancel
-	 __NAME_nocancel:
-	 	li r0,162
-	 	sc
-	 	bnslr+
-	 	b 0x7fe014ef64 <.__syscall_error>
-	 Lpseudo_cancel:
-	 	stdu r1,-128(r1)
-	 	...
-	 *INDENT-ON* */
-      if (((op & 0xffff0000) == 0x38000000 /* li r0,N */
-	   && pc == fdata->func + 0)
-	  || (op == 0x44000002 /* sc */
-	      && pc == fdata->func + 4
-	      && num_skip_syscall_insn == 1)
-	  || (op == 0x4ca30020 /* bnslr+ */
-	      && pc == fdata->func + 8
-	      && num_skip_syscall_insn == 2))
-	{
-	  num_skip_syscall_insn++;
-	  continue;
-	}
-      else if ((op & 0xfc000003) == 0x48000000 /* b __syscall_error */
-	       && pc == fdata->func + 12
-	       && num_skip_syscall_insn == 3)
-	{
-	  num_skip_syscall_insn++;
-	  fdata->func_start = pc;
-	  continue;
-	}
-
       if ((op & 0xfc1fffff) == 0x7c0802a6)
 	{			/* mflr Rx */
-	  /* Since shared library / PIC code, which needs to get its
-	     address at runtime, can appear to save more than one link
-	     register vis:
-
-	     *INDENT-OFF*
-	     stwu r1,-304(r1)
-	     mflr r3
-	     bl 0xff570d0 (blrl)
-	     stw r30,296(r1)
-	     mflr r30
-	     stw r31,300(r1)
-	     stw r3,308(r1);
-	     ...
-	     *INDENT-ON*
-
-	     remember just the first one, but skip over additional
-	     ones.  */
-	  if (lr_reg < 0)
-	    lr_reg = (op & 0x03e00000);
+	  lr_reg = (op & 0x03e00000);
 	  continue;
 
 	}
@@ -1925,12 +1866,12 @@
 	case 0:
 	  return builtin_type_int0;
 	case 4:
-	  return builtin_type_uint32;
+	  return builtin_type_int32;
 	case 8:
 	  if (tdep->ppc_ev0_regnum <= n && n <= tdep->ppc_ev31_regnum)
 	    return builtin_type_vec64;
 	  else
-	    return builtin_type_uint64;
+	    return builtin_type_int64;
 	  break;
 	case 16:
 	  return builtin_type_vec128;
@@ -2699,19 +2640,23 @@
 			 frame_pc_unwind (next_frame));
 }
 
-static void
-rs6000_trad_frame_init (const struct trad_frame *self,
-			struct frame_info *next_frame,
-			struct trad_frame_cache *this_cache)
+static struct trad_frame_cache *
+rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
 {
+  struct trad_frame_cache *cache;
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   struct rs6000_framedata fdata;
-  CORE_ADDR base;
   int wordsize = tdep->wordsize;
+  CORE_ADDR base;
+
+  if ((*this_cache) != NULL)
+    return (*this_cache);
+  cache = trad_frame_cache_zalloc (next_frame);
+  (*this_cache) = cache;
 
-  skip_prologue (frame_unwind_func_by_symtab (next_frame),
-		 frame_pc_unwind (next_frame), &fdata);
+  skip_prologue (frame_func_unwind (next_frame), frame_pc_unwind (next_frame),
+		 &fdata);
 
   /* If there were any saved registers, figure out parent's stack
      pointer.  */
@@ -2739,7 +2684,7 @@
 	/* Frameless really means stackless.  */
 	base = read_memory_addr (base, wordsize);
     }
-  trad_frame_set_value (this_cache, SP_REGNUM, base);
+  trad_frame_set_reg_value (cache, SP_REGNUM, base);
 
   /* if != -1, fdata.saved_fpr is the smallest number of saved_fpr.
      All fpr's from saved_fpr to fp31 are saved.  */
@@ -2750,7 +2695,7 @@
       CORE_ADDR fpr_addr = base + fdata.fpr_offset;
       for (i = fdata.saved_fpr; i < 32; i++)
 	{
-	  this_cache->prev_regs[FP0_REGNUM + i].addr = fpr_addr;
+	  cache->saved_regs[FP0_REGNUM + i].addr = fpr_addr;
 	  fpr_addr += 8;
 	}
     }
@@ -2764,7 +2709,7 @@
       CORE_ADDR gpr_addr = base + fdata.gpr_offset;
       for (i = fdata.saved_gpr; i < 32; i++)
 	{
-	  this_cache->prev_regs[tdep->ppc_gp0_regnum + i].addr = gpr_addr;
+	  cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = gpr_addr;
 	  gpr_addr += wordsize;
 	}
     }
@@ -2779,7 +2724,7 @@
 	  CORE_ADDR vr_addr = base + fdata.vr_offset;
 	  for (i = fdata.saved_vr; i < 32; i++)
 	    {
-	      this_cache->prev_regs[tdep->ppc_vr0_regnum + i].addr = vr_addr;
+	      cache->saved_regs[tdep->ppc_vr0_regnum + i].addr = vr_addr;
 	      vr_addr += register_size (gdbarch, tdep->ppc_vr0_regnum);
 	    }
 	}
@@ -2795,8 +2740,8 @@
 	  CORE_ADDR ev_addr = base + fdata.ev_offset;
 	  for (i = fdata.saved_ev; i < 32; i++)
 	    {
-	      this_cache->prev_regs[tdep->ppc_ev0_regnum + i].addr = ev_addr;
-              this_cache->prev_regs[tdep->ppc_gp0_regnum + i].addr = ev_addr + 4;
+	      cache->saved_regs[tdep->ppc_ev0_regnum + i].addr = ev_addr;
+              cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = ev_addr + 4;
 	      ev_addr += register_size (gdbarch, tdep->ppc_ev0_regnum);
             }
 	}
@@ -2805,43 +2750,95 @@
   /* If != 0, fdata.cr_offset is the offset from the frame that
      holds the CR.  */
   if (fdata.cr_offset != 0)
-    this_cache->prev_regs[tdep->ppc_cr_regnum].addr = base + fdata.cr_offset;
+    cache->saved_regs[tdep->ppc_cr_regnum].addr = base + fdata.cr_offset;
 
   /* If != 0, fdata.lr_offset is the offset from the frame that
      holds the LR.  */
   if (fdata.lr_offset != 0)
-    this_cache->prev_regs[tdep->ppc_lr_regnum].addr = base + fdata.lr_offset;
+    cache->saved_regs[tdep->ppc_lr_regnum].addr = base + fdata.lr_offset;
   /* The PC is found in the link register.  */
-  this_cache->prev_regs[PC_REGNUM] = this_cache->prev_regs[tdep->ppc_lr_regnum];
+  cache->saved_regs[PC_REGNUM] = cache->saved_regs[tdep->ppc_lr_regnum];
 
   /* If != 0, fdata.vrsave_offset is the offset from the frame that
      holds the VRSAVE.  */
   if (fdata.vrsave_offset != 0)
-    this_cache->prev_regs[tdep->ppc_vrsave_regnum].addr = base + fdata.vrsave_offset;
+    cache->saved_regs[tdep->ppc_vrsave_regnum].addr = base + fdata.vrsave_offset;
 
   if (fdata.alloca_reg < 0)
     /* If no alloca register used, then fi->frame is the value of the
        %sp for this frame, and it is good enough.  */
-    this_cache->this_base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
+    cache->this_base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
   else
-    this_cache->this_base = frame_unwind_register_unsigned (next_frame,
+    cache->this_base = frame_unwind_register_unsigned (next_frame,
 						       fdata.alloca_reg);
-  this_cache->this_id = frame_id_build (base, fdata.func);
+
+  cache->this_id = frame_id_build (base, frame_func_unwind (next_frame));
+
+  return cache;
 }
 
-static int
-rs6000_trad_frame_sniffer (const struct trad_frame *self,
-			   struct frame_info *next_frame)
-{
-  return 1;
+static void
+rs6000_frame_this_id (const struct frame_unwind *self,
+		      struct frame_info *next_frame, void **this_cache,
+		      struct frame_id *this_id)
+{
+  struct trad_frame_cache *trad_cache = rs6000_frame_cache (next_frame,
+							    this_cache);
+  trad_frame_this_id (trad_cache, next_frame, this_id);
+}
+
+static void
+rs6000_frame_prev_register (const struct frame_unwind *self,
+			    struct frame_info *next_frame,
+			    void **this_cache,
+			    int regnum, int *optimizedp,
+			    enum lval_type *lvalp, CORE_ADDR *addrp,
+			    int *realnump, void *valuep)
+{
+  struct trad_frame_cache *trad_cache = rs6000_frame_cache (next_frame,
+							    this_cache);
+  trad_frame_prev_register (trad_cache, next_frame, regnum,
+			    optimizedp, lvalp, addrp, realnump, valuep);
 }
 
-struct trad_frame rs6000_trad_frame = {
+static const struct frame_unwind rs6000_frame_unwind =
+{
   NORMAL_FRAME,
-  rs6000_trad_frame_sniffer,
-  rs6000_trad_frame_init,
+  rs6000_frame_this_id,
+  rs6000_frame_prev_register
+};
+
+static const struct frame_unwind *
+rs6000_frame_sniffer (struct frame_info *next_frame)
+{
+  return &rs6000_frame_unwind;
+}
+
+
+
+static CORE_ADDR
+rs6000_frame_base_address (const struct frame_base *self,
+			   struct frame_info *next_frame,
+			   void **this_cache)
+{
+  struct trad_frame_cache *trad_cache = rs6000_frame_cache (next_frame,
+							    this_cache);
+  return trad_cache->this_base;
+}
+
+static const struct frame_base rs6000_frame_base = {
+  &rs6000_frame_unwind,
+  rs6000_frame_base_address,
+  rs6000_frame_base_address,
+  rs6000_frame_base_address
 };
 
+static const struct frame_base *
+rs6000_frame_base_sniffer (const struct frame_base_sniffer *self,
+			   struct frame_info *next_frame)
+{
+  return &rs6000_frame_base;
+}
 
 /* Initialize the current architecture based on INFO.  If possible, re-use an
    architecture from ARCHES, which is a list of architectures already created
@@ -3157,8 +3154,9 @@
     case GDB_OSABI_UNKNOWN:
     case GDB_OSABI_LINUX:
       set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
-      trad_frame_append (gdbarch, &rs6000_trad_frame);
+      frame_unwind_append_sniffer (gdbarch, rs6000_frame_sniffer);
       set_gdbarch_unwind_dummy_id (gdbarch, rs6000_unwind_dummy_id);
+      frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
       break;
     default:
       set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
Index: solib-svr4.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-svr4.c,v
retrieving revision 1.41.6.1
diff -u -r1.41.6.1 solib-svr4.c
--- solib-svr4.c	9 Mar 2004 22:59:01 -0000	1.41.6.1
+++ solib-svr4.c	16 Mar 2004 16:01:48 -0000
@@ -1490,7 +1490,7 @@
 set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch,
                                        struct link_map_offsets *(*flmo) (void))
 {
-  set_gdbarch_data (gdbarch, fetch_link_map_offsets_gdbarch_data, flmo);
+  deprecated_set_gdbarch_data (gdbarch, fetch_link_map_offsets_gdbarch_data, flmo);
 }
 
 /* Initialize the architecture-specific link_map_offsets fetcher.
@@ -1588,7 +1588,7 @@
 _initialize_svr4_solib (void)
 {
   fetch_link_map_offsets_gdbarch_data =
-    register_gdbarch_data (NULL, init_fetch_link_map_offsets);
+    gdbarch_data_register_post_init (init_fetch_link_map_offsets);
 
   svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses;
   svr4_so_ops.free_so = svr4_free_so;
Index: solib-svr4.h
===================================================================
RCS file: /cvs/src/src/gdb/solib-svr4.h,v
retrieving revision 1.6
diff -u -r1.6 solib-svr4.h
--- solib-svr4.h	21 Feb 2004 18:34:45 -0000	1.6
+++ solib-svr4.h	16 Mar 2004 16:01:48 -0000
@@ -20,6 +20,9 @@
    Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#ifndef SOLIB_SVR4
+#define SOLIB_SVR4
+
 struct objfile;
 
 /* Critical offsets and sizes which describe struct r_debug and
@@ -88,3 +91,5 @@
    for ILP32 and LP64 SVR4 systems.  */
 extern struct link_map_offsets *svr4_ilp32_fetch_link_map_offsets (void);
 extern struct link_map_offsets *svr4_lp64_fetch_link_map_offsets (void);
+
+#endif
Index: trad-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/trad-frame.c,v
retrieving revision 1.4.18.1
diff -u -r1.4.18.1 trad-frame.c
--- trad-frame.c	9 Mar 2004 22:59:01 -0000	1.4.18.1
+++ trad-frame.c	16 Mar 2004 16:01:48 -0000
@@ -41,11 +41,11 @@
   int regnum;
 
   trad_cache = FRAME_OBSTACK_ZALLOC (struct trad_frame_cache);
-  trad_cache->prev_regs = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg);
+  trad_cache->saved_regs = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg);
   for (regnum = 0; regnum < numregs; regnum++)
     {
-      trad_cache->prev_regs[regnum].realreg = regnum;
-      trad_cache->prev_regs[regnum].addr = -1;
+      trad_cache->saved_regs[regnum].realreg = regnum;
+      trad_cache->saved_regs[regnum].addr = -1;
     }      
   return trad_cache;
 }
@@ -55,32 +55,42 @@
 int
 trad_frame_value_p (struct trad_frame_cache *this_cache, int regnum)
 {
-  return (this_cache->prev_regs[regnum].realreg == REG_VALUE);
+  return (this_cache->saved_regs[regnum].realreg == REG_VALUE);
 }
 
 int
 trad_frame_addr_p (struct trad_frame_cache *this_cache, int regnum)
 {
-  return (this_cache->prev_regs[regnum].realreg >= 0
-	  && this_cache->prev_regs[regnum].addr != -1);
+  return (this_cache->saved_regs[regnum].realreg >= 0
+	  && this_cache->saved_regs[regnum].addr != -1);
 }
 
 int
 trad_frame_realreg_p (struct trad_frame_cache *this_cache,
 		      int regnum)
 {
-  return (this_cache->prev_regs[regnum].realreg >= 0
-	  && this_cache->prev_regs[regnum].addr == -1);
+  return (this_cache->saved_regs[regnum].realreg >= 0
+	  && this_cache->saved_regs[regnum].addr == -1);
 }
 
 void
-trad_frame_set_value (struct trad_frame_cache *this_cache,
-		      int regnum, LONGEST val)
+trad_frame_set_reg_value (struct trad_frame_cache *this_cache,
+			  int regnum, LONGEST val)
 {
   /* Make the REALREG invalid, indicating that the ADDR contains the
      register's value.  */
-  this_cache->prev_regs[regnum].realreg = REG_VALUE;
-  this_cache->prev_regs[regnum].addr = val;
+  this_cache->saved_regs[regnum].realreg = REG_VALUE;
+  this_cache->saved_regs[regnum].addr = val;
+}
+
+void
+trad_frame_set_addr (struct trad_frame_cache *this_cache,
+		     int regnum, CORE_ADDR addr)
+{
+  /* Make the REALREG invalid, indicating that the ADDR contains the
+     register's value.  */
+  this_cache->saved_regs[regnum].realreg = regnum;
+  this_cache->saved_regs[regnum].addr = addr;
 }
 
 void
@@ -88,8 +98,8 @@
 			int regnum)
 {
   /* Make the REALREG invalid, indicating that the value is not known.  */
-  this_cache->prev_regs[regnum].realreg = REG_UNKNOWN;
-  this_cache->prev_regs[regnum].addr = -1;
+  this_cache->saved_regs[regnum].realreg = REG_UNKNOWN;
+  this_cache->saved_regs[regnum].addr = -1;
 }
 
 struct frame_data
@@ -99,50 +109,34 @@
   const struct trad_frame *trad_frame;
 };
 
-static struct trad_frame_cache *
-trad_frame_cache (const struct frame_data *self,
-		  struct frame_info *next_frame,
-		  void **this_cache)
-{
-  if ((*this_cache) == NULL)
-    {
-      (*this_cache) = trad_frame_cache_zalloc (next_frame);
-      gdb_assert (self->trad_frame->init != NULL);
-      self->trad_frame->init (self->trad_frame, next_frame, (*this_cache));
-    }
-  return (*this_cache);
-}
-
-static void
-trad_frame_prev_register (const struct frame_unwind *self,
+void
+trad_frame_prev_register (struct trad_frame_cache *trad_cache,
 			  struct frame_info *next_frame,
-			  void **this_cache,
 			  int regnum, int *optimizedp,
 			  enum lval_type *lvalp, CORE_ADDR *addrp,
 			  int *realregp, void *bufferp)
 {
-  struct trad_frame_cache *trad_cache
-    = trad_frame_cache (self->unwind_data, next_frame, this_cache);
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
 
+  gdb_assert (trad_cache != NULL);
   if (trad_frame_addr_p (trad_cache, regnum))
     {
       /* The register was saved in memory.  */
       *optimizedp = 0;
       *lvalp = lval_memory;
-      *addrp = trad_cache->prev_regs[regnum].addr;
+      *addrp = trad_cache->saved_regs[regnum].addr;
       *realregp = -1;
       if (bufferp != NULL)
 	{
 	  /* Read the value in from memory.  */
-	  get_frame_memory (next_frame, trad_cache->prev_regs[regnum].addr, bufferp,
+	  get_frame_memory (next_frame, trad_cache->saved_regs[regnum].addr, bufferp,
 			    register_size (gdbarch, regnum));
 	}
     }
   else if (trad_frame_realreg_p (trad_cache, regnum))
     {
       /* Ask the next frame to return the value of the register.  */
-      frame_register_unwind (next_frame, trad_cache->prev_regs[regnum].realreg,
+      frame_register_unwind (next_frame, trad_cache->saved_regs[regnum].realreg,
 			     optimizedp, lvalp, addrp, realregp, bufferp);
     }
   else if (trad_frame_value_p (trad_cache, regnum))
@@ -154,7 +148,7 @@
       *realregp = -1;
       if (bufferp != NULL)
 	store_unsigned_integer (bufferp, register_size (gdbarch, regnum),
-				trad_cache->prev_regs[regnum].addr);
+				trad_cache->saved_regs[regnum].addr);
     }
   else
     {
@@ -163,26 +157,22 @@
     }
 }
 
-static void
-trad_frame_this_id (const struct frame_unwind *self,
-		    struct frame_info *next_frame, void **this_cache,
+void
+trad_frame_this_id (struct trad_frame_cache *trad_cache,
+		    struct frame_info *next_frame,
 		    struct frame_id *this_id)
 {
-  struct trad_frame_cache *trad_cache
-    = trad_frame_cache (self->unwind_data, next_frame, this_cache);
+  gdb_assert (trad_cache != NULL);
   (*this_id) = trad_cache->this_id;
 }
 
-static const struct frame_unwind *
-trad_frame_unwind_sniffer (const struct frame_unwind_sniffer *self,
-			   struct frame_info *next_frame)
+static void *
+trad_frame_sniffer (const struct frame_unwind *self,
+		    struct frame_info *next_frame)
 {
-  const struct trad_frame *trad_frame = self->sniffer_data->trad_frame;
+  const struct trad_frame *trad_frame = self->unwind_data->trad_frame;
   gdb_assert (trad_frame->sniffer != NULL);
-  if (trad_frame->sniffer (trad_frame, next_frame))
-    return self->sniffer_data->frame_unwind;
-  else
-    return NULL;
+  return trad_frame->sniffer (trad_frame, next_frame);
 }
 
 static CORE_ADDR
@@ -190,8 +180,9 @@
 		 struct frame_info *next_frame,
 		 void **this_cache)
 {
-  struct trad_frame_cache *trad_cache
-    = trad_frame_cache (self->base_data, next_frame, this_cache);
+  struct trad_frame_cache *trad_cache = (*this_cache);
+
+  gdb_assert (trad_cache != NULL);
   return trad_cache->this_base;
 }
 
@@ -207,19 +198,19 @@
     return NULL;
 }
 
+#if 0
 void
 trad_frame_append (struct gdbarch *gdbarch,
 		   const struct trad_frame *trad_frame)
 {
   struct frame_data *data;
   struct frame_unwind *unwind;
-  struct frame_unwind_sniffer *unwind_sniffer;
   struct frame_base *base;
   struct frame_base_sniffer *base_sniffer;
 
   data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_data);
   unwind = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind);
-  unwind_sniffer = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_sniffer);
+
   base = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_base);
   base_sniffer = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_base_sniffer);
 
@@ -231,10 +222,9 @@
   unwind->this_id = trad_frame_this_id;
   unwind->prev_register = trad_frame_prev_register;
   unwind->unwind_data = data;
-  unwind_sniffer->sniffer = trad_frame_unwind_sniffer;
-  unwind_sniffer->sniffer_data = data;
+  unwind->sniffer = trad_frame_sniffer;
 
-  frame_unwind_sniffer_append (gdbarch, unwind_sniffer);
+  frame_unwind_append (gdbarch, unwind);
 
   base->base_data = data;
   base->unwind = unwind;
@@ -247,3 +237,4 @@
 
   frame_base_sniffer_append (gdbarch, base_sniffer);
 }
+#endif
Index: trad-frame.h
===================================================================
RCS file: /cvs/src/src/gdb/trad-frame.h,v
retrieving revision 1.4.18.1
diff -u -r1.4.18.1 trad-frame.h
--- trad-frame.h	9 Mar 2004 22:59:01 -0000	1.4.18.1
+++ trad-frame.h	16 Mar 2004 16:01:48 -0000
@@ -63,51 +63,66 @@
 {
   struct frame_id this_id;
   CORE_ADDR this_base;
-  struct trad_frame_saved_reg *prev_regs;
+  struct trad_frame_saved_reg *saved_regs;
 };
 
+struct trad_frame_cache *trad_frame_cache_zalloc (struct frame_info *next_frame);
+
+
 /* Encode REGNUM's value in the trad-frame.  */
-void trad_frame_set_value (struct trad_frame_cache *this_cache,
-			   int regnum, LONGEST val);
-void trad_frame_set_addr (struct trad_frame_cache *this_cache,
-			  int regnum, CORE_ADDR addr);
-void trad_frame_set_realreg (struct trad_frame_cache *this_cache,
-			     int regnum, int realreg);
-void trad_frame_set_unknown (struct trad_frame_cache *this_cache,
-			     int regnum);
+void trad_frame_set_reg_value (struct trad_frame_cache *this_cache,
+			       int regnum, LONGEST val);
+void trad_frame_set_reg_addr (struct trad_frame_cache *this_cache,
+			      int regnum, CORE_ADDR addr);
+void trad_frame_set_reg_reg (struct trad_frame_cache *this_cache,
+			      int regnum, int realreg);
+void trad_frame_set_reg_unknown (struct trad_frame_cache *this_cache,
+				 int regnum);
+void trad_frame_set_this_id (struct trad_frame_cache *this_cache,
+			     struct frame_id *this_id);
+void trad_frame_set_this_base (struct trad_frame_cache *this_cache,
+			       CORE_ADDR base);
 
 /* Set the offset of a register, and then update all offsets.  Useful
    when the offset of a register is known before its absolute
    address.  */
-void trad_frame_set_offset (struct trad_frame_cache *this_cache,
-			    int regnum, LONGEST addr);
-void trad_frame_add_addr (struct trad_frame_cache *this_cache,
-			  int regnum, CORE_ADDR addr);
+void trad_frame_set_reg_offset (struct trad_frame_cache *this_cache,
+				int regnum, LONGEST addr);
+void trad_frame_add_reg_addr (struct trad_frame_cache *this_cache,
+			      int regnum, CORE_ADDR addr);
 
 /* Convenience functions, return non-zero if the register has been
    encoded as specified.  */
-int trad_frame_value_p (struct trad_frame_cache *this_cache,
-			int regnum);
-int trad_frame_addr_p (struct trad_frame_cache *this_cache,
-		       int regnum);
-int trad_frame_realreg_p (struct trad_frame_cache *this_cache,
+int trad_frame_reg_value_p (struct trad_frame_cache *this_cache,
+			    int regnum);
+int trad_frame_reg_addr_p (struct trad_frame_cache *this_cache,
+			   int regnum);
+int trad_frame_reg_reg_p (struct trad_frame_cache *this_cache,
 			  int regnum);
 
-typedef void (trad_frame_init_ftype) (const struct trad_frame *self,
-				      struct frame_info *next_frame,
-				      struct trad_frame_cache *this_cache);
-typedef int (trad_frame_sniffer_ftype) (const struct trad_frame *self,
-					struct frame_info *next_frame);
+typedef struct trad_frame_cache *(trad_frame_sniffer_ftype) (const struct trad_frame *self,
+							     struct frame_info *next_frame);
 
 struct trad_frame
 {
   enum frame_type type;
   trad_frame_sniffer_ftype *sniffer;
-  trad_frame_init_ftype *init;
   const struct trad_frame_data *trad_data;
 };
 
 void trad_frame_append (struct gdbarch *gdbarch,
 			const struct trad_frame *trad_frame);
+
+void trad_frame_this_id (struct trad_frame_cache *trad_cache,
+			 struct frame_info *next_frame,
+			 struct frame_id *this_id);
+
+void trad_frame_prev_register (struct trad_frame_cache *trad_cache,
+			       struct frame_info *next_frame,
+			       int prev_regnum,
+			       int *optimizedp,
+			       enum lval_type * lvalp,
+			       CORE_ADDR *addrp,
+			       int *realnump, void *valuep);
 
 #endif
Index: tramp-frame.c
===================================================================
RCS file: /cvs/src/src/gdb/Attic/tramp-frame.c,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 tramp-frame.c
--- tramp-frame.c	11 Mar 2004 21:59:53 -0000	1.1.2.1
+++ tramp-frame.c	16 Mar 2004 16:01:48 -0000
@@ -21,18 +21,69 @@
 
 #include "defs.h"
 #include "tramp-frame.h"
-#include "trad-frame.h"
 #include "frame-unwind.h"
 #include "gdbcore.h"
 #include "symtab.h"
 #include "objfiles.h"
 #include "target.h"
+#include "trad-frame.h"
 
-struct trad_frame_data
+struct frame_data
 {
   const struct tramp_frame *tramp_frame;
 };
 
+struct tramp_frame_cache
+{
+  CORE_ADDR func;
+  struct trad_frame_cache *trad_cache;
+};
+
+static struct trad_frame_cache *
+tramp_frame_cache (const struct frame_unwind *self,
+		   struct frame_info *next_frame,
+		   void **this_cache)
+{
+  CORE_ADDR pc = frame_pc_unwind (next_frame);
+  struct tramp_frame_cache *tramp_cache = (*this_cache);
+  if (tramp_cache->trad_cache == NULL)
+    {
+      tramp_cache->trad_cache = trad_frame_cache_zalloc (next_frame);
+      self->unwind_data->tramp_frame->init (self->unwind_data->tramp_frame,
+					    next_frame,
+					    tramp_cache->trad_cache,
+					    tramp_cache->func);
+    }
+  return tramp_cache->trad_cache;
+}
+
+static void
+tramp_frame_this_id (const struct frame_unwind *self,
+		     struct frame_info *next_frame,
+		     void **this_cache,
+		     struct frame_id *this_id)
+{
+  struct trad_frame_cache *trad_cache
+    = tramp_frame_cache (self, next_frame, this_cache);
+  trad_frame_this_id (trad_cache, next_frame, this_id);
+}
+
+static void
+tramp_frame_prev_register (const struct frame_unwind *self,
+			   struct frame_info *next_frame,
+			   void **this_cache,
+			   int prev_regnum,
+			   int *optimizedp,
+			   enum lval_type * lvalp,
+			   CORE_ADDR *addrp,
+			   int *realnump, void *valuep)
+{
+  struct trad_frame_cache *trad_cache
+    = tramp_frame_cache (self, next_frame, this_cache);
+  trad_frame_prev_register (trad_cache, next_frame, prev_regnum, optimizedp,
+			    lvalp, addrp, realnump, valuep);
+}
+
 static CORE_ADDR
 tramp_frame_start (CORE_ADDR pc, const struct tramp_frame *tramp)
 {
@@ -61,23 +112,16 @@
   return 0;
 }
 
-static void
-tramp_frame_init (const struct trad_frame *self,
-		  struct frame_info *next_frame,
-		  struct trad_frame_cache *this_cache)
-{
-  CORE_ADDR pc = frame_pc_unwind (next_frame);
-  const struct tramp_frame *tramp = self->trad_data->tramp_frame;
-  tramp->init (tramp, next_frame, this_cache, tramp_frame_start (pc, tramp));
-}
-
-static int
-tramp_frame_sniffer (const struct trad_frame *self,
+static void *
+tramp_frame_sniffer (const struct frame_unwind *self,
 		     struct frame_info *next_frame)
 {
-  const struct tramp_frame *tramp = self->trad_data->tramp_frame;
+  const struct tramp_frame *tramp = self->unwind_data->tramp_frame;
   CORE_ADDR pc = frame_pc_unwind (next_frame);
+  CORE_ADDR func;
   char *name;
+  struct tramp_frame_cache *tramp_cache;
+
   /* If the function has a valid symbol name, it isn't a
      trampoline.  */
   find_pc_partial_function (pc, &name, NULL, NULL);
@@ -87,25 +131,31 @@
      point) it isn't a trampoline.  */
   if (find_pc_section (pc) != NULL)
     return NULL;
-  /* The problem here is that this code, and tramp_frame_cache, both
-     end up doing a search to find the function start :-(.  */
-  return (tramp_frame_start (pc, tramp) != 0);
+  /* Finally, check that the trampoline matches at PC.  */
+  func = tramp_frame_start (pc, tramp);
+  if (func == 0)
+    return NULL;
+  tramp_cache = FRAME_OBSTACK_ZALLOC (struct tramp_frame_cache);
+  tramp_cache->func = func;
+  return tramp_cache;
 }
 
 void
 tramp_frame_append (struct gdbarch *gdbarch,
-		    const struct tramp_frame *tramp)
+		    const struct tramp_frame *tramp_frame)
 {
-  struct trad_frame_data *trad_data;
-  struct trad_frame *trad;
+  struct frame_data *data;
+  struct frame_unwind *unwinder;
+
+  data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_data);
+  unwinder = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind);
 
-  trad_data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct trad_frame_data);
-  trad = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct trad_frame);
+  data->tramp_frame = tramp_frame;
+  unwinder->type = SIGTRAMP_FRAME;
+  unwinder->unwind_data = data;
+  unwinder->sniffer = tramp_frame_sniffer;
+  unwinder->this_id = tramp_frame_this_id;
+  unwinder->prev_register = tramp_frame_prev_register;
 
-  trad_data->tramp_frame = tramp;
-  trad->type = SIGTRAMP_FRAME;
-  trad->trad_data = trad_data;
-  trad->sniffer = tramp_frame_sniffer;
-  trad->init = tramp_frame_init;
-  trad_frame_append (gdbarch, trad);
+  frame_unwind_append (gdbarch, unwinder);
 }
Index: user-regs.c
===================================================================
RCS file: /cvs/src/src/gdb/user-regs.c,v
retrieving revision 1.4.2.1
diff -u -r1.4.2.1 user-regs.c
--- user-regs.c	9 Mar 2004 22:59:01 -0000	1.4.2.1
+++ user-regs.c	16 Mar 2004 16:01:48 -0000
@@ -110,7 +110,7 @@
       /* ULGH, called during architecture initialization.  Patch
          things up.  */
       regs = user_regs_init (gdbarch);
-      set_gdbarch_data (gdbarch, user_regs_data, regs);
+      deprecated_set_gdbarch_data (gdbarch, user_regs_data, regs);
     }
   append_user_reg (regs, name, read,
 		   GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_reg));
@@ -207,5 +207,5 @@
 void
 _initialize_user_regs (void)
 {
-  user_regs_data = register_gdbarch_data (NULL, user_regs_init);
+  user_regs_data = gdbarch_data_register_post_init (user_regs_init);
 }

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