Final tramp-frame code.
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 16e852a..c5d2af4 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,15 @@
 2004-03-21  Andrew Cagney  <cagney@redhat.com>
 
+	* tramp-frame.h, tramp-frame.h: New files.
+	* Makefile.in (SFILES, tramp_frame_h, COMMON_OBS, tramp-frame.o):
+	Update rules to include "tramp-frame.h" and "tramp-frame.c".
+
+	* Makefile.in (ppcnbsd-tdep.o): Update dependencies.
+	* ppcnbsd-tdep.c: Include "tramp-frame.h" and "trad-frame.h".
+	(ppcnbsd_sigtramp_cache_init, ppcnbsd_sigtramp): Handle signal
+	trampoline.
+	(ppcnbsd_init_abi): Call tramp_frame_append with ppcnbsd_sigtramp.
+	
 	* infrun.c (handle_inferior_event): For non legacy frames, use the
 	frame ID and frame type to identify a signal trampoline.  Update
 	comments.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 948bb9b..5f6276d 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -757,7 +757,8 @@
 terminal_h = terminal.h
 top_h = top.h
 tracepoint_h = tracepoint.h
-trad_frame_h = trad-frame.h
+trad_frame_h = trad-frame.h $(frame_h)
+tramp_frame_h = tramp-frame.h
 typeprint_h = typeprint.h
 ui_file_h = ui-file.h
 ui_out_h = ui-out.h
@@ -1535,7 +1536,7 @@
 	$(regcache_h) $(osabi_h) $(gdb_string_h) $(amd64_tdep_h) \
 	$(solib_svr4_h)
 amd64-nat.o: amd64-nat.c $(defs_h) $(gdbarch_h) $(regcache_h) \
-	$(gdb_assert_h) $(i386_tdep_h) $(amd64_tdep_h)
+	$(gdb_assert_h) $(gdb_string_h) $(i386_tdep_h) $(amd64_tdep_h)
 amd64nbsd-nat.o: amd64nbsd-nat.c $(defs_h) $(gdb_assert_h) $(amd64_tdep_h) \
 	$(amd64_nat_h)
 amd64nbsd-tdep.o: amd64nbsd-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) \
@@ -1769,8 +1770,8 @@
 	$(command_h) $(gdbcmd_h)
 frame-unwind.o: frame-unwind.c $(defs_h) $(frame_h) $(frame_unwind_h) \
 	$(gdb_assert_h) $(dummy_frame_h) $(gdb_obstack_h)
-frv-linux-tdep.o: frv-linux-tdep.c $(defs_h) $(target_h) $(osabi_h) \
-	$(elf_bfd_h) $(elf_frv_h) $(frv_tdep_h)
+frv-linux-tdep.o: frv-linux-tdep.c $(defs_h) $(target_h) $(frame_h) \
+	$(osabi_h) $(elf_bfd_h) $(elf_frv_h) $(frv_tdep_h)
 frv-tdep.o: frv-tdep.c $(defs_h) $(gdb_string_h) $(inferior_h) $(gdbcore_h) \
 	$(arch_utils_h) $(regcache_h) $(frame_h) $(frame_unwind_h) \
 	$(frame_base_h) $(trad_frame_h) $(dis_asm_h) $(gdb_assert_h) \
@@ -1857,8 +1858,8 @@
 	$(gdb_proc_service_h)
 i386-linux-tdep.o: i386-linux-tdep.c $(defs_h) $(gdbcore_h) $(frame_h) \
 	$(value_h) $(regcache_h) $(inferior_h) $(osabi_h) $(reggroups_h) \
-	$(solib_svr4_h) $(gdb_string_h) $(i386_tdep_h) $(i386_linux_tdep_h) \
-	$(glibc_tdep_h)
+	$(gdb_string_h) $(i386_tdep_h) $(i386_linux_tdep_h) $(glibc_tdep_h) \
+	$(solib_svr4_h)
 i386ly-tdep.o: i386ly-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
 	$(regcache_h) $(target_h) $(osabi_h) $(i386_tdep_h)
 i386-nat.o: i386-nat.c $(defs_h) $(breakpoint_h) $(command_h) $(gdbcmd_h)
@@ -2139,13 +2140,15 @@
 	$(ppc_tdep_h)
 ppc-linux-tdep.o: ppc-linux-tdep.c $(defs_h) $(frame_h) $(inferior_h) \
 	$(symtab_h) $(target_h) $(gdbcore_h) $(gdbcmd_h) $(symfile_h) \
-	$(objfiles_h) $(regcache_h) $(value_h) $(osabi_h) $(solib_svr4_h) \
-	$(ppc_tdep_h)
+	$(objfiles_h) $(regcache_h) $(value_h) $(osabi_h) $(trad_frame_h) \
+	$(tramp_frame_h) $(regset_h) $(solib_svr4_h) $(ppc_tdep_h) \
+	$(trad_frame_h) $(frame_unwind_h)
 ppcnbsd-nat.o: ppcnbsd-nat.c $(defs_h) $(inferior_h) $(ppc_tdep_h) \
 	$(ppcnbsd_tdep_h)
 ppcnbsd-tdep.o: ppcnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \
 	$(target_h) $(breakpoint_h) $(value_h) $(osabi_h) $(ppc_tdep_h) \
-	$(ppcnbsd_tdep_h) $(nbsd_tdep_h) $(solib_svr4_h)
+	$(ppcnbsd_tdep_h) $(nbsd_tdep_h) $(tramp_frame_h) $(trad_frame_h) \
+	$(solib_svr4_h)
 ppc-sysv-tdep.o: ppc-sysv-tdep.c $(defs_h) $(gdbcore_h) $(inferior_h) \
 	$(regcache_h) $(value_h) $(gdb_string_h) $(gdb_assert_h) \
 	$(ppc_tdep_h) $(target_h) $(objfiles_h)
@@ -2246,7 +2249,8 @@
 	$(regcache_h) $(doublest_h) $(value_h) $(parser_defs_h) $(osabi_h) \
 	$(libbfd_h) $(coff_internal_h) $(libcoff_h) $(coff_xcoff_h) \
 	$(libxcoff_h) $(elf_bfd_h) $(solib_svr4_h) $(ppc_tdep_h) \
-	$(gdb_assert_h) $(dis_asm_h)
+	$(gdb_assert_h) $(dis_asm_h) $(trad_frame_h) $(frame_unwind_h) \
+	$(frame_base_h)
 s390-nat.o: s390-nat.c $(defs_h) $(tm_h) $(regcache_h) $(inferior_h) \
 	$(s390_tdep_h)
 s390-tdep.o: s390-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) $(inferior_h) \
@@ -2302,9 +2306,9 @@
 	$(objfiles_h) $(gdbcore_h) $(command_h) $(target_h) $(frame_h) \
 	$(gdb_regex_h) $(inferior_h) $(environ_h) $(language_h) $(gdbcmd_h) \
 	$(completer_h) $(filenames_h) $(exec_h) $(solist_h) $(readline_h)
-solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) $(gdbcore_h) \
-	$(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) $(language_h) \
-	$(command_h) $(gdbcmd_h) $(elf_frv_h)
+solib-frv.o: solib-frv.c $(defs_h) $(gdb_string_h) $(inferior_h) \
+	$(gdbcore_h) $(solist_h) $(frv_tdep_h) $(objfiles_h) $(symtab_h) \
+	$(language_h) $(command_h) $(gdbcmd_h) $(elf_frv_h)
 solib-irix.o: solib-irix.c $(defs_h) $(symtab_h) $(bfd_h) $(symfile_h) \
 	$(objfiles_h) $(gdbcore_h) $(target_h) $(inferior_h) $(solist_h)
 solib-legacy.o: solib-legacy.c $(defs_h) $(gdbcore_h) $(solib_svr4_h)
@@ -2414,7 +2418,7 @@
 symmisc.o: symmisc.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(bfd_h) \
 	$(symfile_h) $(objfiles_h) $(breakpoint_h) $(command_h) \
 	$(gdb_obstack_h) $(language_h) $(bcache_h) $(block_h) $(gdb_regex_h) \
-	$(dictionary_h) $(gdb_string_h)
+	$(dictionary_h) $(gdb_string_h) $(readline_h)
 symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
 	$(frame_h) $(target_h) $(value_h) $(symfile_h) $(objfiles_h) \
 	$(gdbcmd_h) $(call_cmds_h) $(gdb_regex_h) $(expression_h) \
@@ -2445,6 +2449,9 @@
 	$(readline_history_h)
 trad-frame.o: trad-frame.c $(defs_h) $(frame_h) $(trad_frame_h) \
 	$(regcache_h)
+tramp-frame.o: tramp-frame.c $(defs_h) $(tramp_frame_h) $(frame_unwind_h) \
+	$(gdbcore_h) $(symtab_h) $(objfiles_h) $(target_h) $(trad_frame_h) \
+	$(frame_base_h)
 typeprint.o: typeprint.c $(defs_h) $(gdb_obstack_h) $(bfd_h) $(symtab_h) \
 	$(gdbtypes_h) $(expression_h) $(value_h) $(gdbcore_h) $(command_h) \
 	$(gdbcmd_h) $(target_h) $(language_h) $(cp_abi_h) $(typeprint_h) \
@@ -2838,7 +2845,7 @@
 	$(symtab_h) $(gdbtypes_h) $(gdbcmd_h) $(frame_h) $(regcache_h) \
 	$(inferior_h) $(target_h) $(gdb_string_h) $(tui_layout_h) \
 	$(tui_win_h) $(tui_windata_h) $(tui_wingeneral_h) $(tui_file_h) \
-	$(gdb_curses_h)
+	$(reggroups_h) $(gdb_curses_h)
 	$(CC) -c $(INTERNAL_CFLAGS) $(srcdir)/tui/tui-regs.c
 tui-source.o: $(srcdir)/tui/tui-source.c $(defs_h) $(symtab_h) $(frame_h) \
 	$(breakpoint_h) $(source_h) $(symtab_h) $(tui_h) $(tui_data_h) \
diff --git a/gdb/frame-base.c b/gdb/frame-base.c
index 6d0f8ae..0fce6bc 100644
--- a/gdb/frame-base.c
+++ b/gdb/frame-base.c
@@ -111,10 +111,7 @@
 }
 
 const struct frame_base *
-frame_base_find_by_frame (struct frame_info *next_frame,
-			  void **this_base_cache,
-			  const struct frame_unwind *unwinder,
-			  void **this_prologue_cache)
+frame_base_find_by_frame (struct frame_info *next_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
   struct frame_base_table *table = gdbarch_data (gdbarch, frame_base_data);
diff --git a/gdb/frame-base.h b/gdb/frame-base.h
index ccc3283..680e9d5 100644
--- a/gdb/frame-base.h
+++ b/gdb/frame-base.h
@@ -29,18 +29,6 @@
 struct gdbarch;
 struct regcache;
 
-/* Given the NEXT frame, take a wiff of THIS frame's registers (namely
-   the PC and attributes) and if SELF is the applicable frame-base
-   handler return non-zero.  Optionally also initialize
-   THIS_BASE_CACHE.
-
-   If THIS frame's unwinder is the same as frame-base.unwind, THIS
-   frame's prologue-cache will be passed as THIS_BASE_CACHE.  */
-
-typedef int (frame_base_sniffer) (const struct frame_base *self,
-				  struct frame_info *next_frame,
-				  void **this_base_cache);
-
 /* Assuming the frame chain: (outer) prev <-> this <-> next (inner);
    and that this is a `normal frame'; use the NEXT frame, and its
    register unwind method, to determine the address of THIS frame's
@@ -52,10 +40,7 @@
 
    A typical implmentation will return the same value for base,
    locals-base and args-base.  That value, however, will likely be
-   different to the frame ID's stack address.
-
-   If THIS frame's unwinder is the same as frame-base.unwind, THIS
-   frame's prologue-cache will be passed as THIS_BASE_CACHE.  */
+   different to the frame ID's stack address.  */
 
 /* A generic base address.  */
 
@@ -80,8 +65,6 @@
   frame_this_base_ftype *this_base;
   frame_this_locals_ftype *this_locals;
   frame_this_args_ftype *this_args;
-  const struct frame_data *base_data;
-  frame_base_sniffer *sniffer;
 };
 
 /* Given the NEXT frame, return the frame base methods for THIS frame,
@@ -95,12 +78,6 @@
 extern void frame_base_append_sniffer (struct gdbarch *gdbarch,
 				       frame_base_sniffer_ftype *sniffer);
 
-/* Register a frame base, appending it to the list that need to be
-   searched.  */
-extern void frame_base_register_base (struct gdbarch *gdbarch,
-				      const struct frame_base *base);
-
-
 /* Set the default frame base.  If all else fails, this one is
    returned.  If this isn't set, the default is to use legacy code
    that uses things like the frame ID's base (ulgh!).  */
@@ -111,9 +88,6 @@
 /* Iterate through the list of frame base handlers until one returns
    an implementation.  */
 
-extern const struct frame_base *frame_base_find_by_frame (struct frame_info *next_frame,
-							  void **this_base_cache,
-							  const struct frame_unwind *unwinder,
-							  void **this_prologue_cache);
+extern const struct frame_base *frame_base_find_by_frame (struct frame_info *next_frame);
 
 #endif
diff --git a/gdb/frame.c b/gdb/frame.c
index 004c87c..7df7c43 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -2056,8 +2056,7 @@
   if (get_frame_type (fi) != NORMAL_FRAME)
     return 0;
   if (fi->base == NULL)
-    fi->base = frame_base_find_by_frame (fi->next, &fi->base_cache,
-					 fi->unwind, &fi->prologue_cache);
+    fi->base = frame_base_find_by_frame (fi->next);
   /* Sneaky: If the low-level unwind and high-level base code share a
      common unwinder, let them share the prologue cache.  */
   if (fi->base->unwind == fi->unwind)
@@ -2073,8 +2072,7 @@
     return 0;
   /* If there isn't a frame address method, find it.  */
   if (fi->base == NULL)
-    fi->base = frame_base_find_by_frame (fi->next, &fi->base_cache,
-					 fi->unwind, &fi->prologue_cache);
+    fi->base = frame_base_find_by_frame (fi->next);
   /* Sneaky: If the low-level unwind and high-level base code share a
      common unwinder, let them share the prologue cache.  */
   if (fi->base->unwind == fi->unwind)
@@ -2092,8 +2090,7 @@
     return 0;
   /* If there isn't a frame address method, find it.  */
   if (fi->base == NULL)
-    fi->base = frame_base_find_by_frame (fi->next, &fi->base_cache,
-					 fi->unwind, &fi->prologue_cache);
+    fi->base = frame_base_find_by_frame (fi->next);
   /* Sneaky: If the low-level unwind and high-level base code share a
      common unwinder, let them share the prologue cache.  */
   if (fi->base->unwind == fi->unwind)
diff --git a/gdb/ppcnbsd-tdep.c b/gdb/ppcnbsd-tdep.c
index b6e869b..6872be3 100644
--- a/gdb/ppcnbsd-tdep.c
+++ b/gdb/ppcnbsd-tdep.c
@@ -235,32 +235,33 @@
 			     struct trad_frame_cache *this_cache,
 			     CORE_ADDR func)
 {
+  CORE_ADDR base;
   CORE_ADDR offset;
   int i;
   struct gdbarch *gdbarch = get_frame_arch (next_frame);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  this_cache->this_base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
-  offset = this_cache->this_base + 0x18 + 2 * tdep->wordsize;
+  base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
+  offset = base + 0x18 + 2 * tdep->wordsize;
   for (i = 0; i < 32; i++)
     {
       int regnum = i + tdep->ppc_gp0_regnum;
-      this_cache->prev_regs[regnum].addr = offset;
+      trad_frame_set_reg_addr (this_cache, regnum, offset);
       offset += tdep->wordsize;
     }
-  this_cache->prev_regs[tdep->ppc_lr_regnum].addr = offset;
+  trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, offset);
   offset += tdep->wordsize;
-  this_cache->prev_regs[tdep->ppc_cr_regnum].addr = offset;
+  trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, offset);
   offset += tdep->wordsize;
-  this_cache->prev_regs[tdep->ppc_xer_regnum].addr = offset;
+  trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, offset);
   offset += tdep->wordsize;
-  this_cache->prev_regs[tdep->ppc_ctr_regnum].addr = offset;
+  trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, offset);
   offset += tdep->wordsize;
-  this_cache->prev_regs[PC_REGNUM].addr = offset; /* SRR0? */
+  trad_frame_set_reg_addr (this_cache, PC_REGNUM, offset); /* SRR0? */
   offset += tdep->wordsize;
 
   /* Construct the frame ID using the function start.  */
-  this_cache->this_id = frame_id_build (this_cache->this_base, func);
+  trad_frame_set_id (this_cache, frame_id_build (base, func));
 }
 
 /* Given the NEXT frame, examine the instructions at and around this
diff --git a/gdb/trad-frame.c b/gdb/trad-frame.c
index 3b570e1..85575df 100644
--- a/gdb/trad-frame.c
+++ b/gdb/trad-frame.c
@@ -24,6 +24,14 @@
 #include "trad-frame.h"
 #include "regcache.h"
 
+struct trad_frame_cache
+{
+  struct frame_info *next_frame;
+  CORE_ADDR this_base;
+  struct trad_frame_saved_reg *prev_regs;
+  struct frame_id this_id;
+};
+
 struct trad_frame_cache *
 trad_frame_cache_zalloc (struct frame_info *next_frame)
 {
@@ -31,6 +39,7 @@
 
   this_trad_cache = FRAME_OBSTACK_ZALLOC (struct trad_frame_cache);
   this_trad_cache->prev_regs = trad_frame_alloc_saved_regs (next_frame);
+  this_trad_cache->next_frame = next_frame;
   return this_trad_cache;
 }
 
@@ -89,6 +98,13 @@
 }
 
 void
+trad_frame_set_reg_addr (struct trad_frame_cache *this_trad_cache,
+			 int regnum, CORE_ADDR addr)
+{
+  this_trad_cache->prev_regs[regnum].addr = addr;
+}
+
+void
 trad_frame_set_unknown (struct trad_frame_saved_reg this_saved_regs[],
 			int regnum)
 {
@@ -142,3 +158,29 @@
 	     gdbarch_register_name (gdbarch, regnum));
     }
 }
+
+void
+trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
+			 struct frame_info *next_frame,
+			 int regnum, int *optimizedp,
+			 enum lval_type *lvalp, CORE_ADDR *addrp,
+			 int *realregp, void *bufferp)
+{
+  trad_frame_prev_register (next_frame, this_trad_cache->prev_regs,
+			    regnum, optimizedp, lvalp, addrp, realregp,
+			    bufferp);
+}
+
+void
+trad_frame_set_id (struct trad_frame_cache *this_trad_cache,
+		   struct frame_id this_id)
+{
+  this_trad_cache->this_id = this_id;
+}
+
+void
+trad_frame_get_id (struct trad_frame_cache *this_trad_cache,
+		   struct frame_id *this_id)
+{
+  (*this_id) = this_trad_cache->this_id;
+}
diff --git a/gdb/trad-frame.h b/gdb/trad-frame.h
index 0fe1a5d..da62595 100644
--- a/gdb/trad-frame.h
+++ b/gdb/trad-frame.h
@@ -26,15 +26,23 @@
 
 struct frame_info;
 
-struct trad_frame_cache
-{
-  CORE_ADDR this_base;
-  struct trad_frame_saved_reg *prev_regs;
-  struct frame_id this_id;
-};
+struct trad_frame_cache;
 
 struct trad_frame_cache *trad_frame_cache_zalloc (struct frame_info *next_frame);
 
+void trad_frame_set_id (struct trad_frame_cache *this_trad_cache,
+			     struct frame_id this_id);
+void trad_frame_get_id (struct trad_frame_cache *this_trad_cache,
+			struct frame_id *this_id);
+
+void trad_frame_set_reg_addr (struct trad_frame_cache *this_trad_cache,
+			      int regnum, CORE_ADDR addr);
+void trad_frame_get_register (struct trad_frame_cache *this_trad_cache,
+			      struct frame_info *next_frame,
+			      int regnum, int *optimizedp,
+			      enum lval_type *lvalp, CORE_ADDR *addrp,
+			      int *realregp, void *bufferp);
+
 /* A traditional saved regs table, indexed by REGNUM, encoding where
    the value of REGNUM for the previous frame can be found in this
    frame.
diff --git a/gdb/tramp-frame.c b/gdb/tramp-frame.c
index d047659..7a8057e 100644
--- a/gdb/tramp-frame.c
+++ b/gdb/tramp-frame.c
@@ -65,7 +65,7 @@
 {
   struct trad_frame_cache *trad_cache
     = tramp_frame_cache (next_frame, this_cache);
-  (*this_id) = trad_cache->this_id;
+  trad_frame_get_id (trad_cache, this_id);
 }
 
 static void
@@ -79,8 +79,8 @@
 {
   struct trad_frame_cache *trad_cache
     = tramp_frame_cache (next_frame, this_cache);
-  trad_frame_prev_register (next_frame, trad_cache->prev_regs, prev_regnum,
-			    optimizedp, lvalp, addrp, realnump, valuep);
+  trad_frame_get_register (trad_cache, next_frame, prev_regnum, optimizedp,
+			   lvalp, addrp, realnump, valuep);
 }
 
 static CORE_ADDR