tm.texi (MD_UNWIND_SUPPORT): Document.
authorAlan Modra <amodra@bigpond.net.au>
Wed, 8 Sep 2004 00:17:19 +0000 (00:17 +0000)
committerAlan Modra <amodra@gcc.gnu.org>
Wed, 8 Sep 2004 00:17:19 +0000 (09:47 +0930)
* 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.

From-SVN: r87167

31 files changed:
gcc/ChangeLog
gcc/config/alpha/gnu.h
gcc/config/alpha/linux-unwind.h [new file with mode: 0644]
gcc/config/alpha/linux.h
gcc/config/alpha/vms-unwind.h [new file with mode: 0644]
gcc/config/alpha/vms.h
gcc/config/i386/gnu.h
gcc/config/i386/linux-unwind.h [new file with mode: 0644]
gcc/config/i386/linux.h
gcc/config/i386/linux64.h
gcc/config/ia64/linux-unwind.h [new file with mode: 0644]
gcc/config/ia64/linux.h
gcc/config/ia64/unwind-ia64.c
gcc/config/mips/linux-unwind.h [new file with mode: 0644]
gcc/config/mips/linux.h
gcc/config/pa/linux-unwind.h [new file with mode: 0644]
gcc/config/pa/pa32-linux.h
gcc/config/rs6000/darwin-unwind.h [new file with mode: 0644]
gcc/config/rs6000/darwin.h
gcc/config/rs6000/linux-unwind.h [new file with mode: 0644]
gcc/config/rs6000/linux.h
gcc/config/rs6000/linux64.h
gcc/config/s390/linux-unwind.h [new file with mode: 0644]
gcc/config/s390/linux.h
gcc/config/sh/linux-unwind.h [new file with mode: 0644]
gcc/config/sh/linux.h
gcc/config/sparc/linux-unwind.h [new file with mode: 0644]
gcc/config/sparc/linux.h
gcc/config/sparc/linux64.h
gcc/doc/tm.texi
gcc/unwind-dw2.c

index 3938e7a569519052f70af786cb7d5452aa39fe1c..3177547be526bf4404c4a65b06c60ce40732de5d 100644 (file)
@@ -1,3 +1,37 @@
+2004-09-08  Alan Modra  <amodra@bigpond.net.au>
+
+       * 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.
+
 2004-09-07  Jan Hubicka  <jh@suse.cz>
 
        * cse.c (fold_rtx):  Avoid building of
index 40348c60abbb5baa579923cb91ce61f80c5e69f7..b9bfceafd0a9b310ed1814c060a0a298a4d4569a 100644 (file)
@@ -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
diff --git a/gcc/config/alpha/linux-unwind.h b/gcc/config/alpha/linux-unwind.h
new file mode 100644 (file)
index 0000000..ec0af1a
--- /dev/null
@@ -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 e2a16dff3dba064626467c74fc87a8f79bb8da8b..e9a0e90058044e1e115f9be2cfc7771891c2f7f5 100644 (file)
@@ -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"
diff --git a/gcc/config/alpha/vms-unwind.h b/gcc/config/alpha/vms-unwind.h
new file mode 100644 (file)
index 0000000..cafe72a
--- /dev/null
@@ -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 b062d616c0085e2783d31be3efe90e2d2bceb3d9..39fce013c87b3cc1b3175bbf0d4792fd238308c6 100644 (file)
@@ -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 cc9994bcaed84db220c36777b740cabc0a2f3ad6..ce80c9821fdc1ed4c5781ba78b3d4f126654d9b8 100644 (file)
@@ -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
diff --git a/gcc/config/i386/linux-unwind.h b/gcc/config/i386/linux-unwind.h
new file mode 100644 (file)
index 0000000..ecbce1d
--- /dev/null
@@ -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 08b859ac310d335ed86d5bb4fc869f367f996826..e31c5114e93fbc21bc33843f2fd72ad63715d050 100644 (file)
@@ -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 98536c19bd3752ab3ad791222a990ef16c622b4e..4838cf8fa8ed85cd4e3ef803653df2927456248f 100644 (file)
@@ -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"
diff --git a/gcc/config/ia64/linux-unwind.h b/gcc/config/ia64/linux-unwind.h
new file mode 100644 (file)
index 0000000..801597c
--- /dev/null
@@ -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 5c73b0c25ef40ef8a9e6d81093ad1782ced5bbf9..3d585609f61fd9241a167237e931281af76d0dfb 100644 (file)
@@ -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 692f07b1adfb3f823fd059da3b116d8e850f2662..4a4d65aaa20046da2ad941a97d1e5ccfbdaae5a6 100644 (file)
@@ -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 *context)
   return (_Unwind_Ptr) context->bsp;
 }
 
+#ifdef MD_UNWIND_SUPPORT
+#include MD_UNWIND_SUPPORT
+#endif
 \f
 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_Context *context, _Unwind_FrameState *fs)
         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_Context *context, _Unwind_FrameState *fs)
          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;
diff --git a/gcc/config/mips/linux-unwind.h b/gcc/config/mips/linux-unwind.h
new file mode 100644 (file)
index 0000000..5c136c1
--- /dev/null
@@ -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 a4765d494ee330a4cbc0215aea7c73619690e56b..be5c8d4d21907bc8668c3c9ecaba8293be6e5e84 100644 (file)
@@ -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"
diff --git a/gcc/config/pa/linux-unwind.h b/gcc/config/pa/linux-unwind.h
new file mode 100644 (file)
index 0000000..41ec61c
--- /dev/null
@@ -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 14cc2cf9159a8fad911ce55af76ce5f5cb253cec..07b680de88acc2d25116b12d63c50f2bfea9f04d 100644 (file)
@@ -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"
diff --git a/gcc/config/rs6000/darwin-unwind.h b/gcc/config/rs6000/darwin-unwind.h
new file mode 100644 (file)
index 0000000..e3d0326
--- /dev/null
@@ -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 1e92d5fe2bfc2fcfdf91febc0842dbfea9dacb20..44ae79ac38c62c743ad75ec4eab6df34a574a180 100644 (file)
@@ -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
 
diff --git a/gcc/config/rs6000/linux-unwind.h b/gcc/config/rs6000/linux-unwind.h
new file mode 100644 (file)
index 0000000..bb4f0cf
--- /dev/null
@@ -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 83aef83a387b1174948801033b244ba1829f2557..0f4d046e0496f55f2ac2c51fd4d75cbab92502f0 100644 (file)
 
 #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 e7b57d4f57098bdd0644c1ea5b5b7fead52a82c6..410f31ee49bb5668fdc0f1c24bc083c7c11c9f2a 100644 (file)
@@ -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
diff --git a/gcc/config/s390/linux-unwind.h b/gcc/config/s390/linux-unwind.h
new file mode 100644 (file)
index 0000000..3713f18
--- /dev/null
@@ -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 9dd07c71ef3a57f635e2cee1c291d62b637cfbaf..fc26f7a91a64b06b3171f78730e6d7dfa9d7fa86 100644 (file)
@@ -92,112 +92,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 #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
diff --git a/gcc/config/sh/linux-unwind.h b/gcc/config/sh/linux-unwind.h
new file mode 100644 (file)
index 0000000..ed32e24
--- /dev/null
@@ -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 b01b52d28db9b7b96a90603f265521cbd849482d..1142b126946f49819b8f0a7e81062c50b56c1a0c 100644 (file)
@@ -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
diff --git a/gcc/config/sparc/linux-unwind.h b/gcc/config/sparc/linux-unwind.h
new file mode 100644 (file)
index 0000000..3ce967d
--- /dev/null
@@ -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 2ee6ad90513a8620560f1c0d4273524e877fc9ca..788b1433dc34884e9c417042f143dce37d011103 100644 (file)
@@ -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 78d657c27ecd74c3846fbb735226ae91d051bee2..daf1653bfc775555868897d66213ef31cb423d5f 100644 (file)
@@ -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 e21f72747ed34e248db30f92cd080d788e928115..74d3b4df4073a53c34bbe0c56920b07783efdb28 100644 (file)
@@ -3094,7 +3094,12 @@ of bytes that the format occupies, @var{addr} is the @code{SYMBOL_REF}
 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} is an @code{_Unwind_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.
index db8f3f5e20aa85bd899e72f2911d3a0cbcf7b86d..eb36e207e2ff9068c744942595f9962c078e191f 100644 (file)
 #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_Context *context)
   return (_Unwind_Ptr) context->bases.tbase;
 }
 #endif
+
+#ifdef MD_UNWIND_SUPPORT
+#include MD_UNWIND_SUPPORT
+#endif
 \f
 /* 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_Context *context, _Unwind_FrameState *fs)
   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_Context *context, _Unwind_FrameState *fs)
        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