This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

Re: [PowerPC] Tidy unwind support


Here's MD_FALLBACK_FRAME_STATE_FOR converted to functions.  Tested by
building alpha-linux, hppa-linux, ia64-linux, mips-linux, s390-linux,
sh-linux, sparc-linux, sparc64-linux, x86_64-linux cross compilers.
i686-linux, powerpc-linux, powerpc64-linux bootstrap attempted, but
failed for other reasons on mainline.  I couldn't test alpha-vms due
to lack of system headers.

The patch is a more-or-less straight conversion of macros to functions,
except for the following:  sh/linux-unwind.h differs from sh/linux.h in
that one macro disappears.  rs6000/linux-unwind.h separates out
sigcontext code, which is different for 32 and 64 bit, from the frame
update code, which can be made identical.  For i386, I used the 32-bit
definitions from linux.h, which have extra glibc version guards, rather
than the definition in linux64.h.

	* doc/tm.texi (MD_UNWIND_SUPPORT): Document.
	(MD_FALLBACK_FRAME_STATE_FOR): Update.
	* unwind-dw2.c (MD_UNWIND_SUPPORT): #include if defined.
	(uw_frame_state_for): Adjust MD_FALLBACK_FRAME_STATE_FOR invocation.
	(MD_FROB_UPDATE_CONTEXT): Remove default.
	(uw_update_context_1): Instead #ifdef invocation.
	* config/ia64/unwind-ia64.c (MD_UNWIND_SUPPORT): #include if defined.
	(uw_frame_state_for): Adjust MD_FALLBACK_FRAME_STATE_FOR invocation.
	* config/alpha/gnu.h (MD_FALLBACK_FRAME_STATE_FOR): Don't undef.
	(MD_UNWIND_SUPPORT): Undefine this instead.
	* config/i386/gnu.h: Likewise.
	* config/alpha/linux-unwind.h: New file, macro converted to
	function, extracted from..
	* config/alpha/linux.h (MD_FALLBACK_FRAME_STATE_FOR): ..this.
	(MD_UNWIND_SUPPORT): Define.
	* config/alpha/vms-unwind.h, config/alpha/vms.h: Likewise.
	* config/i386/linux-unwind.h, config/i386/linux.h,
	config/i386/linux64.h: Likewise.
	* config/ia64/linux-unwind.h, config/ia64/linux.h: Likewise.
	MD_HANDLE_UNWABI too.
	* config/mips/linux-unwind.h, config/mips/linux.h: Likewise.
	* config/pa/linux-unwind.h, config/pa/pa32-linux.h: Likewise.
	* config/rs6000/darwin-unwind.h, config/rs6000/darwin.h: Likewise.
	* config/s390/linux-unwind.h, config/s390/linux.h: Likewise.
	* config/sparc/linux-unwind.h, config/sparc/linux.h,
	config/sparc/linux64.h: Likewise.
	* config/sh/linux-unwind.h, config/sh/linux.h: Likewise, but merge
	SH_FALLBACK_FRAME_FLOAT_STATE into sh_fallback_frame_state.
	* config/rs6000/linux-unwind.h, config/rs6000/linux.h,
	config/rs6000/linux64.h: Likewise.  Split out get_sigcontext
	function.  Use ARG_POINTER_REGNUM for 32-bit temp reg too.

OK to apply mainline?

Index: gcc/unwind-dw2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/unwind-dw2.c,v
retrieving revision 1.45
diff -u -p -r1.45 unwind-dw2.c
--- gcc/unwind-dw2.c	4 Sep 2004 00:15:40 -0000	1.45
+++ gcc/unwind-dw2.c	6 Sep 2004 12:53:58 -0000
@@ -60,11 +60,6 @@
 #define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO)
 #endif
 
-/* A target can do some update context frobbing.  */
-#ifndef MD_FROB_UPDATE_CONTEXT
-#define MD_FROB_UPDATE_CONTEXT(CTX, FS) do { } while (0)
-#endif
-
 /* This is the register and unwind state for a particular frame.  This
    provides the information necessary to unwind up past a frame and return
    to its caller.  */
@@ -252,6 +247,10 @@ _Unwind_GetTextRelBase (struct _Unwind_C
   return (_Unwind_Ptr) context->bases.tbase;
 }
 #endif
+
+#ifdef MD_UNWIND_SUPPORT
+#include MD_UNWIND_SUPPORT
+#endif
 
 /* Extract any interesting information from the CIE for the translation
    unit F belongs to.  Return a pointer to the byte after the augmentation,
@@ -963,14 +962,11 @@ uw_frame_state_for (struct _Unwind_Conte
   fde = _Unwind_Find_FDE (context->ra - 1, &context->bases);
   if (fde == NULL)
     {
+#ifdef MD_FALLBACK_FRAME_STATE_FOR
       /* Couldn't find frame unwind info for this function.  Try a
 	 target-specific fallback mechanism.  This will necessarily
 	 not provide a personality routine or LSDA.  */
-#ifdef MD_FALLBACK_FRAME_STATE_FOR
-      MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
-      return _URC_END_OF_STACK;
-    success:
-      return _URC_NO_REASON;
+      return MD_FALLBACK_FRAME_STATE_FOR (context, fs);
 #else
       return _URC_END_OF_STACK;
 #endif
@@ -1176,7 +1172,9 @@ uw_update_context_1 (struct _Unwind_Cont
 	break;
       }
 
+#ifdef MD_FROB_UPDATE_CONTEXT
   MD_FROB_UPDATE_CONTEXT (context, fs);
+#endif
 }
 
 /* CONTEXT describes the unwind state for a frame, and FS describes the FDE
Index: gcc/config/alpha/gnu.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/gnu.h,v
retrieving revision 1.6
diff -u -p -r1.6 gnu.h
--- gcc/config/alpha/gnu.h	29 Nov 2003 03:08:09 -0000	1.6
+++ gcc/config/alpha/gnu.h	6 Sep 2004 12:53:59 -0000
@@ -23,4 +23,4 @@
    %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
 
 /* FIXME: Is a Hurd-specific fallback mechanism necessary?  */
-#undef MD_FALLBACK_FRAME_STATE_FOR
+#undef MD_UNWIND_SUPPORT
Index: gcc/config/alpha/linux-unwind.h
===================================================================
RCS file: gcc/config/alpha/linux-unwind.h
diff -N gcc/config/alpha/linux-unwind.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/alpha/linux-unwind.h	6 Sep 2004 12:53:59 -0000
@@ -0,0 +1,74 @@
+/* DWARF2 EH unwinding support for Alpha Linux.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.  */
+
+#include <signal.h>
+#include <sys/ucontext.h>
+
+#define MD_FALLBACK_FRAME_STATE_FOR alpha_fallback_frame_state
+
+static _Unwind_Reason_Code
+alpha_fallback_frame_state (struct _Unwind_Context *context,
+			    _Unwind_FrameState *fs)
+{
+  unsigned int *pc = context->ra;
+  struct sigcontext *sc;
+  long new_cfa, i;
+
+  if (pc[0] != 0x47fe0410		/* mov $30,$16 */
+      || pc[2] != 0x00000083		/* callsys */)
+    return _URC_END_OF_STACK;
+  if (context->cfa == 0)
+    return _URC_END_OF_STACK;
+  if (pc[1] == 0x201f0067)		/* lda $0,NR_sigreturn */
+    sc = context->cfa;
+  else if (pc[1] == 0x201f015f)	/* lda $0,NR_rt_sigreturn */
+    {
+      struct rt_sigframe {
+	struct siginfo info;
+	struct ucontext uc;
+      } *rt_ = context->cfa;
+      sc = &rt_->uc.uc_mcontext;
+    }
+  else
+    return _URC_END_OF_STACK;
+  new_cfa = sc->sc_regs[30];
+  fs->cfa_how = CFA_REG_OFFSET;
+  fs->cfa_reg = 30;
+  fs->cfa_offset = new_cfa - (long) context->cfa;
+  for (i = 0; i < 30; ++i)
+    {
+      fs->regs.reg[i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i].loc.offset
+	= (long)&sc->sc_regs[i] - new_cfa;
+    }
+  for (i = 0; i < 31; ++i)
+    {
+      fs->regs.reg[i+32].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i+32].loc.offset
+	= (long)&sc->sc_fpregs[i] - new_cfa;
+    }
+  fs->regs.reg[64].how = REG_SAVED_OFFSET;
+  fs->regs.reg[64].loc.offset = (long)&sc->sc_pc - new_cfa;
+  fs->retaddr_column = 64;
+  return _URC_NO_REASON;
+}
Index: gcc/config/alpha/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/linux.h,v
retrieving revision 1.40
diff -u -p -r1.40 linux.h
--- gcc/config/alpha/linux.h	23 Apr 2004 02:16:23 -0000	1.40
+++ gcc/config/alpha/linux.h	6 Sep 2004 12:53:59 -0000
@@ -76,55 +76,4 @@ Boston, MA 02111-1307, USA.  */
 #define USE_LD_AS_NEEDED 1
 #endif
 
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  */
-
-#ifdef IN_LIBGCC2
-#include <signal.h>
-#include <sys/ucontext.h>
-#endif
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned int *pc_ = (CONTEXT)->ra;					\
-    struct sigcontext *sc_;						\
-    long new_cfa_, i_;							\
-									\
-    if (pc_[0] != 0x47fe0410		/* mov $30,$16 */		\
-        || pc_[2] != 0x00000083		/* callsys */)			\
-      break;								\
-    if ((CONTEXT)->cfa == 0)						\
-      break;								\
-    if (pc_[1] == 0x201f0067)		/* lda $0,NR_sigreturn */	\
-      sc_ = (CONTEXT)->cfa;						\
-    else if (pc_[1] == 0x201f015f)	/* lda $0,NR_rt_sigreturn */	\
-      {									\
-	struct rt_sigframe {						\
-	  struct siginfo info;						\
-	  struct ucontext uc;						\
-	} *rt_ = (CONTEXT)->cfa;					\
-	sc_ = &rt_->uc.uc_mcontext;					\
-      }									\
-    else								\
-      break;								\
-    new_cfa_ = sc_->sc_regs[30];					\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = 30;							\
-    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
-    for (i_ = 0; i_ < 30; ++i_)						\
-      {									\
-	(FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i_].loc.offset					\
-	  = (long)&sc_->sc_regs[i_] - new_cfa_;				\
-      }									\
-    for (i_ = 0; i_ < 31; ++i_)						\
-      {									\
-	(FS)->regs.reg[i_+32].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i_+32].loc.offset				\
-	  = (long)&sc_->sc_fpregs[i_] - new_cfa_;			\
-      }									\
-    (FS)->regs.reg[64].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[64].loc.offset = (long)&sc_->sc_pc - new_cfa_;	\
-    (FS)->retaddr_column = 64;						\
-    goto SUCCESS;							\
-  } while (0)
+#define MD_UNWIND_SUPPORT "config/alpha/linux-unwind.h"
Index: gcc/config/alpha/vms-unwind.h
===================================================================
RCS file: gcc/config/alpha/vms-unwind.h
diff -N gcc/config/alpha/vms-unwind.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/alpha/vms-unwind.h	6 Sep 2004 12:53:59 -0000
@@ -0,0 +1,72 @@
+/* DWARF2 EH unwinding support for Alpha VMS.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include <pdscdef.h>
+
+#define MD_FALLBACK_FRAME_STATE_FOR alpha_fallback_frame_state
+
+static _Unwind_Reason_Code
+alpha_fallback_frame_state (struct _Unwind_Context *context,
+			    _Unwind_FrameState *fs)
+{
+  PDSCDEF *pv = *((PDSCDEF **) context->reg [29]);
+
+  if (pv && ((long) pv & 0x7) == 0) /* low bits 0 means address */
+    pv = *(PDSCDEF **) pv;
+
+  if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_STACK))
+    {
+      int i, j;
+
+      fs->cfa_offset = pv->pdsc$l_size;
+      fs->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30;
+      fs->retaddr_column = 26;
+      fs->cfa_how = CFA_REG_OFFSET;
+      fs->regs.reg[27].loc.offset = -pv->pdsc$l_size;
+      fs->regs.reg[27].how = REG_SAVED_OFFSET;
+      fs->regs.reg[26].loc.offset
+	= -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset);
+      fs->regs.reg[26].how = REG_SAVED_OFFSET;
+
+      for (i = 0, j = 0; i < 32; i++)
+	if (1<<i & pv->pdsc$l_ireg_mask)
+	  {
+	    fs->regs.reg[i].loc.offset
+	      = -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset - 8 * ++j);
+	    fs->regs.reg[i].how = REG_SAVED_OFFSET;
+	  }
+
+      return _URC_NO_REASON;
+    }
+  else if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_REGISTER))
+    {
+      fs->cfa_offset = pv->pdsc$l_size;
+      fs->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30;
+      fs->retaddr_column = 26;
+      fs->cfa_how = CFA_REG_OFFSET;
+      fs->regs.reg[26].loc.reg = pv->pdsc$b_save_ra;
+      fs->regs.reg[26].how = REG_SAVED_REG;
+      fs->regs.reg[29].loc.reg = pv->pdsc$b_save_fp;
+      fs->regs.reg[29].how = REG_SAVED_REG;
+
+      return _URC_NO_REASON;
+    }
+  return _URC_END_OF_STACK;
+}
Index: gcc/config/alpha/vms.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/vms.h,v
retrieving revision 1.82
diff -u -p -r1.82 vms.h
--- gcc/config/alpha/vms.h	13 Jul 2004 07:44:54 -0000	1.82
+++ gcc/config/alpha/vms.h	6 Sep 2004 12:53:59 -0000
@@ -318,55 +318,7 @@ do {									\
 
 #define LINK_EH_SPEC "vms-dwarf2eh.o%s "
 
-#ifdef IN_LIBGCC2
-#include <pdscdef.h>
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
- do {									\
-  PDSCDEF *pv = *((PDSCDEF **) (CONTEXT)->reg [29]);                    \
-									\
-  if (pv && ((long) pv & 0x7) == 0) /* low bits 0 means address */      \
-    pv = *(PDSCDEF **) pv;                                              \
-									\
-  if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_STACK))		\
-    {									\
-      int i, j;								\
-									\
-      (FS)->cfa_offset = pv->pdsc$l_size;				\
-      (FS)->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30; \
-      (FS)->retaddr_column = 26;					\
-      (FS)->cfa_how = CFA_REG_OFFSET;					\
-      (FS)->regs.reg[27].loc.offset = -pv->pdsc$l_size;			\
-      (FS)->regs.reg[27].how = REG_SAVED_OFFSET;			\
-      (FS)->regs.reg[26].loc.offset					\
-	 = -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset);			\
-      (FS)->regs.reg[26].how = REG_SAVED_OFFSET;			\
-									\
-      for (i = 0, j = 0; i < 32; i++)					\
-	if (1<<i & pv->pdsc$l_ireg_mask)				\
-	  {								\
-	    (FS)->regs.reg[i].loc.offset				\
-	      = -(pv->pdsc$l_size - pv->pdsc$w_rsa_offset - 8 * ++j);	\
-	    (FS)->regs.reg[i].how = REG_SAVED_OFFSET;			\
-	  }								\
-									\
-      goto SUCCESS;							\
-    }									\
-  else if (pv && ((pv->pdsc$w_flags & 0xf) == PDSC$K_KIND_FP_REGISTER))	\
-    {									\
-      (FS)->cfa_offset = pv->pdsc$l_size;				\
-      (FS)->cfa_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30; \
-      (FS)->retaddr_column = 26;					\
-      (FS)->cfa_how = CFA_REG_OFFSET;					\
-      (FS)->regs.reg[26].loc.reg = pv->pdsc$b_save_ra;			\
-      (FS)->regs.reg[26].how = REG_SAVED_REG;			        \
-      (FS)->regs.reg[29].loc.reg = pv->pdsc$b_save_fp;			\
-      (FS)->regs.reg[29].how = REG_SAVED_REG;			        \
-									\
-      goto SUCCESS;							\
-    }									\
-} while (0)
-#endif
+#define MD_UNWIND_SUPPORT "config/alpha/vms-unwind.h"
 
 /* This is how to output an assembler line
    that says to advance the location counter
Index: gcc/config/i386/gnu.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/gnu.h,v
retrieving revision 1.18
diff -u -p -r1.18 gnu.h
--- gcc/config/i386/gnu.h	29 Nov 2003 03:08:10 -0000	1.18
+++ gcc/config/i386/gnu.h	6 Sep 2004 12:54:00 -0000
@@ -40,4 +40,4 @@
    %{!static:%{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}}"
 
 /* FIXME: Is a Hurd-specific fallback mechanism necessary?  */
-#undef MD_FALLBACK_FRAME_STATE_FOR
+#undef MD_UNWIND_SUPPORT
Index: gcc/config/i386/linux-unwind.h
===================================================================
RCS file: gcc/config/i386/linux-unwind.h
diff -N gcc/config/i386/linux-unwind.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/i386/linux-unwind.h	6 Sep 2004 12:54:00 -0000
@@ -0,0 +1,165 @@
+/* DWARF2 EH unwinding support for AMD x86-64 and x86.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.
+   Don't use this at all if inhibit_libc is used.  */
+
+#ifndef inhibit_libc
+
+#ifdef __x86_64__
+
+#include <signal.h>
+#include <sys/ucontext.h>
+
+#define MD_FALLBACK_FRAME_STATE_FOR x86_64_fallback_frame_state
+
+static _Unwind_Reason_Code
+x86_64_fallback_frame_state (struct _Unwind_Context *context,
+			     _Unwind_FrameState *fs)
+{
+  unsigned char *pc = context->ra;
+  struct sigcontext *sc;
+  long new_cfa;
+
+  /* movq __NR_rt_sigreturn, %rax ; syscall  */
+  if (*(unsigned char *)(pc+0) == 0x48
+      && *(unsigned long *)(pc+1) == 0x050f0000000fc0c7)
+    {
+      struct ucontext *uc_ = context->cfa;
+      sc = (struct sigcontext *) &uc_->uc_mcontext;
+    }
+  else
+    return _URC_END_OF_STACK;
+
+  new_cfa = sc->rsp;
+  fs->cfa_how = CFA_REG_OFFSET;
+  /* Register 7 is rsp  */
+  fs->cfa_reg = 7;
+  fs->cfa_offset = new_cfa - (long) context->cfa;
+
+  /* The SVR4 register numbering macros aren't usable in libgcc.  */
+  fs->regs.reg[0].how = REG_SAVED_OFFSET;
+  fs->regs.reg[0].loc.offset = (long)&sc->rax - new_cfa;
+  fs->regs.reg[1].how = REG_SAVED_OFFSET;
+  fs->regs.reg[1].loc.offset = (long)&sc->rdx - new_cfa;
+  fs->regs.reg[2].how = REG_SAVED_OFFSET;
+  fs->regs.reg[2].loc.offset = (long)&sc->rcx - new_cfa;
+  fs->regs.reg[3].how = REG_SAVED_OFFSET;
+  fs->regs.reg[3].loc.offset = (long)&sc->rbx - new_cfa;
+  fs->regs.reg[4].how = REG_SAVED_OFFSET;
+  fs->regs.reg[4].loc.offset = (long)&sc->rsi - new_cfa;
+  fs->regs.reg[5].how = REG_SAVED_OFFSET;
+  fs->regs.reg[5].loc.offset = (long)&sc->rdi - new_cfa;
+  fs->regs.reg[6].how = REG_SAVED_OFFSET;
+  fs->regs.reg[6].loc.offset = (long)&sc->rbp - new_cfa;
+  fs->regs.reg[8].how = REG_SAVED_OFFSET;
+  fs->regs.reg[8].loc.offset = (long)&sc->r8 - new_cfa;
+  fs->regs.reg[9].how = REG_SAVED_OFFSET;
+  fs->regs.reg[9].loc.offset = (long)&sc->r9 - new_cfa;
+  fs->regs.reg[10].how = REG_SAVED_OFFSET;
+  fs->regs.reg[10].loc.offset = (long)&sc->r10 - new_cfa;
+  fs->regs.reg[11].how = REG_SAVED_OFFSET;
+  fs->regs.reg[11].loc.offset = (long)&sc->r11 - new_cfa;
+  fs->regs.reg[12].how = REG_SAVED_OFFSET;
+  fs->regs.reg[12].loc.offset = (long)&sc->r12 - new_cfa;
+  fs->regs.reg[13].how = REG_SAVED_OFFSET;
+  fs->regs.reg[13].loc.offset = (long)&sc->r13 - new_cfa;
+  fs->regs.reg[14].how = REG_SAVED_OFFSET;
+  fs->regs.reg[14].loc.offset = (long)&sc->r14 - new_cfa;
+  fs->regs.reg[15].how = REG_SAVED_OFFSET;
+  fs->regs.reg[15].loc.offset = (long)&sc->r15 - new_cfa;
+  fs->regs.reg[16].how = REG_SAVED_OFFSET;
+  fs->regs.reg[16].loc.offset = (long)&sc->rip - new_cfa;
+  fs->retaddr_column = 16;
+  return _URC_NO_REASON;
+}
+
+#else /* ifdef __x86_64__  */
+
+/* There's no sys/ucontext.h for glibc 2.0, so no
+   signal-turned-exceptions for them.  There's also no configure-run for
+   the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H.  Using the
+   target libc version macro should be enough.  */
+#if !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
+
+#include <signal.h>
+#include <sys/ucontext.h>
+
+#define MD_FALLBACK_FRAME_STATE_FOR x86_fallback_frame_state
+
+static _Unwind_Reason_Code
+x86_fallback_frame_state (struct _Unwind_Context *context,
+			  _Unwind_FrameState *fs)
+{
+  unsigned char *pc = context->ra;
+  struct sigcontext *sc;
+  long new_cfa;
+
+  /* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80  */
+  if (*(unsigned short *)(pc+0) == 0xb858
+      && *(unsigned int *)(pc+2) == 119
+      && *(unsigned short *)(pc+6) == 0x80cd)
+    sc = context->cfa + 4;
+  /* movl $__NR_rt_sigreturn,%eax ; int $0x80  */
+  else if (*(unsigned char *)(pc+0) == 0xb8
+	   && *(unsigned int *)(pc+1) == 173
+	   && *(unsigned short *)(pc+5) == 0x80cd)
+    {
+      struct rt_sigframe {
+	int sig;
+	struct siginfo *pinfo;
+	void *puc;
+	struct siginfo info;
+	struct ucontext uc;
+      } *rt_ = context->cfa;
+      sc = (struct sigcontext *) &rt_->uc.uc_mcontext;
+    }
+  else
+    return _URC_END_OF_STACK;
+
+  new_cfa = sc->esp;
+  fs->cfa_how = CFA_REG_OFFSET;
+  fs->cfa_reg = 4;
+  fs->cfa_offset = new_cfa - (long) context->cfa;
+
+  /* The SVR4 register numbering macros aren't usable in libgcc.  */
+  fs->regs.reg[0].how = REG_SAVED_OFFSET;
+  fs->regs.reg[0].loc.offset = (long)&sc->eax - new_cfa;
+  fs->regs.reg[3].how = REG_SAVED_OFFSET;
+  fs->regs.reg[3].loc.offset = (long)&sc->ebx - new_cfa;
+  fs->regs.reg[1].how = REG_SAVED_OFFSET;
+  fs->regs.reg[1].loc.offset = (long)&sc->ecx - new_cfa;
+  fs->regs.reg[2].how = REG_SAVED_OFFSET;
+  fs->regs.reg[2].loc.offset = (long)&sc->edx - new_cfa;
+  fs->regs.reg[6].how = REG_SAVED_OFFSET;
+  fs->regs.reg[6].loc.offset = (long)&sc->esi - new_cfa;
+  fs->regs.reg[7].how = REG_SAVED_OFFSET;
+  fs->regs.reg[7].loc.offset = (long)&sc->edi - new_cfa;
+  fs->regs.reg[5].how = REG_SAVED_OFFSET;
+  fs->regs.reg[5].loc.offset = (long)&sc->ebp - new_cfa;
+  fs->regs.reg[8].how = REG_SAVED_OFFSET;
+  fs->regs.reg[8].loc.offset = (long)&sc->eip - new_cfa;
+  fs->retaddr_column = 8;
+  return _URC_NO_REASON;
+}
+#endif /* not glibc 2.0 */
+#endif /* ifdef __x86_64__  */
+#endif /* ifdef inhibit_libc  */
Index: gcc/config/i386/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/linux.h,v
retrieving revision 1.54
diff -u -p -r1.54 linux.h
--- gcc/config/i386/linux.h	5 Aug 2004 09:12:11 -0000	1.54
+++ gcc/config/i386/linux.h	6 Sep 2004 12:54:00 -0000
@@ -181,72 +181,4 @@ Boston, MA 02111-1307, USA.  */
 #undef NEED_INDICATE_EXEC_STACK
 #define NEED_INDICATE_EXEC_STACK 1
 
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  */
-
-#ifdef IN_LIBGCC2
-/* There's no sys/ucontext.h for glibc 2.0, so no
-   signal-turned-exceptions for them.  There's also no configure-run for
-   the target, so we can't check on (e.g.) HAVE_SYS_UCONTEXT_H.  Using the
-   target libc version macro should be enough.  */
-#if !(__GLIBC__ == 2 && __GLIBC_MINOR__ == 0)
-#include <signal.h>
-#include <sys/ucontext.h>
-
-#define REG_NAME(reg) reg
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned char *pc_ = (CONTEXT)->ra;					\
-    struct sigcontext *sc_;						\
-    long new_cfa_;							\
-									\
-    /* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80  */		\
-    if (*(unsigned short *)(pc_+0) == 0xb858				\
-	&& *(unsigned int *)(pc_+2) == 119				\
-	&& *(unsigned short *)(pc_+6) == 0x80cd)			\
-      sc_ = (CONTEXT)->cfa + 4;						\
-    /* movl $__NR_rt_sigreturn,%eax ; int $0x80  */			\
-    else if (*(unsigned char *)(pc_+0) == 0xb8				\
-	     && *(unsigned int *)(pc_+1) == 173				\
-	     && *(unsigned short *)(pc_+5) == 0x80cd)			\
-      {									\
-	struct rt_sigframe {						\
-	  int sig;							\
-	  struct siginfo *pinfo;					\
-	  void *puc;							\
-	  struct siginfo info;						\
-	  struct ucontext uc;						\
-	} *rt_ = (CONTEXT)->cfa;					\
-	sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext;		\
-      }									\
-    else								\
-      break;								\
-									\
-    new_cfa_ = sc_->REG_NAME(esp);						\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = 4;							\
-    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
-									\
-    /* The SVR4 register numbering macros aren't usable in libgcc.  */	\
-    (FS)->regs.reg[0].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[0].loc.offset = (long)&sc_->REG_NAME(eax) - new_cfa_;	\
-    (FS)->regs.reg[3].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[3].loc.offset = (long)&sc_->REG_NAME(ebx) - new_cfa_;	\
-    (FS)->regs.reg[1].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[1].loc.offset = (long)&sc_->REG_NAME(ecx) - new_cfa_;	\
-    (FS)->regs.reg[2].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[2].loc.offset = (long)&sc_->REG_NAME(edx) - new_cfa_;	\
-    (FS)->regs.reg[6].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[6].loc.offset = (long)&sc_->REG_NAME(esi) - new_cfa_;	\
-    (FS)->regs.reg[7].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[7].loc.offset = (long)&sc_->REG_NAME(edi) - new_cfa_;	\
-    (FS)->regs.reg[5].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[5].loc.offset = (long)&sc_->REG_NAME(ebp) - new_cfa_;	\
-    (FS)->regs.reg[8].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[8].loc.offset = (long)&sc_->REG_NAME(eip) - new_cfa_;	\
-    (FS)->retaddr_column = 8;						\
-    goto SUCCESS;							\
-  } while (0)
-#endif /* not glibc 2.0 */
-#endif /* IN_LIBGCC2 */
+#define MD_UNWIND_SUPPORT "config/i386/linux-unwind.h"
Index: gcc/config/i386/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/linux64.h,v
retrieving revision 1.27
diff -u -p -r1.27 linux64.h
--- gcc/config/i386/linux64.h	29 Nov 2003 03:08:10 -0000	1.27
+++ gcc/config/i386/linux64.h	6 Sep 2004 12:54:00 -0000
@@ -69,128 +69,4 @@ Boston, MA 02111-1307, USA.  */
 #undef NEED_INDICATE_EXEC_STACK
 #define NEED_INDICATE_EXEC_STACK 1
 
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  
-   Don't use this at all if inhibit_libc is used.  */
-
-#ifndef inhibit_libc
-#ifdef IN_LIBGCC2
-#include <signal.h>
-#include <sys/ucontext.h>
-#endif
-
-#ifdef __x86_64__
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned char *pc_ = (CONTEXT)->ra;					\
-    struct sigcontext *sc_;						\
-    long new_cfa_;							\
-									\
-    /* movq __NR_rt_sigreturn, %rax ; syscall  */			\
-    if (*(unsigned char *)(pc_+0) == 0x48				\
-	&& *(unsigned long *)(pc_+1) == 0x050f0000000fc0c7)		\
-      {									\
-	struct ucontext *uc_ = (CONTEXT)->cfa;				\
-	sc_ = (struct sigcontext *) &uc_->uc_mcontext;			\
-      }									\
-    else								\
-      break;								\
-									\
-    new_cfa_ = sc_->rsp;						\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    /* Register 7 is rsp  */						\
-    (FS)->cfa_reg = 7;							\
-    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
-									\
-    /* The SVR4 register numbering macros aren't usable in libgcc.  */	\
-    (FS)->regs.reg[0].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[0].loc.offset = (long)&sc_->rax - new_cfa_;		\
-    (FS)->regs.reg[1].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[1].loc.offset = (long)&sc_->rdx - new_cfa_;		\
-    (FS)->regs.reg[2].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[2].loc.offset = (long)&sc_->rcx - new_cfa_;		\
-    (FS)->regs.reg[3].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[3].loc.offset = (long)&sc_->rbx - new_cfa_;		\
-    (FS)->regs.reg[4].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[4].loc.offset = (long)&sc_->rsi - new_cfa_;		\
-    (FS)->regs.reg[5].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[5].loc.offset = (long)&sc_->rdi - new_cfa_;		\
-    (FS)->regs.reg[6].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[6].loc.offset = (long)&sc_->rbp - new_cfa_;		\
-    (FS)->regs.reg[8].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[8].loc.offset = (long)&sc_->r8 - new_cfa_;		\
-    (FS)->regs.reg[9].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[9].loc.offset = (long)&sc_->r9 - new_cfa_;		\
-    (FS)->regs.reg[10].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[10].loc.offset = (long)&sc_->r10 - new_cfa_;		\
-    (FS)->regs.reg[11].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[11].loc.offset = (long)&sc_->r11 - new_cfa_;		\
-    (FS)->regs.reg[12].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[12].loc.offset = (long)&sc_->r12 - new_cfa_;		\
-    (FS)->regs.reg[13].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[13].loc.offset = (long)&sc_->r13 - new_cfa_;		\
-    (FS)->regs.reg[14].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[14].loc.offset = (long)&sc_->r14 - new_cfa_;		\
-    (FS)->regs.reg[15].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[15].loc.offset = (long)&sc_->r15 - new_cfa_;		\
-    (FS)->regs.reg[16].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[16].loc.offset = (long)&sc_->rip - new_cfa_;		\
-    (FS)->retaddr_column = 16;						\
-    goto SUCCESS;							\
-  } while (0)
-#else /* ifdef __x86_64__  */
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned char *pc_ = (CONTEXT)->ra;					\
-    struct sigcontext *sc_;						\
-    long new_cfa_;							\
-									\
-    /* popl %eax ; movl $__NR_sigreturn,%eax ; int $0x80  */		\
-    if (*(unsigned short *)(pc_+0) == 0xb858				\
-	&& *(unsigned int *)(pc_+2) == 119				\
-	&& *(unsigned short *)(pc_+6) == 0x80cd)			\
-      sc_ = (CONTEXT)->cfa + 4;						\
-    /* movl $__NR_rt_sigreturn,%eax ; int $0x80  */			\
-    else if (*(unsigned char *)(pc_+0) == 0xb8				\
-	     && *(unsigned int *)(pc_+1) == 173				\
-	     && *(unsigned short *)(pc_+5) == 0x80cd)			\
-      {									\
-	struct rt_sigframe {						\
-	  int sig;							\
-	  struct siginfo *pinfo;					\
-	  void *puc;							\
-	  struct siginfo info;						\
-	  struct ucontext uc;						\
-	} *rt_ = (CONTEXT)->cfa;					\
-	sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext;		\
-      }									\
-    else								\
-      break;								\
-									\
-    new_cfa_ = sc_->esp;						\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = 4;							\
-    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
-									\
-    /* The SVR4 register numbering macros aren't usable in libgcc.  */	\
-    (FS)->regs.reg[0].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[0].loc.offset = (long)&sc_->eax - new_cfa_;		\
-    (FS)->regs.reg[3].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[3].loc.offset = (long)&sc_->ebx - new_cfa_;		\
-    (FS)->regs.reg[1].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[1].loc.offset = (long)&sc_->ecx - new_cfa_;		\
-    (FS)->regs.reg[2].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[2].loc.offset = (long)&sc_->edx - new_cfa_;		\
-    (FS)->regs.reg[6].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[6].loc.offset = (long)&sc_->esi - new_cfa_;		\
-    (FS)->regs.reg[7].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[7].loc.offset = (long)&sc_->edi - new_cfa_;		\
-    (FS)->regs.reg[5].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[5].loc.offset = (long)&sc_->ebp - new_cfa_;		\
-    (FS)->regs.reg[8].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[8].loc.offset = (long)&sc_->eip - new_cfa_;		\
-    (FS)->retaddr_column = 8;						\
-    goto SUCCESS;							\
-  } while (0)
-#endif /* ifdef __x86_64__  */
-#endif /* ifdef inhibit_libc  */
+#define MD_UNWIND_SUPPORT "config/i386/linux-unwind.h"
Index: gcc/config/ia64/linux-unwind.h
===================================================================
RCS file: gcc/config/ia64/linux-unwind.h
diff -N gcc/config/ia64/linux-unwind.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/ia64/linux-unwind.h	6 Sep 2004 12:54:00 -0000
@@ -0,0 +1,185 @@
+/* DWARF2 EH unwinding support for IA64 Linux.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 2, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the
+   Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.  */
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.  */
+
+/* This works only for glibc-2.3 and later, because sigcontext is different
+   in glibc-2.2.4.  */
+
+#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
+#include <signal.h>
+#include <sys/ucontext.h>
+
+#define IA64_GATE_AREA_START 0xa000000000000100LL
+#define IA64_GATE_AREA_END   0xa000000000030000LL
+
+#define MD_FALLBACK_FRAME_STATE_FOR ia64_fallback_frame_state
+
+static _Unwind_Reason_Code
+ia64_fallback_frame_state (struct _Unwind_Context *context,
+			   _Unwind_FrameState *fs)
+{
+  if (context->rp >= IA64_GATE_AREA_START
+      && context->rp < IA64_GATE_AREA_END)
+    {
+      struct sigframe {
+	char scratch[16];
+	unsigned long sig_number;
+	struct siginfo *info;
+	struct sigcontext *sc;
+      } *frame_ = (struct sigframe *)context->psp;
+      struct sigcontext *sc = frame_->sc;
+
+      /* Restore scratch registers in case the unwinder needs to
+	 refer to a value stored in one of them.  */
+      {
+	int i;
+
+	for (i = 2; i < 4; i++)
+	  context->ireg[i - 2].loc = &sc->sc_gr[i];
+	for (i = 8; i < 12; i++)
+	  context->ireg[i - 2].loc = &sc->sc_gr[i];
+	for (i = 14; i < 32; i++)
+	  context->ireg[i - 2].loc = &sc->sc_gr[i];
+      }
+
+      context->fpsr_loc = &(sc->sc_ar_fpsr);
+      context->pfs_loc = &(sc->sc_ar_pfs);
+      context->lc_loc = &(sc->sc_ar_lc);
+      context->unat_loc = &(sc->sc_ar_unat);
+      context->br_loc[0] = &(sc->sc_br[0]);
+      context->br_loc[6] = &(sc->sc_br[6]);
+      context->br_loc[7] = &(sc->sc_br[7]);
+      context->pr = sc->sc_pr;
+      context->psp = sc->sc_gr[12];
+      context->gp = sc->sc_gr[1];
+      /* Signal frame doesn't have an associated reg. stack frame
+         other than what we adjust for below.	  */
+      fs -> no_reg_stack_frame = 1;
+
+      if (sc->sc_rbs_base)
+	{
+	  /* Need to switch from alternate register backing store.  */
+	  long ndirty, loadrs = sc->sc_loadrs >> 16;
+	  unsigned long alt_bspstore = context->bsp - loadrs;
+	  unsigned long bspstore;
+	  unsigned long *ar_bsp = (unsigned long *)(sc->sc_ar_bsp);
+
+	  ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore,
+				      (unsigned long *) context->bsp);
+	  bspstore = (unsigned long)
+	    ia64_rse_skip_regs (ar_bsp, -ndirty);
+	  ia64_copy_rbs (context, bspstore, alt_bspstore, loadrs,
+			 sc->sc_ar_rnat);
+	}
+
+      /* Don't touch the branch registers o.t. b0, b6 and b7.
+	 The kernel doesn't pass the preserved branch registers
+	 in the sigcontext but leaves them intact, so there's no
+	 need to do anything with them here.  */
+      {
+	unsigned long sof = sc->sc_cfm & 0x7f;
+	context->bsp = (unsigned long)
+	  ia64_rse_skip_regs ((unsigned long *)(sc->sc_ar_bsp), -sof);
+      }
+
+      fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_SPREL;
+      fs->curr.reg[UNW_REG_RP].val
+	= (unsigned long)&(sc->sc_ip) - context->psp;
+      fs->curr.reg[UNW_REG_RP].when = -1;
+
+      return _URC_NO_REASON;
+    }
+  return _URC_END_OF_STACK;
+}
+
+#define MD_HANDLE_UNWABI ia64_handle_unwabi
+
+static void
+ia64_handle_unwabi (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  if (fs->unwabi == ((3 << 8) | 's')
+      || fs->unwabi == ((0 << 8) | 's'))
+    {
+      struct sigframe {
+	char scratch[16];
+	unsigned long sig_number;
+	struct siginfo *info;
+	struct sigcontext *sc;
+      } *frame = (struct sigframe *)context->psp;
+      struct sigcontext *sc = frame->sc;
+
+      /* Restore scratch registers in case the unwinder needs to
+	 refer to a value stored in one of them.  */
+      {
+	int i;
+
+	for (i = 2; i < 4; i++)
+	  context->ireg[i - 2].loc = &sc->sc_gr[i];
+	for (i = 8; i < 12; i++)
+	  context->ireg[i - 2].loc = &sc->sc_gr[i];
+	for (i = 14; i < 32; i++)
+	  context->ireg[i - 2].loc = &sc->sc_gr[i];
+      }
+
+      context->pfs_loc = &(sc->sc_ar_pfs);
+      context->lc_loc = &(sc->sc_ar_lc);
+      context->unat_loc = &(sc->sc_ar_unat);
+      context->br_loc[0] = &(sc->sc_br[0]);
+      context->br_loc[6] = &(sc->sc_br[6]);
+      context->br_loc[7] = &(sc->sc_br[7]);
+      context->pr = sc->sc_pr;
+      context->gp = sc->sc_gr[1];
+      /* Signal frame doesn't have an associated reg. stack frame
+         other than what we adjust for below.	  */
+      fs -> no_reg_stack_frame = 1;
+
+      if (sc->sc_rbs_base)
+	{
+	  /* Need to switch from alternate register backing store.  */
+	  long ndirty, loadrs = sc->sc_loadrs >> 16;
+	  unsigned long alt_bspstore = context->bsp - loadrs;
+	  unsigned long bspstore;
+	  unsigned long *ar_bsp = (unsigned long *)(sc->sc_ar_bsp);
+
+	  ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore,
+				      (unsigned long *) context->bsp);
+	  bspstore = (unsigned long) ia64_rse_skip_regs (ar_bsp, -ndirty);
+	  ia64_copy_rbs (context, bspstore, alt_bspstore, loadrs,
+			 sc->sc_ar_rnat);
+	}
+
+      /* Don't touch the branch registers o.t. b0, b6 and b7.
+	 The kernel doesn't pass the preserved branch registers
+	 in the sigcontext but leaves them intact, so there's no
+	 need to do anything with them here.  */
+      {
+	unsigned long sof = sc->sc_cfm & 0x7f;
+	context->bsp = (unsigned long)
+	  ia64_rse_skip_regs ((unsigned long *)(sc->sc_ar_bsp), -sof);
+      }
+
+      /* pfs_loc already set above.  Without this pfs_loc would point
+	 incorrectly to sc_cfm instead of sc_ar_pfs.  */
+      fs->curr.reg[UNW_REG_PFS].where = UNW_WHERE_NONE;
+    }
+}
+#endif /* glibc-2.3 or better */
Index: gcc/config/ia64/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/linux.h,v
retrieving revision 1.28
diff -u -p -r1.28 linux.h
--- gcc/config/ia64/linux.h	7 Feb 2004 07:30:48 -0000	1.28
+++ gcc/config/ia64/linux.h	6 Sep 2004 12:54:00 -0000
@@ -55,161 +55,4 @@ do {						\
 #undef LINK_EH_SPEC
 #define LINK_EH_SPEC ""
 
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  */
-
-/* This works only for glibc-2.3 and later, because sigcontext is different
-   in glibc-2.2.4.  */
-
-#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 3)
-
-#ifdef IN_LIBGCC2
-#include <signal.h>
-#include <sys/ucontext.h>
-
-#define IA64_GATE_AREA_START 0xa000000000000100LL
-#define IA64_GATE_AREA_END   0xa000000000030000LL
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  if ((CONTEXT)->rp >= IA64_GATE_AREA_START				\
-      && (CONTEXT)->rp < IA64_GATE_AREA_END)				\
-    {									\
-      struct sigframe {							\
-	char scratch[16];						\
-	unsigned long sig_number;					\
-	struct siginfo *info;						\
-	struct sigcontext *sc;						\
-      } *frame_ = (struct sigframe *)(CONTEXT)->psp;			\
-      struct sigcontext *sc_ = frame_->sc;				\
-									\
-      /* Restore scratch registers in case the unwinder needs to	\
-	 refer to a value stored in one of them.  */			\
-      {									\
-	int i_;								\
-									\
-	for (i_ = 2; i_ < 4; i_++)					\
-	  (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_];		\
-	for (i_ = 8; i_ < 12; i_++)					\
-	  (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_];		\
-	for (i_ = 14; i_ < 32; i_++)					\
-	  (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_];		\
-      }									\
-	  								\
-      (CONTEXT)->fpsr_loc = &(sc_->sc_ar_fpsr);				\
-      (CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs);				\
-      (CONTEXT)->lc_loc = &(sc_->sc_ar_lc);				\
-      (CONTEXT)->unat_loc = &(sc_->sc_ar_unat);				\
-      (CONTEXT)->br_loc[0] = &(sc_->sc_br[0]);				\
-      (CONTEXT)->br_loc[6] = &(sc_->sc_br[6]);				\
-      (CONTEXT)->br_loc[7] = &(sc_->sc_br[7]);				\
-      (CONTEXT)->pr = sc_->sc_pr;					\
-      (CONTEXT)->psp = sc_->sc_gr[12];					\
-      (CONTEXT)->gp = sc_->sc_gr[1];					\
-      /* Signal frame doesn't have an associated reg. stack frame 	\
-         other than what we adjust for below.	  */			\
-      (FS) -> no_reg_stack_frame = 1;					\
-									\
-      if (sc_->sc_rbs_base)						\
-	{								\
-	  /* Need to switch from alternate register backing store.  */	\
-	  long ndirty, loadrs = sc_->sc_loadrs >> 16;			\
-	  unsigned long alt_bspstore = (CONTEXT)->bsp - loadrs;		\
-	  unsigned long bspstore;					\
-	  unsigned long *ar_bsp = (unsigned long *)(sc_->sc_ar_bsp);	\
-									\
-	  ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore,	\
-				      (unsigned long *) (CONTEXT)->bsp);\
-	  bspstore = (unsigned long)					\
-		     ia64_rse_skip_regs (ar_bsp, -ndirty);		\
-	  ia64_copy_rbs ((CONTEXT), bspstore, alt_bspstore, loadrs,	\
-			 sc_->sc_ar_rnat);				\
-	}								\
-									\
-      /* Don't touch the branch registers o.t. b0, b6 and b7.		\
-	 The kernel doesn't pass the preserved branch registers		\
-	 in the sigcontext but leaves them intact, so there's no	\
-	 need to do anything with them here.  */			\
-      {									\
-	unsigned long sof = sc_->sc_cfm & 0x7f;				\
-	(CONTEXT)->bsp = (unsigned long)				\
-	  ia64_rse_skip_regs ((unsigned long *)(sc_->sc_ar_bsp), -sof); \
-      }									\
-									\
-      (FS)->curr.reg[UNW_REG_RP].where = UNW_WHERE_SPREL;		\
-      (FS)->curr.reg[UNW_REG_RP].val 					\
-	= (unsigned long)&(sc_->sc_ip) - (CONTEXT)->psp;		\
-      (FS)->curr.reg[UNW_REG_RP].when = -1;				\
-									\
-      goto SUCCESS;							\
-    }
-
-#define MD_HANDLE_UNWABI(CONTEXT, FS)					\
-  if ((FS)->unwabi == ((3 << 8) | 's')					\
-      || (FS)->unwabi == ((0 << 8) | 's'))				\
-    {									\
-      struct sigframe {							\
-	char scratch[16];						\
-	unsigned long sig_number;					\
-	struct siginfo *info;						\
-	struct sigcontext *sc;						\
-      } *frame_ = (struct sigframe *)(CONTEXT)->psp;			\
-      struct sigcontext *sc_ = frame_->sc;				\
-									\
-      /* Restore scratch registers in case the unwinder needs to	\
-	 refer to a value stored in one of them.  */			\
-      {									\
-	int i_;								\
-									\
-	for (i_ = 2; i_ < 4; i_++)					\
-	  (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_];		\
-	for (i_ = 8; i_ < 12; i_++)					\
-	  (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_];		\
-	for (i_ = 14; i_ < 32; i_++)					\
-	  (CONTEXT)->ireg[i_ - 2].loc = &sc_->sc_gr[i_];		\
-      }									\
-	  								\
-      (CONTEXT)->pfs_loc = &(sc_->sc_ar_pfs);				\
-      (CONTEXT)->lc_loc = &(sc_->sc_ar_lc);				\
-      (CONTEXT)->unat_loc = &(sc_->sc_ar_unat);				\
-      (CONTEXT)->br_loc[0] = &(sc_->sc_br[0]);				\
-      (CONTEXT)->br_loc[6] = &(sc_->sc_br[6]);				\
-      (CONTEXT)->br_loc[7] = &(sc_->sc_br[7]);				\
-      (CONTEXT)->pr = sc_->sc_pr;					\
-      (CONTEXT)->gp = sc_->sc_gr[1];					\
-      /* Signal frame doesn't have an associated reg. stack frame 	\
-         other than what we adjust for below.	  */			\
-      (FS) -> no_reg_stack_frame = 1;					\
-									\
-      if (sc_->sc_rbs_base)						\
-	{								\
-	  /* Need to switch from alternate register backing store.  */	\
-	  long ndirty, loadrs = sc_->sc_loadrs >> 16;			\
-	  unsigned long alt_bspstore = (CONTEXT)->bsp - loadrs;		\
-	  unsigned long bspstore;					\
-	  unsigned long *ar_bsp = (unsigned long *)(sc_->sc_ar_bsp);	\
-									\
-	  ndirty = ia64_rse_num_regs ((unsigned long *) alt_bspstore,	\
-				      (unsigned long *) (CONTEXT)->bsp);\
-	  bspstore = (unsigned long)					\
-		     ia64_rse_skip_regs (ar_bsp, -ndirty);		\
-	  ia64_copy_rbs ((CONTEXT), bspstore, alt_bspstore, loadrs,	\
-			 sc_->sc_ar_rnat);				\
-	}								\
-									\
-      /* Don't touch the branch registers o.t. b0, b6 and b7.		\
-	 The kernel doesn't pass the preserved branch registers		\
-	 in the sigcontext but leaves them intact, so there's no	\
-	 need to do anything with them here.  */			\
-      {									\
-	unsigned long sof = sc_->sc_cfm & 0x7f;				\
-	(CONTEXT)->bsp = (unsigned long)				\
-	  ia64_rse_skip_regs ((unsigned long *)(sc_->sc_ar_bsp), -sof); \
-      }									\
-									\
-      /* pfs_loc already set above.  Without this pfs_loc would point	\
-	 incorrectly to sc_cfm instead of sc_ar_pfs.  */		\
-      (FS)->curr.reg[UNW_REG_PFS].where = UNW_WHERE_NONE;		\
-    }
-
-#endif /* IN_LIBGCC2 */
-#endif /* glibc-2.3 or better */
+#define MD_UNWIND_SUPPORT "config/ia64/linux-unwind.h"
Index: gcc/config/ia64/unwind-ia64.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/ia64/unwind-ia64.c,v
retrieving revision 1.26
diff -u -p -r1.26 unwind-ia64.c
--- gcc/config/ia64/unwind-ia64.c	4 Sep 2004 00:15:41 -0000	1.26
+++ gcc/config/ia64/unwind-ia64.c	6 Sep 2004 12:54:01 -0000
@@ -44,6 +44,7 @@
 #undef ENABLE_MALLOC_CHECKING
 
 #ifndef __USING_SJLJ_EXCEPTIONS__
+
 #define UNW_VER(x)		((x) >> 48)
 #define UNW_FLAG_MASK		0x0000ffff00000000
 #define UNW_FLAG_OSMASK		0x0000f00000000000
@@ -1754,6 +1755,9 @@ _Unwind_GetBSP (struct _Unwind_Context *
   return (_Unwind_Ptr) context->bsp;
 }
 
+#ifdef MD_UNWIND_SUPPORT
+#include MD_UNWIND_SUPPORT
+#endif
 
 static _Unwind_Reason_Code
 uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs)
@@ -1777,7 +1781,8 @@ uw_frame_state_for (struct _Unwind_Conte
 	 os-specific fallback mechanism.  This will necessarily
 	 not provide a personality routine or LSDA.  */
 #ifdef MD_FALLBACK_FRAME_STATE_FOR
-      MD_FALLBACK_FRAME_STATE_FOR (context, fs, success);
+      if (MD_FALLBACK_FRAME_STATE_FOR (context, fs) == _URC_NO_REASON)
+	return _URC_NO_REASON;
 
       /* [SCRA 11.4.1] A leaf function with no memory stack, no exception
 	 handlers, and which keeps the return value in B0 does not need
@@ -1792,15 +1797,10 @@ uw_frame_state_for (struct _Unwind_Conte
 	  fs->curr.reg[UNW_REG_RP].where = UNW_WHERE_BR;
 	  fs->curr.reg[UNW_REG_RP].when = -1;
 	  fs->curr.reg[UNW_REG_RP].val = 0;
-	  goto success;
+	  return _URC_NO_REASON;
 	}
-
-      return _URC_END_OF_STACK;
-    success:
-      return _URC_NO_REASON;
-#else
-      return _URC_END_OF_STACK;
 #endif
+      return _URC_END_OF_STACK;
     }
 
   context->region_start = ent->start_offset + segment_base;
Index: gcc/config/mips/linux-unwind.h
===================================================================
RCS file: gcc/config/mips/linux-unwind.h
diff -N gcc/config/mips/linux-unwind.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/mips/linux-unwind.h	6 Sep 2004 12:54:01 -0000
@@ -0,0 +1,93 @@
+/* DWARF2 EH unwinding support for MIPS Linux.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#ifndef inhibit_libc
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.  */
+
+#include <signal.h>
+
+/* The third parameter to the signal handler points to something with
+ * this structure defined in asm/ucontext.h, but the name clashes with
+ * struct ucontext from sys/ucontext.h so this private copy is used.  */
+typedef struct _sig_ucontext {
+    unsigned long         uc_flags;
+    struct _sig_ucontext  *uc_link;
+    stack_t               uc_stack;
+    struct sigcontext uc_mcontext;
+    sigset_t      uc_sigmask;
+} _sig_ucontext_t;
+
+#define MD_FALLBACK_FRAME_STATE_FOR mips_fallback_frame_state
+
+static _Unwind_Reason_Code
+mips_fallback_frame_state (struct _Unwind_Context *context,
+			   _Unwind_FrameState *fs)
+{
+  u_int32_t *pc = (u_int32_t *) context->ra;
+  struct sigcontext *sc;
+  _Unwind_Ptr new_cfa;
+  int i;
+
+  /* 24021061 li v0, 0x1061 (rt_sigreturn)*/
+  /* 0000000c syscall    */
+  /*    or */
+  /* 24021017 li v0, 0x1017 (sigreturn) */
+  /* 0000000c syscall  */
+  if (*(pc + 1) != 0x0000000c)
+    return _URC_END_OF_STACK;
+  if (*(pc + 0) == 0x24021017)
+    {
+      struct sigframe {
+	u_int32_t  trampoline[2];
+	struct sigcontext sigctx;
+      } *rt_ = context->ra;
+      sc = &rt_->sigctx;
+    }
+  else if (*(pc + 0) == 0x24021061)
+    {
+      struct rt_sigframe {
+	u_int32_t  trampoline[2];
+	struct siginfo info;
+	_sig_ucontext_t uc;
+      } *rt_ = context->ra;
+      sc = &rt_->uc.uc_mcontext;
+    }
+  else
+    return _URC_END_OF_STACK;
+
+  new_cfa = (_Unwind_Ptr)sc;
+  fs->cfa_how = CFA_REG_OFFSET;
+  fs->cfa_reg = STACK_POINTER_REGNUM;
+  fs->cfa_offset = new_cfa - (_Unwind_Ptr) context->cfa;
+
+  for (i = 0; i < 32; i++) {
+    fs->regs.reg[i].how = REG_SAVED_OFFSET;
+    fs->regs.reg[i].loc.offset
+      = (_Unwind_Ptr)&(sc->sc_regs[i]) - new_cfa;
+  }
+  fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].how = REG_SAVED_OFFSET;
+  fs->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].loc.offset
+    = (_Unwind_Ptr)&(sc->sc_pc) - new_cfa;
+  fs->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN;
+
+  return _URC_NO_REASON;
+}
+#endif
Index: gcc/config/mips/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/mips/linux.h,v
retrieving revision 1.79
diff -u -p -r1.79 linux.h
--- gcc/config/mips/linux.h	23 Aug 2004 06:53:46 -0000	1.79
+++ gcc/config/mips/linux.h	6 Sep 2004 12:54:01 -0000
@@ -183,74 +183,4 @@ Boston, MA 02111-1307, USA.  */
 %{!shared: %{pthread:-lpthread} \
   %{profile:-lc_p} %{!profile: -lc}}"
 
-#ifndef inhibit_libc
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  */
-#ifdef IN_LIBGCC2
-#include <signal.h>
-
-/* The third parameter to the signal handler points to something with
- * this structure defined in asm/ucontext.h, but the name clashes with
- * struct ucontext from sys/ucontext.h so this private copy is used.  */
-typedef struct _sig_ucontext {
-    unsigned long         uc_flags;
-    struct _sig_ucontext  *uc_link;
-    stack_t               uc_stack;
-    struct sigcontext uc_mcontext;
-    sigset_t      uc_sigmask;
-} _sig_ucontext_t;
-
-#endif /* IN_LIBGCC2  */
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)            \
-  do {                                                               \
-    u_int32_t *pc_ = (u_int32_t *) (CONTEXT)->ra;                \
-    struct sigcontext *sc_;                                          \
-    _Unwind_Ptr new_cfa_;                                            \
-    int i_;                                                          \
-                                                                     \
-    /* 24021061 li v0, 0x1061 (rt_sigreturn)*/                       \
-    /* 0000000c syscall    */                                        \
-    /*    or */                                                      \
-    /* 24021017 li v0, 0x1017 (sigreturn) */                         \
-    /* 0000000c syscall  */                                          \
-    if (*(pc_ + 1) != 0x0000000c)                                    \
-      break;                                                         \
-    if (*(pc_ + 0) == 0x24021017)                                    \
-      {                                                              \
-        struct sigframe {                                            \
-          u_int32_t  trampoline[2];                                \
-          struct sigcontext sigctx;                                  \
-        } *rt_ = (CONTEXT)->ra;                                      \
-        sc_ = &rt_->sigctx;                                          \
-      }                                                              \
-    else if (*(pc_ + 0) == 0x24021061)                               \
-      {                                                              \
-        struct rt_sigframe {                                         \
-          u_int32_t  trampoline[2];                                \
-          struct siginfo info;                                       \
-          _sig_ucontext_t uc;                                        \
-        } *rt_ = (CONTEXT)->ra;                                      \
-        sc_ = &rt_->uc.uc_mcontext;                                  \
-      }                                                              \
-    else                                                             \
-      break;                                                         \
-                                                                     \
-    new_cfa_ = (_Unwind_Ptr)sc_;                                     \
-    (FS)->cfa_how = CFA_REG_OFFSET;                                  \
-    (FS)->cfa_reg = STACK_POINTER_REGNUM;                            \
-    (FS)->cfa_offset = new_cfa_ - (_Unwind_Ptr) (CONTEXT)->cfa;      \
-                                                                     \
-    for (i_ = 0; i_ < 32; i_++) {                                    \
-      (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;                     \
-      (FS)->regs.reg[i_].loc.offset                                  \
-        = (_Unwind_Ptr)&(sc_->sc_regs[i_]) - new_cfa_;               \
-    }                                                                \
-    (FS)->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].how = REG_SAVED_OFFSET; \
-    (FS)->regs.reg[SIGNAL_UNWIND_RETURN_COLUMN].loc.offset           \
-        = (_Unwind_Ptr)&(sc_->sc_pc) - new_cfa_;                     \
-    (FS)->retaddr_column = SIGNAL_UNWIND_RETURN_COLUMN;              \
-                                                                     \
-    goto SUCCESS;                                                    \
-  } while (0)
-#endif
+#define MD_UNWIND_SUPPORT "config/mips/linux-unwind.h"
Index: gcc/config/pa/linux-unwind.h
===================================================================
RCS file: gcc/config/pa/linux-unwind.h
diff -N gcc/config/pa/linux-unwind.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/pa/linux-unwind.h	6 Sep 2004 12:54:01 -0000
@@ -0,0 +1,115 @@
+/* DWARF2 EH unwinding support for PA Linux.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.  */
+
+#include <signal.h>
+#include <sys/ucontext.h>
+
+/* Unfortunately, because of various bugs and changes to the kernel,
+   we have several cases to deal with.
+
+   In 2.4, the signal trampoline is 4 words, and (CONTEXT)->ra should
+   point directly at the beginning of the trampoline and struct rt_sigframe.
+
+   In <= 2.6.5-rc2-pa3, the signal trampoline is 9 words, and 
+   (CONTEXT)->ra points at the 4th word in the trampoline structure.  This 
+   is wrong, it should point at the 5th word.  This is fixed in 2.6.5-rc2-pa4.
+
+   To detect these cases, we first take (CONTEXT)->ra, align it to 64-bytes
+   to get the beginning of the signal frame, and then check offsets 0, 4
+   and 5 to see if we found the beginning of the trampoline.  This will
+   tell us how to locate the sigcontext structure.
+
+   Note that with a 2.4 64-bit kernel, the signal context is not properly
+   passed back to userspace so the unwind will not work correctly.  */
+
+#define MD_FALLBACK_FRAME_STATE_FOR pa32_fallback_frame_state
+
+static _Unwind_Reason_Code
+pa32_fallback_frame_state (struct _Unwind_Context *context,
+			   _Unwind_FrameState *fs)
+{
+  unsigned long sp = (unsigned long)context->ra & ~63;
+  unsigned int *pc = (unsigned int *)sp;
+  unsigned long off;
+  _Unwind_Ptr new_cfa;
+  int i;
+  struct sigcontext *sc;
+  struct rt_sigframe {
+    struct siginfo info;
+    struct ucontext uc;
+  } *frame;
+
+  /* rt_sigreturn trampoline:
+     3419000x ldi 0, %r25 or ldi 1, %r25   (x = 0 or 2)
+     3414015a ldi __NR_rt_sigreturn, %r20
+     e4008200 be,l 0x100(%sr2, %r0), %sr0, %r31
+     08000240 nop  */
+
+  if (pc[0] == 0x34190000 || pc[0] == 0x34190002)
+    off = 4*4;
+  else if (pc[4] == 0x34190000 || pc[4] == 0x34190002)
+    {
+      pc += 4;
+      off = 10 * 4;
+    }
+  else if (pc[5] == 0x34190000 || pc[5] == 0x34190002)
+    {
+      pc += 5;
+      off = 10 * 4;
+    }
+  else
+    return _URC_END_OF_STACK;
+  if (pc[1] != 0x3414015a
+      || pc[2] != 0xe4008200
+      || pc[3] != 0x08000240)
+    return _URC_END_OF_STACK;
+
+  frame = (struct rt_sigframe *)(sp + off);
+  sc = &frame->uc.uc_mcontext;
+
+  new_cfa = sc->sc_gr[30];
+  fs->cfa_how = CFA_REG_OFFSET;
+  fs->cfa_reg = 30;
+  fs->cfa_offset = new_cfa - (long) context->cfa;
+  for (i = 1; i <= 31; i++)
+    {
+      fs->regs.reg[i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i].loc.offset = (long)&sc->sc_gr[i] - new_cfa;
+    }
+  for (i = 4; i <= 31; i++)
+    {
+      /* FP regs have left and right halves */
+      fs->regs.reg[2*i+24].how = REG_SAVED_OFFSET;
+      fs->regs.reg[2*i+24].loc.offset
+	= (long)&sc->sc_fr[i] - new_cfa;
+      fs->regs.reg[2*i+24+1].how = REG_SAVED_OFFSET;
+      fs->regs.reg[2*i+24+1].loc.offset
+	= (long)&sc->sc_fr[i] + 4 - new_cfa;
+    }
+  fs->regs.reg[88].how = REG_SAVED_OFFSET;
+  fs->regs.reg[88].loc.offset = (long) &sc->sc_sar - new_cfa;
+  fs->regs.reg[2].how = REG_SAVED_OFFSET;
+  fs->regs.reg[2].loc.offset = (long) &sc->sc_iaoq[0] - new_cfa;
+  fs->retaddr_column = 2;
+  return _URC_NO_REASON;
+}
Index: gcc/config/pa/pa32-linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/pa/pa32-linux.h,v
retrieving revision 1.13
diff -u -p -r1.13 pa32-linux.h
--- gcc/config/pa/pa32-linux.h	9 Jul 2004 03:39:32 -0000	1.13
+++ gcc/config/pa/pa32-linux.h	6 Sep 2004 12:54:01 -0000
@@ -36,96 +36,4 @@ Boston, MA 02111-1307, USA.  */
 		    aligned(sizeof(func_ptr))))				\
     = { (func_ptr) (-1) }
 
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  */
-
-#ifdef IN_LIBGCC2
-#include <signal.h>
-#include <sys/ucontext.h>
-
-/* Unfortunately, because of various bugs and changes to the kernel,
-   we have several cases to deal with.
-
-   In 2.4, the signal trampoline is 4 words, and (CONTEXT)->ra should
-   point directly at the beginning of the trampoline and struct rt_sigframe.
-
-   In <= 2.6.5-rc2-pa3, the signal trampoline is 9 words, and 
-   (CONTEXT)->ra points at the 4th word in the trampoline structure.  This 
-   is wrong, it should point at the 5th word.  This is fixed in 2.6.5-rc2-pa4.
-
-   To detect these cases, we first take (CONTEXT)->ra, align it to 64-bytes
-   to get the beginning of the signal frame, and then check offsets 0, 4
-   and 5 to see if we found the beginning of the trampoline.  This will
-   tell us how to locate the sigcontext structure.
-
-   Note that with a 2.4 64-bit kernel, the signal context is not properly
-   passed back to userspace so the unwind will not work correctly.  */
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned long sp = (unsigned long)(CONTEXT)->ra & ~63;		\
-    unsigned int *pc = (unsigned int *)sp;				\
-    unsigned long off;							\
-    _Unwind_Ptr new_cfa;						\
-    int i;								\
-    struct sigcontext *sc;						\
-    struct rt_sigframe {						\
-      struct siginfo info;						\
-      struct ucontext uc;						\
-    } *frame;								\
-									\
-    /* rt_sigreturn trampoline: 					\
-       3419000x ldi 0, %r25 or ldi 1, %r25   (x = 0 or 2)  		\
-       3414015a ldi __NR_rt_sigreturn, %r20 				\
-       e4008200 be,l 0x100(%sr2, %r0), %sr0, %r31 			\
-       08000240 nop  */							\
-    									\
-    if (pc[0] == 0x34190000 || pc[0] == 0x34190002)			\
-      off = 4*4;							\
-    else if (pc[4] == 0x34190000 || pc[4] == 0x34190002)		\
-      {									\
-	pc += 4;							\
-	off = 10 * 4;							\
-      }									\
-    else if (pc[5] == 0x34190000 || pc[5] == 0x34190002)		\
-      {									\
-	pc += 5;							\
-	off = 10 * 4;							\
-      }									\
-    else								\
-      break;								\
-    if (pc[1] != 0x3414015a 						\
-	|| pc[2] != 0xe4008200 						\
-	|| pc[3] != 0x08000240)						\
-      break;								\
-									\
-    frame = (struct rt_sigframe *)(sp + off);				\
-    sc = &frame->uc.uc_mcontext;					\
-									\
-    new_cfa = sc->sc_gr[30];						\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = 30;							\
-    (FS)->cfa_offset = new_cfa - (long) (CONTEXT)->cfa;			\
-    for (i = 1; i <= 31; i++)						\
-      {									\
-	(FS)->regs.reg[i].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i].loc.offset = (long)&sc->sc_gr[i] - new_cfa;	\
-      }									\
-    for (i = 4; i <= 31; i++)						\
-      {									\
-	/* FP regs have left and right halves */			\
-	(FS)->regs.reg[2*i+24].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[2*i+24].loc.offset				\
-	  = (long)&sc->sc_fr[i] - new_cfa;				\
-	(FS)->regs.reg[2*i+24+1].how = REG_SAVED_OFFSET;		\
-	(FS)->regs.reg[2*i+24+1].loc.offset				\
-	  = (long)&sc->sc_fr[i] + 4 - new_cfa;				\
-      }									\
-    (FS)->regs.reg[88].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[88].loc.offset = (long) &sc->sc_sar - new_cfa;	\
-    (FS)->regs.reg[2].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[2].loc.offset = (long) &sc->sc_iaoq[0] - new_cfa;	\
-    (FS)->retaddr_column = 2;						\
-    goto SUCCESS;							\
-  } while (0)
-
-#endif /* IN_LIBGCC2 */
+#define MD_UNWIND_SUPPORT "config/pa/linux-unwind.h"
Index: gcc/config/rs6000/darwin-unwind.h
===================================================================
RCS file: gcc/config/rs6000/darwin-unwind.h
diff -N gcc/config/rs6000/darwin-unwind.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/rs6000/darwin-unwind.h	6 Sep 2004 12:54:02 -0000
@@ -0,0 +1,35 @@
+/* DWARF2 EH unwinding support for Darwin.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   In addition to the permissions in the GNU General Public License, the
+   Free Software Foundation gives you unlimited permission to link the
+   compiled version of this file into combinations with other programs,
+   and to distribute those combinations without any restriction coming
+   from the use of this file.  (The General Public License restrictions
+   do apply in other respects; for example, they cover modification of
+   the file, and distribution when not linked into a combined
+   executable.)
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the Free
+   Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+   02111-1307, USA.  */
+
+extern bool _Unwind_fallback_frame_state_for
+  (struct _Unwind_Context *context, _Unwind_FrameState *fs);
+
+#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS)	\
+  (_Unwind_fallback_frame_state_for (CONTEXT, FS)	\
+   ? _URC_NO_REASON : _URC_END_OF_STACK)
Index: gcc/config/rs6000/darwin.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/darwin.h,v
retrieving revision 1.61
diff -u -p -r1.61 darwin.h
--- gcc/config/rs6000/darwin.h	2 Sep 2004 00:01:37 -0000	1.61
+++ gcc/config/rs6000/darwin.h	6 Sep 2004 12:54:02 -0000
@@ -371,14 +371,7 @@ extern const char *darwin_one_byte_bool;
 #include <stdbool.h>
 #endif
 
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  {									\
-    extern bool _Unwind_fallback_frame_state_for			\
-      (struct _Unwind_Context *context, _Unwind_FrameState *fs);	\
-									\
-    if (_Unwind_fallback_frame_state_for (CONTEXT, FS))			\
-      goto SUCCESS;							\
-  }
+#define MD_UNWIND_SUPPORT "config/rs6000/darwin-unwind.h"
 
 #define HAS_MD_FALLBACK_FRAME_STATE_FOR 1
 
Index: gcc/config/rs6000/linux-unwind.h
===================================================================
RCS file: gcc/config/rs6000/linux-unwind.h
diff -N gcc/config/rs6000/linux-unwind.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/rs6000/linux-unwind.h	6 Sep 2004 12:54:02 -0000
@@ -0,0 +1,186 @@
+/* DWARF2 EH unwinding support for PowerPC and PowerPC64 Linux.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+   This file is part of GCC.
+
+   GCC is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 2, or (at your
+   option) any later version.
+
+   GCC is distributed in the hope that it will be useful, but WITHOUT
+   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
+   License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GCC; see the file COPYING.  If not, write to the
+   Free Software Foundation, 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.  */
+
+/* This file defines our own versions of various kernel and user
+   structs, so that system headers are not needed, which otherwise
+   can make bootstrapping a new toolchain difficult.  Do not use
+   these structs elsewhere;  Many fields are missing, particularly
+   from the end of the structures.  */
+
+struct gcc_pt_regs
+{
+  unsigned long gpr[32];
+  unsigned long nip;
+  unsigned long msr;
+  unsigned long orig_gpr3;
+  unsigned long ctr;
+  unsigned long link;
+};
+
+struct gcc_sigcontext
+{
+  unsigned long	pad[7];
+  struct gcc_pt_regs *regs;
+};
+
+struct gcc_ucontext
+{
+#ifdef __powerpc64__
+  unsigned long pad[21];
+#else
+  unsigned long pad[5];
+#endif
+  struct gcc_sigcontext uc_mcontext;
+};
+
+#ifdef __powerpc64__
+
+enum { SIGNAL_FRAMESIZE = 128 };
+
+/* If the current unwind info (FS) does not contain explicit info
+   saving R2, then we have to do a minor amount of code reading to
+   figure out if it was saved.  The big problem here is that the
+   code that does the save/restore is generated by the linker, so
+   we have no good way to determine at compile time what to do.  */
+
+#define MD_FROB_UPDATE_CONTEXT frob_update_context
+
+static void
+frob_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs)
+{
+  if (fs->regs.reg[2].how == REG_UNSAVED)
+    {
+      unsigned int *insn
+	= (unsigned int *) _Unwind_GetGR (context, LINK_REGISTER_REGNUM);
+      if (*insn == 0xE8410028)
+	_Unwind_SetGRPtr (context, 2, context->cfa + 40);
+    }
+}
+
+/* If PC is at a sigreturn trampoline, return a pointer to the
+   sigcontext.  Otherwise return NULL.  */
+
+static struct gcc_sigcontext *
+get_sigcontext (struct _Unwind_Context *context)
+{
+  const unsigned char *pc = context->ra;
+
+  /* addi r1, r1, 128; li r0, 0x0077; sc  (sigreturn) */
+  /* addi r1, r1, 128; li r0, 0x00AC; sc  (rt_sigreturn) */
+  if (*(unsigned int *) (pc+0) != 0x38210000 + SIGNAL_FRAMESIZE
+      || *(unsigned int *) (pc+8) != 0x44000002)
+    return NULL;
+  if (*(unsigned int *) (pc+4) == 0x38000077)
+    {
+      struct sigframe {
+	char gap[SIGNAL_FRAMESIZE];
+	struct gcc_sigcontext sigctx;
+      } *rt_ = context->cfa;
+      return &rt_->sigctx;
+    }
+  else if (*(unsigned int *) (pc+4) == 0x380000AC)
+    {
+      struct rt_sigframe {
+	int tramp[6];
+	void *pinfo;
+	struct gcc_ucontext *puc;
+      } *rt_ = (struct rt_sigframe *) pc;
+      return &rt_->puc->uc_mcontext;
+    }
+  return NULL;
+}
+
+#else  /* !__powerpc64__ */
+
+enum { SIGNAL_FRAMESIZE = 64 };
+
+static struct gcc_sigcontext *
+get_sigcontext (struct _Unwind_Context *context)
+{
+  const unsigned char *pc = context->ra;
+
+  /* li r0, 0x7777; sc  (sigreturn old)  */
+  /* li r0, 0x0077; sc  (sigreturn new)  */
+  /* li r0, 0x6666; sc  (rt_sigreturn old)  */
+  /* li r0, 0x00AC; sc  (rt_sigreturn new)  */
+  if (*(unsigned int *) (pc+4) != 0x44000002)
+    return NULL;
+  if (*(unsigned int *) (pc+0) == 0x38007777
+      || *(unsigned int *) (pc+0) == 0x38000077)
+    {
+      struct sigframe {
+	char gap[SIGNAL_FRAMESIZE];
+	struct gcc_sigcontext sigctx;
+      } *rt_ = context->cfa;
+      return &rt_->sigctx;
+    }
+  else if (*(unsigned int *) (pc+0) == 0x38006666
+	   || *(unsigned int *) (pc+0) == 0x380000AC)
+    {
+      struct rt_sigframe {
+	char gap[SIGNAL_FRAMESIZE + 16];
+	char siginfo[128];
+	struct gcc_ucontext uc;
+      } *rt_ = context->cfa;
+      return &rt_->uc.uc_mcontext;
+    }
+  return NULL;
+}
+#endif
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.  */
+
+#define MD_FALLBACK_FRAME_STATE_FOR ppc_fallback_frame_state
+
+static _Unwind_Reason_Code
+ppc_fallback_frame_state (struct _Unwind_Context *context,
+			  _Unwind_FrameState *fs)
+{
+  struct gcc_sigcontext *sc = get_sigcontext (context);
+  long new_cfa;
+  int i;
+
+  if (sc == NULL)
+    return _URC_END_OF_STACK;
+
+  new_cfa = sc->regs->gpr[STACK_POINTER_REGNUM];
+  fs->cfa_how = CFA_REG_OFFSET;
+  fs->cfa_reg = STACK_POINTER_REGNUM;
+  fs->cfa_offset = new_cfa - (long) context->cfa;
+
+  for (i = 0; i < 32; i++)
+    if (i != STACK_POINTER_REGNUM)
+      {
+	fs->regs.reg[i].how = REG_SAVED_OFFSET;
+	fs->regs.reg[i].loc.offset
+	  = (long)&(sc->regs->gpr[i]) - new_cfa;
+      }
+
+  fs->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;
+  fs->regs.reg[LINK_REGISTER_REGNUM].loc.offset
+    = (long)&(sc->regs->link) - new_cfa;
+
+  fs->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET;
+  fs->regs.reg[ARG_POINTER_REGNUM].loc.offset
+    = (long)&(sc->regs->nip) - new_cfa;
+  fs->retaddr_column = ARG_POINTER_REGNUM;
+  return _URC_NO_REASON;
+}
Index: gcc/config/rs6000/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux.h,v
retrieving revision 1.46
diff -u -p -r1.46 linux.h
--- gcc/config/rs6000/linux.h	23 Apr 2004 02:16:24 -0000	1.46
+++ gcc/config/rs6000/linux.h	6 Sep 2004 12:54:02 -0000
@@ -98,88 +98,6 @@
 
 #define TARGET_HAS_F_SETLKW
 
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  */
-
-#ifdef IN_LIBGCC2
-#include <signal.h>
-
-/* During the 2.5 kernel series the kernel ucontext was changed, but
-   the new layout is compatible with the old one, so we just define
-   and use the old one here for simplicity and compatibility.  */
-
-struct kernel_old_ucontext {
-  unsigned long     uc_flags;
-  struct ucontext  *uc_link;
-  stack_t           uc_stack;
-  struct sigcontext_struct uc_mcontext;
-  sigset_t          uc_sigmask;
-};
-
-enum { SIGNAL_FRAMESIZE = 64 };
-#endif
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned char *pc_ = (CONTEXT)->ra;					\
-    struct sigcontext *sc_;						\
-    long new_cfa_;							\
-    int i_;								\
-									\
-    /* li r0, 0x7777; sc  (sigreturn old)  */				\
-    /* li r0, 0x0077; sc  (sigreturn new)  */				\
-    /* li r0, 0x6666; sc  (rt_sigreturn old)  */			\
-    /* li r0, 0x00AC; sc  (rt_sigreturn new)  */			\
-    if (*(unsigned int *) (pc_+4) != 0x44000002)			\
-      break;								\
-    if (*(unsigned int *) (pc_+0) == 0x38007777				\
-	|| *(unsigned int *) (pc_+0) == 0x38000077)			\
-      {									\
-	struct sigframe {						\
-	  char gap[SIGNAL_FRAMESIZE];					\
-	  struct sigcontext sigctx;					\
-	} *rt_ = (CONTEXT)->cfa;					\
-	sc_ = &rt_->sigctx;						\
-      }									\
-    else if (*(unsigned int *) (pc_+0) == 0x38006666			\
-	     || *(unsigned int *) (pc_+0) == 0x380000AC)		\
-      {									\
-	struct rt_sigframe {						\
-	  char gap[SIGNAL_FRAMESIZE];					\
-	  unsigned long _unused[2];					\
-	  struct siginfo *pinfo;					\
-	  void *puc;							\
-	  struct siginfo info;						\
-	  struct kernel_old_ucontext uc;				\
-	} *rt_ = (CONTEXT)->cfa;					\
-	sc_ = &rt_->uc.uc_mcontext;					\
-      }									\
-    else								\
-      break;								\
-    									\
-    new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM];			\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = STACK_POINTER_REGNUM;				\
-    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
-    									\
-    for (i_ = 0; i_ < 32; i_++)						\
-      if (i_ != STACK_POINTER_REGNUM)					\
-	{	    							\
-	  (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
-	  (FS)->regs.reg[i_].loc.offset 				\
-	    = (long)&(sc_->regs->gpr[i_]) - new_cfa_;			\
-	}								\
-									\
-    (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;	\
-    (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset 			\
-      = (long)&(sc_->regs->link) - new_cfa_;				\
-									\
-    (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET;			\
-    (FS)->regs.reg[CR0_REGNO].loc.offset 				\
-      = (long)&(sc_->regs->nip) - new_cfa_;				\
-    (FS)->retaddr_column = CR0_REGNO;					\
-    goto SUCCESS;							\
-  } while (0)
-
+#define MD_UNWIND_SUPPORT "config/rs6000/linux-unwind.h"
 
 #define OS_MISSING_POWERPC64 1
Index: gcc/config/rs6000/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/linux64.h,v
retrieving revision 1.64
diff -u -p -r1.64 linux64.h
--- gcc/config/rs6000/linux64.h	2 Sep 2004 12:46:27 -0000	1.64
+++ gcc/config/rs6000/linux64.h	6 Sep 2004 12:54:02 -0000
@@ -557,185 +557,6 @@ while (0)
 #define USE_LD_AS_NEEDED 1
 #endif
 
-#ifdef IN_LIBGCC2
-
-/* This file defines our own versions of various kernel and user
-   structs, so that system headers are not needed, which otherwise
-   can make bootstrapping a new toolchain difficult.  Do not use
-   these structs elsewhere;  Many fields are missing, particularly
-   from the end of the structures.  */
-
-struct gcc_pt_regs
-{
-  unsigned long gpr[32];
-  unsigned long nip;
-  unsigned long msr;
-  unsigned long orig_gpr3;
-  unsigned long ctr;
-  unsigned long link;
-};
-
-struct gcc_sigcontext
-{
-  unsigned long	pad[7];
-  struct gcc_pt_regs *regs;
-};
-
-struct gcc_ucontext
-{
-#ifdef __powerpc64__
-  unsigned long pad[21];
-#else
-  unsigned long pad[5];
-#endif
-  struct gcc_sigcontext uc_mcontext;
-};
-
-#ifdef __powerpc64__
-
-enum { SIGNAL_FRAMESIZE = 128 };
-
-/* If the current unwind info (FS) does not contain explicit info
-   saving R2, then we have to do a minor amount of code reading to
-   figure out if it was saved.  The big problem here is that the
-   code that does the save/restore is generated by the linker, so
-   we have no good way to determine at compile time what to do.  */
-
-#define MD_FROB_UPDATE_CONTEXT(CTX, FS)					\
-  do {									\
-    if ((FS)->regs.reg[2].how == REG_UNSAVED)				\
-      {									\
-	unsigned int *insn						\
-	  = (unsigned int *)						\
-	    _Unwind_GetGR ((CTX), LINK_REGISTER_REGNUM);		\
-	if (*insn == 0xE8410028)					\
-	  _Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 40);			\
-      }									\
-  } while (0)
-
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  */
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned char *pc_ = (CONTEXT)->ra;					\
-    struct gcc_sigcontext *sc_;						\
-    long new_cfa_;							\
-    int i_;								\
-									\
-    /* addi r1, r1, 128; li r0, 0x0077; sc  (sigreturn) */		\
-    /* addi r1, r1, 128; li r0, 0x00AC; sc  (rt_sigreturn) */		\
-    if (*(unsigned int *) (pc_+0) != 0x38210000 + SIGNAL_FRAMESIZE	\
-	|| *(unsigned int *) (pc_+8) != 0x44000002)			\
-      break;								\
-    if (*(unsigned int *) (pc_+4) == 0x38000077)			\
-      {									\
-	struct sigframe {						\
-	  char gap[SIGNAL_FRAMESIZE];					\
-	  struct gcc_sigcontext sigctx;					\
-	} *rt_ = (CONTEXT)->cfa;					\
-	sc_ = &rt_->sigctx;						\
-      }									\
-    else if (*(unsigned int *) (pc_+4) == 0x380000AC)			\
-      {									\
-	struct rt_sigframe {						\
-	  int tramp[6];							\
-	  void *pinfo;							\
-	  struct gcc_ucontext *puc;					\
-	} *rt_ = (struct rt_sigframe *) pc_;				\
-	sc_ = &rt_->puc->uc_mcontext;					\
-      }									\
-    else								\
-      break;								\
-    									\
-    new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM];			\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = STACK_POINTER_REGNUM;				\
-    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
-    									\
-    for (i_ = 0; i_ < 32; i_++)						\
-      if (i_ != STACK_POINTER_REGNUM)					\
-	{	    							\
-	  (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
-	  (FS)->regs.reg[i_].loc.offset 				\
-	    = (long)&(sc_->regs->gpr[i_]) - new_cfa_;			\
-	}								\
-									\
-    (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;	\
-    (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset 			\
-      = (long)&(sc_->regs->link) - new_cfa_;				\
-									\
-    (FS)->regs.reg[ARG_POINTER_REGNUM].how = REG_SAVED_OFFSET;		\
-    (FS)->regs.reg[ARG_POINTER_REGNUM].loc.offset 			\
-      = (long)&(sc_->regs->nip) - new_cfa_;				\
-    (FS)->retaddr_column = ARG_POINTER_REGNUM;				\
-    goto SUCCESS;							\
-  } while (0)
-
-#else  /* !__powerpc64__ */
-
-enum { SIGNAL_FRAMESIZE = 64 };
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned char *pc_ = (CONTEXT)->ra;					\
-    struct gcc_sigcontext *sc_;						\
-    long new_cfa_;							\
-    int i_;								\
-									\
-    /* li r0, 0x7777; sc  (sigreturn old)  */				\
-    /* li r0, 0x0077; sc  (sigreturn new)  */				\
-    /* li r0, 0x6666; sc  (rt_sigreturn old)  */			\
-    /* li r0, 0x00AC; sc  (rt_sigreturn new)  */			\
-    if (*(unsigned int *) (pc_+4) != 0x44000002)			\
-      break;								\
-    if (*(unsigned int *) (pc_+0) == 0x38007777				\
-	|| *(unsigned int *) (pc_+0) == 0x38000077)			\
-      {									\
-	struct sigframe {						\
-	  char gap[SIGNAL_FRAMESIZE];					\
-	  struct gcc_sigcontext sigctx;					\
-	} *rt_ = (CONTEXT)->cfa;					\
-	sc_ = &rt_->sigctx;						\
-      }									\
-    else if (*(unsigned int *) (pc_+0) == 0x38006666			\
-	     || *(unsigned int *) (pc_+0) == 0x380000AC)		\
-      {									\
-	struct rt_sigframe {						\
-	  char gap[SIGNAL_FRAMESIZE + 16];				\
-	  char siginfo[128];						\
-	  struct gcc_ucontext uc;					\
-	} *rt_ = (CONTEXT)->cfa;					\
-	sc_ = &rt_->uc.uc_mcontext;					\
-      }									\
-    else								\
-      break;								\
-    									\
-    new_cfa_ = sc_->regs->gpr[STACK_POINTER_REGNUM];			\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = STACK_POINTER_REGNUM;				\
-    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
-    									\
-    for (i_ = 0; i_ < 32; i_++)						\
-      if (i_ != STACK_POINTER_REGNUM)					\
-	{	    							\
-	  (FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
-	  (FS)->regs.reg[i_].loc.offset 				\
-	    = (long)&(sc_->regs->gpr[i_]) - new_cfa_;			\
-	}								\
-									\
-    (FS)->regs.reg[LINK_REGISTER_REGNUM].how = REG_SAVED_OFFSET;	\
-    (FS)->regs.reg[LINK_REGISTER_REGNUM].loc.offset 			\
-      = (long)&(sc_->regs->link) - new_cfa_;				\
-									\
-    (FS)->regs.reg[CR0_REGNO].how = REG_SAVED_OFFSET;			\
-    (FS)->regs.reg[CR0_REGNO].loc.offset 				\
-      = (long)&(sc_->regs->nip) - new_cfa_;				\
-    (FS)->retaddr_column = CR0_REGNO;					\
-    goto SUCCESS;							\
-  } while (0)
-
-#endif
-#endif /* LIBGCC2 */
+#define MD_UNWIND_SUPPORT "config/rs6000/linux-unwind.h"
 
 #define OS_MISSING_POWERPC64 !TARGET_64BIT
Index: gcc/config/s390/linux-unwind.h
===================================================================
RCS file: gcc/config/s390/linux-unwind.h
diff -N gcc/config/s390/linux-unwind.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/s390/linux-unwind.h	6 Sep 2004 12:54:02 -0000
@@ -0,0 +1,131 @@
+/* DWARF2 EH unwinding support for S/390 Linux.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.  */
+
+#define MD_FALLBACK_FRAME_STATE_FOR s390_fallback_frame_state
+
+static _Unwind_Reason_Code
+s390_fallback_frame_state (struct _Unwind_Context *context,
+			   _Unwind_FrameState *fs)
+{
+  unsigned char *pc = context->ra;
+  long new_cfa;
+  int i;
+
+  typedef struct
+  {
+    unsigned long psw_mask;
+    unsigned long psw_addr;
+    unsigned long gprs[16];
+    unsigned int  acrs[16];
+    unsigned int  fpc;
+    unsigned int  __pad;
+    double        fprs[16];
+  } __attribute__ ((__aligned__ (8))) sigregs_;
+
+  sigregs_ *regs;
+  int *signo = NULL;
+
+  /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn  */
+  if (pc[0] != 0x0a || (pc[1] != 119 && pc[1] != 173))
+    return _URC_END_OF_STACK;
+
+  /* New-style RT frame:
+     retcode + alignment (8 bytes)
+     siginfo (128 bytes)
+     ucontext (contains sigregs)  */
+  if (context->ra == context->cfa)
+    {
+      struct ucontext_
+      {
+	unsigned long     uc_flags;
+	struct ucontext_ *uc_link;
+	unsigned long     uc_stack[3];
+	sigregs_          uc_mcontext;
+      } *uc = context->cfa + 8 + 128;
+
+      regs = &uc->uc_mcontext;
+      signo = context->cfa + sizeof(long);
+    }
+
+  /* Old-style RT frame and all non-RT frames:
+     old signal mask (8 bytes)
+     pointer to sigregs  */
+  else
+    {
+      regs = *(sigregs_ **)(context->cfa + 8);
+
+      /* Recent kernels store the signal number immediately after
+	 the sigregs; old kernels have the return trampoline at
+	 this location.  */
+      if ((void *)(regs + 1) != context->ra)
+	signo = (int *)(regs + 1);
+    }
+
+  new_cfa = regs->gprs[15] + 16*sizeof(long) + 32;
+  fs->cfa_how = CFA_REG_OFFSET;
+  fs->cfa_reg = 15;
+  fs->cfa_offset =
+    new_cfa - (long) context->cfa + 16*sizeof(long) + 32;
+
+  for (i = 0; i < 16; i++)
+    {
+      fs->regs.reg[i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i].loc.offset =
+	(long)&regs->gprs[i] - new_cfa;
+    }
+  for (i = 0; i < 16; i++)
+    {
+      fs->regs.reg[16+i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[16+i].loc.offset =
+	(long)&regs->fprs[i] - new_cfa;
+    }
+
+  /* Load return addr from PSW into dummy register 32.  */
+
+  fs->regs.reg[32].how = REG_SAVED_OFFSET;
+  fs->regs.reg[32].loc.offset = (long)&regs->psw_addr - new_cfa;
+  fs->retaddr_column = 32;
+
+  /* If we got a SIGSEGV or a SIGBUS, the PSW address points *to*
+     the faulting instruction, not after it.  This causes the logic
+     in unwind-dw2.c that decrements the RA to determine the correct
+     CFI region to get confused.  To fix that, we *increment* the RA
+     here in that case.  Note that we cannot modify the RA in place,
+     and the frame state wants a *pointer*, not a value; thus we put
+     the modified RA value into the unused register 33 slot of FS and
+     have the register 32 save address point to that slot.
+
+     Unfortunately, for regular signals on old kernels, we don't know
+     the signal number.  We default to not fiddling with the RA;
+     that can fail in rare cases.  Upgrade your kernel.  */
+
+  if (signo && (*signo == 11 || *signo == 7))
+    {
+      fs->regs.reg[33].loc.exp =
+	(unsigned char *)regs->psw_addr + 1;
+      fs->regs.reg[32].loc.offset =
+	(long)&fs->regs.reg[33].loc.exp - new_cfa;
+    }
+
+  return _URC_NO_REASON;
+}
Index: gcc/config/s390/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/linux.h,v
retrieving revision 1.36
diff -u -p -r1.36 linux.h
--- gcc/config/s390/linux.h	19 Aug 2004 21:41:32 -0000	1.36
+++ gcc/config/s390/linux.h	6 Sep 2004 12:54:02 -0000
@@ -92,112 +92,6 @@ Software Foundation, 59 Temple Place - S
 
 #define TARGET_ASM_FILE_END file_end_indicate_exec_stack
 
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  */
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned char *pc_ = (CONTEXT)->ra;					\
-    long new_cfa_;							\
-    int i_;								\
-									\
-    typedef struct 							\
-      {									\
-        unsigned long psw_mask;						\
-        unsigned long psw_addr;						\
-        unsigned long gprs[16];						\
-        unsigned int  acrs[16];						\
-        unsigned int  fpc;						\
-        unsigned int  __pad;						\
-        double        fprs[16];						\
-      } __attribute__ ((__aligned__ (8))) sigregs_;			\
-									\
-    sigregs_ *regs_;							\
-    int *signo_ = NULL;							\
-									\
-    /* svc $__NR_sigreturn or svc $__NR_rt_sigreturn  */		\
-    if (pc_[0] != 0x0a || (pc_[1] != 119 && pc_[1] != 173))		\
-      break;								\
-									\
-    /* New-style RT frame:  						\
-	retcode + alignment (8 bytes)					\
-	siginfo (128 bytes)						\
-	ucontext (contains sigregs)  */					\
-    if ((CONTEXT)->ra == (CONTEXT)->cfa)				\
-      {									\
-	struct ucontext_						\
-	  {								\
-	    unsigned long     uc_flags;					\
-	    struct ucontext_ *uc_link;					\
-	    unsigned long     uc_stack[3];				\
-	    sigregs_          uc_mcontext;				\
-	  } *uc_ = (CONTEXT)->cfa + 8 + 128;				\
-									\
-	regs_ = &uc_->uc_mcontext;					\
-	signo_ = (CONTEXT)->cfa + sizeof(long);				\
-      }									\
-									\
-    /* Old-style RT frame and all non-RT frames:			\
-	old signal mask (8 bytes)					\
-	pointer to sigregs  */						\
-    else								\
-      {									\
-	regs_ = *(sigregs_ **)((CONTEXT)->cfa + 8);			\
-									\
-	/* Recent kernels store the signal number immediately after	\
-	   the sigregs; old kernels have the return trampoline at	\
-	   this location.  */						\
-	if ((void *)(regs_ + 1) != (CONTEXT)->ra)			\
-	  signo_ = (int *)(regs_ + 1);					\
-      }									\
-      									\
-    new_cfa_ = regs_->gprs[15] + 16*sizeof(long) + 32;			\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = 15;							\
-    (FS)->cfa_offset = 							\
-      new_cfa_ - (long) (CONTEXT)->cfa + 16*sizeof(long) + 32;		\
-									\
-    for (i_ = 0; i_ < 16; i_++)						\
-      {									\
-	(FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i_].loc.offset = 				\
-	  (long)&regs_->gprs[i_] - new_cfa_;				\
-      }									\
-    for (i_ = 0; i_ < 16; i_++)						\
-      {									\
-	(FS)->regs.reg[16+i_].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[16+i_].loc.offset = 				\
-	  (long)&regs_->fprs[i_] - new_cfa_;				\
-      }									\
-									\
-    /* Load return addr from PSW into dummy register 32.  */		\
-									\
-    (FS)->regs.reg[32].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[32].loc.offset = (long)&regs_->psw_addr - new_cfa_;	\
-    (FS)->retaddr_column = 32;						\
-									\
-    /* If we got a SIGSEGV or a SIGBUS, the PSW address points *to*	\
-       the faulting instruction, not after it.  This causes the logic	\
-       in unwind-dw2.c that decrements the RA to determine the correct	\
-       CFI region to get confused.  To fix that, we *increment* the RA	\
-       here in that case.  Note that we cannot modify the RA in place,	\
-       and the frame state wants a *pointer*, not a value; thus we put	\
-       the modified RA value into the unused register 33 slot of FS and	\
-       have the register 32 save address point to that slot.		\
-									\
-       Unfortunately, for regular signals on old kernels, we don't know	\
-       the signal number.  We default to not fiddling with the RA; 	\
-       that can fail in rare cases.  Upgrade your kernel.  */		\
-									\
-    if (signo_ && (*signo_ == 11 || *signo_ == 7))			\
-      {									\
-	(FS)->regs.reg[33].loc.exp = 					\
-		(unsigned char *)regs_->psw_addr + 1;			\
-	(FS)->regs.reg[32].loc.offset = 				\
-		(long)&(FS)->regs.reg[33].loc.exp - new_cfa_;		\
-      }									\
-									\
-    goto SUCCESS;							\
-  } while (0)
+#define MD_UNWIND_SUPPORT "config/s390/linux-unwind.h"
 
 #endif
Index: gcc/config/sh/linux-unwind.h
===================================================================
RCS file: gcc/config/sh/linux-unwind.h
diff -N gcc/config/sh/linux-unwind.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/sh/linux-unwind.h	6 Sep 2004 12:54:03 -0000
@@ -0,0 +1,167 @@
+/* DWARF2 EH unwinding support for SH Linux.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.  */
+
+#include <signal.h>
+#include <sys/ucontext.h>
+#include "insn-constants.h"
+
+# if defined (__SH5__)
+#define SH_DWARF_FRAME_GP0	0
+#define SH_DWARF_FRAME_FP0	(__SH5__ == 32 ? 245 : 77)
+#define SH_DWARF_FRAME_XD0	289
+#define SH_DWARF_FRAME_BT0	68
+#define SH_DWARF_FRAME_PR	241
+#define SH_DWARF_FRAME_PR_MEDIA	18
+#define SH_DWARF_FRAME_GBR	238
+#define SH_DWARF_FRAME_MACH	239
+#define SH_DWARF_FRAME_MACL	240
+#define SH_DWARF_FRAME_PC	64
+#define SH_DWARF_FRAME_SR	65
+#define SH_DWARF_FRAME_FPUL	244
+#define SH_DWARF_FRAME_FPSCR	243
+#else
+#define SH_DWARF_FRAME_GP0	0
+#define SH_DWARF_FRAME_FP0	25
+#define SH_DWARF_FRAME_XD0	87
+#define SH_DWARF_FRAME_PR	17
+#define SH_DWARF_FRAME_GBR	19
+#define SH_DWARF_FRAME_MACH	20
+#define SH_DWARF_FRAME_MACL	21
+#define SH_DWARF_FRAME_PC	16
+#define SH_DWARF_FRAME_SR	22
+#define SH_DWARF_FRAME_FPUL	23
+#define SH_DWARF_FRAME_FPSCR	24
+#endif /* defined (__SH5__) */
+
+#if defined (__SH5__)
+/* MD_FALLBACK_FRAME_STATE_FOR is not yet defined for SHMEDIA.  */
+#else /* defined (__SH5__) */
+
+#define MD_FALLBACK_FRAME_STATE_FOR sh_fallback_frame_state
+
+static _Unwind_Reason_Code
+sh_fallback_frame_state (struct _Unwind_Context *context,
+			 _Unwind_FrameState *fs)
+{
+  unsigned char *pc = context->ra;
+  struct sigcontext *sc;
+  long new_cfa;
+  int i;
+#if defined (__SH3E__) || defined (__SH4__)
+  int r;
+#endif
+
+  /* mov.w 1f,r3; trapa #0x10; 1: .short 0x77  (sigreturn)  */
+  /* mov.w 1f,r3; trapa #0x10; 1: .short 0xad  (rt_sigreturn)  */
+  /* Newer kernel uses pad instructions to avoid an SH-4 core bug.  */
+  /* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;
+     or r0,r0; 1: .short 0x77  (sigreturn)  */
+  /* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;
+     or r0,r0; 1: .short 0xad  (rt_sigreturn)  */
+  if (((*(unsigned short *) (pc+0)  == 0x9300)
+       && (*(unsigned short *) (pc+2)  == 0xc310)
+       && (*(unsigned short *) (pc+4)  == 0x0077))
+      || (((*(unsigned short *) (pc+0)  == 0x9305)
+	   && (*(unsigned short *) (pc+2)  == 0xc310)
+	   && (*(unsigned short *) (pc+14)  == 0x0077))))
+    sc = context->cfa;
+  else if (((*(unsigned short *) (pc+0) == 0x9300)
+	    && (*(unsigned short *) (pc+2)  == 0xc310)
+	    && (*(unsigned short *) (pc+4)  == 0x00ad))
+	   || (((*(unsigned short *) (pc+0) == 0x9305)
+		&& (*(unsigned short *) (pc+2)  == 0xc310)
+		&& (*(unsigned short *) (pc+14)  == 0x00ad))))
+    {
+      struct rt_sigframe {
+	struct siginfo info;
+	struct ucontext uc;
+      } *rt_ = context->cfa;
+      sc = (struct sigcontext *) &rt_->uc.uc_mcontext;
+    }
+  else
+    return _URC_END_OF_STACK;
+
+  new_cfa = sc->sc_regs[15];
+  fs->cfa_how = CFA_REG_OFFSET;
+  fs->cfa_reg = 15;
+  fs->cfa_offset = new_cfa - (long) context->cfa;
+
+  for (i = 0; i < 15; i++)
+    {
+      fs->regs.reg[i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i].loc.offset
+	= (long)&(sc->sc_regs[i]) - new_cfa;
+    }
+
+  fs->regs.reg[SH_DWARF_FRAME_PR].how = REG_SAVED_OFFSET;
+  fs->regs.reg[SH_DWARF_FRAME_PR].loc.offset
+    = (long)&(sc->sc_pr) - new_cfa;
+  fs->regs.reg[SH_DWARF_FRAME_SR].how = REG_SAVED_OFFSET;
+  fs->regs.reg[SH_DWARF_FRAME_SR].loc.offset
+    = (long)&(sc->sc_sr) - new_cfa;
+  fs->regs.reg[SH_DWARF_FRAME_GBR].how = REG_SAVED_OFFSET;
+  fs->regs.reg[SH_DWARF_FRAME_GBR].loc.offset
+    = (long)&(sc->sc_gbr) - new_cfa;
+  fs->regs.reg[SH_DWARF_FRAME_MACH].how = REG_SAVED_OFFSET;
+  fs->regs.reg[SH_DWARF_FRAME_MACH].loc.offset
+    = (long)&(sc->sc_mach) - new_cfa;
+  fs->regs.reg[SH_DWARF_FRAME_MACL].how = REG_SAVED_OFFSET;
+  fs->regs.reg[SH_DWARF_FRAME_MACL].loc.offset
+    = (long)&(sc->sc_macl) - new_cfa;
+
+#if defined (__SH3E__) || defined (__SH4__)
+  r = SH_DWARF_FRAME_FP0;
+  for (i = 0; i < 16; i++)
+    {
+      fs->regs.reg[r+i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[r+i].loc.offset
+	= (long)&(sc->sc_fpregs[i]) - new_cfa;
+    }
+
+  r = SH_DWARF_FRAME_XD0;
+  for (i = 0; i < 8; i++)
+    {
+      fs->regs.reg[i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i].loc.offset
+	= (long)&(sc->sc_xfpregs[2*i]) - new_cfa;
+    }
+
+  fs->regs.reg[SH_DWARF_FRAME_FPUL].how = REG_SAVED_OFFSET;
+  fs->regs.reg[SH_DWARF_FRAME_FPUL].loc.offset
+    = (long)&(sc->sc_fpul) - new_cfa;
+  fs->regs.reg[SH_DWARF_FRAME_FPSCR].how = REG_SAVED_OFFSET;
+  fs->regs.reg[SH_DWARF_FRAME_FPSCR].loc.offset
+    = (long)&(sc->sc_fpscr) - new_cfa;
+#endif
+
+  /* The unwinder expects the PC to point to the following insn,
+     whereas the kernel returns the address of the actual
+     faulting insn.  */
+  sc->sc_pc += 2;
+  fs->regs.reg[SH_DWARF_FRAME_PC].how = REG_SAVED_OFFSET;
+  fs->regs.reg[SH_DWARF_FRAME_PC].loc.offset
+    = (long)&(sc->sc_pc) - new_cfa;
+  fs->retaddr_column = SH_DWARF_FRAME_PC;
+  return _URC_NO_REASON;
+}
+#endif /* defined (__SH5__) */
Index: gcc/config/sh/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/linux.h,v
retrieving revision 1.23
diff -u -p -r1.23 linux.h
--- gcc/config/sh/linux.h	23 Apr 2004 02:16:25 -0000	1.23
+++ gcc/config/sh/linux.h	6 Sep 2004 12:54:03 -0000
@@ -147,159 +147,7 @@ do { \
     fprintf (STREAM, "2:\tlds.l\t@r15+,pr\n");				\
   } while (0)
 
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  */
-
-#ifdef IN_LIBGCC2
-#include <signal.h>
-#include <sys/ucontext.h>
-#include "insn-constants.h"
-
-# if defined (__SH5__)
-#define SH_DWARF_FRAME_GP0	0
-#define SH_DWARF_FRAME_FP0	(__SH5__ == 32 ? 245 : 77)
-#define SH_DWARF_FRAME_XD0	289
-#define SH_DWARF_FRAME_BT0	68
-#define SH_DWARF_FRAME_PR	241
-#define SH_DWARF_FRAME_PR_MEDIA	18
-#define SH_DWARF_FRAME_GBR	238
-#define SH_DWARF_FRAME_MACH	239
-#define SH_DWARF_FRAME_MACL	240
-#define SH_DWARF_FRAME_PC	64
-#define SH_DWARF_FRAME_SR	65
-#define SH_DWARF_FRAME_FPUL	244
-#define SH_DWARF_FRAME_FPSCR	243
-#else
-#define SH_DWARF_FRAME_GP0	0
-#define SH_DWARF_FRAME_FP0	25
-#define SH_DWARF_FRAME_XD0	87
-#define SH_DWARF_FRAME_PR	17
-#define SH_DWARF_FRAME_GBR	19
-#define SH_DWARF_FRAME_MACH	20
-#define SH_DWARF_FRAME_MACL	21
-#define SH_DWARF_FRAME_PC	16
-#define SH_DWARF_FRAME_SR	22
-#define SH_DWARF_FRAME_FPUL	23
-#define SH_DWARF_FRAME_FPSCR	24
-#endif /* defined (__SH5__) */
-
-#if defined (__SH5__)
-/* MD_FALLBACK_FRAME_STATE_FOR is not yet defined for SHMEDIA.  */
-#else /* defined (__SH5__) */
-
-#if defined (__SH3E__) || defined (__SH4__)
-#define SH_FALLBACK_FRAME_FLOAT_STATE(SC, FS, CFA)			\
-  do {									\
-    int i_, r_;								\
-									\
-    r_ = SH_DWARF_FRAME_FP0;						\
-    for (i_ = 0; i_ < 16; i_++)						\
-      {		    							\
-	(FS)->regs.reg[r_+i_].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[r_+i_].loc.offset 				\
-	  = (long)&((SC)->sc_fpregs[i_]) - (CFA);			\
-      }									\
-									\
-    r_ = SH_DWARF_FRAME_XD0	;					\
-    for (i_ = 0; i_ < 8; i_++)						\
-      {		    							\
-	(FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i_].loc.offset	 				\
-	  = (long)&((SC)->sc_xfpregs[2*i_]) - (CFA);			\
-      }									\
-									\
-    (FS)->regs.reg[SH_DWARF_FRAME_FPUL].how = REG_SAVED_OFFSET;		\
-    (FS)->regs.reg[SH_DWARF_FRAME_FPUL].loc.offset			\
-      = (long)&((SC)->sc_fpul) - (CFA);					\
-    (FS)->regs.reg[SH_DWARF_FRAME_FPSCR].how = REG_SAVED_OFFSET;	\
-    (FS)->regs.reg[SH_DWARF_FRAME_FPSCR].loc.offset			\
-      = (long)&((SC)->sc_fpscr) - (CFA);				\
-  } while (0)
-
-#else
-#define SH_FALLBACK_FRAME_FLOAT_STATE(SC, FS, CFA)
-#endif
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned char *pc_ = (CONTEXT)->ra;					\
-    struct sigcontext *sc_;						\
-    long new_cfa_;							\
-    int i_;								\
-									\
-    /* mov.w 1f,r3; trapa #0x10; 1: .short 0x77  (sigreturn)  */	\
-    /* mov.w 1f,r3; trapa #0x10; 1: .short 0xad  (rt_sigreturn)  */	\
-    /* Newer kernel uses pad instructions to avoid an SH-4 core bug.  */\
-    /* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;\
-       or r0,r0; 1: .short 0x77  (sigreturn)  */			\
-    /* mov.w 1f,r3; trapa #0x10; or r0,r0; or r0,r0; or r0,r0; or r0,r0;\
-       or r0,r0; 1: .short 0xad  (rt_sigreturn)  */			\
-    if (((*(unsigned short *) (pc_+0)  == 0x9300)			\
-	 && (*(unsigned short *) (pc_+2)  == 0xc310)			\
-	 && (*(unsigned short *) (pc_+4)  == 0x0077))			\
-	|| (((*(unsigned short *) (pc_+0)  == 0x9305)			\
-	    && (*(unsigned short *) (pc_+2)  == 0xc310)			\
-	    && (*(unsigned short *) (pc_+14)  == 0x0077))))		\
-      sc_ = (CONTEXT)->cfa;						\
-    else if (((*(unsigned short *) (pc_+0) == 0x9300)			\
-	      && (*(unsigned short *) (pc_+2)  == 0xc310)		\
-	      && (*(unsigned short *) (pc_+4)  == 0x00ad))		\
-	     || (((*(unsigned short *) (pc_+0) == 0x9305)		\
-		 && (*(unsigned short *) (pc_+2)  == 0xc310)		\
-		 && (*(unsigned short *) (pc_+14)  == 0x00ad))))	\
-      {									\
-	struct rt_sigframe {						\
-	  struct siginfo info;						\
-	  struct ucontext uc;						\
-	} *rt_ = (CONTEXT)->cfa;					\
-	sc_ = (struct sigcontext *) &rt_->uc.uc_mcontext;		\
-      }									\
-    else								\
-      break;								\
-    									\
-    new_cfa_ = sc_->sc_regs[15];					\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = 15;							\
-    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
-    									\
-    for (i_ = 0; i_ < 15; i_++)						\
-      {		    							\
-	(FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i_].loc.offset	 				\
-	  = (long)&(sc_->sc_regs[i_]) - new_cfa_;			\
-      }									\
-									\
-    (FS)->regs.reg[SH_DWARF_FRAME_PR].how = REG_SAVED_OFFSET;		\
-    (FS)->regs.reg[SH_DWARF_FRAME_PR].loc.offset			\
-      = (long)&(sc_->sc_pr) - new_cfa_;					\
-    (FS)->regs.reg[SH_DWARF_FRAME_SR].how = REG_SAVED_OFFSET;		\
-    (FS)->regs.reg[SH_DWARF_FRAME_SR].loc.offset			\
-      = (long)&(sc_->sc_sr) - new_cfa_;					\
-    (FS)->regs.reg[SH_DWARF_FRAME_GBR].how = REG_SAVED_OFFSET;		\
-    (FS)->regs.reg[SH_DWARF_FRAME_GBR].loc.offset			\
-      = (long)&(sc_->sc_gbr) - new_cfa_;				\
-    (FS)->regs.reg[SH_DWARF_FRAME_MACH].how = REG_SAVED_OFFSET;		\
-    (FS)->regs.reg[SH_DWARF_FRAME_MACH].loc.offset			\
-      = (long)&(sc_->sc_mach) - new_cfa_;				\
-    (FS)->regs.reg[SH_DWARF_FRAME_MACL].how = REG_SAVED_OFFSET;		\
-    (FS)->regs.reg[SH_DWARF_FRAME_MACL].loc.offset			\
-      = (long)&(sc_->sc_macl) - new_cfa_;				\
-									\
-     SH_FALLBACK_FRAME_FLOAT_STATE(sc_, (FS), new_cfa_);		\
-									\
-    /* The unwinder expects the PC to point to the following insn,	\
-       whereas the kernel returns the address of the actual		\
-       faulting insn.  */						\
-    sc_->sc_pc += 2;	  						\
-    (FS)->regs.reg[SH_DWARF_FRAME_PC].how = REG_SAVED_OFFSET;		\
-    (FS)->regs.reg[SH_DWARF_FRAME_PC].loc.offset			\
-      = (long)&(sc_->sc_pc) - new_cfa_;					\
-    (FS)->retaddr_column = SH_DWARF_FRAME_PC;				\
-    goto SUCCESS;							\
-  } while (0)
-
-#endif /* defined (__SH5__) */
-#endif /* IN_LIBGCC2 */
+#define MD_UNWIND_SUPPORT "config/sh/linux-unwind.h"
 
 /* For SH3 and SH4, we use a slot of the unwind frame which correspond
    to a fake register number 16 as a placeholder for the return address
Index: gcc/config/sparc/linux-unwind.h
===================================================================
RCS file: gcc/config/sparc/linux-unwind.h
diff -N gcc/config/sparc/linux-unwind.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gcc/config/sparc/linux-unwind.h	6 Sep 2004 12:54:03 -0000
@@ -0,0 +1,150 @@
+/* DWARF2 EH unwinding support for SPARC Linux.
+   Copyright 2004 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+/* Do code reading to identify a signal frame, and set the frame
+   state data appropriately.  See unwind-dw2.c for the structs.  */
+
+/* Handle multilib correctly.  */
+#if defined(__arch64__)
+
+/* 64-bit SPARC version */
+#define MD_FALLBACK_FRAME_STATE_FOR sparc64_fallback_frame_state
+
+static _Unwind_Reason_Code
+sparc64_fallback_frame_state (struct _Unwind_Context *context,
+			      _Unwind_FrameState *fs)
+{
+  unsigned int *pc = context->ra;
+  long new_cfa, i;
+  long regs_off, fpu_save_off;
+  long this_cfa, fpu_save;
+
+  if (pc[0] != 0x82102065		/* mov NR_rt_sigreturn, %g1 */
+      || pc[1] != 0x91d0206d)		/* ta 0x6d */
+    return _URC_END_OF_STACK;
+  regs_off = 192 + 128;
+  fpu_save_off = regs_off + (16 * 8) + (3 * 8) + (2 * 4);
+  this_cfa = (long) context->cfa;
+  new_cfa = *(long *)((context->cfa) + (regs_off + (14 * 8)));
+  new_cfa += 2047; /* Stack bias */
+  fpu_save = *(long *)((this_cfa) + (fpu_save_off));
+  fs->cfa_how = CFA_REG_OFFSET;
+  fs->cfa_reg = 14;
+  fs->cfa_offset = new_cfa - (long) context->cfa;
+  for (i = 1; i < 16; ++i)
+    {
+      fs->regs.reg[i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i].loc.offset =
+	this_cfa + (regs_off + (i * 8)) - new_cfa;
+    }
+  for (i = 0; i < 16; ++i)
+    {
+      fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i + 16].loc.offset =
+	this_cfa + (i * 8) - new_cfa;
+    }
+  if (fpu_save)
+    {
+      for (i = 0; i < 64; ++i)
+	{
+	  if (i > 32 && (i & 0x1))
+	    continue;
+	  fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
+	  fs->regs.reg[i + 32].loc.offset =
+	    (fpu_save + (i * 4)) - new_cfa;
+	}
+    }
+  /* Stick return address into %g0, same trick Alpha uses.  */
+  fs->regs.reg[0].how = REG_SAVED_OFFSET;
+  fs->regs.reg[0].loc.offset =
+    this_cfa + (regs_off + (16 * 8) + 8) - new_cfa;
+  fs->retaddr_column = 0;
+  return _URC_NO_REASON;
+}
+
+#else
+
+/* 32-bit SPARC version */
+#define MD_FALLBACK_FRAME_STATE_FOR sparc_fallback_frame_state
+
+static _Unwind_Reason_Code
+sparc_fallback_frame_state (struct _Unwind_Context *context,
+			    _Unwind_FrameState *fs)
+{
+  unsigned int *pc = context->ra;
+  int new_cfa, i, oldstyle;
+  int regs_off, fpu_save_off;
+  int fpu_save, this_cfa;
+
+  if (pc[1] != 0x91d02010)		/* ta 0x10 */
+    return _URC_END_OF_STACK;
+  if (pc[0] == 0x821020d8)		/* mov NR_sigreturn, %g1 */
+    oldstyle = 1;
+  else if (pc[0] == 0x82102065)	/* mov NR_rt_sigreturn, %g1 */
+    oldstyle = 0;
+  else
+    return _URC_END_OF_STACK;
+  if (oldstyle)
+    {
+      regs_off = 96;
+      fpu_save_off = regs_off + (4 * 4) + (16 * 4);
+    }
+  else
+    {
+      regs_off = 96 + 128;
+      fpu_save_off = regs_off + (4 * 4) + (16 * 4) + (2 * 4);
+    }
+  this_cfa = (int) context->cfa;
+  new_cfa = *(int *)((context->cfa) + (regs_off+(4*4)+(14 * 4)));
+  fpu_save = *(int *)((this_cfa) + (fpu_save_off));
+  fs->cfa_how = CFA_REG_OFFSET;
+  fs->cfa_reg = 14;
+  fs->cfa_offset = new_cfa - (int) context->cfa;
+  for (i = 1; i < 16; ++i)
+    {
+      if (i == 14)
+	continue;
+      fs->regs.reg[i].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i].loc.offset =
+	this_cfa + (regs_off+(4 * 4)+(i * 4)) - new_cfa;
+    }
+  for (i = 0; i < 16; ++i)
+    {
+      fs->regs.reg[i + 16].how = REG_SAVED_OFFSET;
+      fs->regs.reg[i + 16].loc.offset =
+	this_cfa + (i * 4) - new_cfa;
+    }
+  if (fpu_save)
+    {
+      for (i = 0; i < 32; ++i)
+	{
+	  fs->regs.reg[i + 32].how = REG_SAVED_OFFSET;
+	  fs->regs.reg[i + 32].loc.offset =
+	    (fpu_save + (i * 4)) - new_cfa;
+	}
+    }
+  /* Stick return address into %g0, same trick Alpha uses.  */
+  fs->regs.reg[0].how = REG_SAVED_OFFSET;
+  fs->regs.reg[0].loc.offset = this_cfa+(regs_off+4)-new_cfa;
+  fs->retaddr_column = 0;
+  return _URC_NO_REASON;
+}
+
+#endif
Index: gcc/config/sparc/linux.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/linux.h,v
retrieving revision 1.63
diff -u -p -r1.63 linux.h
--- gcc/config/sparc/linux.h	5 Aug 2004 09:12:12 -0000	1.63
+++ gcc/config/sparc/linux.h	6 Sep 2004 12:54:06 -0000
@@ -228,66 +228,4 @@ do {									\
 #define USE_LD_AS_NEEDED 1
 #endif
 
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  */
-
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned int *pc_ = (CONTEXT)->ra;					\
-    int new_cfa_, i_, oldstyle_;					\
-    int regs_off_, fpu_save_off_;					\
-    int fpu_save_, this_cfa_;						\
-									\
-    if (pc_[1] != 0x91d02010)		/* ta 0x10 */			\
-      break;								\
-    if (pc_[0] == 0x821020d8)		/* mov NR_sigreturn, %g1 */	\
-      oldstyle_ = 1;							\
-    else if (pc_[0] == 0x82102065)	/* mov NR_rt_sigreturn, %g1 */	\
-      oldstyle_ = 0;							\
-    else								\
-      break;								\
-    if (oldstyle_)							\
-      {									\
-        regs_off_ = 96;							\
-        fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4);			\
-      }									\
-    else								\
-      {									\
-        regs_off_ = 96 + 128;						\
-        fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4) + (2 * 4);	\
-      }									\
-    this_cfa_ = (int) (CONTEXT)->cfa;					\
-    new_cfa_ = *(int *)(((CONTEXT)->cfa) + (regs_off_+(4*4)+(14 * 4)));	\
-    fpu_save_ = *(int *)((this_cfa_) + (fpu_save_off_));		\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = 14;							\
-    (FS)->cfa_offset = new_cfa_ - (int) (CONTEXT)->cfa;			\
-    for (i_ = 1; i_ < 16; ++i_)						\
-      {									\
-        if (i_ == 14)							\
-          continue;							\
-	(FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i_].loc.offset =					\
-	   this_cfa_ + (regs_off_+(4 * 4)+(i_ * 4)) - new_cfa_;		\
-      }									\
-    for (i_ = 0; i_ < 16; ++i_)						\
-      {									\
-	(FS)->regs.reg[i_ + 16].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i_ + 16].loc.offset =				\
-	  this_cfa_ + (i_ * 4) - new_cfa_;				\
-      }									\
-    if (fpu_save_)							\
-      {									\
-	for (i_ = 0; i_ < 32; ++i_)					\
-	  {								\
-	    (FS)->regs.reg[i_ + 32].how = REG_SAVED_OFFSET;		\
-	    (FS)->regs.reg[i_ + 32].loc.offset =			\
-	      (fpu_save_ + (i_ * 4)) - new_cfa_;			\
-	  }								\
-      }									\
-    /* Stick return address into %g0, same trick Alpha uses.  */	\
-    (FS)->regs.reg[0].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[0].loc.offset = this_cfa_+(regs_off_+4)-new_cfa_;	\
-    (FS)->retaddr_column = 0;						\
-    goto SUCCESS;							\
-  } while (0)
+#define MD_UNWIND_SUPPORT "config/sparc/linux-unwind.h"
Index: gcc/config/sparc/linux64.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/linux64.h,v
retrieving revision 1.85
diff -u -p -r1.85 linux64.h
--- gcc/config/sparc/linux64.h	6 Jun 2004 03:57:35 -0000	1.85
+++ gcc/config/sparc/linux64.h	6 Sep 2004 12:54:06 -0000
@@ -366,121 +366,4 @@ do {									\
 #define USE_LD_AS_NEEDED 1
 #endif
 
-/* Do code reading to identify a signal frame, and set the frame
-   state data appropriately.  See unwind-dw2.c for the structs.  */
-
-/* Handle multilib correctly.  */
-#if defined(__arch64__)
-/* 64-bit SPARC version */
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned int *pc_ = (CONTEXT)->ra;					\
-    long new_cfa_, i_;							\
-    long regs_off_, fpu_save_off_;					\
-    long this_cfa_, fpu_save_;						\
-									\
-    if (pc_[0] != 0x82102065		/* mov NR_rt_sigreturn, %g1 */	\
-        || pc_[1] != 0x91d0206d)		/* ta 0x6d */		\
-      break;								\
-    regs_off_ = 192 + 128;						\
-    fpu_save_off_ = regs_off_ + (16 * 8) + (3 * 8) + (2 * 4);		\
-    this_cfa_ = (long) (CONTEXT)->cfa;					\
-    new_cfa_ = *(long *)(((CONTEXT)->cfa) + (regs_off_ + (14 * 8)));	\
-    new_cfa_ += 2047; /* Stack bias */					\
-    fpu_save_ = *(long *)((this_cfa_) + (fpu_save_off_));		\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = 14;							\
-    (FS)->cfa_offset = new_cfa_ - (long) (CONTEXT)->cfa;		\
-    for (i_ = 1; i_ < 16; ++i_)						\
-      {									\
-	(FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i_].loc.offset =					\
-	  this_cfa_ + (regs_off_ + (i_ * 8)) - new_cfa_;		\
-      }									\
-    for (i_ = 0; i_ < 16; ++i_)						\
-      {									\
-	(FS)->regs.reg[i_ + 16].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i_ + 16].loc.offset =				\
-	  this_cfa_ + (i_ * 8) - new_cfa_;				\
-      }									\
-    if (fpu_save_)							\
-      {									\
-	for (i_ = 0; i_ < 64; ++i_)					\
-	  {								\
-            if (i_ > 32 && (i_ & 0x1))					\
-              continue;							\
-	    (FS)->regs.reg[i_ + 32].how = REG_SAVED_OFFSET;		\
-	    (FS)->regs.reg[i_ + 32].loc.offset =			\
-	      (fpu_save_ + (i_ * 4)) - new_cfa_;			\
-	  }								\
-      }									\
-    /* Stick return address into %g0, same trick Alpha uses.  */	\
-    (FS)->regs.reg[0].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[0].loc.offset =					\
-      this_cfa_ + (regs_off_ + (16 * 8) + 8) - new_cfa_;		\
-    (FS)->retaddr_column = 0;						\
-    goto SUCCESS;							\
-  } while (0)
-#else
-/* 32-bit SPARC version */
-#define MD_FALLBACK_FRAME_STATE_FOR(CONTEXT, FS, SUCCESS)		\
-  do {									\
-    unsigned int *pc_ = (CONTEXT)->ra;					\
-    int new_cfa_, i_, oldstyle_;					\
-    int regs_off_, fpu_save_off_;					\
-    int fpu_save_, this_cfa_;						\
-									\
-    if (pc_[1] != 0x91d02010)		/* ta 0x10 */			\
-      break;								\
-    if (pc_[0] == 0x821020d8)		/* mov NR_sigreturn, %g1 */	\
-      oldstyle_ = 1;							\
-    else if (pc_[0] == 0x82102065)	/* mov NR_rt_sigreturn, %g1 */	\
-      oldstyle_ = 0;							\
-    else								\
-      break;								\
-    if (oldstyle_)							\
-      {									\
-        regs_off_ = 96;							\
-        fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4);			\
-      }									\
-    else								\
-      {									\
-        regs_off_ = 96 + 128;						\
-        fpu_save_off_ = regs_off_ + (4 * 4) + (16 * 4) + (2 * 4);	\
-      }									\
-    this_cfa_ = (int) (CONTEXT)->cfa;					\
-    new_cfa_ = *(int *)(((CONTEXT)->cfa) + (regs_off_+(4*4)+(14 * 4)));	\
-    fpu_save_ = *(int *)((this_cfa_) + (fpu_save_off_));		\
-    (FS)->cfa_how = CFA_REG_OFFSET;					\
-    (FS)->cfa_reg = 14;							\
-    (FS)->cfa_offset = new_cfa_ - (int) (CONTEXT)->cfa;			\
-    for (i_ = 1; i_ < 16; ++i_)						\
-      {									\
-        if (i_ == 14)							\
-          continue;							\
-	(FS)->regs.reg[i_].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i_].loc.offset =					\
-	   this_cfa_ + (regs_off_+(4 * 4)+(i_ * 4)) - new_cfa_;		\
-      }									\
-    for (i_ = 0; i_ < 16; ++i_)						\
-      {									\
-	(FS)->regs.reg[i_ + 16].how = REG_SAVED_OFFSET;			\
-	(FS)->regs.reg[i_ + 16].loc.offset =				\
-	  this_cfa_ + (i_ * 4) - new_cfa_;				\
-      }									\
-    if (fpu_save_)							\
-      {									\
-	for (i_ = 0; i_ < 32; ++i_)					\
-	  {								\
-	    (FS)->regs.reg[i_ + 32].how = REG_SAVED_OFFSET;		\
-	    (FS)->regs.reg[i_ + 32].loc.offset =			\
-	      (fpu_save_ + (i_ * 4)) - new_cfa_;			\
-	  }								\
-      }									\
-    /* Stick return address into %g0, same trick Alpha uses.  */	\
-    (FS)->regs.reg[0].how = REG_SAVED_OFFSET;				\
-    (FS)->regs.reg[0].loc.offset = this_cfa_+(regs_off_+4)-new_cfa_;	\
-    (FS)->retaddr_column = 0;						\
-    goto SUCCESS;							\
-  } while (0)
-#endif
+#define MD_UNWIND_SUPPORT "config/sparc/linux-unwind.h"
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.364
diff -u -p -r1.364 tm.texi
--- gcc/doc/tm.texi	4 Sep 2004 08:50:36 -0000	1.364
+++ gcc/doc/tm.texi	6 Sep 2004 12:54:12 -0000
@@ -3094,7 +3094,12 @@ of bytes that the format occupies, @var{
 to be emitted.
 @end defmac
 
-@defmac MD_FALLBACK_FRAME_STATE_FOR (@var{context}, @var{fs}, @var{success})
+@defmac MD_UNWIND_SUPPORT
+A string specifying a file to be #include'd in unwind-dw2.c.  The file
+so included typically defines @code{MD_FALLBACK_FRAME_STATE_FOR}.
+@end defmac
+
+@defmac MD_FALLBACK_FRAME_STATE_FOR (@var{context}, @var{fs})
 This macro allows the target to add cpu and operating system specific
 code to the call-frame unwinder for use when there is no unwind data
 available.  The most common reason to implement this macro is to unwind
@@ -3105,9 +3110,9 @@ and @file{unwind-ia64.c}.  @var{context}
 @var{fs} is an @code{_Unwind_FrameState}.  Examine @code{context->ra}
 for the address of the code being executed and @code{context->cfa} for
 the stack pointer value.  If the frame can be decoded, the register save
-addresses should be updated in @var{fs} and the macro should branch to
-@var{success}.  If the frame cannot be decoded, the macro should do
-nothing.
+addresses should be updated in @var{fs} and the macro should evaluate to
+@code{_URC_NO_REASON}.  If the frame cannot be decoded, the macro should
+evaluate to @code{_URC_END_OF_STACK}.
 
 For proper signal handling in Java this macro is accompanied by
 @code{MAKE_THROW_FRAME}, defined in @file{libjava/include/*-signal.h} headers.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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