summaryrefslogtreecommitdiff
path: root/libgcc/config/s390/tpf-unwind.h
diff options
context:
space:
mode:
authorRainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>2011-06-03 18:30:39 +0000
committerRainer Orth <ro@gcc.gnu.org>2011-06-03 18:30:39 +0000
commit58cd1d70dd8cd4b95773c0487a5d2aecad2b4dc1 (patch)
treef430fed8dbe1ebf2c96bc2f167ea68cb1e504948 /libgcc/config/s390/tpf-unwind.h
parent34e0c8d5fe61e28903fd89685e091a9654015dbf (diff)
downloadgcc-58cd1d70dd8cd4b95773c0487a5d2aecad2b4dc1.tar.gz
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 'libgcc/config/s390/tpf-unwind.h')
-rw-r--r--libgcc/config/s390/tpf-unwind.h252
1 files changed, 252 insertions, 0 deletions
diff --git a/libgcc/config/s390/tpf-unwind.h b/libgcc/config/s390/tpf-unwind.h
new file mode 100644
index 00000000000..33fd5f5c8c5
--- /dev/null
+++ b/libgcc/config/s390/tpf-unwind.h
@@ -0,0 +1,252 @@
+/* DWARF2 EH unwinding support for TPF OS.
+ Copyright (C) 2004, 2005, 2009 Free Software Foundation, Inc.
+ Contributed by P.J. Darcy (darcypj@us.ibm.com).
+
+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 <dlfcn.h>
+
+/* Function Name: __isPATrange
+ Parameters passed into it: address to check
+ Return Value: A 1 if address is in pat code "range", 0 if not
+ Description: This function simply checks to see if the address
+ passed to it is in the CP pat code range. */
+
+#define MIN_PATRANGE 0x10000
+#define MAX_PATRANGE 0x800000
+
+static inline unsigned int
+__isPATrange (void *addr)
+{
+ if (addr > (void *)MIN_PATRANGE && addr < (void *)MAX_PATRANGE)
+ return 1;
+ else
+ return 0;
+}
+
+/* TPF return address offset from start of stack frame. */
+#define TPFRA_OFFSET 168
+
+/* Exceptions macro defined for TPF so that functions without
+ dwarf frame information can be used with exceptions. */
+#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 long int regs;
+ unsigned long int new_cfa;
+ int i;
+
+ regs = *((unsigned long int *)
+ (((unsigned long int) context->cfa) - STACK_POINTER_OFFSET));
+
+ /* Are we going through special linkage code? */
+ if (__isPATrange (context->ra))
+ {
+
+ /* Our return register isn't zero for end of stack, so
+ check backward stackpointer to see if it is zero. */
+ if (regs == NULL)
+ return _URC_END_OF_STACK;
+
+ /* No stack frame. */
+ fs->regs.cfa_how = CFA_REG_OFFSET;
+ fs->regs.cfa_reg = 15;
+ fs->regs.cfa_offset = STACK_POINTER_OFFSET;
+
+ /* All registers remain unchanged ... */
+ for (i = 0; i < 32; i++)
+ {
+ fs->regs.reg[i].how = REG_SAVED_REG;
+ fs->regs.reg[i].loc.reg = i;
+ }
+
+ /* ... except for %r14, which is stored at CFA-112
+ and used as return address. */
+ fs->regs.reg[14].how = REG_SAVED_OFFSET;
+ fs->regs.reg[14].loc.offset = TPFRA_OFFSET - STACK_POINTER_OFFSET;
+ fs->retaddr_column = 14;
+
+ return _URC_NO_REASON;
+ }
+
+ regs = *((unsigned long int *)
+ (((unsigned long int) context->cfa) - STACK_POINTER_OFFSET));
+ new_cfa = regs + STACK_POINTER_OFFSET;
+
+ fs->regs.cfa_how = CFA_REG_OFFSET;
+ fs->regs.cfa_reg = 15;
+ fs->regs.cfa_offset = new_cfa -
+ (unsigned long int) context->cfa + STACK_POINTER_OFFSET;
+
+ for (i = 0; i < 16; i++)
+ {
+ fs->regs.reg[i].how = REG_SAVED_OFFSET;
+ fs->regs.reg[i].loc.offset = regs + i*8 - new_cfa;
+ }
+
+ for (i = 0; i < 4; i++)
+ {
+ fs->regs.reg[16 + i].how = REG_SAVED_OFFSET;
+ fs->regs.reg[16 + i].loc.offset = regs + 16*8 + i*8 - new_cfa;
+ }
+
+ fs->retaddr_column = 14;
+
+ return _URC_NO_REASON;
+}
+
+/* Function Name: __tpf_eh_return
+ Parameters passed into it: Destination address to jump to.
+ Return Value: Converted Destination address if a Pat Stub exists.
+ Description: This function swaps the unwinding return address
+ with the cp stub code. The original target return address is
+ then stored into the tpf return address field. The cp stub
+ code is searched for by climbing back up the stack and
+ comparing the tpf stored return address object address to
+ that of the targets object address. */
+
+#define CURRENT_STACK_PTR() \
+ ({ register unsigned long int *stack_ptr asm ("%r15"); stack_ptr; })
+
+#define PREVIOUS_STACK_PTR() \
+ ((unsigned long int *)(*(CURRENT_STACK_PTR())))
+
+#define RA_OFFSET 112
+#define R15_OFFSET 120
+#define TPFAREA_OFFSET 160
+#define TPFAREA_SIZE STACK_POINTER_OFFSET-TPFAREA_OFFSET
+#define INVALID_RETURN 0
+
+void * __tpf_eh_return (void *target);
+
+void *
+__tpf_eh_return (void *target)
+{
+ Dl_info targetcodeInfo, currentcodeInfo;
+ int retval;
+ void *current, *stackptr, *destination_frame;
+ unsigned long int shifter, is_a_stub;
+
+ is_a_stub = 0;
+
+ /* Get code info for target return's address. */
+ retval = dladdr (target, &targetcodeInfo);
+
+ /* Ensure the code info is valid (for target). */
+ if (retval != INVALID_RETURN)
+ {
+
+ /* Get the stack pointer of the stack frame to be modified by
+ the exception unwinder. So that we can begin our climb
+ there. */
+ stackptr = (void *) *((unsigned long int *) (*(PREVIOUS_STACK_PTR())));
+
+ /* Begin looping through stack frames. Stop if invalid
+ code information is retrieved or if a match between the
+ current stack frame iteration shared object's address
+ matches that of the target, calculated above. */
+ do
+ {
+ /* Get return address based on our stackptr iterator. */
+ current = (void *) *((unsigned long int *)
+ (stackptr+RA_OFFSET));
+
+ /* Is it a Pat Stub? */
+ if (__isPATrange (current))
+ {
+ /* Yes it was, get real return address
+ in TPF stack area. */
+ current = (void *) *((unsigned long int *)
+ (stackptr+TPFRA_OFFSET));
+ is_a_stub = 1;
+ }
+
+ /* Get codeinfo on RA so that we can figure out
+ the module address. */
+ retval = dladdr (current, &currentcodeInfo);
+
+ /* Check that codeinfo for current stack frame is valid.
+ Then compare the module address of current stack frame
+ to target stack frame to determine if we have the pat
+ stub address we want. Also ensure we are dealing
+ with a module crossing, stub return address. */
+ if (is_a_stub && retval != INVALID_RETURN
+ && targetcodeInfo.dli_fbase == currentcodeInfo.dli_fbase)
+ {
+ /* Yes! They are in the same module.
+ Force copy of TPF private stack area to
+ destination stack frame TPF private area. */
+ destination_frame = (void *) *((unsigned long int *)
+ (*PREVIOUS_STACK_PTR() + R15_OFFSET));
+
+ /* Copy TPF linkage area from current frame to
+ destination frame. */
+ memcpy((void *) (destination_frame + TPFAREA_OFFSET),
+ (void *) (stackptr + TPFAREA_OFFSET), TPFAREA_SIZE);
+
+ /* Now overlay the
+ real target address into the TPF stack area of
+ the target frame we are jumping to. */
+ *((unsigned long int *) (destination_frame +
+ TPFRA_OFFSET)) = (unsigned long int) target;
+
+ /* Before returning the desired pat stub address to
+ the exception handling unwinder so that it can
+ actually do the "leap" shift out the low order
+ bit designated to determine if we are in 64BIT mode.
+ This is necessary for CTOA stubs.
+ Otherwise we leap one byte past where we want to
+ go to in the TPF pat stub linkage code. */
+ shifter = *((unsigned long int *)
+ (stackptr + RA_OFFSET));
+
+ shifter &= ~1ul;
+
+ /* Store Pat Stub Address in destination Stack Frame. */
+ *((unsigned long int *) (destination_frame +
+ RA_OFFSET)) = shifter;
+
+ /* Re-adjust pat stub address to go to correct place
+ in linkage. */
+ shifter = shifter - 4;
+
+ return (void *) shifter;
+ }
+
+ /* Desired module pat stub not found ...
+ Bump stack frame iterator. */
+ stackptr = (void *) *(unsigned long int *) stackptr;
+
+ is_a_stub = 0;
+
+ } while (stackptr && retval != INVALID_RETURN
+ && targetcodeInfo.dli_fbase != currentcodeInfo.dli_fbase);
+ }
+
+ /* No pat stub found, could be a problem? Simply return unmodified
+ target address. */
+ return target;
+}
+