aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/ia64
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2004-09-08 00:17:19 +0000
committerAlan Modra <amodra@gcc.gnu.org>2004-09-08 09:47:19 +0930
commit8662eb14c0ef6531d7086ec08f5e52b87c472ede (patch)
treef6927bd90fe84c682dd04619d255d6355aac36d5 /gcc/config/ia64
parenta9e10feb68d5cbc371f581ebca229043b7854fe5 (diff)
downloadgcc-8662eb14c0ef6531d7086ec08f5e52b87c472ede.zip
gcc-8662eb14c0ef6531d7086ec08f5e52b87c472ede.tar.gz
gcc-8662eb14c0ef6531d7086ec08f5e52b87c472ede.tar.bz2
tm.texi (MD_UNWIND_SUPPORT): Document.
* 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
Diffstat (limited to 'gcc/config/ia64')
-rw-r--r--gcc/config/ia64/linux-unwind.h185
-rw-r--r--gcc/config/ia64/linux.h159
-rw-r--r--gcc/config/ia64/unwind-ia64.c16
3 files changed, 194 insertions, 166 deletions
diff --git a/gcc/config/ia64/linux-unwind.h b/gcc/config/ia64/linux-unwind.h
new file mode 100644
index 0000000..801597c
--- /dev/null
+++ b/gcc/config/ia64/linux-unwind.h
@@ -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 */
diff --git a/gcc/config/ia64/linux.h b/gcc/config/ia64/linux.h
index 5c73b0c..3d58560 100644
--- a/gcc/config/ia64/linux.h
+++ b/gcc/config/ia64/linux.h
@@ -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"
diff --git a/gcc/config/ia64/unwind-ia64.c b/gcc/config/ia64/unwind-ia64.c
index 692f07b..4a4d65a 100644
--- a/gcc/config/ia64/unwind-ia64.c
+++ b/gcc/config/ia64/unwind-ia64.c
@@ -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
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;