diff options
author | Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> | 2011-06-03 18:30:39 +0000 |
---|---|---|
committer | Rainer Orth <ro@gcc.gnu.org> | 2011-06-03 18:30:39 +0000 |
commit | 58cd1d70dd8cd4b95773c0487a5d2aecad2b4dc1 (patch) | |
tree | f430fed8dbe1ebf2c96bc2f167ea68cb1e504948 /gcc/config/alpha | |
parent | 34e0c8d5fe61e28903fd89685e091a9654015dbf (diff) | |
download | gcc-58cd1d70dd8cd4b95773c0487a5d2aecad2b4dc1.zip gcc-58cd1d70dd8cd4b95773c0487a5d2aecad2b4dc1.tar.gz gcc-58cd1d70dd8cd4b95773c0487a5d2aecad2b4dc1.tar.bz2 |
linux.h (MD_UNWIND_SUPPORT): Remove.
gcc:
* config/alpha/linux.h (MD_UNWIND_SUPPORT): Remove.
* config/alpha/osf5.h (MD_UNWIND_SUPPORT): Remove.
* config/alpha/vms.h (MD_UNWIND_SUPPORT): Remove.
* config/bfin/linux.h (MD_UNWIND_SUPPORT): Remove.
* config/bfin/uclinux.h (MD_UNWIND_SUPPORT): Remove.
* config/i386/linux.h (MD_UNWIND_SUPPORT): Remove.
* config/i386/linux64.h (MD_UNWIND_SUPPORT): Remove.
* config/i386/sol2.h (MD_UNWIND_SUPPORT): Remove.
* config/i386/mingw32.h (MD_UNWIND_SUPPORT): Remove.
* config/ia64/linux.h (MD_UNWIND_SUPPORT): Remove.
* config/ia64/vms.h (MD_UNWIND_SUPPORT): Remove.
* config/m68k/linux.h (MD_UNWIND_SUPPORT): Remove.
* config/mips/linux.h (MD_UNWIND_SUPPORT): Remove.
* config/pa/pa-hpux.h (MD_UNWIND_SUPPORT): Remove.
* config/pa/pa32-linux.h (MD_UNWIND_SUPPORT): Remove.
* config/rs6000/darwin.h (MD_UNWIND_SUPPORT): Remove.
* config/rs6000/linux.h (MD_UNWIND_SUPPORT): Remove.
* config/rs6000/linux64.h (MD_UNWIND_SUPPORT): Remove.
* config/s390/linux.h (MD_UNWIND_SUPPORT): Remove.
* config/s390/tpf.h (MD_UNWIND_SUPPORT): Remove.
* config/sh/linux.h (MD_UNWIND_SUPPORT): Remove.
* config/sparc/linux.h (MD_UNWIND_SUPPORT): Remove.
* config/sparc/linux64.h (MD_UNWIND_SUPPORT): Remove.
* config/sparc/sol2.h (MD_UNWIND_SUPPORT): Remove.
* config/xtensa/linux.h (MD_UNWIND_SUPPORT): Remove.
* config/alpha/linux-unwind.h: Move to ../libgcc/config/alpha.
* config/alpha/osf5-unwind.h: Move to ../libgcc/config/alpha.
* config/alpha/vms-unwind.h: Move to ../libgcc/config/alpha.
* config/bfin/linux-unwind.h: Move to ../libgcc/config/bfin.
* config/i386/linux-unwind.h: Move to ../libgcc/config/i386.
* config/i386/sol2-unwind.h: Move to ../libgcc/config/i386.
* config/i386/w32-unwind.h: Move to ../libgcc/config/i386.
* config/ia64/linux-unwind.h: Move to ../libgcc/config/ia64.
* config/ia64/vms-unwind.h: Move to ../libgcc/config/ia64.
* config/m68k/linux-unwind.h: Move to ../libgcc/config/m68k.
* config/mips/linux-unwind.h: Move to ../libgcc/config/mips.
* config/pa/hpux-unwind.h: Move to ../libgcc/config/pa.
* config/pa/linux-unwind.h: Move to ../libgcc/config/pa.
* config/rs6000/darwin-unwind.h: Move to ../libgcc/config/rs6000.
* config/rs6000/linux-unwind.h: Move to ../libgcc/config/rs6000.
* config/s390/linux-unwind.h: Move to ../libgcc/config/s390.
* config/s390/tpf-unwind.h: Move to ../libgcc/config/s390.
* config/sh/linux-unwind.h: Move to ../libgcc/config/sh.
* config/sparc/linux-unwind.h: Move to ../libgcc/config/sparc.
* config/sparc/sol2-unwind.h: Move to ../libgcc/config/sparc.
* config/xtensa/linux-unwind.h: Move to ../libgcc/config/xtensa.
* config/darwin9.h (DARWIN_LIBSYSTEM_HAS_UNWIND): Remove.
* system.h (MD_UNWIND_SUPPORT): Poison.
* doc/tm.texi.in (Exception Handling, MD_UNWIND_SUPPORT): Remove.
* doc/tm.texi: Regenerate.
* unwind-dw2.c: Include md-unwind-support.h instead of
MD_UNWIND_SUPPORT.
* config/ia64/unwind-ia64.c: Likewise.
* config/xtensa/unwind-dw2-xtensa.c: Likewise.
libgcc:
* config/alpha/linux-unwind.h: Move from ../gcc/config/alpha.
* config/alpha/osf5-unwind.h: Move from ../gcc/config/alpha.
* config/alpha/vms-unwind.h: Move from ../gcc/config/alpha.
* config/bfin/linux-unwind.h: Move from ../gcc/config/bfin.
* config/i386/linux-unwind.h: Move from ../gcc/config/i386.
* config/i386/sol2-unwind.h: Move from ../gcc/config/i386.
* config/i386/w32-unwind.h: Move from ../gcc/config/i386.
Wrap in !__MINGW64__.
* config/ia64/linux-unwind.h: Move from ../gcc/config/ia64.
* config/ia64/vms-unwind.h: Move from ../gcc/config/ia64.
* config/m68k/linux-unwind.h: Move from ../gcc/config/m68k.
* config/mips/linux-unwind.h: Move from ../gcc/config/mips.
* config/pa/hpux-unwind.h: Move from ../gcc/config/pa.
* config/pa/linux-unwind.h: Move from ../gcc/config/pa.
* config/rs6000/darwin-unwind.h: Move from ../gcc/config/rs6000.
Wrap in !__LP64__.
* config/rs6000/linux-unwind.h: Move from ../gcc/config/rs6000.
* config/s390/linux-unwind.h: Move from ../gcc/config/s390.
* config/s390/tpf-unwind.h: Move from ../gcc/config/s390.
* config/sh/linux-unwind.h: Move from ../gcc/config/sh.
* config/sparc/linux-unwind.h: Move from ../gcc/config/sparc.
* config/sparc/sol2-unwind.h: Move from ../gcc/config/sparc.
* config/xtensa/linux-unwind.h: Move from ../gcc/config/xtensa.
* config/no-unwind.h: New file.
* config.host (md_unwind_header): Document.
Define.
(alpha*-*-linux*, alpha*-dec-osf5.1*, alpha64-dec-*vms*,
alpha*-dec-*vms*, bfin*-uclinux*, bfin*-linux-uclibc*,
hppa*-*-linux*, hppa[12]*-*-hpux10*, hppa*64*-*-hpux11*,
hppa[12]*-*-hpux11*): Set md_unwind_header.
(i[34567]86-*-linux*): Handle i[34567]86-*-kopensolaris*-gnu.
Set md_unwind_header.
(x86_64-*-linux*, i[34567]86-*-solaris2*): Set md_unwind_header.
(i[34567]86-*-cygwin*): Split from i[34567]86-*-mingw*.
(i[34567]86-*-mingw*, ia64*-*-linux*, ia64-hp-*vms*,
m68k-*-uclinux*, m68k-*-linux*, mips64*-*-linux*, mips*-*-linux*,
powerpc-*-darwin*, powerpc-*-linux*, s390-*-linux*,
s390x-*-linux*, s390x-ibm-tpf*, sh*-*-linux*, sparc-*-linux*,
sparc*-*-solaris2*, sparc64-*-linux*, xtensa*-*-linux*): Set
md_unwind_header.
* configure.ac: Link md-unwind-support.h to $md_unwind_header.
* configure: Regenerate.
From-SVN: r174613
Diffstat (limited to 'gcc/config/alpha')
-rw-r--r-- | gcc/config/alpha/linux-unwind.h | 78 | ||||
-rw-r--r-- | gcc/config/alpha/linux.h | 4 | ||||
-rw-r--r-- | gcc/config/alpha/osf5-unwind.h | 329 | ||||
-rw-r--r-- | gcc/config/alpha/osf5.h | 2 | ||||
-rw-r--r-- | gcc/config/alpha/vms-unwind.h | 293 | ||||
-rw-r--r-- | gcc/config/alpha/vms.h | 8 |
6 files changed, 1 insertions, 713 deletions
diff --git a/gcc/config/alpha/linux-unwind.h b/gcc/config/alpha/linux-unwind.h deleted file mode 100644 index e43aacf..0000000 --- a/gcc/config/alpha/linux-unwind.h +++ /dev/null @@ -1,78 +0,0 @@ -/* DWARF2 EH unwinding support for Alpha Linux. - Copyright (C) 2004, 2005, 2009 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 3, 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. - -Under Section 7 of GPL version 3, you are granted additional -permissions described in the GCC Runtime Library Exception, version -3.1, as published by the Free Software Foundation. - -You should have received a copy of the GNU General Public License and -a copy of the GCC Runtime Library Exception along with this program; -see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -<http://www.gnu.org/licenses/>. */ - -/* 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->regs.cfa_how = CFA_REG_OFFSET; - fs->regs.cfa_reg = 30; - fs->regs.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; -} diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h index a1881c8..38dbdb0 100644 --- a/gcc/config/alpha/linux.h +++ b/gcc/config/alpha/linux.h @@ -1,7 +1,7 @@ /* Definitions of target machine for GNU compiler, for Alpha Linux-based GNU systems. Copyright (C) 1996, 1997, 1998, 2002, 2003, 2004, 2005, 2006, 2007, 2009, - 2010 Free Software Foundation, Inc. + 2010, 2011 Free Software Foundation, Inc. Contributed by Richard Henderson. This file is part of GCC. @@ -84,8 +84,6 @@ along with GCC; see the file COPYING3. If not see #define USE_LD_AS_NEEDED 1 #endif -#define MD_UNWIND_SUPPORT "config/alpha/linux-unwind.h" - /* Define if long doubles should be mangled as 'g'. */ #define TARGET_ALTERNATE_LONG_DOUBLE_MANGLING diff --git a/gcc/config/alpha/osf5-unwind.h b/gcc/config/alpha/osf5-unwind.h deleted file mode 100644 index c649099..0000000 --- a/gcc/config/alpha/osf5-unwind.h +++ /dev/null @@ -1,329 +0,0 @@ -/* DWARF2 EH unwinding support for Alpha Tru64. - Copyright (C) 2010 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 3, 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 COPYING3. If not see -<http://www.gnu.org/licenses/>. */ - -/* This file implements the MD_FALLBACK_FRAME_STATE_FOR macro, triggered when - the GCC table based unwinding process hits a frame for which no unwind info - has been registered. This typically occurs when raising an exception from a - signal handler, because the handler is actually called from the OS kernel. - - The basic idea is to detect that we are indeed trying to unwind past a - signal handler and to fill out the GCC internal unwinding structures for - the OS kernel frame as if it had been directly called from the interrupted - context. - - This is all assuming that the code to set the handler asked the kernel to - pass a pointer to such context information. */ - -/* -------------------------------------------------------------------------- - -- Basic principles of operation: - -------------------------------------------------------------------------- - - 1/ We first need a way to detect if we are trying to unwind past a signal - handler. - - The typical method that is used on most platforms is to look at the code - around the return address we have and check if it matches the OS code - calling a handler. To determine what this code is expected to be, get a - breakpoint into a real signal handler and look at the code around the - return address. Depending on the library versions the pattern of the - signal handler is different; this is the reason why we check against more - than one pattern. - - On this target, the return address is right after the call and every - instruction is 4 bytes long. For the simple case of a null dereference in - a single-threaded app, it went like: - - # Check that we indeed have something we expect: the instruction right - # before the return address is within a __sigtramp function and is a call. - - [... run gdb and break at the signal handler entry ...] - - (gdb) x /i $ra-4 - <__sigtramp+160>: jsr ra,(a3),0x3ff800d0ed4 <_fpdata+36468> - - # Look at the code around that return address, and eventually observe a - # significantly large chunk of *constant* code right before the call: - - (gdb) x /10i $ra-44 - <__sigtramp+120>: lda gp,-27988(gp) - <__sigtramp+124>: ldq at,-18968(gp) - <__sigtramp+128>: lda t0,-1 - <__sigtramp+132>: stq t0,0(at) - <__sigtramp+136>: ldq at,-18960(gp) - <__sigtramp+140>: ldl t1,8(at) - <__sigtramp+144>: ldq at,-18960(gp) - <__sigtramp+148>: stl t1,12(at) - <__sigtramp+152>: ldq at,-18960(gp) - <__sigtramp+156>: stl t0,8(at) - - # The hexadecimal equivalent that we will have to match is: - - (gdb) x /10x $ra-44 - <__sigtramp+120>: 0x23bd92ac 0xa79db5e8 0x203fffff 0xb43c0000 - <__sigtramp+136>: 0xa79db5f0 0xa05c0008 0xa79db5f0 0xb05c000c - <__sigtramp+152>: 0xa79db5f0 0xb03c0008 - - The problem observed on this target with this approach is that although - we found a constant set of instruction patterns there were some - gp-related offsets that made the machine code to differ from one - installation to another. This problem could have been overcome by masking - these offsets, but we found that it would be simpler and more efficient to - check whether the return address was part of a signal handler, by comparing - it against some expected code offset from __sigtramp. - - # Check that we indeed have something we expect: the instruction - # right before the return address is within a __sigtramp - # function and is a call. We also need to obtain the offset - # between the return address and the start address of __sigtramp. - - [... run gdb and break at the signal handler entry ...] - - (gdb) x /2i $ra-4 - <__sigtramp+160>: jsr ra,(a3),0x3ff800d0ed4 <_fpdata+36468> - <__sigtramp+164>: ldah gp,16381(ra) - - (gdb) p (long)$ra - (long)&__sigtramp - $2 = 164 - - -------------------------------------------------------------------------- - - 2/ Once we know we are going through a signal handler, we need a way to - retrieve information about the interrupted run-time context. - - On this platform, the third handler's argument is a pointer to a structure - describing this context (struct sigcontext *). We unfortunately have no - direct way to transfer this value here, so a couple of tricks are required - to compute it. - - As documented at least in some header files (e.g. sys/machine/context.h), - the structure the handler gets a pointer to is located on the stack. As of - today, while writing this macro, we have unfortunately not been able to - find a detailed description of the full stack layout at handler entry time, - so we'll have to resort to empirism :) - - When unwinding here, we have the handler's CFA at hand, as part of the - current unwinding context which is one of our arguments. We presume that - for each call to a signal handler by the same kernel routine, the context's - structure location on the stack is always at the same offset from the - handler's CFA, and we compute that offset from bare observation: - - For the simple case of a bare null dereference in a single-threaded app, - computing the offset was done using GNAT like this: - - # Break on the first handler's instruction, before the prologue to have the - # CFA in $sp, and get there: - - (gdb) b *&__gnat_error_handler - Breakpoint 1 at 0x120016090: file init.c, line 378. - - (gdb) r - Program received signal SIGSEGV, Segmentation fault. - - (gdb) c - Breakpoint 1, __gnat_error_handler (sig=..., sip=..., context=...) - - # The displayed argument value are meaningless because we stopped before - # their final "homing". We know they are passed through $a0, $a1 and $a2 - # from the ABI, though, so ... - - # Observe that $sp and the context pointer are in the same (stack) area, - # and compute the offset: - - (gdb) p /x $sp - $2 = 0x11fffbc80 - - (gdb) p /x $a2 - $3 = 0x11fffbcf8 - - (gdb) p /x (long)$a2 - (long)$sp - $4 = 0x78 - - -------------------------------------------------------------------------- - - 3/ Once we know we are unwinding through a signal handler and have the - address of the structure describing the interrupted context at hand, we - have to fill the internal frame-state/unwind-context structures properly - to allow the unwinding process to proceed. - - Roughly, we are provided with an *unwinding* CONTEXT, describing the state - of some point P in the call chain we are unwinding through. The macro we - implement has to fill a "frame state" structure FS that describe the P's - caller state, by way of *rules* to compute its CFA, return address, and - **saved** registers *locations*. - - For the case we are going to deal with, the caller is some kernel code - calling a signal handler, and: - - o The saved registers are all in the interrupted run-time context, - - o The CFA is the stack pointer value when the kernel code is entered, that - is, the stack pointer value at the interruption point, also part of the - interrupted run-time context. - - o We want the return address to appear as the address of the active - instruction at the interruption point, so that the unwinder proceeds as - if the interruption had been a regular call. This address is also part - of the interrupted run-time context. - - -- - - Also, note that there is an important difference between the return address - we need to claim for the kernel frame and the value of the return address - register at the interruption point. - - The latter might be required to be able to unwind past the interrupted - routine, for instance if it is interrupted before saving the incoming - register value in its own frame, which may typically happen during stack - probes for stack-checking purposes. - - It is then essential that the rules stated to locate the kernel frame - return address don't clobber the rules describing where is saved the return - address register at the interruption point, so some scratch register state - entry should be used for the former. We have DWARF_ALT_FRAME_RETURN_COLUMN - at hand exactly for that purpose. - - -------------------------------------------------------------------------- - - 4/ Depending on the context (single-threaded or multi-threaded app, ...), - the code calling the handler and the handler-cfa to interrupted-context - offset might change, so we use a simple generic data structure to track - the possible variants. */ - -/* This is the structure to wrap information about each possible sighandler - caller we may have to identify. */ - -typedef struct { - /* Expected return address when being called from a sighandler. */ - void *ra_value; - - /* Offset to get to the sigcontext structure from the handler's CFA - when the pattern matches. */ - int cfa_to_context_offset; - -} sighandler_call_t; - -/* Helper macro for MD_FALLBACK_FRAME_STATE_FOR below. - - Look at RA to see if it matches within a sighandler caller. - Set SIGCTX to the corresponding sigcontext structure (computed from - CFA) if it does, or to 0 otherwise. */ - -#define COMPUTE_SIGCONTEXT_FOR(RA,CFA,SIGCTX) \ -do { \ - /* Define and register the applicable patterns. */ \ - extern void __sigtramp (void); \ - \ - sighandler_call_t sighandler_calls [] = { \ - {__sigtramp + 164, 0x78} \ - }; \ - \ - int n_patterns_to_match \ - = sizeof (sighandler_calls) / sizeof (sighandler_call_t); \ - \ - int pn; /* pattern number */ \ - \ - int match = 0; /* Did last pattern match ? */ \ - \ - /* Try to match each pattern in turn. */ \ - for (pn = 0; !match && pn < n_patterns_to_match; pn ++) \ - match = ((RA) == sighandler_calls[pn].ra_value); \ - \ - (SIGCTX) = (struct sigcontext *) \ - (match ? ((CFA) + sighandler_calls[pn - 1].cfa_to_context_offset) : 0); \ -} while (0); - -#include <sys/context_t.h> - -#define REG_SP 30 /* hard reg for stack pointer */ -#define REG_RA 26 /* hard reg for return address */ - -#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) -{ - /* Return address and CFA of the frame we're attempting to unwind through, - possibly a signal handler. */ - void *ctx_ra = (void *)context->ra; - void *ctx_cfa = (void *)context->cfa; - - /* CFA of the intermediate abstract kernel frame between the interrupted - code and the signal handler, if we're indeed unwinding through a signal - handler. */ - void *k_cfa; - - /* Pointer to the sigcontext structure pushed by the kernel when we're - unwinding through a signal handler. */ - struct sigcontext *sigctx; - int i; - - COMPUTE_SIGCONTEXT_FOR (ctx_ra, ctx_cfa, sigctx); - - if (sigctx == 0) - return _URC_END_OF_STACK; - - /* The kernel frame's CFA is exactly the stack pointer value at the - interruption point. */ - k_cfa = (void *) sigctx->sc_regs [REG_SP]; - - /* State the rules to compute the CFA we have the value of: use the - previous CFA and offset by the difference between the two. See - uw_update_context_1 for the supporting details. */ - fs->regs.cfa_how = CFA_REG_OFFSET; - fs->regs.cfa_reg = __builtin_dwarf_sp_column (); - fs->regs.cfa_offset = k_cfa - ctx_cfa; - - /* Fill the internal frame_state structure with information stating - where each register of interest in the saved context can be found - from the CFA. */ - - /* The general registers are in sigctx->sc_regs. Leave out r31, which - is read-as-zero. It makes no sense restoring it, and we are going to - use the state entry for the kernel return address rule below. - - This loop must cover at least all the callee-saved registers, and - we just don't bother specializing the set here. */ - for (i = 0; i <= 30; i ++) - { - fs->regs.reg[i].how = REG_SAVED_OFFSET; - fs->regs.reg[i].loc.offset - = (void *) &sigctx->sc_regs[i] - (void *) k_cfa; - } - - /* Ditto for the floating point registers in sigctx->sc_fpregs. */ - for (i = 0; i <= 31; i ++) - { - fs->regs.reg[32+i].how = REG_SAVED_OFFSET; - fs->regs.reg[32+i].loc.offset - = (void *) &sigctx->sc_fpregs[i] - (void *) k_cfa; - } - - /* State the rules to find the kernel's code "return address", which - is the address of the active instruction when the signal was caught, - in sigctx->sc_pc. Use DWARF_ALT_FRAME_RETURN_COLUMN since the return - address register is a general register and should be left alone. */ - fs->retaddr_column = DWARF_ALT_FRAME_RETURN_COLUMN; - fs->regs.reg[DWARF_ALT_FRAME_RETURN_COLUMN].how = REG_SAVED_OFFSET; - fs->regs.reg[DWARF_ALT_FRAME_RETURN_COLUMN].loc.offset - = (void *) &sigctx->sc_pc - (void *) k_cfa; - fs->signal_frame = 1; - - return _URC_NO_REASON; -} diff --git a/gcc/config/alpha/osf5.h b/gcc/config/alpha/osf5.h index 7713b7e..995f35d 100644 --- a/gcc/config/alpha/osf5.h +++ b/gcc/config/alpha/osf5.h @@ -274,5 +274,3 @@ __enable_execute_stack (void *addr) \ /* Handle #pragma extern_prefix. */ #define TARGET_HANDLE_PRAGMA_EXTERN_PREFIX 1 - -#define MD_UNWIND_SUPPORT "config/alpha/osf5-unwind.h" diff --git a/gcc/config/alpha/vms-unwind.h b/gcc/config/alpha/vms-unwind.h deleted file mode 100644 index 71cb7b8..0000000 --- a/gcc/config/alpha/vms-unwind.h +++ /dev/null @@ -1,293 +0,0 @@ -/* Fallback frame unwinding for Alpha/VMS. - Copyright (C) 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2009, 2010, 2011 - 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 3, 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. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - <http://www.gnu.org/licenses/>. */ - -#include <stdlib.h> -#include <stdio.h> -#include <vms/pdscdef.h> -#include <vms/libicb.h> -#include <vms/chfctxdef.h> -#include <vms/chfdef.h> - -#define MD_FALLBACK_FRAME_STATE_FOR alpha_vms_fallback_frame_state - -typedef void * ADDR; -typedef unsigned long long REG; -typedef PDSCDEF * PV; - -#define REG_AT(addr) (*(REG *)(addr)) -#define ADDR_AT(addr) (*(ADDR *)(addr)) - -/* Compute pointer to procedure descriptor (Procedure Value) from Frame - Pointer FP, according to the rules in [ABI-3.5.1 Current Procedure]. */ -#define PV_FOR(FP) \ - (((FP) != 0) \ - ? (((REG_AT (FP) & 0x7) == 0) ? *(PDSCDEF **)(FP) : (PDSCDEF *)(FP)) : 0) - -extern int SYS$GL_CALL_HANDL; -/* This is actually defined as a "long", but in system code where longs - are always 4bytes while GCC longs might be 8bytes. */ - -#define UPDATE_FS_FOR_CFA_GR(FS, GRN, LOC, CFA) \ -do { \ -(FS)->regs.reg[GRN].how = REG_SAVED_OFFSET; \ -(FS)->regs.reg[GRN].loc.offset = (_Unwind_Sword) ((REG) (LOC) - (REG) (CFA)); \ -} while (0); - -#define GIVEUP_ON_FAILURE(STATUS) \ - { if ((((STATUS) & 1) != 1)) return _URC_END_OF_STACK; } -#define DENOTES_EXC_DISPATCHER(PV) ((PV) == (ADDR) (REG) SYS$GL_CALL_HANDL) - -#define RA_COLUMN (DWARF_ALT_FRAME_RETURN_COLUMN) - -static int -alpha_vms_fallback_frame_state (struct _Unwind_Context *context, - _Unwind_FrameState *fs) -{ - static int eh_debug = -1; - - /* Our goal is to update FS to reflect the state one step up CONTEXT, that - is: the CFA, return address and *saved* registers locations associated - with the function designated by CONTEXT->ra. We are called when the - libgcc unwinder has not found any dwarf FDE for this address, which - typically happens when trying to propagate a language exception through a - signal global vector or frame based handler. - - The CONTEXT->reg[] entries reflect the state/location of register saves - so designate values live at the CONTEXT->ra point. Of precious value to - us here is the frame pointer (r29), which gets us a procedure value. */ - - PV pv = (context->reg[29] != 0) ? PV_FOR (ADDR_AT (context->reg[29])) : 0; - - int pkind = pv ? pv->pdsc$w_flags & 0xf : 0; - /* VMS procedure kind, as indicated by the procedure descriptor. We only - know how to deal with FP_STACK or FP_REGISTER here. */ - - ADDR new_cfa = 0; - /* CFA we will establish for the caller, computed in different ways, - e.g. depending whether we cross an exception dispatcher frame. */ - - CHFCTX *chfctx = 0; - /* Pointer to the VMS CHF context associated with an exception dispatcher - frame, if we happen to come across one. */ - - int i,j; - - if (eh_debug == -1) - { - char * eh_debug_env = getenv ("EH_DEBUG"); - eh_debug = eh_debug_env ? atoi (eh_debug_env) : 0; - } - - if (eh_debug) - printf ("MD_FALLBACK running ...\n"); - - /* We only know how to deal with stack or reg frame procedures, so give - up if we're handed anything else. */ - if (pkind != PDSC$K_KIND_FP_STACK && pkind != PDSC$K_KIND_FP_REGISTER) - return _URC_END_OF_STACK; - - if (eh_debug) - printf ("FALLBACK: CTX FP = 0x%p, PV = 0x%p, EN = 0x%llx, RA = 0x%p\n", - ADDR_AT (context->reg[29]), pv, pv->pdsc$q_entry, context->ra); - - fs->retaddr_column = RA_COLUMN; - - /* If PV designates a VMS exception vector or condition handler, we need to - do as if the caller was the signaling point and estabish the state of the - intermediate VMS code (CFA, RA and saved register locations) as if it was - a single regular function. This requires special processing. - - The datastructures available from an condition dispatcher frame (signal - context) do not contain the values of most callee-saved registers, so - whathever PV designates, we need to account for the registers it saves. - - Besides, we need to express all the locations with respect to a - consistent CFA value, so we compute this first. */ - - if (DENOTES_EXC_DISPATCHER (pv)) - { - /* The CFA to establish is the signaling point's stack pointer. We - compute it using the system invocation context unwinding services and - save the CHF context data pointer along the way for later uses. */ - - INVO_CONTEXT_BLK icb; - int status, invo_handle; - - if (eh_debug) - printf ("FALLBACK: SYS$HANDLER\n"); - - icb.libicb$q_ireg [29] = REG_AT (context->reg[29]); - icb.libicb$q_ireg [30] = 0; - invo_handle = LIB$GET_INVO_HANDLE (&icb); - - status = LIB$GET_INVO_CONTEXT (invo_handle, &icb); - GIVEUP_ON_FAILURE (status); - - chfctx = (CHFCTX *) icb.libicb$ph_chfctx_addr; - - status = LIB$GET_PREV_INVO_CONTEXT (&icb); - GIVEUP_ON_FAILURE (status); - - new_cfa = (ADDR) icb.libicb$q_ireg[30]; - } - else - { - /* The CFA to establish is the SP value on entry of the procedure - designated by PV, which we compute as the corresponding frame base - register value + frame size. Note that the frame base may differ - from CONTEXT->cfa, typically if the caller has performed dynamic - stack allocations. */ - - int base_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30; - ADDR base_addr = ADDR_AT (context->reg[base_reg]); - - new_cfa = base_addr + pv->pdsc$l_size; - } - - /* State to compute the caller's CFA by adding an offset to the current - one in CONTEXT. */ - fs->regs.cfa_how = CFA_REG_OFFSET; - fs->regs.cfa_reg = __builtin_dwarf_sp_column (); - fs->regs.cfa_offset = new_cfa - context->cfa; - - /* Regular unwind first, accounting for the register saves performed by - the procedure designated by PV. */ - - switch (pkind) - { - case PDSC$K_KIND_FP_STACK: - { - /* The saved registers are all located in the Register Save Area, - except for the procedure value register (R27) found at the frame - base address. */ - - int base_reg = pv->pdsc$w_flags & PDSC$M_BASE_REG_IS_FP ? 29 : 30; - ADDR base_addr = ADDR_AT (context->reg[base_reg]); - ADDR rsa_addr = base_addr + pv->pdsc$w_rsa_offset; - - if (eh_debug) - printf ("FALLBACK: STACK frame procedure\n"); - - UPDATE_FS_FOR_CFA_GR (fs, 27, base_addr, new_cfa); - - /* The first RSA entry is for the return address register, R26. */ - - UPDATE_FS_FOR_CFA_GR (fs, 26, rsa_addr, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, RA_COLUMN, rsa_addr, new_cfa); - - /* The following entries are for registers marked as saved according - to ireg_mask. */ - for (i = 0, j = 0; i < 32; i++) - if ((1 << i) & pv->pdsc$l_ireg_mask) - UPDATE_FS_FOR_CFA_GR (fs, i, rsa_addr + 8 * ++j, new_cfa); - - /* ??? floating point registers ? */ - - break; - } - - case PDSC$K_KIND_FP_REGISTER: - { - if (eh_debug) - printf ("FALLBACK: REGISTER frame procedure\n"); - - fs->regs.reg[RA_COLUMN].how = REG_SAVED_REG; - fs->regs.reg[RA_COLUMN].loc.reg = pv->pdsc$b_save_ra; - - fs->regs.reg[29].how = REG_SAVED_REG; - fs->regs.reg[29].loc.reg = pv->pdsc$b_save_fp; - - break; - } - - default: - /* Should never reach here. */ - return _URC_END_OF_STACK; - } - - /* If PV designates an exception dispatcher, we have to adjust the return - address column to get at the signal occurrence point, and account for - what the CHF context contains. */ - - if (DENOTES_EXC_DISPATCHER (pv)) - { - /* The PC of the instruction causing the condition is available from the - signal argument vector. Extra saved register values are available - from the mechargs array. */ - - CHF$SIGNAL_ARRAY *sigargs - = (CHF$SIGNAL_ARRAY *) chfctx->chfctx$q_sigarglst; - - CHF$MECH_ARRAY *mechargs - = (CHF$MECH_ARRAY *) chfctx->chfctx$q_mcharglst; - - ADDR condpc_addr - = &((int *)(&sigargs->chf$l_sig_name)) [sigargs->chf$is_sig_args-2]; - - ADDR rei_frame_addr = (void *) mechargs->chf$q_mch_esf_addr; - - /* Adjust the return address location. */ - - UPDATE_FS_FOR_CFA_GR (fs, RA_COLUMN, condpc_addr, new_cfa); - - /* The frame pointer at the condition point is available from the - chf context directly. */ - - UPDATE_FS_FOR_CFA_GR (fs, 29, &chfctx->chfctx$q_expt_fp, new_cfa); - - /* Registers available from the mechargs array. */ - - UPDATE_FS_FOR_CFA_GR (fs, 0, &mechargs->chf$q_mch_savr0, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 1, &mechargs->chf$q_mch_savr1, new_cfa); - - UPDATE_FS_FOR_CFA_GR (fs, 16, &mechargs->chf$q_mch_savr16, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 17, &mechargs->chf$q_mch_savr17, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 18, &mechargs->chf$q_mch_savr18, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 19, &mechargs->chf$q_mch_savr19, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 20, &mechargs->chf$q_mch_savr20, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 21, &mechargs->chf$q_mch_savr21, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 22, &mechargs->chf$q_mch_savr22, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 23, &mechargs->chf$q_mch_savr23, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 24, &mechargs->chf$q_mch_savr24, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 25, &mechargs->chf$q_mch_savr25, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 26, &mechargs->chf$q_mch_savr26, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 27, &mechargs->chf$q_mch_savr27, new_cfa); - UPDATE_FS_FOR_CFA_GR (fs, 28, &mechargs->chf$q_mch_savr28, new_cfa); - - /* Registers R2 to R7 are available from the rei frame pointer. */ - - for (i = 2; i <= 7; i ++) - UPDATE_FS_FOR_CFA_GR (fs, i, rei_frame_addr+(i - 2)*8, new_cfa); - - /* ??? floating point registers ? */ - } - - fs->signal_frame = 1; - - return _URC_NO_REASON; -} - - - diff --git a/gcc/config/alpha/vms.h b/gcc/config/alpha/vms.h index 8e93103..f730ea1 100644 --- a/gcc/config/alpha/vms.h +++ b/gcc/config/alpha/vms.h @@ -225,14 +225,6 @@ typedef struct {int num_args; enum avms_arg_type atypes[6];} avms_arg_info; #define LINK_EH_SPEC "vms-dwarf2eh.o%s " #define LINK_GCC_C_SEQUENCE_SPEC "%G" -#ifdef IN_LIBGCC2 -/* Get the definition for MD_FALLBACK_FRAME_STATE_FOR from a separate - file. This avoids having to recompile the world instead of libgcc only - when changes to this macro are exercised. */ - -#define MD_UNWIND_SUPPORT "config/alpha/vms-unwind.h" -#endif - #define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \ avms_asm_output_external (FILE, DECL, NAME) |