diff options
author | Rainer Orth <ro@gcc.gnu.org> | 2011-08-05 14:37:48 +0000 |
---|---|---|
committer | Rainer Orth <ro@gcc.gnu.org> | 2011-08-05 14:37:48 +0000 |
commit | 201cdb743879cbffd38c53d8ebf85fa9fff1e0e4 (patch) | |
tree | 80376027cf518687afe9d3c715d908e42d42c267 /gcc/config | |
parent | d50f4827c7062e3247baf493e646c365114c28cd (diff) | |
download | gcc-201cdb743879cbffd38c53d8ebf85fa9fff1e0e4.zip gcc-201cdb743879cbffd38c53d8ebf85fa9fff1e0e4.tar.gz gcc-201cdb743879cbffd38c53d8ebf85fa9fff1e0e4.tar.bz2 |
Makefile.in (UNWIND_H): Remove.
gcc:
* Makefile.in (UNWIND_H): Remove.
(LIB2ADDEH, LIB2ADDEHSTATIC, LIB2ADDEHSHARED): Move to
../libgcc/Makefile.in.
(LIBUNWIND, SHLIBUNWIND_LINK, SHLIBUNWIND_INSTALL): Likewise.
(LIBUNWINDDEP): Remove.
(libgcc-support): Remove LIB2ADDEH, $(srcdir)/emutls.c dependencies.
(libgcc.mvars): Remove LIB2ADDEH, LIB2ADDEHSTATIC, LIB2ADDEHSHARED,
LIBUNWIND, SHLIBUNWIND_LINK, SHLIBUNWIND_INSTALL.
(stmp-int-hdrs): Remove $(UNWIND_H) dependency.
Don't copy $(UNWIND_H).
* config.gcc (ia64*-*-linux*): Remove with_system_libunwind
handling.
* configure.ac (GCC_CHECK_UNWIND_GETIPINFO): Remove.
* aclocal.m4: Regenerate.
* configure: Regenerate.
* emutls.c, unwind-c.c, unwind-compat.c, unwind-compat.h,
unwind-dw2-fde-compat.c, unwind-dw2-fde-glibc.c, unwind-dw2-fde.c,
unwind-dw2-fde.h, unwind-dw2.c, unwind-dw2.h, unwind-generic.h,
unwind-pe.h, unwind-sjlj.c, unwind.inc: Move to ../libgcc.
* unwind-dw2-fde-darwin.c: Move to ../libgcc/config.
* config/arm/libunwind.S, config/arm/pr-support.c,
config/arm/unwind-arm.c, config/arm/unwind-arm.h: Move to
../libgcc/config/arm.
* config/arm/t-bpabi (UNWIND_H, LIB2ADDEH): Remove.
* config/arm/t-symbian (UNWIND_H, LIB2ADDEH): Remove.
* config/frv/t-frv ($(T)frvbegin$(objext)): Use
$(srcdir)/../libgcc to refer to unwind-dw2-fde.h.
($(T)frvend$(objext)): Likewise.
* config/ia64/t-glibc (LIB2ADDEH): Remove.
* config/ia64/t-glibc-libunwind: Move to ../libgcc/config/ia64.
* config/ia64/fde-glibc.c, config/ia64/fde-vms.c,
config/ia64/unwind-ia64.c, config/ia64/unwind-ia64.h: Move to
../libgcc/config/ia64.
* config/ia64/t-hpux (LIB2ADDEH): Remove.
* config/ia64/t-ia64 (LIB2ADDEH): Remove.
* config/ia64/t-vms (LIB2ADDEH): Remove.
* config/ia64/vms.h (UNW_IVMS_MODE,
MD_UNW_COMPATIBLE_PERSONALITY_P): Remove.
* config/picochip/t-picochip (LIB2ADDEH): Remove.
* config/rs6000/aix.h (R_LR, MD_FROB_UPDATE_CONTEXT): Remove.
* config/rs6000/t-darwin (LIB2ADDEH): Remove.
* config/rs6000/darwin-fallback.c: Move to ../libgcc/config/rs6000.
* config/sh/t-sh ($(T)unwind-dw2-Os-4-200.o): Use
$(srcdir)/../libgcc to refer to unwinder sources.
* config/spu/t-spu-elf (LIB2ADDEH): Remove.
* config/t-darwin (LIB2ADDEH): Remove.
* config/t-freebsd (LIB2ADDEH): Remove.
* config/t-libunwind (LIB2ADDEH, LIB2ADDEHSTATIC): Remove.
* config/t-libunwind-elf: Move to ../libgcc/config.
* config/t-linux (LIB2ADDEH): Remove.
* config/t-sol2 (LIB2ADDEH): Remove.
* config/xtensa/t-xtensa (LIB2ADDEH): Remove.
* system.h (MD_FROB_UPDATE_CONTEXT): Poison.
gcc/po:
* EXCLUDES (unwind-c.c, unwind-dw2-fde-darwin.c)
(unwind-dw2-fde-glibc.c, unwind-dw2-fde.c, unwind-dw2-fde.h)
(unwind-dw2.c, unwind-pe.h, unwind-sjlj.c, unwind.h): Remove.
libgcc:
* Makefile.in (LIB2ADDEH, LIB2ADDEHSTATIC, LIB2ADDEHSHARED): New
variables.
(LIBUNWIND, SHLIBUNWIND_LINK, SHLIBUNWIND_INSTALL): New variables.
(LIB2ADDEH, LIB2ADDEHSTATIC, LIB2ADDEHSHARED): Add $(srcdir)/emutls.c.
(install-unwind_h): New target.
(all): Depend on it.
* config.host (unwind_header): New variable.
(*-*-freebsd*): Set tmake_file to t-eh-dw2-dip.
(*-*-linux*, frv-*-*linux*, *-*-kfreebsd*-gnu, *-*-knetbsd*-gnu,
*-*-gnu*): Likewise, also for *-*-kopensolaris*-gnu.
(*-*-solaris2*): Add t-eh-dw2-dip to tmake_file.
(arm*-*-linux*): Add arm/t-bpabi for arm*-*-linux-*eabi.
Set unwind_header.
(arm*-*-uclinux*): Add arm/t-bpabi for arm*-*-uclinux*eabi.
Set unwind_header.
(arm*-*-eabi*, arm*-*-symbianelf*): Add arm/t-bpabi for
arm*-*-eabi*.
Add arm/t-symbian to tmake_file for arm*-*-symbianelf*.
Set unwind_header.
(ia64*-*-elf*): Add ia64/t-eh-ia64 to tmake_file.
(ia64*-*-freebsd*): Likewise.
(ia64*-*-linux*): Add ia64/t-glibc, ia64/t-eh-ia64, t-libunwind to
tmake_file.
Add t-libunwind-elf, ia64/t-glibc-libunwind unless
$with_system_libunwind.
(ia64*-*-hpux*): Set tmake_file.
(ia64-hp-*vms*): Add ia64/t-eh-ia64 to tmake_file.
(picochip-*-*): Set tmake_file.
(rs6000-ibm-aix4.[3456789]*, powerpc-ibm-aix4.[3456789]*): Set
md_unwind_header.
(rs6000-ibm-aix5.1.*, powerpc-ibm-aix5.1.*): Likewise.
(rs6000-ibm-aix[56789].*, powerpc-ibm-aix[56789].*): Likewise.
(s390x-ibm-tpf*): Add t-eh-dw2-dip to tmake_file.
(xtensa*-*-elf*): Set tmake_file.
(xtensa*-*-linux*): Likewise.
* configure.ac: Include ../config/unwind_ipinfo.m4.
Call GCC_CHECK_UNWIND_GETIPINFO.
Link unwind.h to $unwind_header.
* configure: Regenerate.
* emutls.c, unwind-c.c, unwind-compat.c, unwind-compat.h,
unwind-dw2-fde-compat.c, unwind-dw2-fde-dip.c, unwind-dw2-fde.c,
unwind-dw2-fde.h, unwind-dw2.c, unwind-dw2.h, unwind-generic.h,
unwind-pe.h, unwind-sjlj.c, unwind.inc: New files.
* config/unwind-dw2-fde-darwin.c: New file.
* config/arm/libunwind.S, config/arm/pr-support.c,
config/arm/t-bpabi, config/arm/t-symbian, config/arm/unwind-arm.c,
config/arm/unwind-arm.h,: New files.
* config/ia64/fde-glibc.c, config/ia64/fde-vms.c,
config/ia64/t-eh-ia64, config/ia64/t-glibc,
config/ia64/t-glibc-libunwind, config/ia64/t-hpux,
config/ia64/t-vms, config/ia64/unwind-ia64.c,
config/ia64/unwind-ia64.h: New files.
* config/picochip/t-picochip: New file.
* config/rs6000/aix-unwind.h, config/rs6000/darwin-fallback.c: New
files.
* config/rs6000/t-darwin (LIB2ADDEH): Set.
* config/s390/t-tpf (LIB2ADDEH): Remove.
* config/t-darwin (LIB2ADDEH): Set.
* config/t-eh-dw2-dip: New file.
* config/t-libunwind, config/t-libunwind-elf: New files.
* config/t-sol2 (LIB2ADDEH): Remove.
* config/xtensa/t-xtensa: New file.
gcc/ada:
* gcc-interface/Makefile.in (raise-gcc.o): Search
$(srcdir)/../libgcc.
libgo:
* Makefile.am (AM_CFLAGS): Search $(srcdir)/../libgcc.
* Makefile.in: Regenerate.
libjava:
* configure.ac (GCC_UNWIND_INCLUDE): Rename to
LIBGCC_UNWIND_INCLUDE.
Point to $(multi_basedir)/./libjava/../libgcc.
* configure: Regenerate.
* Makefile.am (GCC_UNWIND_INCLUDE): Reflect this.
* Makefile.in: Regenerate.
libobjc:
* Makefile.in (INCLUDES): Search
$(srcdir)/$(MULTISRCTOP)../libgcc.
libstdc++-v3:
* acinclude.m4 (GLIBCXX_EXPORT_INCLUDES): Point TOPLEVEL_INCLUDES
to $(toplevel_srcdir)/libgcc.
* configure: Regenerate.
From-SVN: r177447
Diffstat (limited to 'gcc/config')
32 files changed, 10 insertions, 6378 deletions
diff --git a/gcc/config/arm/libunwind.S b/gcc/config/arm/libunwind.S deleted file mode 100644 index 48eb592..0000000 --- a/gcc/config/arm/libunwind.S +++ /dev/null @@ -1,363 +0,0 @@ -/* Support functions for the unwinder. - Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. - Contributed by Paul Brook - - This file 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. - - This file 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/>. */ - -/* An executable stack is *not* required for these functions. */ -#if defined(__ELF__) && defined(__linux__) -.section .note.GNU-stack,"",%progbits -.previous -#endif - -#ifdef __ARM_EABI__ -/* Some attributes that are common to all routines in this file. */ - /* Tag_ABI_align_needed: This code does not require 8-byte - alignment from the caller. */ - /* .eabi_attribute 24, 0 -- default setting. */ - /* Tag_ABI_align_preserved: This code preserves 8-byte - alignment in any callee. */ - .eabi_attribute 25, 1 -#endif /* __ARM_EABI__ */ - -#ifndef __symbian__ - -#include "lib1funcs.asm" - -.macro UNPREFIX name - .global SYM (\name) - EQUIV SYM (\name), SYM (__\name) -.endm - -#if (__ARM_ARCH__ == 4) -/* Some coprocessors require armv5. We know this code will never be run on - other cpus. Tell gas to allow armv5, but only mark the objects as armv4. - */ -.arch armv5t -#ifdef __ARM_ARCH_4T__ -.object_arch armv4t -#else -.object_arch armv4 -#endif -#endif - -#ifdef __ARM_ARCH_6M__ - -/* r0 points to a 16-word block. Upload these values to the actual core - state. */ -FUNC_START restore_core_regs - mov r1, r0 - add r1, r1, #52 - ldmia r1!, {r3, r4, r5} - sub r3, r3, #4 - mov ip, r3 - str r5, [r3] - mov lr, r4 - /* Restore r8-r11. */ - mov r1, r0 - add r1, r1, #32 - ldmia r1!, {r2, r3, r4, r5} - mov r8, r2 - mov r9, r3 - mov sl, r4 - mov fp, r5 - mov r1, r0 - add r1, r1, #8 - ldmia r1!, {r2, r3, r4, r5, r6, r7} - ldr r1, [r0, #4] - ldr r0, [r0] - mov sp, ip - pop {pc} - FUNC_END restore_core_regs - UNPREFIX restore_core_regs - -/* ARMV6M does not have coprocessors, so these should never be used. */ -FUNC_START gnu_Unwind_Restore_VFP - RET - -/* Store VFR regsters d0-d15 to the address in r0. */ -FUNC_START gnu_Unwind_Save_VFP - RET - -/* Load VFP registers d0-d15 from the address in r0. - Use this to load from FSTMD format. */ -FUNC_START gnu_Unwind_Restore_VFP_D - RET - -/* Store VFP registers d0-d15 to the address in r0. - Use this to store in FLDMD format. */ -FUNC_START gnu_Unwind_Save_VFP_D - RET - -/* Load VFP registers d16-d31 from the address in r0. - Use this to load from FSTMD (=VSTM) format. Needs VFPv3. */ -FUNC_START gnu_Unwind_Restore_VFP_D_16_to_31 - RET - -/* Store VFP registers d16-d31 to the address in r0. - Use this to store in FLDMD (=VLDM) format. Needs VFPv3. */ -FUNC_START gnu_Unwind_Save_VFP_D_16_to_31 - RET - -FUNC_START gnu_Unwind_Restore_WMMXD - RET - -FUNC_START gnu_Unwind_Save_WMMXD - RET - -FUNC_START gnu_Unwind_Restore_WMMXC - RET - -FUNC_START gnu_Unwind_Save_WMMXC - RET - -.macro UNWIND_WRAPPER name nargs - FUNC_START \name - /* Create a phase2_vrs structure. */ - /* Save r0 in the PC slot so we can use it as a scratch register. */ - push {r0} - add r0, sp, #4 - push {r0, lr} /* Push original SP and LR. */ - /* Make space for r8-r12. */ - sub sp, sp, #20 - /* Save low registers. */ - push {r0, r1, r2, r3, r4, r5, r6, r7} - /* Save high registers. */ - add r0, sp, #32 - mov r1, r8 - mov r2, r9 - mov r3, sl - mov r4, fp - mov r5, ip - stmia r0!, {r1, r2, r3, r4, r5} - /* Restore original low register values. */ - add r0, sp, #4 - ldmia r0!, {r1, r2, r3, r4, r5} - /* Restore orginial r0. */ - ldr r0, [sp, #60] - str r0, [sp] - /* Demand-save flags, plus an extra word for alignment. */ - mov r3, #0 - push {r2, r3} - /* Point r1 at the block. Pass r[0..nargs) unchanged. */ - add r\nargs, sp, #4 - - bl SYM (__gnu\name) - - ldr r3, [sp, #64] - add sp, sp, #72 - bx r3 - - FUNC_END \name - UNPREFIX \name -.endm - -#else /* !__ARM_ARCH_6M__ */ - -/* r0 points to a 16-word block. Upload these values to the actual core - state. */ -ARM_FUNC_START restore_core_regs - /* We must use sp as the base register when restoring sp. Push the - last 3 registers onto the top of the current stack to achieve - this. */ - add r1, r0, #52 - ldmia r1, {r3, r4, r5} /* {sp, lr, pc}. */ -#if defined(__thumb2__) - /* Thumb-2 doesn't allow sp in a load-multiple instruction, so push - the target address onto the target stack. This is safe as - we're always returning to somewhere further up the call stack. */ - mov ip, r3 - mov lr, r4 - str r5, [ip, #-4]! -#elif defined(__INTERWORKING__) - /* Restore pc into ip. */ - mov r2, r5 - stmfd sp!, {r2, r3, r4} -#else - stmfd sp!, {r3, r4, r5} -#endif - /* Don't bother restoring ip. */ - ldmia r0, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp} -#if defined(__thumb2__) - /* Pop the return address off the target stack. */ - mov sp, ip - pop {pc} -#elif defined(__INTERWORKING__) - /* Pop the three registers we pushed earlier. */ - ldmfd sp, {ip, sp, lr} - bx ip -#else - ldmfd sp, {sp, lr, pc} -#endif - FUNC_END restore_core_regs - UNPREFIX restore_core_regs - -/* Load VFP registers d0-d15 from the address in r0. - Use this to load from FSTMX format. */ -ARM_FUNC_START gnu_Unwind_Restore_VFP - /* Use the generic coprocessor form so that gas doesn't complain - on soft-float targets. */ - ldc p11,cr0,[r0],{0x21} /* fldmiax r0, {d0-d15} */ - RET - -/* Store VFP registers d0-d15 to the address in r0. - Use this to store in FSTMX format. */ -ARM_FUNC_START gnu_Unwind_Save_VFP - /* Use the generic coprocessor form so that gas doesn't complain - on soft-float targets. */ - stc p11,cr0,[r0],{0x21} /* fstmiax r0, {d0-d15} */ - RET - -/* Load VFP registers d0-d15 from the address in r0. - Use this to load from FSTMD format. */ -ARM_FUNC_START gnu_Unwind_Restore_VFP_D - ldc p11,cr0,[r0],{0x20} /* fldmiad r0, {d0-d15} */ - RET - -/* Store VFP registers d0-d15 to the address in r0. - Use this to store in FLDMD format. */ -ARM_FUNC_START gnu_Unwind_Save_VFP_D - stc p11,cr0,[r0],{0x20} /* fstmiad r0, {d0-d15} */ - RET - -/* Load VFP registers d16-d31 from the address in r0. - Use this to load from FSTMD (=VSTM) format. Needs VFPv3. */ -ARM_FUNC_START gnu_Unwind_Restore_VFP_D_16_to_31 - ldcl p11,cr0,[r0],{0x20} /* vldm r0, {d16-d31} */ - RET - -/* Store VFP registers d16-d31 to the address in r0. - Use this to store in FLDMD (=VLDM) format. Needs VFPv3. */ -ARM_FUNC_START gnu_Unwind_Save_VFP_D_16_to_31 - stcl p11,cr0,[r0],{0x20} /* vstm r0, {d16-d31} */ - RET - -ARM_FUNC_START gnu_Unwind_Restore_WMMXD - /* Use the generic coprocessor form so that gas doesn't complain - on non-iWMMXt targets. */ - ldcl p1, cr0, [r0], #8 /* wldrd wr0, [r0], #8 */ - ldcl p1, cr1, [r0], #8 /* wldrd wr1, [r0], #8 */ - ldcl p1, cr2, [r0], #8 /* wldrd wr2, [r0], #8 */ - ldcl p1, cr3, [r0], #8 /* wldrd wr3, [r0], #8 */ - ldcl p1, cr4, [r0], #8 /* wldrd wr4, [r0], #8 */ - ldcl p1, cr5, [r0], #8 /* wldrd wr5, [r0], #8 */ - ldcl p1, cr6, [r0], #8 /* wldrd wr6, [r0], #8 */ - ldcl p1, cr7, [r0], #8 /* wldrd wr7, [r0], #8 */ - ldcl p1, cr8, [r0], #8 /* wldrd wr8, [r0], #8 */ - ldcl p1, cr9, [r0], #8 /* wldrd wr9, [r0], #8 */ - ldcl p1, cr10, [r0], #8 /* wldrd wr10, [r0], #8 */ - ldcl p1, cr11, [r0], #8 /* wldrd wr11, [r0], #8 */ - ldcl p1, cr12, [r0], #8 /* wldrd wr12, [r0], #8 */ - ldcl p1, cr13, [r0], #8 /* wldrd wr13, [r0], #8 */ - ldcl p1, cr14, [r0], #8 /* wldrd wr14, [r0], #8 */ - ldcl p1, cr15, [r0], #8 /* wldrd wr15, [r0], #8 */ - RET - -ARM_FUNC_START gnu_Unwind_Save_WMMXD - /* Use the generic coprocessor form so that gas doesn't complain - on non-iWMMXt targets. */ - stcl p1, cr0, [r0], #8 /* wstrd wr0, [r0], #8 */ - stcl p1, cr1, [r0], #8 /* wstrd wr1, [r0], #8 */ - stcl p1, cr2, [r0], #8 /* wstrd wr2, [r0], #8 */ - stcl p1, cr3, [r0], #8 /* wstrd wr3, [r0], #8 */ - stcl p1, cr4, [r0], #8 /* wstrd wr4, [r0], #8 */ - stcl p1, cr5, [r0], #8 /* wstrd wr5, [r0], #8 */ - stcl p1, cr6, [r0], #8 /* wstrd wr6, [r0], #8 */ - stcl p1, cr7, [r0], #8 /* wstrd wr7, [r0], #8 */ - stcl p1, cr8, [r0], #8 /* wstrd wr8, [r0], #8 */ - stcl p1, cr9, [r0], #8 /* wstrd wr9, [r0], #8 */ - stcl p1, cr10, [r0], #8 /* wstrd wr10, [r0], #8 */ - stcl p1, cr11, [r0], #8 /* wstrd wr11, [r0], #8 */ - stcl p1, cr12, [r0], #8 /* wstrd wr12, [r0], #8 */ - stcl p1, cr13, [r0], #8 /* wstrd wr13, [r0], #8 */ - stcl p1, cr14, [r0], #8 /* wstrd wr14, [r0], #8 */ - stcl p1, cr15, [r0], #8 /* wstrd wr15, [r0], #8 */ - RET - -ARM_FUNC_START gnu_Unwind_Restore_WMMXC - /* Use the generic coprocessor form so that gas doesn't complain - on non-iWMMXt targets. */ - ldc2 p1, cr8, [r0], #4 /* wldrw wcgr0, [r0], #4 */ - ldc2 p1, cr9, [r0], #4 /* wldrw wcgr1, [r0], #4 */ - ldc2 p1, cr10, [r0], #4 /* wldrw wcgr2, [r0], #4 */ - ldc2 p1, cr11, [r0], #4 /* wldrw wcgr3, [r0], #4 */ - RET - -ARM_FUNC_START gnu_Unwind_Save_WMMXC - /* Use the generic coprocessor form so that gas doesn't complain - on non-iWMMXt targets. */ - stc2 p1, cr8, [r0], #4 /* wstrw wcgr0, [r0], #4 */ - stc2 p1, cr9, [r0], #4 /* wstrw wcgr1, [r0], #4 */ - stc2 p1, cr10, [r0], #4 /* wstrw wcgr2, [r0], #4 */ - stc2 p1, cr11, [r0], #4 /* wstrw wcgr3, [r0], #4 */ - RET - -/* Wrappers to save core registers, then call the real routine. */ - -.macro UNWIND_WRAPPER name nargs - ARM_FUNC_START \name - /* Create a phase2_vrs structure. */ - /* Split reg push in two to ensure the correct value for sp. */ -#if defined(__thumb2__) - mov ip, sp - push {lr} /* PC is ignored. */ - push {ip, lr} /* Push original SP and LR. */ -#else - stmfd sp!, {sp, lr, pc} -#endif - stmfd sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip} - - /* Demand-save flags, plus an extra word for alignment. */ - mov r3, #0 - stmfd sp!, {r2, r3} - - /* Point r1 at the block. Pass r[0..nargs) unchanged. */ - add r\nargs, sp, #4 -#if defined(__thumb__) && !defined(__thumb2__) - /* Switch back to thumb mode to avoid interworking hassle. */ - adr ip, .L1_\name - orr ip, ip, #1 - bx ip - .thumb -.L1_\name: - bl SYM (__gnu\name) __PLT__ - ldr r3, [sp, #64] - add sp, #72 - bx r3 -#else - bl SYM (__gnu\name) __PLT__ - ldr lr, [sp, #64] - add sp, sp, #72 - RET -#endif - FUNC_END \name - UNPREFIX \name -.endm - -#endif /* !__ARM_ARCH_6M__ */ - -UNWIND_WRAPPER _Unwind_RaiseException 1 -UNWIND_WRAPPER _Unwind_Resume 1 -UNWIND_WRAPPER _Unwind_Resume_or_Rethrow 1 -UNWIND_WRAPPER _Unwind_ForcedUnwind 3 -UNWIND_WRAPPER _Unwind_Backtrace 2 - -#endif /* ndef __symbian__ */ diff --git a/gcc/config/arm/pr-support.c b/gcc/config/arm/pr-support.c deleted file mode 100644 index deee661..0000000 --- a/gcc/config/arm/pr-support.c +++ /dev/null @@ -1,401 +0,0 @@ -/* ARM EABI compliant unwinding routines - Copyright (C) 2004, 2005, 2009 Free Software Foundation, Inc. - Contributed by Paul Brook - - This file 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. - - This file 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 "unwind.h" - -/* We add a prototype for abort here to avoid creating a dependency on - target headers. */ -extern void abort (void); - -typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */ - -/* Misc constants. */ -#define R_IP 12 -#define R_SP 13 -#define R_LR 14 -#define R_PC 15 - -#define uint32_highbit (((_uw) 1) << 31) - -void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp); - -/* Unwind descriptors. */ - -typedef struct -{ - _uw16 length; - _uw16 offset; -} EHT16; - -typedef struct -{ - _uw length; - _uw offset; -} EHT32; - -/* Calculate the address encoded by a 31-bit self-relative offset at address - P. Copy of routine in unwind-arm.c. */ - -static inline _uw -selfrel_offset31 (const _uw *p) -{ - _uw offset; - - offset = *p; - /* Sign extend to 32 bits. */ - if (offset & (1 << 30)) - offset |= 1u << 31; - - return offset + (_uw) p; -} - - -/* Personality routine helper functions. */ - -#define CODE_FINISH (0xb0) - -/* Return the next byte of unwinding information, or CODE_FINISH if there is - no data remaining. */ -static inline _uw8 -next_unwind_byte (__gnu_unwind_state * uws) -{ - _uw8 b; - - if (uws->bytes_left == 0) - { - /* Load another word */ - if (uws->words_left == 0) - return CODE_FINISH; /* Nothing left. */ - uws->words_left--; - uws->data = *(uws->next++); - uws->bytes_left = 3; - } - else - uws->bytes_left--; - - /* Extract the most significant byte. */ - b = (uws->data >> 24) & 0xff; - uws->data <<= 8; - return b; -} - -/* Execute the unwinding instructions described by UWS. */ -_Unwind_Reason_Code -__gnu_unwind_execute (_Unwind_Context * context, __gnu_unwind_state * uws) -{ - _uw op; - int set_pc; - _uw reg; - - set_pc = 0; - for (;;) - { - op = next_unwind_byte (uws); - if (op == CODE_FINISH) - { - /* If we haven't already set pc then copy it from lr. */ - if (!set_pc) - { - _Unwind_VRS_Get (context, _UVRSC_CORE, R_LR, _UVRSD_UINT32, - ®); - _Unwind_VRS_Set (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32, - ®); - set_pc = 1; - } - /* Drop out of the loop. */ - break; - } - if ((op & 0x80) == 0) - { - /* vsp = vsp +- (imm6 << 2 + 4). */ - _uw offset; - - offset = ((op & 0x3f) << 2) + 4; - _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); - if (op & 0x40) - reg -= offset; - else - reg += offset; - _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); - continue; - } - - if ((op & 0xf0) == 0x80) - { - op = (op << 8) | next_unwind_byte (uws); - if (op == 0x8000) - { - /* Refuse to unwind. */ - return _URC_FAILURE; - } - /* Pop r4-r15 under mask. */ - op = (op << 4) & 0xfff0; - if (_Unwind_VRS_Pop (context, _UVRSC_CORE, op, _UVRSD_UINT32) - != _UVRSR_OK) - return _URC_FAILURE; - if (op & (1 << R_PC)) - set_pc = 1; - continue; - } - if ((op & 0xf0) == 0x90) - { - op &= 0xf; - if (op == 13 || op == 15) - /* Reserved. */ - return _URC_FAILURE; - /* vsp = r[nnnn]. */ - _Unwind_VRS_Get (context, _UVRSC_CORE, op, _UVRSD_UINT32, ®); - _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); - continue; - } - if ((op & 0xf0) == 0xa0) - { - /* Pop r4-r[4+nnn], [lr]. */ - _uw mask; - - mask = (0xff0 >> (7 - (op & 7))) & 0xff0; - if (op & 8) - mask |= (1 << R_LR); - if (_Unwind_VRS_Pop (context, _UVRSC_CORE, mask, _UVRSD_UINT32) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xf0) == 0xb0) - { - /* op == 0xb0 already handled. */ - if (op == 0xb1) - { - op = next_unwind_byte (uws); - if (op == 0 || ((op & 0xf0) != 0)) - /* Spare. */ - return _URC_FAILURE; - /* Pop r0-r4 under mask. */ - if (_Unwind_VRS_Pop (context, _UVRSC_CORE, op, _UVRSD_UINT32) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if (op == 0xb2) - { - /* vsp = vsp + 0x204 + (uleb128 << 2). */ - int shift; - - _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, - ®); - op = next_unwind_byte (uws); - shift = 2; - while (op & 0x80) - { - reg += ((op & 0x7f) << shift); - shift += 7; - op = next_unwind_byte (uws); - } - reg += ((op & 0x7f) << shift) + 0x204; - _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, - ®); - continue; - } - if (op == 0xb3) - { - /* Pop VFP registers with fldmx. */ - op = next_unwind_byte (uws); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_VFPX) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xfc) == 0xb4) - { - /* Pop FPA E[4]-E[4+nn]. */ - op = 0x40000 | ((op & 3) + 1); - if (_Unwind_VRS_Pop (context, _UVRSC_FPA, op, _UVRSD_FPAX) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - /* op & 0xf8 == 0xb8. */ - /* Pop VFP D[8]-D[8+nnn] with fldmx. */ - op = 0x80000 | ((op & 7) + 1); - if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_VFPX) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xf0) == 0xc0) - { - if (op == 0xc6) - { - /* Pop iWMMXt D registers. */ - op = next_unwind_byte (uws); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (_Unwind_VRS_Pop (context, _UVRSC_WMMXD, op, _UVRSD_UINT64) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if (op == 0xc7) - { - op = next_unwind_byte (uws); - if (op == 0 || (op & 0xf0) != 0) - /* Spare. */ - return _URC_FAILURE; - /* Pop iWMMXt wCGR{3,2,1,0} under mask. */ - if (_Unwind_VRS_Pop (context, _UVRSC_WMMXC, op, _UVRSD_UINT32) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xf8) == 0xc0) - { - /* Pop iWMMXt wR[10]-wR[10+nnn]. */ - op = 0xa0000 | ((op & 0xf) + 1); - if (_Unwind_VRS_Pop (context, _UVRSC_WMMXD, op, _UVRSD_UINT64) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if (op == 0xc8) - { -#ifndef __VFP_FP__ - /* Pop FPA registers. */ - op = next_unwind_byte (uws); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (_Unwind_VRS_Pop (context, _UVRSC_FPA, op, _UVRSD_FPAX) - != _UVRSR_OK) - return _URC_FAILURE; - continue; -#else - /* Pop VFPv3 registers D[16+ssss]-D[16+ssss+cccc] with vldm. */ - op = next_unwind_byte (uws); - op = (((op & 0xf0) + 16) << 12) | ((op & 0xf) + 1); - if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_DOUBLE) - != _UVRSR_OK) - return _URC_FAILURE; - continue; -#endif - } - if (op == 0xc9) - { - /* Pop VFP registers with fldmd. */ - op = next_unwind_byte (uws); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_DOUBLE) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - /* Spare. */ - return _URC_FAILURE; - } - if ((op & 0xf8) == 0xd0) - { - /* Pop VFP D[8]-D[8+nnn] with fldmd. */ - op = 0x80000 | ((op & 7) + 1); - if (_Unwind_VRS_Pop (context, _UVRSC_VFP, op, _UVRSD_DOUBLE) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - /* Spare. */ - return _URC_FAILURE; - } - return _URC_OK; -} - - -/* Execute the unwinding instructions associated with a frame. UCBP and - CONTEXT are the current exception object and virtual CPU state - respectively. */ - -_Unwind_Reason_Code -__gnu_unwind_frame (_Unwind_Control_Block * ucbp, _Unwind_Context * context) -{ - _uw *ptr; - __gnu_unwind_state uws; - - ptr = (_uw *) ucbp->pr_cache.ehtp; - /* Skip over the personality routine address. */ - ptr++; - /* Setup the unwinder state. */ - uws.data = (*ptr) << 8; - uws.next = ptr + 1; - uws.bytes_left = 3; - uws.words_left = ((*ptr) >> 24) & 0xff; - - return __gnu_unwind_execute (context, &uws); -} - -/* Get the _Unwind_Control_Block from an _Unwind_Context. */ - -static inline _Unwind_Control_Block * -unwind_UCB_from_context (_Unwind_Context * context) -{ - return (_Unwind_Control_Block *) _Unwind_GetGR (context, R_IP); -} - -/* Get the start address of the function being unwound. */ - -_Unwind_Ptr -_Unwind_GetRegionStart (_Unwind_Context * context) -{ - _Unwind_Control_Block *ucbp; - - ucbp = unwind_UCB_from_context (context); - return (_Unwind_Ptr) ucbp->pr_cache.fnstart; -} - -/* Find the Language specific exception data. */ - -void * -_Unwind_GetLanguageSpecificData (_Unwind_Context * context) -{ - _Unwind_Control_Block *ucbp; - _uw *ptr; - - /* Get a pointer to the exception table entry. */ - ucbp = unwind_UCB_from_context (context); - ptr = (_uw *) ucbp->pr_cache.ehtp; - /* Skip the personality routine address. */ - ptr++; - /* Skip the unwind opcodes. */ - ptr += (((*ptr) >> 24) & 0xff) + 1; - - return ptr; -} - - -/* These two should never be used. */ - -_Unwind_Ptr -_Unwind_GetDataRelBase (_Unwind_Context *context __attribute__ ((unused))) -{ - abort (); -} - -_Unwind_Ptr -_Unwind_GetTextRelBase (_Unwind_Context *context __attribute__ ((unused))) -{ - abort (); -} diff --git a/gcc/config/arm/t-bpabi b/gcc/config/arm/t-bpabi index 78812b3..b6b5f40 100644 --- a/gcc/config/arm/t-bpabi +++ b/gcc/config/arm/t-bpabi @@ -25,11 +25,6 @@ LIB2FUNCS_EXTRA = $(srcdir)/config/arm/bpabi.c \ LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/arm/fp16.c -UNWIND_H = $(srcdir)/config/arm/unwind-arm.h -LIB2ADDEH = $(srcdir)/config/arm/unwind-arm.c \ - $(srcdir)/config/arm/libunwind.S \ - $(srcdir)/config/arm/pr-support.c $(srcdir)/unwind-c.c - # Add the BPABI names. SHLIB_MAPFILES += $(srcdir)/config/arm/libgcc-bpabi.ver diff --git a/gcc/config/arm/t-symbian b/gcc/config/arm/t-symbian index 3be83f4..f074591 100644 --- a/gcc/config/arm/t-symbian +++ b/gcc/config/arm/t-symbian @@ -30,10 +30,6 @@ LIB1ASMFUNCS += \ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \ _fixsfsi _fixunssfsi -# Include the gcc personality routine -UNWIND_H = $(srcdir)/config/arm/unwind-arm.h -LIB2ADDEH = $(srcdir)/unwind-c.c $(srcdir)/config/arm/pr-support.c - # Include half-float helpers. LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/arm/fp16.c diff --git a/gcc/config/arm/unwind-arm.c b/gcc/config/arm/unwind-arm.c deleted file mode 100644 index 90d258d..0000000 --- a/gcc/config/arm/unwind-arm.c +++ /dev/null @@ -1,1283 +0,0 @@ -/* ARM EABI compliant unwinding routines. - Copyright (C) 2004, 2005, 2009 Free Software Foundation, Inc. - Contributed by Paul Brook - - This file 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. - - This file 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 "unwind.h" - -/* We add a prototype for abort here to avoid creating a dependency on - target headers. */ -extern void abort (void); - -/* Definitions for C++ runtime support routines. We make these weak - declarations to avoid pulling in libsupc++ unnecessarily. */ -typedef unsigned char bool; - -typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */ -enum __cxa_type_match_result - { - ctm_failed = 0, - ctm_succeeded = 1, - ctm_succeeded_with_ptr_to_base = 2 - }; - -void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp); -bool __attribute__((weak)) __cxa_begin_cleanup(_Unwind_Control_Block *ucbp); -enum __cxa_type_match_result __attribute__((weak)) __cxa_type_match - (_Unwind_Control_Block *ucbp, const type_info *rttip, - bool is_reference, void **matched_object); - -_Unwind_Ptr __attribute__((weak)) -__gnu_Unwind_Find_exidx (_Unwind_Ptr, int *); - -/* Misc constants. */ -#define R_IP 12 -#define R_SP 13 -#define R_LR 14 -#define R_PC 15 - -#define EXIDX_CANTUNWIND 1 -#define uint32_highbit (((_uw) 1) << 31) - -#define UCB_FORCED_STOP_FN(ucbp) ((ucbp)->unwinder_cache.reserved1) -#define UCB_PR_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved2) -#define UCB_SAVED_CALLSITE_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved3) -#define UCB_FORCED_STOP_ARG(ucbp) ((ucbp)->unwinder_cache.reserved4) - -struct core_regs -{ - _uw r[16]; -}; - -/* We use normal integer types here to avoid the compiler generating - coprocessor instructions. */ -struct vfp_regs -{ - _uw64 d[16]; - _uw pad; -}; - -struct vfpv3_regs -{ - /* Always populated via VSTM, so no need for the "pad" field from - vfp_regs (which is used to store the format word for FSTMX). */ - _uw64 d[16]; -}; - -struct fpa_reg -{ - _uw w[3]; -}; - -struct fpa_regs -{ - struct fpa_reg f[8]; -}; - -struct wmmxd_regs -{ - _uw64 wd[16]; -}; - -struct wmmxc_regs -{ - _uw wc[4]; -}; - -/* Unwind descriptors. */ - -typedef struct -{ - _uw16 length; - _uw16 offset; -} EHT16; - -typedef struct -{ - _uw length; - _uw offset; -} EHT32; - -/* The ABI specifies that the unwind routines may only use core registers, - except when actually manipulating coprocessor state. This allows - us to write one implementation that works on all platforms by - demand-saving coprocessor registers. - - During unwinding we hold the coprocessor state in the actual hardware - registers and allocate demand-save areas for use during phase1 - unwinding. */ - -typedef struct -{ - /* The first fields must be the same as a phase2_vrs. */ - _uw demand_save_flags; - struct core_regs core; - _uw prev_sp; /* Only valid during forced unwinding. */ - struct vfp_regs vfp; - struct vfpv3_regs vfp_regs_16_to_31; - struct fpa_regs fpa; - struct wmmxd_regs wmmxd; - struct wmmxc_regs wmmxc; -} phase1_vrs; - -#define DEMAND_SAVE_VFP 1 /* VFP state has been saved if not set */ -#define DEMAND_SAVE_VFP_D 2 /* VFP state is for FLDMD/FSTMD if set */ -#define DEMAND_SAVE_VFP_V3 4 /* VFPv3 state for regs 16 .. 31 has - been saved if not set */ -#define DEMAND_SAVE_WMMXD 8 /* iWMMXt data registers have been - saved if not set. */ -#define DEMAND_SAVE_WMMXC 16 /* iWMMXt control registers have been - saved if not set. */ - -/* This must match the structure created by the assembly wrappers. */ -typedef struct -{ - _uw demand_save_flags; - struct core_regs core; -} phase2_vrs; - - -/* An exception index table entry. */ - -typedef struct __EIT_entry -{ - _uw fnoffset; - _uw content; -} __EIT_entry; - -/* Assembly helper functions. */ - -/* Restore core register state. Never returns. */ -void __attribute__((noreturn)) restore_core_regs (struct core_regs *); - - -/* Coprocessor register state manipulation functions. */ - -/* Routines for FLDMX/FSTMX format... */ -void __gnu_Unwind_Save_VFP (struct vfp_regs * p); -void __gnu_Unwind_Restore_VFP (struct vfp_regs * p); -void __gnu_Unwind_Save_WMMXD (struct wmmxd_regs * p); -void __gnu_Unwind_Restore_WMMXD (struct wmmxd_regs * p); -void __gnu_Unwind_Save_WMMXC (struct wmmxc_regs * p); -void __gnu_Unwind_Restore_WMMXC (struct wmmxc_regs * p); - -/* ...and those for FLDMD/FSTMD format... */ -void __gnu_Unwind_Save_VFP_D (struct vfp_regs * p); -void __gnu_Unwind_Restore_VFP_D (struct vfp_regs * p); - -/* ...and those for VLDM/VSTM format, saving/restoring only registers - 16 through 31. */ -void __gnu_Unwind_Save_VFP_D_16_to_31 (struct vfpv3_regs * p); -void __gnu_Unwind_Restore_VFP_D_16_to_31 (struct vfpv3_regs * p); - -/* Restore coprocessor state after phase1 unwinding. */ -static void -restore_non_core_regs (phase1_vrs * vrs) -{ - if ((vrs->demand_save_flags & DEMAND_SAVE_VFP) == 0) - { - if (vrs->demand_save_flags & DEMAND_SAVE_VFP_D) - __gnu_Unwind_Restore_VFP_D (&vrs->vfp); - else - __gnu_Unwind_Restore_VFP (&vrs->vfp); - } - - if ((vrs->demand_save_flags & DEMAND_SAVE_VFP_V3) == 0) - __gnu_Unwind_Restore_VFP_D_16_to_31 (&vrs->vfp_regs_16_to_31); - - if ((vrs->demand_save_flags & DEMAND_SAVE_WMMXD) == 0) - __gnu_Unwind_Restore_WMMXD (&vrs->wmmxd); - if ((vrs->demand_save_flags & DEMAND_SAVE_WMMXC) == 0) - __gnu_Unwind_Restore_WMMXC (&vrs->wmmxc); -} - -/* A better way to do this would probably be to compare the absolute address - with a segment relative relocation of the same symbol. */ - -extern int __text_start; -extern int __data_start; - -/* The exception index table location. */ -extern __EIT_entry __exidx_start; -extern __EIT_entry __exidx_end; - -/* ABI defined personality routines. */ -extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr0 (_Unwind_State, - _Unwind_Control_Block *, _Unwind_Context *);// __attribute__((weak)); -extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr1 (_Unwind_State, - _Unwind_Control_Block *, _Unwind_Context *) __attribute__((weak)); -extern _Unwind_Reason_Code __aeabi_unwind_cpp_pr2 (_Unwind_State, - _Unwind_Control_Block *, _Unwind_Context *) __attribute__((weak)); - -/* ABI defined routine to store a virtual register to memory. */ - -_Unwind_VRS_Result _Unwind_VRS_Get (_Unwind_Context *context, - _Unwind_VRS_RegClass regclass, - _uw regno, - _Unwind_VRS_DataRepresentation representation, - void *valuep) -{ - phase1_vrs *vrs = (phase1_vrs *) context; - - switch (regclass) - { - case _UVRSC_CORE: - if (representation != _UVRSD_UINT32 - || regno > 15) - return _UVRSR_FAILED; - *(_uw *) valuep = vrs->core.r[regno]; - return _UVRSR_OK; - - case _UVRSC_VFP: - case _UVRSC_FPA: - case _UVRSC_WMMXD: - case _UVRSC_WMMXC: - return _UVRSR_NOT_IMPLEMENTED; - - default: - return _UVRSR_FAILED; - } -} - - -/* ABI defined function to load a virtual register from memory. */ - -_Unwind_VRS_Result _Unwind_VRS_Set (_Unwind_Context *context, - _Unwind_VRS_RegClass regclass, - _uw regno, - _Unwind_VRS_DataRepresentation representation, - void *valuep) -{ - phase1_vrs *vrs = (phase1_vrs *) context; - - switch (regclass) - { - case _UVRSC_CORE: - if (representation != _UVRSD_UINT32 - || regno > 15) - return _UVRSR_FAILED; - - vrs->core.r[regno] = *(_uw *) valuep; - return _UVRSR_OK; - - case _UVRSC_VFP: - case _UVRSC_FPA: - case _UVRSC_WMMXD: - case _UVRSC_WMMXC: - return _UVRSR_NOT_IMPLEMENTED; - - default: - return _UVRSR_FAILED; - } -} - - -/* ABI defined function to pop registers off the stack. */ - -_Unwind_VRS_Result _Unwind_VRS_Pop (_Unwind_Context *context, - _Unwind_VRS_RegClass regclass, - _uw discriminator, - _Unwind_VRS_DataRepresentation representation) -{ - phase1_vrs *vrs = (phase1_vrs *) context; - - switch (regclass) - { - case _UVRSC_CORE: - { - _uw *ptr; - _uw mask; - int i; - - if (representation != _UVRSD_UINT32) - return _UVRSR_FAILED; - - mask = discriminator & 0xffff; - ptr = (_uw *) vrs->core.r[R_SP]; - /* Pop the requested registers. */ - for (i = 0; i < 16; i++) - { - if (mask & (1 << i)) - vrs->core.r[i] = *(ptr++); - } - /* Writeback the stack pointer value if it wasn't restored. */ - if ((mask & (1 << R_SP)) == 0) - vrs->core.r[R_SP] = (_uw) ptr; - } - return _UVRSR_OK; - - case _UVRSC_VFP: - { - _uw start = discriminator >> 16; - _uw count = discriminator & 0xffff; - struct vfp_regs tmp; - struct vfpv3_regs tmp_16_to_31; - int tmp_count; - _uw *sp; - _uw *dest; - int num_vfpv3_regs = 0; - - /* We use an approximation here by bounding _UVRSD_DOUBLE - register numbers at 32 always, since we can't detect if - VFPv3 isn't present (in such a case the upper limit is 16). */ - if ((representation != _UVRSD_VFPX && representation != _UVRSD_DOUBLE) - || start + count > (representation == _UVRSD_VFPX ? 16 : 32) - || (representation == _UVRSD_VFPX && start >= 16)) - return _UVRSR_FAILED; - - /* Check if we're being asked to pop VFPv3-only registers - (numbers 16 through 31). */ - if (start >= 16) - num_vfpv3_regs = count; - else if (start + count > 16) - num_vfpv3_regs = start + count - 16; - - if (num_vfpv3_regs && representation != _UVRSD_DOUBLE) - return _UVRSR_FAILED; - - /* Demand-save coprocessor registers for stage1. */ - if (start < 16 && (vrs->demand_save_flags & DEMAND_SAVE_VFP)) - { - vrs->demand_save_flags &= ~DEMAND_SAVE_VFP; - - if (representation == _UVRSD_DOUBLE) - { - /* Save in FLDMD/FSTMD format. */ - vrs->demand_save_flags |= DEMAND_SAVE_VFP_D; - __gnu_Unwind_Save_VFP_D (&vrs->vfp); - } - else - { - /* Save in FLDMX/FSTMX format. */ - vrs->demand_save_flags &= ~DEMAND_SAVE_VFP_D; - __gnu_Unwind_Save_VFP (&vrs->vfp); - } - } - - if (num_vfpv3_regs > 0 - && (vrs->demand_save_flags & DEMAND_SAVE_VFP_V3)) - { - vrs->demand_save_flags &= ~DEMAND_SAVE_VFP_V3; - __gnu_Unwind_Save_VFP_D_16_to_31 (&vrs->vfp_regs_16_to_31); - } - - /* Restore the registers from the stack. Do this by saving the - current VFP registers to a memory area, moving the in-memory - values into that area, and restoring from the whole area. - For _UVRSD_VFPX we assume FSTMX standard format 1. */ - if (representation == _UVRSD_VFPX) - __gnu_Unwind_Save_VFP (&tmp); - else - { - /* Save registers 0 .. 15 if required. */ - if (start < 16) - __gnu_Unwind_Save_VFP_D (&tmp); - - /* Save VFPv3 registers 16 .. 31 if required. */ - if (num_vfpv3_regs) - __gnu_Unwind_Save_VFP_D_16_to_31 (&tmp_16_to_31); - } - - /* Work out how many registers below register 16 need popping. */ - tmp_count = num_vfpv3_regs > 0 ? 16 - start : count; - - /* Copy registers below 16, if needed. - The stack address is only guaranteed to be word aligned, so - we can't use doubleword copies. */ - sp = (_uw *) vrs->core.r[R_SP]; - if (tmp_count > 0) - { - tmp_count *= 2; - dest = (_uw *) &tmp.d[start]; - while (tmp_count--) - *(dest++) = *(sp++); - } - - /* Copy VFPv3 registers numbered >= 16, if needed. */ - if (num_vfpv3_regs > 0) - { - /* num_vfpv3_regs is needed below, so copy it. */ - int tmp_count_2 = num_vfpv3_regs * 2; - int vfpv3_start = start < 16 ? 16 : start; - - dest = (_uw *) &tmp_16_to_31.d[vfpv3_start - 16]; - while (tmp_count_2--) - *(dest++) = *(sp++); - } - - /* Skip the format word space if using FLDMX/FSTMX format. */ - if (representation == _UVRSD_VFPX) - sp++; - - /* Set the new stack pointer. */ - vrs->core.r[R_SP] = (_uw) sp; - - /* Reload the registers. */ - if (representation == _UVRSD_VFPX) - __gnu_Unwind_Restore_VFP (&tmp); - else - { - /* Restore registers 0 .. 15 if required. */ - if (start < 16) - __gnu_Unwind_Restore_VFP_D (&tmp); - - /* Restore VFPv3 registers 16 .. 31 if required. */ - if (num_vfpv3_regs > 0) - __gnu_Unwind_Restore_VFP_D_16_to_31 (&tmp_16_to_31); - } - } - return _UVRSR_OK; - - case _UVRSC_FPA: - return _UVRSR_NOT_IMPLEMENTED; - - case _UVRSC_WMMXD: - { - _uw start = discriminator >> 16; - _uw count = discriminator & 0xffff; - struct wmmxd_regs tmp; - _uw *sp; - _uw *dest; - - if ((representation != _UVRSD_UINT64) || start + count > 16) - return _UVRSR_FAILED; - - if (vrs->demand_save_flags & DEMAND_SAVE_WMMXD) - { - /* Demand-save resisters for stage1. */ - vrs->demand_save_flags &= ~DEMAND_SAVE_WMMXD; - __gnu_Unwind_Save_WMMXD (&vrs->wmmxd); - } - - /* Restore the registers from the stack. Do this by saving the - current WMMXD registers to a memory area, moving the in-memory - values into that area, and restoring from the whole area. */ - __gnu_Unwind_Save_WMMXD (&tmp); - - /* The stack address is only guaranteed to be word aligned, so - we can't use doubleword copies. */ - sp = (_uw *) vrs->core.r[R_SP]; - dest = (_uw *) &tmp.wd[start]; - count *= 2; - while (count--) - *(dest++) = *(sp++); - - /* Set the new stack pointer. */ - vrs->core.r[R_SP] = (_uw) sp; - - /* Reload the registers. */ - __gnu_Unwind_Restore_WMMXD (&tmp); - } - return _UVRSR_OK; - - case _UVRSC_WMMXC: - { - int i; - struct wmmxc_regs tmp; - _uw *sp; - - if ((representation != _UVRSD_UINT32) || discriminator > 16) - return _UVRSR_FAILED; - - if (vrs->demand_save_flags & DEMAND_SAVE_WMMXC) - { - /* Demand-save resisters for stage1. */ - vrs->demand_save_flags &= ~DEMAND_SAVE_WMMXC; - __gnu_Unwind_Save_WMMXC (&vrs->wmmxc); - } - - /* Restore the registers from the stack. Do this by saving the - current WMMXC registers to a memory area, moving the in-memory - values into that area, and restoring from the whole area. */ - __gnu_Unwind_Save_WMMXC (&tmp); - - sp = (_uw *) vrs->core.r[R_SP]; - for (i = 0; i < 4; i++) - if (discriminator & (1 << i)) - tmp.wc[i] = *(sp++); - - /* Set the new stack pointer. */ - vrs->core.r[R_SP] = (_uw) sp; - - /* Reload the registers. */ - __gnu_Unwind_Restore_WMMXC (&tmp); - } - return _UVRSR_OK; - - default: - return _UVRSR_FAILED; - } -} - - -/* Core unwinding functions. */ - -/* Calculate the address encoded by a 31-bit self-relative offset at address - P. */ -static inline _uw -selfrel_offset31 (const _uw *p) -{ - _uw offset; - - offset = *p; - /* Sign extend to 32 bits. */ - if (offset & (1 << 30)) - offset |= 1u << 31; - else - offset &= ~(1u << 31); - - return offset + (_uw) p; -} - - -/* Perform a binary search for RETURN_ADDRESS in TABLE. The table contains - NREC entries. */ - -static const __EIT_entry * -search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address) -{ - _uw next_fn; - _uw this_fn; - int n, left, right; - - if (nrec == 0) - return (__EIT_entry *) 0; - - left = 0; - right = nrec - 1; - - while (1) - { - n = (left + right) / 2; - this_fn = selfrel_offset31 (&table[n].fnoffset); - if (n != nrec - 1) - next_fn = selfrel_offset31 (&table[n + 1].fnoffset) - 1; - else - next_fn = (_uw)0 - 1; - - if (return_address < this_fn) - { - if (n == left) - return (__EIT_entry *) 0; - right = n - 1; - } - else if (return_address <= next_fn) - return &table[n]; - else - left = n + 1; - } -} - -/* Find the exception index table eintry for the given address. - Fill in the relevant fields of the UCB. - Returns _URC_FAILURE if an error occurred, _URC_OK on success. */ - -static _Unwind_Reason_Code -get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address) -{ - const __EIT_entry * eitp; - int nrec; - - /* The return address is the address of the instruction following the - call instruction (plus one in thumb mode). If this was the last - instruction in the function the address will lie in the following - function. Subtract 2 from the address so that it points within the call - instruction itself. */ - return_address -= 2; - - if (__gnu_Unwind_Find_exidx) - { - eitp = (const __EIT_entry *) __gnu_Unwind_Find_exidx (return_address, - &nrec); - if (!eitp) - { - UCB_PR_ADDR (ucbp) = 0; - return _URC_FAILURE; - } - } - else - { - eitp = &__exidx_start; - nrec = &__exidx_end - &__exidx_start; - } - - eitp = search_EIT_table (eitp, nrec, return_address); - - if (!eitp) - { - UCB_PR_ADDR (ucbp) = 0; - return _URC_FAILURE; - } - ucbp->pr_cache.fnstart = selfrel_offset31 (&eitp->fnoffset); - - /* Can this frame be unwound at all? */ - if (eitp->content == EXIDX_CANTUNWIND) - { - UCB_PR_ADDR (ucbp) = 0; - return _URC_END_OF_STACK; - } - - /* Obtain the address of the "real" __EHT_Header word. */ - - if (eitp->content & uint32_highbit) - { - /* It is immediate data. */ - ucbp->pr_cache.ehtp = (_Unwind_EHT_Header *)&eitp->content; - ucbp->pr_cache.additional = 1; - } - else - { - /* The low 31 bits of the content field are a self-relative - offset to an _Unwind_EHT_Entry structure. */ - ucbp->pr_cache.ehtp = - (_Unwind_EHT_Header *) selfrel_offset31 (&eitp->content); - ucbp->pr_cache.additional = 0; - } - - /* Discover the personality routine address. */ - if (*ucbp->pr_cache.ehtp & (1u << 31)) - { - /* One of the predefined standard routines. */ - _uw idx = (*(_uw *) ucbp->pr_cache.ehtp >> 24) & 0xf; - if (idx == 0) - UCB_PR_ADDR (ucbp) = (_uw) &__aeabi_unwind_cpp_pr0; - else if (idx == 1) - UCB_PR_ADDR (ucbp) = (_uw) &__aeabi_unwind_cpp_pr1; - else if (idx == 2) - UCB_PR_ADDR (ucbp) = (_uw) &__aeabi_unwind_cpp_pr2; - else - { /* Failed */ - UCB_PR_ADDR (ucbp) = 0; - return _URC_FAILURE; - } - } - else - { - /* Execute region offset to PR */ - UCB_PR_ADDR (ucbp) = selfrel_offset31 (ucbp->pr_cache.ehtp); - } - return _URC_OK; -} - - -/* Perform phase2 unwinding. VRS is the initial virtual register state. */ - -static void __attribute__((noreturn)) -unwind_phase2 (_Unwind_Control_Block * ucbp, phase2_vrs * vrs) -{ - _Unwind_Reason_Code pr_result; - - do - { - /* Find the entry for this routine. */ - if (get_eit_entry (ucbp, vrs->core.r[R_PC]) != _URC_OK) - abort (); - - UCB_SAVED_CALLSITE_ADDR (ucbp) = vrs->core.r[R_PC]; - - /* Call the pr to decide what to do. */ - pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) - (_US_UNWIND_FRAME_STARTING, ucbp, (_Unwind_Context *) vrs); - } - while (pr_result == _URC_CONTINUE_UNWIND); - - if (pr_result != _URC_INSTALL_CONTEXT) - abort(); - - restore_core_regs (&vrs->core); -} - -/* Perform phase2 forced unwinding. */ - -static _Unwind_Reason_Code -unwind_phase2_forced (_Unwind_Control_Block *ucbp, phase2_vrs *entry_vrs, - int resuming) -{ - _Unwind_Stop_Fn stop_fn = (_Unwind_Stop_Fn) UCB_FORCED_STOP_FN (ucbp); - void *stop_arg = (void *)UCB_FORCED_STOP_ARG (ucbp); - _Unwind_Reason_Code pr_result = 0; - /* We use phase1_vrs here even though we do not demand save, for the - prev_sp field. */ - phase1_vrs saved_vrs, next_vrs; - - /* Save the core registers. */ - saved_vrs.core = entry_vrs->core; - /* We don't need to demand-save the non-core registers, because we - unwind in a single pass. */ - saved_vrs.demand_save_flags = 0; - - /* Unwind until we reach a propagation barrier. */ - do - { - _Unwind_State action; - _Unwind_Reason_Code entry_code; - _Unwind_Reason_Code stop_code; - - /* Find the entry for this routine. */ - entry_code = get_eit_entry (ucbp, saved_vrs.core.r[R_PC]); - - if (resuming) - { - action = _US_UNWIND_FRAME_RESUME | _US_FORCE_UNWIND; - resuming = 0; - } - else - action = _US_UNWIND_FRAME_STARTING | _US_FORCE_UNWIND; - - if (entry_code == _URC_OK) - { - UCB_SAVED_CALLSITE_ADDR (ucbp) = saved_vrs.core.r[R_PC]; - - next_vrs = saved_vrs; - - /* Call the pr to decide what to do. */ - pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) - (action, ucbp, (void *) &next_vrs); - - saved_vrs.prev_sp = next_vrs.core.r[R_SP]; - } - else - { - /* Treat any failure as the end of unwinding, to cope more - gracefully with missing EH information. Mixed EH and - non-EH within one object will usually result in failure, - because the .ARM.exidx tables do not indicate the end - of the code to which they apply; but mixed EH and non-EH - shared objects should return an unwind failure at the - entry of a non-EH shared object. */ - action |= _US_END_OF_STACK; - - saved_vrs.prev_sp = saved_vrs.core.r[R_SP]; - } - - stop_code = stop_fn (1, action, ucbp->exception_class, ucbp, - (void *)&saved_vrs, stop_arg); - if (stop_code != _URC_NO_REASON) - return _URC_FAILURE; - - if (entry_code != _URC_OK) - return entry_code; - - saved_vrs = next_vrs; - } - while (pr_result == _URC_CONTINUE_UNWIND); - - if (pr_result != _URC_INSTALL_CONTEXT) - { - /* Some sort of failure has occurred in the pr and probably the - pr returned _URC_FAILURE. */ - return _URC_FAILURE; - } - - restore_core_regs (&saved_vrs.core); -} - -/* This is a very limited implementation of _Unwind_GetCFA. It returns - the stack pointer as it is about to be unwound, and is only valid - while calling the stop function during forced unwinding. If the - current personality routine result is going to run a cleanup, this - will not be the CFA; but when the frame is really unwound, it will - be. */ - -_Unwind_Word -_Unwind_GetCFA (_Unwind_Context *context) -{ - return ((phase1_vrs *) context)->prev_sp; -} - -/* Perform phase1 unwinding. UCBP is the exception being thrown, and - entry_VRS is the register state on entry to _Unwind_RaiseException. */ - -_Unwind_Reason_Code -__gnu_Unwind_RaiseException (_Unwind_Control_Block *, phase2_vrs *); - -_Unwind_Reason_Code -__gnu_Unwind_RaiseException (_Unwind_Control_Block * ucbp, - phase2_vrs * entry_vrs) -{ - phase1_vrs saved_vrs; - _Unwind_Reason_Code pr_result; - - /* Set the pc to the call site. */ - entry_vrs->core.r[R_PC] = entry_vrs->core.r[R_LR]; - - /* Save the core registers. */ - saved_vrs.core = entry_vrs->core; - /* Set demand-save flags. */ - saved_vrs.demand_save_flags = ~(_uw) 0; - - /* Unwind until we reach a propagation barrier. */ - do - { - /* Find the entry for this routine. */ - if (get_eit_entry (ucbp, saved_vrs.core.r[R_PC]) != _URC_OK) - return _URC_FAILURE; - - /* Call the pr to decide what to do. */ - pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) - (_US_VIRTUAL_UNWIND_FRAME, ucbp, (void *) &saved_vrs); - } - while (pr_result == _URC_CONTINUE_UNWIND); - - /* We've unwound as far as we want to go, so restore the original - register state. */ - restore_non_core_regs (&saved_vrs); - if (pr_result != _URC_HANDLER_FOUND) - { - /* Some sort of failure has occurred in the pr and probably the - pr returned _URC_FAILURE. */ - return _URC_FAILURE; - } - - unwind_phase2 (ucbp, entry_vrs); -} - -/* Resume unwinding after a cleanup has been run. UCBP is the exception - being thrown and ENTRY_VRS is the register state on entry to - _Unwind_Resume. */ -_Unwind_Reason_Code -__gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *, - _Unwind_Stop_Fn, void *, phase2_vrs *); - -_Unwind_Reason_Code -__gnu_Unwind_ForcedUnwind (_Unwind_Control_Block *ucbp, - _Unwind_Stop_Fn stop_fn, void *stop_arg, - phase2_vrs *entry_vrs) -{ - UCB_FORCED_STOP_FN (ucbp) = (_uw) stop_fn; - UCB_FORCED_STOP_ARG (ucbp) = (_uw) stop_arg; - - /* Set the pc to the call site. */ - entry_vrs->core.r[R_PC] = entry_vrs->core.r[R_LR]; - - return unwind_phase2_forced (ucbp, entry_vrs, 0); -} - -_Unwind_Reason_Code -__gnu_Unwind_Resume (_Unwind_Control_Block *, phase2_vrs *); - -_Unwind_Reason_Code -__gnu_Unwind_Resume (_Unwind_Control_Block * ucbp, phase2_vrs * entry_vrs) -{ - _Unwind_Reason_Code pr_result; - - /* Recover the saved address. */ - entry_vrs->core.r[R_PC] = UCB_SAVED_CALLSITE_ADDR (ucbp); - - if (UCB_FORCED_STOP_FN (ucbp)) - { - unwind_phase2_forced (ucbp, entry_vrs, 1); - - /* We can't return failure at this point. */ - abort (); - } - - /* Call the cached PR. */ - pr_result = ((personality_routine) UCB_PR_ADDR (ucbp)) - (_US_UNWIND_FRAME_RESUME, ucbp, (_Unwind_Context *) entry_vrs); - - switch (pr_result) - { - case _URC_INSTALL_CONTEXT: - /* Upload the registers to enter the landing pad. */ - restore_core_regs (&entry_vrs->core); - - case _URC_CONTINUE_UNWIND: - /* Continue unwinding the next frame. */ - unwind_phase2 (ucbp, entry_vrs); - - default: - abort (); - } -} - -_Unwind_Reason_Code -__gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block *, phase2_vrs *); - -_Unwind_Reason_Code -__gnu_Unwind_Resume_or_Rethrow (_Unwind_Control_Block * ucbp, - phase2_vrs * entry_vrs) -{ - if (!UCB_FORCED_STOP_FN (ucbp)) - return __gnu_Unwind_RaiseException (ucbp, entry_vrs); - - /* Set the pc to the call site. */ - entry_vrs->core.r[R_PC] = entry_vrs->core.r[R_LR]; - /* Continue unwinding the next frame. */ - return unwind_phase2_forced (ucbp, entry_vrs, 0); -} - -/* Clean up an exception object when unwinding is complete. */ -void -_Unwind_Complete (_Unwind_Control_Block * ucbp __attribute__((unused))) -{ -} - - -/* Get the _Unwind_Control_Block from an _Unwind_Context. */ - -static inline _Unwind_Control_Block * -unwind_UCB_from_context (_Unwind_Context * context) -{ - return (_Unwind_Control_Block *) _Unwind_GetGR (context, R_IP); -} - - -/* Free an exception. */ - -void -_Unwind_DeleteException (_Unwind_Exception * exc) -{ - if (exc->exception_cleanup) - (*exc->exception_cleanup) (_URC_FOREIGN_EXCEPTION_CAUGHT, exc); -} - - -/* Perform stack backtrace through unwind data. */ -_Unwind_Reason_Code -__gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument, - phase2_vrs * entry_vrs); -_Unwind_Reason_Code -__gnu_Unwind_Backtrace(_Unwind_Trace_Fn trace, void * trace_argument, - phase2_vrs * entry_vrs) -{ - phase1_vrs saved_vrs; - _Unwind_Reason_Code code; - - _Unwind_Control_Block ucb; - _Unwind_Control_Block *ucbp = &ucb; - - /* Set the pc to the call site. */ - entry_vrs->core.r[R_PC] = entry_vrs->core.r[R_LR]; - - /* Save the core registers. */ - saved_vrs.core = entry_vrs->core; - /* Set demand-save flags. */ - saved_vrs.demand_save_flags = ~(_uw) 0; - - do - { - /* Find the entry for this routine. */ - if (get_eit_entry (ucbp, saved_vrs.core.r[R_PC]) != _URC_OK) - { - code = _URC_FAILURE; - break; - } - - /* The dwarf unwinder assumes the context structure holds things - like the function and LSDA pointers. The ARM implementation - caches these in the exception header (UCB). To avoid - rewriting everything we make the virtual IP register point at - the UCB. */ - _Unwind_SetGR((_Unwind_Context *)&saved_vrs, 12, (_Unwind_Ptr) ucbp); - - /* Call trace function. */ - if ((*trace) ((_Unwind_Context *) &saved_vrs, trace_argument) - != _URC_NO_REASON) - { - code = _URC_FAILURE; - break; - } - - /* Call the pr to decide what to do. */ - code = ((personality_routine) UCB_PR_ADDR (ucbp)) - (_US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND, - ucbp, (void *) &saved_vrs); - } - while (code != _URC_END_OF_STACK - && code != _URC_FAILURE); - - restore_non_core_regs (&saved_vrs); - return code; -} - - -/* Common implementation for ARM ABI defined personality routines. - ID is the index of the personality routine, other arguments are as defined - by __aeabi_unwind_cpp_pr{0,1,2}. */ - -static _Unwind_Reason_Code -__gnu_unwind_pr_common (_Unwind_State state, - _Unwind_Control_Block *ucbp, - _Unwind_Context *context, - int id) -{ - __gnu_unwind_state uws; - _uw *data; - _uw offset; - _uw len; - _uw rtti_count; - int phase2_call_unexpected_after_unwind = 0; - int in_range = 0; - int forced_unwind = state & _US_FORCE_UNWIND; - - state &= _US_ACTION_MASK; - - data = (_uw *) ucbp->pr_cache.ehtp; - uws.data = *(data++); - uws.next = data; - if (id == 0) - { - uws.data <<= 8; - uws.words_left = 0; - uws.bytes_left = 3; - } - else - { - uws.words_left = (uws.data >> 16) & 0xff; - uws.data <<= 16; - uws.bytes_left = 2; - data += uws.words_left; - } - - /* Restore the saved pointer. */ - if (state == _US_UNWIND_FRAME_RESUME) - data = (_uw *) ucbp->cleanup_cache.bitpattern[0]; - - if ((ucbp->pr_cache.additional & 1) == 0) - { - /* Process descriptors. */ - while (*data) - { - _uw addr; - _uw fnstart; - - if (id == 2) - { - len = ((EHT32 *) data)->length; - offset = ((EHT32 *) data)->offset; - data += 2; - } - else - { - len = ((EHT16 *) data)->length; - offset = ((EHT16 *) data)->offset; - data++; - } - - fnstart = ucbp->pr_cache.fnstart + (offset & ~1); - addr = _Unwind_GetGR (context, R_PC); - in_range = (fnstart <= addr && addr < fnstart + (len & ~1)); - - switch (((offset & 1) << 1) | (len & 1)) - { - case 0: - /* Cleanup. */ - if (state != _US_VIRTUAL_UNWIND_FRAME - && in_range) - { - /* Cleanup in range, and we are running cleanups. */ - _uw lp; - - /* Landing pad address is 31-bit pc-relative offset. */ - lp = selfrel_offset31 (data); - data++; - /* Save the exception data pointer. */ - ucbp->cleanup_cache.bitpattern[0] = (_uw) data; - if (!__cxa_begin_cleanup (ucbp)) - return _URC_FAILURE; - /* Setup the VRS to enter the landing pad. */ - _Unwind_SetGR (context, R_PC, lp); - return _URC_INSTALL_CONTEXT; - } - /* Cleanup not in range, or we are in stage 1. */ - data++; - break; - - case 1: - /* Catch handler. */ - if (state == _US_VIRTUAL_UNWIND_FRAME) - { - if (in_range) - { - /* Check for a barrier. */ - _uw rtti; - bool is_reference = (data[0] & uint32_highbit) != 0; - void *matched; - enum __cxa_type_match_result match_type; - - /* Check for no-throw areas. */ - if (data[1] == (_uw) -2) - return _URC_FAILURE; - - /* The thrown object immediately follows the ECB. */ - matched = (void *)(ucbp + 1); - if (data[1] != (_uw) -1) - { - /* Match a catch specification. */ - rtti = _Unwind_decode_target2 ((_uw) &data[1]); - match_type = __cxa_type_match (ucbp, - (type_info *) rtti, - is_reference, - &matched); - } - else - match_type = ctm_succeeded; - - if (match_type) - { - ucbp->barrier_cache.sp = - _Unwind_GetGR (context, R_SP); - // ctm_succeeded_with_ptr_to_base really - // means _c_t_m indirected the pointer - // object. We have to reconstruct the - // additional pointer layer by using a temporary. - if (match_type == ctm_succeeded_with_ptr_to_base) - { - ucbp->barrier_cache.bitpattern[2] - = (_uw) matched; - ucbp->barrier_cache.bitpattern[0] - = (_uw) &ucbp->barrier_cache.bitpattern[2]; - } - else - ucbp->barrier_cache.bitpattern[0] = (_uw) matched; - ucbp->barrier_cache.bitpattern[1] = (_uw) data; - return _URC_HANDLER_FOUND; - } - } - /* Handler out of range, or not matched. */ - } - else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP) - && ucbp->barrier_cache.bitpattern[1] == (_uw) data) - { - /* Matched a previous propagation barrier. */ - _uw lp; - - /* Setup for entry to the handler. */ - lp = selfrel_offset31 (data); - _Unwind_SetGR (context, R_PC, lp); - _Unwind_SetGR (context, 0, (_uw) ucbp); - return _URC_INSTALL_CONTEXT; - } - /* Catch handler not matched. Advance to the next descriptor. */ - data += 2; - break; - - case 2: - rtti_count = data[0] & 0x7fffffff; - /* Exception specification. */ - if (state == _US_VIRTUAL_UNWIND_FRAME) - { - if (in_range && (!forced_unwind || !rtti_count)) - { - /* Match against the exception specification. */ - _uw i; - _uw rtti; - void *matched; - - for (i = 0; i < rtti_count; i++) - { - matched = (void *)(ucbp + 1); - rtti = _Unwind_decode_target2 ((_uw) &data[i + 1]); - if (__cxa_type_match (ucbp, (type_info *) rtti, 0, - &matched)) - break; - } - - if (i == rtti_count) - { - /* Exception does not match the spec. */ - ucbp->barrier_cache.sp = - _Unwind_GetGR (context, R_SP); - ucbp->barrier_cache.bitpattern[0] = (_uw) matched; - ucbp->barrier_cache.bitpattern[1] = (_uw) data; - return _URC_HANDLER_FOUND; - } - } - /* Handler out of range, or exception is permitted. */ - } - else if (ucbp->barrier_cache.sp == _Unwind_GetGR (context, R_SP) - && ucbp->barrier_cache.bitpattern[1] == (_uw) data) - { - /* Matched a previous propagation barrier. */ - _uw lp; - /* Record the RTTI list for __cxa_call_unexpected. */ - ucbp->barrier_cache.bitpattern[1] = rtti_count; - ucbp->barrier_cache.bitpattern[2] = 0; - ucbp->barrier_cache.bitpattern[3] = 4; - ucbp->barrier_cache.bitpattern[4] = (_uw) &data[1]; - - if (data[0] & uint32_highbit) - { - data += rtti_count + 1; - /* Setup for entry to the handler. */ - lp = selfrel_offset31 (data); - data++; - _Unwind_SetGR (context, R_PC, lp); - _Unwind_SetGR (context, 0, (_uw) ucbp); - return _URC_INSTALL_CONTEXT; - } - else - phase2_call_unexpected_after_unwind = 1; - } - if (data[0] & uint32_highbit) - data++; - data += rtti_count + 1; - break; - - default: - /* Should never happen. */ - return _URC_FAILURE; - } - /* Finished processing this descriptor. */ - } - } - - if (__gnu_unwind_execute (context, &uws) != _URC_OK) - return _URC_FAILURE; - - if (phase2_call_unexpected_after_unwind) - { - /* Enter __cxa_unexpected as if called from the call site. */ - _Unwind_SetGR (context, R_LR, _Unwind_GetGR (context, R_PC)); - _Unwind_SetGR (context, R_PC, (_uw) &__cxa_call_unexpected); - return _URC_INSTALL_CONTEXT; - } - - return _URC_CONTINUE_UNWIND; -} - - -/* ABI defined personality routine entry points. */ - -_Unwind_Reason_Code -__aeabi_unwind_cpp_pr0 (_Unwind_State state, - _Unwind_Control_Block *ucbp, - _Unwind_Context *context) -{ - return __gnu_unwind_pr_common (state, ucbp, context, 0); -} - -_Unwind_Reason_Code -__aeabi_unwind_cpp_pr1 (_Unwind_State state, - _Unwind_Control_Block *ucbp, - _Unwind_Context *context) -{ - return __gnu_unwind_pr_common (state, ucbp, context, 1); -} - -_Unwind_Reason_Code -__aeabi_unwind_cpp_pr2 (_Unwind_State state, - _Unwind_Control_Block *ucbp, - _Unwind_Context *context) -{ - return __gnu_unwind_pr_common (state, ucbp, context, 2); -} diff --git a/gcc/config/arm/unwind-arm.h b/gcc/config/arm/unwind-arm.h deleted file mode 100644 index 1a51d8d..0000000 --- a/gcc/config/arm/unwind-arm.h +++ /dev/null @@ -1,281 +0,0 @@ -/* Header file for the ARM EABI unwinder - Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011 - Free Software Foundation, Inc. - Contributed by Paul Brook - - This file 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. - - This file 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/>. */ - -/* Language-independent unwinder header public defines. This contains both - ABI defined objects, and GNU support routines. */ - -#ifndef UNWIND_ARM_H -#define UNWIND_ARM_H - -#define __ARM_EABI_UNWINDER__ 1 - -#ifdef __cplusplus -extern "C" { -#endif - typedef unsigned _Unwind_Word __attribute__((__mode__(__word__))); - typedef signed _Unwind_Sword __attribute__((__mode__(__word__))); - typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__))); - typedef unsigned _Unwind_Internal_Ptr __attribute__((__mode__(__pointer__))); - typedef _Unwind_Word _uw; - typedef unsigned _uw64 __attribute__((mode(__DI__))); - typedef unsigned _uw16 __attribute__((mode(__HI__))); - typedef unsigned _uw8 __attribute__((mode(__QI__))); - - typedef enum - { - _URC_OK = 0, /* operation completed successfully */ - _URC_FOREIGN_EXCEPTION_CAUGHT = 1, - _URC_END_OF_STACK = 5, - _URC_HANDLER_FOUND = 6, - _URC_INSTALL_CONTEXT = 7, - _URC_CONTINUE_UNWIND = 8, - _URC_FAILURE = 9 /* unspecified failure of some kind */ - } - _Unwind_Reason_Code; - - typedef enum - { - _US_VIRTUAL_UNWIND_FRAME = 0, - _US_UNWIND_FRAME_STARTING = 1, - _US_UNWIND_FRAME_RESUME = 2, - _US_ACTION_MASK = 3, - _US_FORCE_UNWIND = 8, - _US_END_OF_STACK = 16 - } - _Unwind_State; - - /* Provided only for compatibility with existing code. */ - typedef int _Unwind_Action; -#define _UA_SEARCH_PHASE 1 -#define _UA_CLEANUP_PHASE 2 -#define _UA_HANDLER_FRAME 4 -#define _UA_FORCE_UNWIND 8 -#define _UA_END_OF_STACK 16 -#define _URC_NO_REASON _URC_OK - - typedef struct _Unwind_Control_Block _Unwind_Control_Block; - typedef struct _Unwind_Context _Unwind_Context; - typedef _uw _Unwind_EHT_Header; - - - /* UCB: */ - - struct _Unwind_Control_Block - { - char exception_class[8]; - void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block *); - /* Unwinder cache, private fields for the unwinder's use */ - struct - { - _uw reserved1; /* Forced unwind stop fn, 0 if not forced */ - _uw reserved2; /* Personality routine address */ - _uw reserved3; /* Saved callsite address */ - _uw reserved4; /* Forced unwind stop arg */ - _uw reserved5; - } - unwinder_cache; - /* Propagation barrier cache (valid after phase 1): */ - struct - { - _uw sp; - _uw bitpattern[5]; - } - barrier_cache; - /* Cleanup cache (preserved over cleanup): */ - struct - { - _uw bitpattern[4]; - } - cleanup_cache; - /* Pr cache (for pr's benefit): */ - struct - { - _uw fnstart; /* function start address */ - _Unwind_EHT_Header *ehtp; /* pointer to EHT entry header word */ - _uw additional; /* additional data */ - _uw reserved1; - } - pr_cache; - long long int :0; /* Force alignment to 8-byte boundary */ - }; - - /* Virtual Register Set*/ - - typedef enum - { - _UVRSC_CORE = 0, /* integer register */ - _UVRSC_VFP = 1, /* vfp */ - _UVRSC_FPA = 2, /* fpa */ - _UVRSC_WMMXD = 3, /* Intel WMMX data register */ - _UVRSC_WMMXC = 4 /* Intel WMMX control register */ - } - _Unwind_VRS_RegClass; - - typedef enum - { - _UVRSD_UINT32 = 0, - _UVRSD_VFPX = 1, - _UVRSD_FPAX = 2, - _UVRSD_UINT64 = 3, - _UVRSD_FLOAT = 4, - _UVRSD_DOUBLE = 5 - } - _Unwind_VRS_DataRepresentation; - - typedef enum - { - _UVRSR_OK = 0, - _UVRSR_NOT_IMPLEMENTED = 1, - _UVRSR_FAILED = 2 - } - _Unwind_VRS_Result; - - /* Frame unwinding state. */ - typedef struct - { - /* The current word (bytes packed msb first). */ - _uw data; - /* Pointer to the next word of data. */ - _uw *next; - /* The number of bytes left in this word. */ - _uw8 bytes_left; - /* The number of words pointed to by ptr. */ - _uw8 words_left; - } - __gnu_unwind_state; - - typedef _Unwind_Reason_Code (*personality_routine) (_Unwind_State, - _Unwind_Control_Block *, _Unwind_Context *); - - _Unwind_VRS_Result _Unwind_VRS_Set(_Unwind_Context *, _Unwind_VRS_RegClass, - _uw, _Unwind_VRS_DataRepresentation, - void *); - - _Unwind_VRS_Result _Unwind_VRS_Get(_Unwind_Context *, _Unwind_VRS_RegClass, - _uw, _Unwind_VRS_DataRepresentation, - void *); - - _Unwind_VRS_Result _Unwind_VRS_Pop(_Unwind_Context *, _Unwind_VRS_RegClass, - _uw, _Unwind_VRS_DataRepresentation); - - - /* Support functions for the PR. */ -#define _Unwind_Exception _Unwind_Control_Block - typedef char _Unwind_Exception_Class[8]; - - void * _Unwind_GetLanguageSpecificData (_Unwind_Context *); - _Unwind_Ptr _Unwind_GetRegionStart (_Unwind_Context *); - - /* These two should never be used. */ - _Unwind_Ptr _Unwind_GetDataRelBase (_Unwind_Context *); - _Unwind_Ptr _Unwind_GetTextRelBase (_Unwind_Context *); - - /* Interface functions: */ - _Unwind_Reason_Code _Unwind_RaiseException(_Unwind_Control_Block *ucbp); - void __attribute__((noreturn)) _Unwind_Resume(_Unwind_Control_Block *ucbp); - _Unwind_Reason_Code _Unwind_Resume_or_Rethrow (_Unwind_Control_Block *ucbp); - - typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) - (int, _Unwind_Action, _Unwind_Exception_Class, - _Unwind_Control_Block *, struct _Unwind_Context *, void *); - _Unwind_Reason_Code _Unwind_ForcedUnwind (_Unwind_Control_Block *, - _Unwind_Stop_Fn, void *); - /* @@@ Use unwind data to perform a stack backtrace. The trace callback - is called for every stack frame in the call chain, but no cleanup - actions are performed. */ - typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn) (_Unwind_Context *, void *); - _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, - void*); - - _Unwind_Word _Unwind_GetCFA (struct _Unwind_Context *); - void _Unwind_Complete(_Unwind_Control_Block *ucbp); - void _Unwind_DeleteException (_Unwind_Exception *); - - _Unwind_Reason_Code __gnu_unwind_frame (_Unwind_Control_Block *, - _Unwind_Context *); - _Unwind_Reason_Code __gnu_unwind_execute (_Unwind_Context *, - __gnu_unwind_state *); - - /* Decode an R_ARM_TARGET2 relocation. */ - static inline _Unwind_Word - _Unwind_decode_target2 (_Unwind_Word ptr) - { - _Unwind_Word tmp; - - tmp = *(_Unwind_Word *) ptr; - /* Zero values are always NULL. */ - if (!tmp) - return 0; - -#if (defined(linux) && !defined(__uClinux__)) || defined(__NetBSD__) - /* Pc-relative indirect. */ - tmp += ptr; - tmp = *(_Unwind_Word *) tmp; -#elif defined(__symbian__) || defined(__uClinux__) - /* Absolute pointer. Nothing more to do. */ -#else - /* Pc-relative pointer. */ - tmp += ptr; -#endif - return tmp; - } - - static inline _Unwind_Word - _Unwind_GetGR (_Unwind_Context *context, int regno) - { - _uw val; - _Unwind_VRS_Get (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val); - return val; - } - - /* Return the address of the instruction, not the actual IP value. */ -#define _Unwind_GetIP(context) \ - (_Unwind_GetGR (context, 15) & ~(_Unwind_Word)1) - -#define _Unwind_GetIPInfo(context, ip_before_insn) \ - (*ip_before_insn = 0, _Unwind_GetGR (context, 15) & ~(_Unwind_Word)1) - - static inline void - _Unwind_SetGR (_Unwind_Context *context, int regno, _Unwind_Word val) - { - _Unwind_VRS_Set (context, _UVRSC_CORE, regno, _UVRSD_UINT32, &val); - } - - /* The dwarf unwinder doesn't understand arm/thumb state. We assume the - landing pad uses the same instruction set as the call site. */ -#define _Unwind_SetIP(context, val) \ - _Unwind_SetGR (context, 15, val | (_Unwind_GetGR (context, 15) & 1)) - -/* leb128 type numbers have a potentially unlimited size. - The target of the following definitions of _sleb128_t and _uleb128_t - is to have efficient data types large enough to hold the leb128 type - numbers used in the unwind code. */ -typedef long _sleb128_t; -typedef unsigned long _uleb128_t; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* defined UNWIND_ARM_H */ diff --git a/gcc/config/frv/t-frv b/gcc/config/frv/t-frv index 0c58bb1..2729008 100644 --- a/gcc/config/frv/t-frv +++ b/gcc/config/frv/t-frv @@ -1,4 +1,4 @@ -# Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc. # # This file is part of GCC. # @@ -81,12 +81,12 @@ EXTRA_MULTILIB_PARTS=frvbegin.o frvend.o FRVSTUFF_CFLAGS = $(TARGET_LIBGCC2_CFLAGS) $(T)frvbegin$(objext): $(srcdir)/config/frv/frvbegin.c $(GCC_PASSES) \ - $(CONFIG_H) defaults.h unwind-dw2-fde.h gbl-ctors.h + $(CONFIG_H) defaults.h $(srcdir)/../libgcc/unwind-dw2-fde.h gbl-ctors.h $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) $(FRVSTUFF_CFLAGS) \ -c $(srcdir)/config/frv/frvbegin.c -o $(T)frvbegin$(objext) $(T)frvend$(objext): $(srcdir)/config/frv/frvend.c $(GCC_PASSES) \ - $(CONFIG_H) defaults.h unwind-dw2-fde.h gbl-ctors.h + $(CONFIG_H) defaults.h $(srcdir)/../libgcc/unwind-dw2-fde.h gbl-ctors.h $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) $(FRVSTUFF_CFLAGS) \ -c $(srcdir)/config/frv/frvend.c -o $(T)frvend$(objext) diff --git a/gcc/config/ia64/fde-glibc.c b/gcc/config/ia64/fde-glibc.c deleted file mode 100644 index 12760b9..0000000 --- a/gcc/config/ia64/fde-glibc.c +++ /dev/null @@ -1,162 +0,0 @@ -/* Copyright (C) 2000, 2001, 2003, 2009 Free Software Foundation, Inc. - Contributed by Richard Henderson <rth@cygnus.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/>. */ - -/* Locate the FDE entry for a given address, using glibc ld.so routines - to avoid register/deregister calls at DSO load/unload. */ - -#ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 -#endif -#include "config.h" -#include <stddef.h> -#include <stdlib.h> -#include <link.h> -#include "unwind-ia64.h" - -#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2) \ - || (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && !defined(DT_CONFIG)) -# error You need GLIBC 2.2.4 or later on IA-64 Linux -#endif - -struct unw_ia64_callback_data -{ - Elf64_Addr pc; - unsigned long *segment_base; - unsigned long *gp; - struct unw_table_entry *ret; -}; - -static int -_Unwind_IteratePhdrCallback (struct dl_phdr_info *info, size_t size, void *ptr) -{ - struct unw_ia64_callback_data *data = (struct unw_ia64_callback_data *) ptr; - const Elf64_Phdr *phdr, *p_unwind, *p_dynamic; - long n, match; - Elf64_Addr load_base, seg_base; - struct unw_table_entry *f_base, *f; - size_t lo, hi; - - /* Make sure struct dl_phdr_info is at least as big as we need. */ - if (size < offsetof (struct dl_phdr_info, dlpi_phnum) - + sizeof (info->dlpi_phnum)) - return -1; - - match = 0; - phdr = info->dlpi_phdr; - load_base = info->dlpi_addr; - p_unwind = NULL; - p_dynamic = NULL; - seg_base = ~(Elf64_Addr) 0; - - /* See if PC falls into one of the loaded segments. Find the unwind - segment at the same time. */ - for (n = info->dlpi_phnum; --n >= 0; phdr++) - { - if (phdr->p_type == PT_LOAD) - { - Elf64_Addr vaddr = phdr->p_vaddr + load_base; - if (data->pc >= vaddr && data->pc < vaddr + phdr->p_memsz) - match = 1; - if (vaddr < seg_base) - seg_base = vaddr; - } - else if (phdr->p_type == PT_IA_64_UNWIND) - p_unwind = phdr; - else if (phdr->p_type == PT_DYNAMIC) - p_dynamic = phdr; - } - if (!match || !p_unwind) - return 0; - - /* Search for the FDE within the unwind segment. */ - - f_base = (struct unw_table_entry *) (p_unwind->p_vaddr + load_base); - lo = 0; - hi = p_unwind->p_memsz / sizeof (struct unw_table_entry); - - while (lo < hi) - { - size_t mid = (lo + hi) / 2; - - f = f_base + mid; - if (data->pc < f->start_offset + seg_base) - hi = mid; - else if (data->pc >= f->end_offset + seg_base) - lo = mid + 1; - else - goto found; - } - /* No need to search for further libraries when we know pc is contained - in this library. */ - return 1; - - found: - *data->segment_base = seg_base; - *data->gp = 0; - data->ret = f; - - if (p_dynamic) - { - /* For dynamically linked executables and shared libraries, - DT_PLTGOT is the gp value for that object. */ - Elf64_Dyn *dyn = (Elf64_Dyn *)(p_dynamic->p_vaddr + load_base); - for (; dyn->d_tag != DT_NULL ; dyn++) - if (dyn->d_tag == DT_PLTGOT) - { - /* On IA-64, _DYNAMIC is writable and GLIBC has relocated it. */ - *data->gp = dyn->d_un.d_ptr; - break; - } - } - else - { - /* Otherwise this is a static executable with no _DYNAMIC. - The gp is constant program-wide. */ - register unsigned long gp __asm__("gp"); - *data->gp = gp; - } - - return 1; -} - -/* Return a pointer to the unwind table entry for the function - containing PC. */ - -struct unw_table_entry * -_Unwind_FindTableEntry (void *pc, unsigned long *segment_base, - unsigned long *gp, - struct unw_table_entry *ent ATTRIBUTE_UNUSED) -{ - struct unw_ia64_callback_data data; - - data.pc = (Elf64_Addr) pc; - data.segment_base = segment_base; - data.gp = gp; - data.ret = NULL; - - if (dl_iterate_phdr (_Unwind_IteratePhdrCallback, &data) < 0) - return NULL; - - return data.ret; -} diff --git a/gcc/config/ia64/fde-vms.c b/gcc/config/ia64/fde-vms.c deleted file mode 100644 index b310f0d..0000000 --- a/gcc/config/ia64/fde-vms.c +++ /dev/null @@ -1,157 +0,0 @@ -/* Copyright (C) 2004, 2009 Free Software Foundation, Inc. - Contributed by Douglas B Rupp <rupp@gnat.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/>. */ - -/* Locate the FDE entry for a given address, using VMS Starlet routines - to avoid register/deregister calls at DSO load/unload. */ - -#include "tconfig.h" -#include "tsystem.h" -#include "coretypes.h" -#include "tm.h" -#include <stddef.h> -#include <stdlib.h> -#include <stdio.h> -#include "unwind-ia64.h" - -#define __int64 long -#include <vms/ossddef.h> -#ifndef SS$_NORMAL -#define SS$_NORMAL 1 -#endif - -typedef struct -{ - unsigned long start_offset; - unsigned long end_offset; - unsigned long info_offset; - unsigned long gp_value; -} vms_unw_table_entry; - -typedef unsigned long long uqword; - -/* ENTRY is the unwind table entry found for a PC part of call chain we're - unwinding through. Return whether we should force the generic unwinder - to resort to "fallback" processing. */ - -static int -force_fallback_processing_for (void * pc, vms_unw_table_entry * entry) -{ - static int eh_debug = -1; - - uqword * unw_info_block = (uqword *)entry->info_offset; - uqword header = *unw_info_block; - - /* We need to force fallback processing in two cases: - - 1/ The exception dispatch frame, since only our fallback - processing knows how to properly unwind through it, and - - 2/ A bottom of stack frame, since only our fallback processing - will ensure we don't try to unwind further past it, which - would get us into unknown territory and likely cause a severe - crash along the way. - - The two cases are indicated by non-default values for specific - bits in the OS Specific Data (OSSD) General Information block - associated with such frames. */ - - ossddef * ossd; - - if (eh_debug == -1) - { - char * EH_DEBUG = getenv ("EH_DEBUG"); - eh_debug = EH_DEBUG ? atoi (EH_DEBUG) : 0; - } - - if (eh_debug) - { - printf ("pc @ 0x%p, block @ 0x%p, header = 0x%016llx\n", - pc, unw_info_block, header); - printf ("mode = %d, length = %ld, handler = %d\n", - (int)UNW_IVMS_MODE (header), UNW_LENGTH (header), - UNW_FLAG_EHANDLER (header) || UNW_FLAG_EHANDLER (header)); - } - - /* An OSSD block is there for IVMS_MODE == 3 only. */ - if (UNW_IVMS_MODE (header) != 3) - return 0; - - /* The OSSD block is found past the header, unwind descriptor area - and condition handler pointer, if any. */ - ossd = (ossddef *) - /* Beware: uqword pointer arithmetic below. */ - (unw_info_block - + 1 - + UNW_LENGTH (header) - + (UNW_FLAG_EHANDLER (header) || UNW_FLAG_EHANDLER (header))); - - /* "A General Information segment may be omitted if all of its fields - would have their default values. If a General Information segment - is present, it must be the first in the OSSD area." So ... */ - - if (eh_debug) - printf ("ossd @ 0x%p\n", ossd); - - if (eh_debug && ossd->ossd$v_type == OSSD$K_GENERAL_INFO) - printf ("exc_frame = %d - bot_frame = %d - base_frame = %d\n", - ossd->ossd$v_exception_frame, - ossd->ossd$v_bottom_of_stack, - ossd->ossd$v_base_frame); - - return - ossd->ossd$v_type == OSSD$K_GENERAL_INFO - && (ossd->ossd$v_exception_frame - || ossd->ossd$v_bottom_of_stack || ossd->ossd$v_base_frame); -} - -/* Return a pointer to the unwind table entry for the function - containing PC, 0 if we cannot find an entry or if the one we find - calls for fallback processing. */ - -struct unw_table_entry * -_Unwind_FindTableEntry (void *pc, unsigned long *segment_base, - unsigned long *gp, struct unw_table_entry *ent) -{ - vms_unw_table_entry vueblock; - - if (SYS$GET_UNWIND_ENTRY_INFO (pc, &vueblock, 0) != SS$_NORMAL) - return 0; - - /* If there is no unwind information, use fallback. */ - if (vueblock.info_offset == 0) - return 0; - - /* If we need to force fallback processing, just pretend there is - no entry. */ - if (force_fallback_processing_for (pc, &vueblock)) - return 0; - - *segment_base = 0; /* ??? Fixme. ??? */ - *gp = vueblock.gp_value; - ent->start_offset = vueblock.start_offset; - ent->end_offset = vueblock.end_offset; - ent->info_offset = vueblock.info_offset; - - return ent; -} diff --git a/gcc/config/ia64/t-glibc b/gcc/config/ia64/t-glibc index e6d72b9..ce18a92 100644 --- a/gcc/config/ia64/t-glibc +++ b/gcc/config/ia64/t-glibc @@ -1,5 +1 @@ -# Use system libunwind library on IA-64 GLIBC based system. -LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c \ - $(srcdir)/unwind-compat.c - SHLIB_MAPFILES += $(srcdir)/config/ia64/libgcc-glibc.ver diff --git a/gcc/config/ia64/t-glibc-libunwind b/gcc/config/ia64/t-glibc-libunwind deleted file mode 100644 index df78f1d..0000000 --- a/gcc/config/ia64/t-glibc-libunwind +++ /dev/null @@ -1,4 +0,0 @@ -# Build libunwind for IA-64 GLIBC based system. -LIBUNWIND = $(srcdir)/config/ia64/fde-glibc.c \ - $(srcdir)/config/ia64/unwind-ia64.c -LIBUNWINDDEP = unwind.inc diff --git a/gcc/config/ia64/t-hpux b/gcc/config/ia64/t-hpux index a97ab5c..4aa6614 100644 --- a/gcc/config/ia64/t-hpux +++ b/gcc/config/ia64/t-hpux @@ -1,5 +1,5 @@ # Copyright (C) 2001, 2002, 2003, 2004, 2005, -# 2006 Free Software Foundation, Inc. +# 2006, 2011 Free Software Foundation, Inc. # # This file is part of GCC. # @@ -50,8 +50,6 @@ LIBGCC1_TEST = T_CFLAGS += -DUSE_LIBUNWIND_EXCEPTIONS -LIB2ADDEH = $(srcdir)/unwind-c.c - SHLIB_EXT = .so # Must include -lunwind in the link, so that libgcc_s.so has the necessary # DT_NEEDED entry for libunwind. diff --git a/gcc/config/ia64/t-ia64 b/gcc/config/ia64/t-ia64 index 4f013e2..f130f7c 100644 --- a/gcc/config/ia64/t-ia64 +++ b/gcc/config/ia64/t-ia64 @@ -43,9 +43,6 @@ SHLIB_MAPFILES += $(srcdir)/config/ia64/libgcc-ia64.ver # Effectively disable the crtbegin/end rules using crtstuff.c T = disable -LIB2ADDEH = $(srcdir)/config/ia64/unwind-ia64.c $(srcdir)/unwind-sjlj.c \ - $(srcdir)/unwind-c.c - ia64-c.o: $(srcdir)/config/ia64/ia64-c.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) $(CPPLIB_H) $(C_COMMON_H) $(C_PRAGMA_H) $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ diff --git a/gcc/config/ia64/t-vms b/gcc/config/ia64/t-vms index bcd7534..094d534 100644 --- a/gcc/config/ia64/t-vms +++ b/gcc/config/ia64/t-vms @@ -32,8 +32,6 @@ $(T)crtinitS.o: $(srcdir)/config/ia64/vms-crtinit.asm $(GCC_PASSES) $(GCC_FOR_TARGET) -I. -c -o $(T)crtinitS.o -x assembler-with-cpp \ $(srcdir)/config/ia64/vms-crtinit.asm -LIB2ADDEH += $(srcdir)/config/ia64/fde-vms.c - # Shared library macros shlib_version:=$(shell echo $(BASEVER_c) | sed -e 's/\./,/' -e 's/\.//g') SHLIB_EXT = .exe diff --git a/gcc/config/ia64/unwind-ia64.c b/gcc/config/ia64/unwind-ia64.c deleted file mode 100644 index 061bd4b..0000000 --- a/gcc/config/ia64/unwind-ia64.c +++ /dev/null @@ -1,2458 +0,0 @@ -/* Subroutines needed for unwinding IA-64 standard format stack frame - info for exception handling. - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, - 2009, 2011 Free Software Foundation, Inc. - Contributed by Andrew MacLeod <amacleod@cygnus.com> - Andrew Haley <aph@cygnus.com> - David Mosberger-Tang <davidm@hpl.hp.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 "tconfig.h" -#include "tsystem.h" -#include "coretypes.h" -#include "tm.h" -#include "unwind.h" -#include "unwind-ia64.h" -#include "unwind-compat.h" -#include "ia64intrin.h" - -/* This isn't thread safe, but nice for occasional tests. */ -#undef ENABLE_MALLOC_CHECKING - -#ifndef __USING_SJLJ_EXCEPTIONS__ - - -/* By default, assume personality routine interface compatibility with - our expectations. */ -#ifndef MD_UNW_COMPATIBLE_PERSONALITY_P -#define MD_UNW_COMPATIBLE_PERSONALITY_P(HEADER) 1 -#endif - -enum unw_application_register -{ - UNW_AR_BSP, - UNW_AR_BSPSTORE, - UNW_AR_PFS, - UNW_AR_RNAT, - UNW_AR_UNAT, - UNW_AR_LC, - UNW_AR_EC, - UNW_AR_FPSR, - UNW_AR_RSC, - UNW_AR_CCV -}; - -enum unw_register_index -{ - /* Primary UNAT. */ - UNW_REG_PRI_UNAT_GR, - UNW_REG_PRI_UNAT_MEM, - - /* Memory Stack. */ - UNW_REG_PSP, /* previous memory stack pointer */ - - /* Register Stack. */ - UNW_REG_BSP, /* register stack pointer */ - UNW_REG_BSPSTORE, - UNW_REG_PFS, /* previous function state */ - UNW_REG_RNAT, - /* Return Pointer. */ - UNW_REG_RP, - - /* Special preserved registers. */ - UNW_REG_UNAT, UNW_REG_PR, UNW_REG_LC, UNW_REG_FPSR, - - /* Non-stacked general registers. */ - UNW_REG_R2, - UNW_REG_R4 = UNW_REG_R2 + 2, - UNW_REG_R7 = UNW_REG_R2 + 5, - UNW_REG_R31 = UNW_REG_R2 + 29, - - /* Non-stacked floating point registers. */ - UNW_REG_F2, - UNW_REG_F5 = UNW_REG_F2 + 3, - UNW_REG_F16 = UNW_REG_F2 + 14, - UNW_REG_F31 = UNW_REG_F2 + 29, - - /* Branch registers. */ - UNW_REG_B0, UNW_REG_B1, - UNW_REG_B5 = UNW_REG_B1 + 4, - - UNW_NUM_REGS -}; - -enum unw_where -{ - UNW_WHERE_NONE, /* register isn't saved at all */ - UNW_WHERE_GR, /* register is saved in a general register */ - UNW_WHERE_FR, /* register is saved in a floating-point register */ - UNW_WHERE_BR, /* register is saved in a branch register */ - UNW_WHERE_SPREL, /* register is saved on memstack (sp-relative) */ - UNW_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */ - - /* At the end of each prologue these locations get resolved to - UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively. */ - UNW_WHERE_SPILL_HOME, /* register is saved in its spill home */ - UNW_WHERE_GR_SAVE /* register is saved in next general register */ -}; - -#define UNW_WHEN_NEVER 0x7fffffff - -struct unw_reg_info -{ - unsigned long val; /* save location: register number or offset */ - enum unw_where where; /* where the register gets saved */ - int when; /* when the register gets saved */ -}; - -struct unw_reg_state { - struct unw_reg_state *next; /* next (outer) element on state stack */ - struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */ -}; - -struct unw_labeled_state { - struct unw_labeled_state *next; /* next labeled state (or NULL) */ - unsigned long label; /* label for this state */ - struct unw_reg_state saved_state; -}; - -typedef struct unw_state_record -{ - unsigned int first_region : 1; /* is this the first region? */ - unsigned int done : 1; /* are we done scanning descriptors? */ - unsigned int any_spills : 1; /* got any register spills? */ - unsigned int in_body : 1; /* are we inside a body? */ - unsigned int no_reg_stack_frame : 1; /* Don't adjust bsp for i&l regs */ - unsigned char *imask; /* imask of spill_mask record or NULL */ - unsigned long pr_val; /* predicate values */ - unsigned long pr_mask; /* predicate mask */ - long spill_offset; /* psp-relative offset for spill base */ - int region_start; - int region_len; - int epilogue_start; - int epilogue_count; - int when_target; - - unsigned char gr_save_loc; /* next general register to use for saving */ - unsigned char return_link_reg; /* branch register for return link */ - unsigned short unwabi; - - struct unw_labeled_state *labeled_states; /* list of all labeled states */ - struct unw_reg_state curr; /* current state */ - - _Unwind_Personality_Fn personality; - -} _Unwind_FrameState; - -enum unw_nat_type -{ - UNW_NAT_NONE, /* NaT not represented */ - UNW_NAT_VAL, /* NaT represented by NaT value (fp reg) */ - UNW_NAT_MEMSTK, /* NaT value is in unat word at offset OFF */ - UNW_NAT_REGSTK /* NaT is in rnat */ -}; - -struct unw_stack -{ - unsigned long limit; - unsigned long top; -}; - -struct _Unwind_Context -{ - /* Initial frame info. */ - unsigned long rnat; /* rse nat collection */ - unsigned long regstk_top; /* lowest address of rbs stored register - which uses context->rnat collection */ - - /* Current frame info. */ - unsigned long bsp; /* backing store pointer value - corresponding to psp. */ - unsigned long sp; /* stack pointer value */ - unsigned long psp; /* previous sp value */ - unsigned long rp; /* return pointer */ - unsigned long pr; /* predicate collection */ - - unsigned long region_start; /* start of unwind region */ - unsigned long gp; /* global pointer value */ - void *lsda; /* language specific data area */ - - /* Preserved state. */ - unsigned long *bsp_loc; /* previous bsp save location - Appears to be write-only? */ - unsigned long *bspstore_loc; - unsigned long *pfs_loc; /* Save location for pfs in current - (corr. to sp) frame. Target - contains cfm for caller. */ - unsigned long *signal_pfs_loc;/* Save location for pfs in current - signal frame. Target contains - pfs for caller. */ - unsigned long *pri_unat_loc; - unsigned long *unat_loc; - unsigned long *lc_loc; - unsigned long *fpsr_loc; - - unsigned long eh_data[4]; - - struct unw_ireg - { - unsigned long *loc; - struct unw_ireg_nat - { - enum unw_nat_type type : 3; - signed long off : 61; /* NaT word is at loc+nat.off */ - } nat; - } ireg[32 - 2]; /* Indexed by <register number> - 2 */ - - unsigned long *br_loc[8]; - void *fr_loc[32 - 2]; - - /* ??? We initially point pri_unat_loc here. The entire NAT bit - logic needs work. */ - unsigned long initial_unat; -}; - -typedef unsigned long unw_word; - -/* Implicit register save order. See section 11.4.2.3 Rules for Using - Unwind Descriptors, rule 3. */ - -static unsigned char const save_order[] = -{ - UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR, - UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR -}; - - -#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) - -/* MASK is a bitmap describing the allocation state of emergency buffers, - with bit set indicating free. Return >= 0 if allocation is successful; - < 0 if failure. */ - -static inline int -atomic_alloc (unsigned int *mask) -{ - unsigned int old = *mask, ret, new; - - while (1) - { - if (old == 0) - return -1; - ret = old & -old; - new = old & ~ret; - new = __sync_val_compare_and_swap (mask, old, new); - if (old == new) - break; - old = new; - } - - return __builtin_ffs (ret) - 1; -} - -/* Similarly, free an emergency buffer. */ - -static inline void -atomic_free (unsigned int *mask, int bit) -{ - __sync_xor_and_fetch (mask, 1 << bit); -} - - -#define SIZE(X) (sizeof(X) / sizeof(*(X))) -#define MASK_FOR(X) ((2U << (SIZE (X) - 1)) - 1) -#define PTR_IN(X, P) ((P) >= (X) && (P) < (X) + SIZE (X)) - -static struct unw_reg_state emergency_reg_state[32]; -static unsigned int emergency_reg_state_free = MASK_FOR (emergency_reg_state); - -static struct unw_labeled_state emergency_labeled_state[8]; -static unsigned int emergency_labeled_state_free = MASK_FOR (emergency_labeled_state); - -#ifdef ENABLE_MALLOC_CHECKING -static int reg_state_alloced; -static int labeled_state_alloced; -#endif - -/* Allocation and deallocation of structures. */ - -static struct unw_reg_state * -alloc_reg_state (void) -{ - struct unw_reg_state *rs; - -#ifdef ENABLE_MALLOC_CHECKING - reg_state_alloced++; -#endif - - rs = malloc (sizeof (struct unw_reg_state)); - if (!rs) - { - int n = atomic_alloc (&emergency_reg_state_free); - if (n >= 0) - rs = &emergency_reg_state[n]; - } - - return rs; -} - -static void -free_reg_state (struct unw_reg_state *rs) -{ -#ifdef ENABLE_MALLOC_CHECKING - reg_state_alloced--; -#endif - - if (PTR_IN (emergency_reg_state, rs)) - atomic_free (&emergency_reg_state_free, rs - emergency_reg_state); - else - free (rs); -} - -static struct unw_labeled_state * -alloc_label_state (void) -{ - struct unw_labeled_state *ls; - -#ifdef ENABLE_MALLOC_CHECKING - labeled_state_alloced++; -#endif - - ls = malloc(sizeof(struct unw_labeled_state)); - if (!ls) - { - int n = atomic_alloc (&emergency_labeled_state_free); - if (n >= 0) - ls = &emergency_labeled_state[n]; - } - - return ls; -} - -static void -free_label_state (struct unw_labeled_state *ls) -{ -#ifdef ENABLE_MALLOC_CHECKING - labeled_state_alloced--; -#endif - - if (PTR_IN (emergency_labeled_state, ls)) - atomic_free (&emergency_labeled_state_free, emergency_labeled_state - ls); - else - free (ls); -} - -/* Routines to manipulate the state stack. */ - -static void -push (struct unw_state_record *sr) -{ - struct unw_reg_state *rs = alloc_reg_state (); - memcpy (rs, &sr->curr, sizeof (*rs)); - sr->curr.next = rs; -} - -static void -pop (struct unw_state_record *sr) -{ - struct unw_reg_state *rs = sr->curr.next; - - if (!rs) - abort (); - memcpy (&sr->curr, rs, sizeof(*rs)); - free_reg_state (rs); -} - -/* Make a copy of the state stack. Non-recursive to avoid stack overflows. */ - -static struct unw_reg_state * -dup_state_stack (struct unw_reg_state *rs) -{ - struct unw_reg_state *copy, *prev = NULL, *first = NULL; - - while (rs) - { - copy = alloc_reg_state (); - memcpy (copy, rs, sizeof(*copy)); - if (first) - prev->next = copy; - else - first = copy; - rs = rs->next; - prev = copy; - } - - return first; -} - -/* Free all stacked register states (but not RS itself). */ -static void -free_state_stack (struct unw_reg_state *rs) -{ - struct unw_reg_state *p, *next; - - for (p = rs->next; p != NULL; p = next) - { - next = p->next; - free_reg_state (p); - } - rs->next = NULL; -} - -/* Free all labeled states. */ - -static void -free_label_states (struct unw_labeled_state *ls) -{ - struct unw_labeled_state *next; - - for (; ls ; ls = next) - { - next = ls->next; - - free_state_stack (&ls->saved_state); - free_label_state (ls); - } -} - -/* Unwind decoder routines */ - -static enum unw_register_index __attribute__((const)) -decode_abreg (unsigned char abreg, int memory) -{ - switch (abreg) - { -#if TARGET_ABI_OPEN_VMS - /* OpenVMS Calling Standard specifies R3 - R31. */ - case 0x03 ... 0x1f: return UNW_REG_R2 + (abreg - 0x02); -#else - /* Standard Intel ABI specifies GR 4 - 7. */ - case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04); -#endif - case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22); - case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30); - case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41); - case 0x60: return UNW_REG_PR; - case 0x61: return UNW_REG_PSP; - case 0x62: return memory ? UNW_REG_PRI_UNAT_MEM : UNW_REG_PRI_UNAT_GR; - case 0x63: return UNW_REG_RP; - case 0x64: return UNW_REG_BSP; - case 0x65: return UNW_REG_BSPSTORE; - case 0x66: return UNW_REG_RNAT; - case 0x67: return UNW_REG_UNAT; - case 0x68: return UNW_REG_FPSR; - case 0x69: return UNW_REG_PFS; - case 0x6a: return UNW_REG_LC; - default: - abort (); - } -} - -static void -set_reg (struct unw_reg_info *reg, enum unw_where where, - int when, unsigned long val) -{ - reg->val = val; - reg->where = where; - if (reg->when == UNW_WHEN_NEVER) - reg->when = when; -} - -static void -alloc_spill_area (unsigned long *offp, unsigned long regsize, - struct unw_reg_info *lo, struct unw_reg_info *hi) -{ - struct unw_reg_info *reg; - - for (reg = hi; reg >= lo; --reg) - { - if (reg->where == UNW_WHERE_SPILL_HOME) - { - reg->where = UNW_WHERE_PSPREL; - *offp -= regsize; - reg->val = *offp; - } - } -} - -static inline void -spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim, - unw_word t) -{ - struct unw_reg_info *reg; - - for (reg = *regp; reg <= lim; ++reg) - { - if (reg->where == UNW_WHERE_SPILL_HOME) - { - reg->when = t; - *regp = reg + 1; - return; - } - } - /* Excess spill. */ - abort (); -} - -static void -finish_prologue (struct unw_state_record *sr) -{ - struct unw_reg_info *reg; - unsigned long off; - int i; - - /* First, resolve implicit register save locations - (see Section "11.4.2.3 Rules for Using Unwind Descriptors", rule 3). */ - - for (i = 0; i < (int) sizeof (save_order); ++i) - { - reg = sr->curr.reg + save_order[i]; - if (reg->where == UNW_WHERE_GR_SAVE) - { - reg->where = UNW_WHERE_GR; - reg->val = sr->gr_save_loc++; - } - } - - /* Next, compute when the fp, general, and branch registers get saved. - This must come before alloc_spill_area() because we need to know - which registers are spilled to their home locations. */ - if (sr->imask) - { - static unsigned char const limit[3] = { - UNW_REG_F31, UNW_REG_R7, UNW_REG_B5 - }; - - unsigned char kind, mask = 0, *cp = sr->imask; - int t; - struct unw_reg_info *(regs[3]); - - regs[0] = sr->curr.reg + UNW_REG_F2; - regs[1] = sr->curr.reg + UNW_REG_R4; - regs[2] = sr->curr.reg + UNW_REG_B1; - - for (t = 0; t < sr->region_len; ++t) - { - if ((t & 3) == 0) - mask = *cp++; - kind = (mask >> 2*(3-(t & 3))) & 3; - if (kind > 0) - spill_next_when (®s[kind - 1], sr->curr.reg + limit[kind - 1], - sr->region_start + t); - } - } - - /* Next, lay out the memory stack spill area. */ - if (sr->any_spills) - { - off = sr->spill_offset; - alloc_spill_area (&off, 16, sr->curr.reg + UNW_REG_F2, - sr->curr.reg + UNW_REG_F31); - alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_B1, - sr->curr.reg + UNW_REG_B5); - alloc_spill_area (&off, 8, sr->curr.reg + UNW_REG_R4, - sr->curr.reg + UNW_REG_R7); - } -} - -/* - * Region header descriptors. - */ - -static void -desc_prologue (int body, unw_word rlen, unsigned char mask, - unsigned char grsave, struct unw_state_record *sr) -{ - int i; - - if (!(sr->in_body || sr->first_region)) - finish_prologue (sr); - sr->first_region = 0; - - /* Check if we're done. */ - if (sr->when_target < sr->region_start + sr->region_len) - { - sr->done = 1; - return; - } - - for (i = 0; i < sr->epilogue_count; ++i) - pop (sr); - - sr->epilogue_count = 0; - sr->epilogue_start = UNW_WHEN_NEVER; - - if (!body) - push (sr); - - sr->region_start += sr->region_len; - sr->region_len = rlen; - sr->in_body = body; - - if (!body) - { - for (i = 0; i < 4; ++i) - { - if (mask & 0x8) - set_reg (sr->curr.reg + save_order[i], UNW_WHERE_GR, - sr->region_start + sr->region_len - 1, grsave++); - mask <<= 1; - } - sr->gr_save_loc = grsave; - sr->any_spills = 0; - sr->imask = 0; - sr->spill_offset = 0x10; /* default to psp+16 */ - } -} - -/* - * Prologue descriptors. - */ - -static inline void -desc_abi (unsigned char abi, - unsigned char context, - struct unw_state_record *sr) -{ - sr->unwabi = (abi << 8) | context; -} - -static inline void -desc_br_gr (unsigned char brmask, unsigned char gr, - struct unw_state_record *sr) -{ - int i; - - for (i = 0; i < 5; ++i) - { - if (brmask & 1) - set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_GR, - sr->region_start + sr->region_len - 1, gr++); - brmask >>= 1; - } -} - -static inline void -desc_br_mem (unsigned char brmask, struct unw_state_record *sr) -{ - int i; - - for (i = 0; i < 5; ++i) - { - if (brmask & 1) - { - set_reg (sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_SPILL_HOME, - sr->region_start + sr->region_len - 1, 0); - sr->any_spills = 1; - } - brmask >>= 1; - } -} - -static inline void -desc_frgr_mem (unsigned char grmask, unw_word frmask, - struct unw_state_record *sr) -{ - int i; - - for (i = 0; i < 4; ++i) - { - if ((grmask & 1) != 0) - { - set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME, - sr->region_start + sr->region_len - 1, 0); - sr->any_spills = 1; - } - grmask >>= 1; - } - for (i = 0; i < 20; ++i) - { - if ((frmask & 1) != 0) - { - enum unw_register_index base = i < 4 ? UNW_REG_F2 : UNW_REG_F16 - 4; - set_reg (sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME, - sr->region_start + sr->region_len - 1, 0); - sr->any_spills = 1; - } - frmask >>= 1; - } -} - -static inline void -desc_fr_mem (unsigned char frmask, struct unw_state_record *sr) -{ - int i; - - for (i = 0; i < 4; ++i) - { - if ((frmask & 1) != 0) - { - set_reg (sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME, - sr->region_start + sr->region_len - 1, 0); - sr->any_spills = 1; - } - frmask >>= 1; - } -} - -static inline void -desc_gr_gr (unsigned char grmask, unsigned char gr, - struct unw_state_record *sr) -{ - int i; - - for (i = 0; i < 4; ++i) - { - if ((grmask & 1) != 0) - set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_GR, - sr->region_start + sr->region_len - 1, gr++); - grmask >>= 1; - } -} - -static inline void -desc_gr_mem (unsigned char grmask, struct unw_state_record *sr) -{ - int i; - - for (i = 0; i < 4; ++i) - { - if ((grmask & 1) != 0) - { - set_reg (sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME, - sr->region_start + sr->region_len - 1, 0); - sr->any_spills = 1; - } - grmask >>= 1; - } -} - -static inline void -desc_mem_stack_f (unw_word t, unw_word size, struct unw_state_record *sr) -{ - set_reg (sr->curr.reg + UNW_REG_PSP, UNW_WHERE_NONE, - sr->region_start + MIN ((int)t, sr->region_len - 1), 16*size); -} - -static inline void -desc_mem_stack_v (unw_word t, struct unw_state_record *sr) -{ - sr->curr.reg[UNW_REG_PSP].when - = sr->region_start + MIN ((int)t, sr->region_len - 1); -} - -static inline void -desc_reg_gr (unsigned char reg, unsigned char dst, struct unw_state_record *sr) -{ - set_reg (sr->curr.reg + reg, UNW_WHERE_GR, - sr->region_start + sr->region_len - 1, dst); -} - -static inline void -desc_reg_psprel (unsigned char reg, unw_word pspoff, - struct unw_state_record *sr) -{ - set_reg (sr->curr.reg + reg, UNW_WHERE_PSPREL, - sr->region_start + sr->region_len - 1, - 0x10 - 4*pspoff); -} - -static inline void -desc_reg_sprel (unsigned char reg, unw_word spoff, struct unw_state_record *sr) -{ - set_reg (sr->curr.reg + reg, UNW_WHERE_SPREL, - sr->region_start + sr->region_len - 1, - 4*spoff); -} - -static inline void -desc_rp_br (unsigned char dst, struct unw_state_record *sr) -{ - sr->return_link_reg = dst; -} - -static inline void -desc_reg_when (unsigned char regnum, unw_word t, struct unw_state_record *sr) -{ - struct unw_reg_info *reg = sr->curr.reg + regnum; - - if (reg->where == UNW_WHERE_NONE) - reg->where = UNW_WHERE_GR_SAVE; - reg->when = sr->region_start + MIN ((int)t, sr->region_len - 1); -} - -static inline void -desc_spill_base (unw_word pspoff, struct unw_state_record *sr) -{ - sr->spill_offset = 0x10 - 4*pspoff; -} - -static inline unsigned char * -desc_spill_mask (unsigned char *imaskp, struct unw_state_record *sr) -{ - sr->imask = imaskp; - return imaskp + (2*sr->region_len + 7)/8; -} - -/* - * Body descriptors. - */ -static inline void -desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr) -{ - sr->epilogue_start = sr->region_start + sr->region_len - 1 - t; - sr->epilogue_count = ecount + 1; -} - -static inline void -desc_copy_state (unw_word label, struct unw_state_record *sr) -{ - struct unw_labeled_state *ls; - - for (ls = sr->labeled_states; ls; ls = ls->next) - { - if (ls->label == label) - { - free_state_stack (&sr->curr); - memcpy (&sr->curr, &ls->saved_state, sizeof (sr->curr)); - sr->curr.next = dup_state_stack (ls->saved_state.next); - return; - } - } - abort (); -} - -static inline void -desc_label_state (unw_word label, struct unw_state_record *sr) -{ - struct unw_labeled_state *ls = alloc_label_state (); - - ls->label = label; - memcpy (&ls->saved_state, &sr->curr, sizeof (ls->saved_state)); - ls->saved_state.next = dup_state_stack (sr->curr.next); - - /* Insert into list of labeled states. */ - ls->next = sr->labeled_states; - sr->labeled_states = ls; -} - -/* - * General descriptors. - */ - -static inline int -desc_is_active (unsigned char qp, unw_word t, struct unw_state_record *sr) -{ - if (sr->when_target <= sr->region_start + MIN ((int)t, sr->region_len - 1)) - return 0; - if (qp > 0) - { - if ((sr->pr_val & (1UL << qp)) == 0) - return 0; - sr->pr_mask |= (1UL << qp); - } - return 1; -} - -static inline void -desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg, - struct unw_state_record *sr) -{ - struct unw_reg_info *r; - - if (! desc_is_active (qp, t, sr)) - return; - - r = sr->curr.reg + decode_abreg (abreg, 0); - r->where = UNW_WHERE_NONE; - r->when = sr->region_start + MIN ((int)t, sr->region_len - 1); - r->val = 0; -} - -static inline void -desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg, - unsigned char x, unsigned char ytreg, - struct unw_state_record *sr) -{ - enum unw_where where = UNW_WHERE_GR; - struct unw_reg_info *r; - - if (! desc_is_active (qp, t, sr)) - return; - - if (x) - where = UNW_WHERE_BR; - else if (ytreg & 0x80) - where = UNW_WHERE_FR; - - r = sr->curr.reg + decode_abreg (abreg, 0); - r->where = where; - r->when = sr->region_start + MIN ((int)t, sr->region_len - 1); - r->val = ytreg & 0x7f; -} - -static inline void -desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg, - unw_word pspoff, struct unw_state_record *sr) -{ - struct unw_reg_info *r; - - if (! desc_is_active (qp, t, sr)) - return; - - r = sr->curr.reg + decode_abreg (abreg, 1); - r->where = UNW_WHERE_PSPREL; - r->when = sr->region_start + MIN((int)t, sr->region_len - 1); - r->val = 0x10 - 4*pspoff; -} - -static inline void -desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, - unw_word spoff, struct unw_state_record *sr) -{ - struct unw_reg_info *r; - - if (! desc_is_active (qp, t, sr)) - return; - - r = sr->curr.reg + decode_abreg (abreg, 1); - r->where = UNW_WHERE_SPREL; - r->when = sr->region_start + MIN ((int)t, sr->region_len - 1); - r->val = 4*spoff; -} - - -#define UNW_DEC_BAD_CODE(code) abort (); - -/* Region headers. */ -#define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg) -#define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg) - -/* Prologue descriptors. */ -#define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg) -#define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg) -#define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg) -#define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg) -#define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg) -#define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg) -#define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg) -#define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg) -#define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg) -#define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg) -#define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg) -#define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg) -#define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg) -#define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg) -#define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg) -#define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg) -#define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg) -#define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg) -#define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg) -#define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg) -#define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg)) - -/* Body descriptors. */ -#define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg) -#define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg) -#define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg) - -/* General unwind descriptors. */ -#define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg) -#define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg) -#define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg) -#define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg) -#define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg) -#define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg) -#define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg) -#define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg) - - -/* - * Generic IA-64 unwind info decoder. - * - * This file is used both by the Linux kernel and objdump. Please keep - * the copies of this file in sync. - * - * You need to customize the decoder by defining the following - * macros/constants before including this file: - * - * Types: - * unw_word Unsigned integer type with at least 64 bits - * - * Register names: - * UNW_REG_BSP - * UNW_REG_BSPSTORE - * UNW_REG_FPSR - * UNW_REG_LC - * UNW_REG_PFS - * UNW_REG_PR - * UNW_REG_RNAT - * UNW_REG_PSP - * UNW_REG_RP - * UNW_REG_UNAT - * - * Decoder action macros: - * UNW_DEC_BAD_CODE(code) - * UNW_DEC_ABI(fmt,abi,context,arg) - * UNW_DEC_BR_GR(fmt,brmask,gr,arg) - * UNW_DEC_BR_MEM(fmt,brmask,arg) - * UNW_DEC_COPY_STATE(fmt,label,arg) - * UNW_DEC_EPILOGUE(fmt,t,ecount,arg) - * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg) - * UNW_DEC_FR_MEM(fmt,frmask,arg) - * UNW_DEC_GR_GR(fmt,grmask,gr,arg) - * UNW_DEC_GR_MEM(fmt,grmask,arg) - * UNW_DEC_LABEL_STATE(fmt,label,arg) - * UNW_DEC_MEM_STACK_F(fmt,t,size,arg) - * UNW_DEC_MEM_STACK_V(fmt,t,arg) - * UNW_DEC_PRIUNAT_GR(fmt,r,arg) - * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) - * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) - * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg) - * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg) - * UNW_DEC_PROLOGUE(fmt,body,rlen,arg) - * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg) - * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg) - * UNW_DEC_REG_REG(fmt,src,dst,arg) - * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg) - * UNW_DEC_REG_WHEN(fmt,reg,t,arg) - * UNW_DEC_RESTORE(fmt,t,abreg,arg) - * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg) - * UNW_DEC_SPILL_BASE(fmt,pspoff,arg) - * UNW_DEC_SPILL_MASK(fmt,imaskp,arg) - * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg) - * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg) - * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg) - * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg) - * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg) - * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg) - */ - -static unw_word -unw_decode_uleb128 (unsigned char **dpp) -{ - unsigned shift = 0; - unw_word byte, result = 0; - unsigned char *bp = *dpp; - - while (1) - { - byte = *bp++; - result |= (byte & 0x7f) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - *dpp = bp; - return result; -} - -static unsigned char * -unw_decode_x1 (unsigned char *dp, - unsigned char code __attribute__((unused)), - void *arg) -{ - unsigned char byte1, abreg; - unw_word t, off; - - byte1 = *dp++; - t = unw_decode_uleb128 (&dp); - off = unw_decode_uleb128 (&dp); - abreg = (byte1 & 0x7f); - if (byte1 & 0x80) - UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg); - else - UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg); - return dp; -} - -static unsigned char * -unw_decode_x2 (unsigned char *dp, - unsigned char code __attribute__((unused)), - void *arg) -{ - unsigned char byte1, byte2, abreg, x, ytreg; - unw_word t; - - byte1 = *dp++; byte2 = *dp++; - t = unw_decode_uleb128 (&dp); - abreg = (byte1 & 0x7f); - ytreg = byte2; - x = (byte1 >> 7) & 1; - if ((byte1 & 0x80) == 0 && ytreg == 0) - UNW_DEC_RESTORE(X2, t, abreg, arg); - else - UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg); - return dp; -} - -static unsigned char * -unw_decode_x3 (unsigned char *dp, - unsigned char code __attribute__((unused)), - void *arg) -{ - unsigned char byte1, byte2, abreg, qp; - unw_word t, off; - - byte1 = *dp++; byte2 = *dp++; - t = unw_decode_uleb128 (&dp); - off = unw_decode_uleb128 (&dp); - - qp = (byte1 & 0x3f); - abreg = (byte2 & 0x7f); - - if (byte1 & 0x80) - UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg); - else - UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg); - return dp; -} - -static unsigned char * -unw_decode_x4 (unsigned char *dp, - unsigned char code __attribute__((unused)), - void *arg) -{ - unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg; - unw_word t; - - byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; - t = unw_decode_uleb128 (&dp); - - qp = (byte1 & 0x3f); - abreg = (byte2 & 0x7f); - x = (byte2 >> 7) & 1; - ytreg = byte3; - - if ((byte2 & 0x80) == 0 && byte3 == 0) - UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg); - else - UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg); - return dp; -} - -static unsigned char * -unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg) -{ - int body = (code & 0x20) != 0; - unw_word rlen; - - rlen = (code & 0x1f); - UNW_DEC_PROLOGUE(R1, body, rlen, arg); - return dp; -} - -static unsigned char * -unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg) -{ - unsigned char byte1, mask, grsave; - unw_word rlen; - - byte1 = *dp++; - - mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); - grsave = (byte1 & 0x7f); - rlen = unw_decode_uleb128 (&dp); - UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg); - return dp; -} - -static unsigned char * -unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg) -{ - unw_word rlen; - - rlen = unw_decode_uleb128 (&dp); - UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg); - return dp; -} - -static unsigned char * -unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg) -{ - unsigned char brmask = (code & 0x1f); - - UNW_DEC_BR_MEM(P1, brmask, arg); - return dp; -} - -static unsigned char * -unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg) -{ - if ((code & 0x10) == 0) - { - unsigned char byte1 = *dp++; - - UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1), - (byte1 & 0x7f), arg); - } - else if ((code & 0x08) == 0) - { - unsigned char byte1 = *dp++, r, dst; - - r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); - dst = (byte1 & 0x7f); - switch (r) - { - case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break; - case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break; - case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break; - case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break; - case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break; - case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break; - case 6: UNW_DEC_RP_BR(P3, dst, arg); break; - case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break; - case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break; - case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break; - case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break; - case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break; - default: UNW_DEC_BAD_CODE(r); break; - } - } - else if ((code & 0x7) == 0) - UNW_DEC_SPILL_MASK(P4, dp, arg); - else if ((code & 0x7) == 1) - { - unw_word grmask, frmask, byte1, byte2, byte3; - - byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; - grmask = ((byte1 >> 4) & 0xf); - frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3; - UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg); - } - else - UNW_DEC_BAD_CODE(code); - return dp; -} - -static unsigned char * -unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg) -{ - int gregs = (code & 0x10) != 0; - unsigned char mask = (code & 0x0f); - - if (gregs) - UNW_DEC_GR_MEM(P6, mask, arg); - else - UNW_DEC_FR_MEM(P6, mask, arg); - return dp; -} - -static unsigned char * -unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg) -{ - unsigned char r, byte1, byte2; - unw_word t, size; - - if ((code & 0x10) == 0) - { - r = (code & 0xf); - t = unw_decode_uleb128 (&dp); - switch (r) - { - case 0: - size = unw_decode_uleb128 (&dp); - UNW_DEC_MEM_STACK_F(P7, t, size, arg); - break; - - case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break; - case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break; - case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break; - case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break; - case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break; - case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break; - case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break; - case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break; - case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break; - case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break; - case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break; - case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break; - case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break; - case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break; - case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break; - default: UNW_DEC_BAD_CODE(r); break; - } - } - else - { - switch (code & 0xf) - { - case 0x0: /* p8 */ - { - r = *dp++; - t = unw_decode_uleb128 (&dp); - switch (r) - { - case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break; - case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break; - case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break; - case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break; - case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break; - case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break; - case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break; - case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break; - case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break; - case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break; - case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break; - case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break; - case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break; - case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break; - case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break; - case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break; - case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break; - case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break; - case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break; - default: UNW_DEC_BAD_CODE(r); break; - } - } - break; - - case 0x1: - byte1 = *dp++; byte2 = *dp++; - UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg); - break; - - case 0xf: /* p10 */ - byte1 = *dp++; byte2 = *dp++; - UNW_DEC_ABI(P10, byte1, byte2, arg); - break; - - case 0x9: - return unw_decode_x1 (dp, code, arg); - - case 0xa: - return unw_decode_x2 (dp, code, arg); - - case 0xb: - return unw_decode_x3 (dp, code, arg); - - case 0xc: - return unw_decode_x4 (dp, code, arg); - - default: - UNW_DEC_BAD_CODE(code); - break; - } - } - return dp; -} - -static unsigned char * -unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg) -{ - unw_word label = (code & 0x1f); - - if ((code & 0x20) != 0) - UNW_DEC_COPY_STATE(B1, label, arg); - else - UNW_DEC_LABEL_STATE(B1, label, arg); - return dp; -} - -static unsigned char * -unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg) -{ - unw_word t; - - t = unw_decode_uleb128 (&dp); - UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg); - return dp; -} - -static unsigned char * -unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg) -{ - unw_word t, ecount, label; - - if ((code & 0x10) == 0) - { - t = unw_decode_uleb128 (&dp); - ecount = unw_decode_uleb128 (&dp); - UNW_DEC_EPILOGUE(B3, t, ecount, arg); - } - else if ((code & 0x07) == 0) - { - label = unw_decode_uleb128 (&dp); - if ((code & 0x08) != 0) - UNW_DEC_COPY_STATE(B4, label, arg); - else - UNW_DEC_LABEL_STATE(B4, label, arg); - } - else - switch (code & 0x7) - { - case 1: return unw_decode_x1 (dp, code, arg); - case 2: return unw_decode_x2 (dp, code, arg); - case 3: return unw_decode_x3 (dp, code, arg); - case 4: return unw_decode_x4 (dp, code, arg); - default: UNW_DEC_BAD_CODE(code); break; - } - return dp; -} - -typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *); - -static const unw_decoder unw_decode_table[2][8] = -{ - /* prologue table: */ - { - unw_decode_r1, /* 0 */ - unw_decode_r1, - unw_decode_r2, - unw_decode_r3, - unw_decode_p1, /* 4 */ - unw_decode_p2_p5, - unw_decode_p6, - unw_decode_p7_p10 - }, - { - unw_decode_r1, /* 0 */ - unw_decode_r1, - unw_decode_r2, - unw_decode_r3, - unw_decode_b1, /* 4 */ - unw_decode_b1, - unw_decode_b2, - unw_decode_b3_x4 - } -}; - -/* - * Decode one descriptor and return address of next descriptor. - */ -static inline unsigned char * -unw_decode (unsigned char *dp, int inside_body, void *arg) -{ - unw_decoder decoder; - unsigned char code; - - code = *dp++; - decoder = unw_decode_table[inside_body][code >> 5]; - dp = (*decoder) (dp, code, arg); - return dp; -} - - -/* RSE helper functions. */ - -static inline unsigned long -ia64_rse_slot_num (unsigned long *addr) -{ - return (((unsigned long) addr) >> 3) & 0x3f; -} - -/* Return TRUE if ADDR is the address of an RNAT slot. */ -static inline unsigned long -ia64_rse_is_rnat_slot (unsigned long *addr) -{ - return ia64_rse_slot_num (addr) == 0x3f; -} - -/* Returns the address of the RNAT slot that covers the slot at - address SLOT_ADDR. */ -static inline unsigned long * -ia64_rse_rnat_addr (unsigned long *slot_addr) -{ - return (unsigned long *) ((unsigned long) slot_addr | (0x3f << 3)); -} - -/* Calculate the number of registers in the dirty partition starting at - BSPSTORE with a size of DIRTY bytes. This isn't simply DIRTY - divided by eight because the 64th slot is used to store ar.rnat. */ -static inline unsigned long -ia64_rse_num_regs (unsigned long *bspstore, unsigned long *bsp) -{ - unsigned long slots = (bsp - bspstore); - - return slots - (ia64_rse_slot_num (bspstore) + slots)/0x40; -} - -/* The inverse of the above: given bspstore and the number of - registers, calculate ar.bsp. */ -static inline unsigned long * -ia64_rse_skip_regs (unsigned long *addr, long num_regs) -{ - long delta = ia64_rse_slot_num (addr) + num_regs; - - if (num_regs < 0) - delta -= 0x3e; - return addr + num_regs + delta/0x3f; -} - - -/* Copy register backing store from SRC to DST, LEN words - (which include both saved registers and nat collections). - DST_RNAT is a partial nat collection for DST. SRC and DST - don't have to be equal modulo 64 slots, so it cannot be - done with a simple memcpy as the nat collections will be - at different relative offsets and need to be combined together. */ -static void -ia64_copy_rbs (struct _Unwind_Context *info, unsigned long dst, - unsigned long src, long len, unsigned long dst_rnat) -{ - long count; - unsigned long src_rnat; - unsigned long shift1, shift2; - - len <<= 3; - dst_rnat &= (1UL << ((dst >> 3) & 0x3f)) - 1; - src_rnat = src >= info->regstk_top - ? info->rnat : *(unsigned long *) (src | 0x1f8); - src_rnat &= ~((1UL << ((src >> 3) & 0x3f)) - 1); - /* Just to make sure. */ - src_rnat &= ~(1UL << 63); - shift1 = ((dst - src) >> 3) & 0x3f; - if ((dst & 0x1f8) < (src & 0x1f8)) - shift1--; - shift2 = 0x3f - shift1; - if ((dst & 0x1f8) >= (src & 0x1f8)) - { - count = ~dst & 0x1f8; - goto first; - } - count = ~src & 0x1f8; - goto second; - while (len > 0) - { - src_rnat = src >= info->regstk_top - ? info->rnat : *(unsigned long *) (src | 0x1f8); - /* Just to make sure. */ - src_rnat &= ~(1UL << 63); - count = shift2 << 3; -first: - if (count > len) - count = len; - memcpy ((char *) dst, (char *) src, count); - dst += count; - src += count; - len -= count; - dst_rnat |= (src_rnat << shift1) & ~(1UL << 63); - if (len <= 0) - break; - *(long *) dst = dst_rnat; - dst += 8; - dst_rnat = 0; - count = shift1 << 3; -second: - if (count > len) - count = len; - memcpy ((char *) dst, (char *) src, count); - dst += count; - src += count + 8; - len -= count + 8; - dst_rnat |= (src_rnat >> shift2); - } - if ((dst & 0x1f8) == 0x1f8) - { - *(long *) dst = dst_rnat; - dst += 8; - dst_rnat = 0; - } - /* Set info->regstk_top to lowest rbs address which will use - info->rnat collection. */ - info->regstk_top = dst & ~0x1ffUL; - info->rnat = dst_rnat; -} - -/* Unwind accessors. */ - -static void -unw_access_gr (struct _Unwind_Context *info, int regnum, - unsigned long *val, char *nat, int write) -{ - unsigned long *addr, *nat_addr = 0, nat_mask = 0, dummy_nat; - struct unw_ireg *ireg; - - if ((unsigned) regnum - 1 >= 127) - abort (); - - if (regnum < 1) - { - nat_addr = addr = &dummy_nat; - dummy_nat = 0; - } - else if (regnum < 32) - { - /* Access a non-stacked register. */ - ireg = &info->ireg[regnum - 2]; - addr = ireg->loc; - if (addr) - { - nat_addr = addr + ireg->nat.off; - switch (ireg->nat.type) - { - case UNW_NAT_VAL: - /* Simulate getf.sig/setf.sig. */ - if (write) - { - if (*nat) - { - /* Write NaTVal and be done with it. */ - addr[0] = 0; - addr[1] = 0x1fffe; - return; - } - addr[1] = 0x1003e; - } - else if (addr[0] == 0 && addr[1] == 0x1ffe) - { - /* Return NaT and be done with it. */ - *val = 0; - *nat = 1; - return; - } - /* FALLTHRU */ - - case UNW_NAT_NONE: - dummy_nat = 0; - nat_addr = &dummy_nat; - break; - - case UNW_NAT_MEMSTK: - nat_mask = 1UL << ((long) addr & 0x1f8)/8; - break; - - case UNW_NAT_REGSTK: - if ((unsigned long) addr >= info->regstk_top) - nat_addr = &info->rnat; - else - nat_addr = ia64_rse_rnat_addr (addr); - nat_mask = 1UL << ia64_rse_slot_num (addr); - break; - } - } - } - else - { - /* Access a stacked register. */ - addr = ia64_rse_skip_regs ((unsigned long *) info->bsp, regnum - 32); - if ((unsigned long) addr >= info->regstk_top) - nat_addr = &info->rnat; - else - nat_addr = ia64_rse_rnat_addr (addr); - nat_mask = 1UL << ia64_rse_slot_num (addr); - } - - if (write) - { - *addr = *val; - if (*nat) - *nat_addr |= nat_mask; - else - *nat_addr &= ~nat_mask; - } - else - { - *val = *addr; - *nat = (*nat_addr & nat_mask) != 0; - } -} - -/* Get the value of register REG as saved in CONTEXT. */ - -_Unwind_Word -_Unwind_GetGR (struct _Unwind_Context *context, int index) -{ - _Unwind_Word ret; - char nat; - - if (index == 1) - return context->gp; - else if (index >= 15 && index <= 18) - return context->eh_data[index - 15]; - else - unw_access_gr (context, index, &ret, &nat, 0); - - return ret; -} - -/* Overwrite the saved value for register REG in CONTEXT with VAL. */ - -void -_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val) -{ - char nat = 0; - - if (index == 1) - context->gp = val; - else if (index >= 15 && index <= 18) - context->eh_data[index - 15] = val; - else - unw_access_gr (context, index, &val, &nat, 1); -} - -/* Retrieve the return address for CONTEXT. */ - -inline _Unwind_Ptr -_Unwind_GetIP (struct _Unwind_Context *context) -{ - return context->rp; -} - -inline _Unwind_Ptr -_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) -{ - *ip_before_insn = 0; - return context->rp; -} - -/* Overwrite the return address for CONTEXT with VAL. */ - -inline void -_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val) -{ - context->rp = val; -} - -void * -_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context) -{ - return context->lsda; -} - -_Unwind_Ptr -_Unwind_GetRegionStart (struct _Unwind_Context *context) -{ - return context->region_start; -} - -void * -_Unwind_FindEnclosingFunction (void *pc) -{ - struct unw_table_entry *entp, ent; - unsigned long segment_base, gp; - - entp = _Unwind_FindTableEntry (pc, &segment_base, &gp, &ent); - if (entp == NULL) - return NULL; - else - return (void *)(segment_base + entp->start_offset); -} - -/* Get the value of the CFA as saved in CONTEXT. In GCC/Dwarf2 parlance, - the CFA is the value of the stack pointer on entry; In IA-64 unwind - parlance, this is the PSP. */ - -_Unwind_Word -_Unwind_GetCFA (struct _Unwind_Context *context) -{ - return (_Unwind_Ptr) context->psp; -} - -/* Get the value of the Backing Store Pointer as saved in CONTEXT. */ - -_Unwind_Word -_Unwind_GetBSP (struct _Unwind_Context *context) -{ - return (_Unwind_Ptr) context->bsp; -} - -#include "md-unwind-support.h" - -static _Unwind_Reason_Code -uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) -{ - struct unw_table_entry *entp, ent; - unsigned long *unw, header, length; - unsigned char *insn, *insn_end; - unsigned long segment_base; - struct unw_reg_info *r; - - memset (fs, 0, sizeof (*fs)); - for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r) - r->when = UNW_WHEN_NEVER; - context->lsda = 0; - - entp = _Unwind_FindTableEntry ((void *) context->rp, - &segment_base, &context->gp, &ent); - if (entp == NULL) - { - /* Couldn't find unwind info for this function. Try an - os-specific fallback mechanism. This will necessarily - not provide a personality routine or LSDA. */ -#ifdef MD_FALLBACK_FRAME_STATE_FOR - if (MD_FALLBACK_FRAME_STATE_FOR (context, fs) == _URC_NO_REASON) - return _URC_NO_REASON; -#endif - - /* [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 - an unwind table entry. - - This can only happen in the frame after unwinding through a signal - handler. Avoid infinite looping by requiring that B0 != RP. - RP == 0 terminates the chain. */ - if (context->br_loc[0] - && *context->br_loc[0] != context->rp - && context->rp != 0) - goto skip_unwind_info; - - return _URC_END_OF_STACK; - } - - context->region_start = entp->start_offset + segment_base; - fs->when_target = ((context->rp & -16) - context->region_start) / 16 * 3 - + (context->rp & 15); - - unw = (unsigned long *) (entp->info_offset + segment_base); - header = *unw; - length = UNW_LENGTH (header); - - /* Some operating systems use the personality routine slot in way not - compatible with what we expect. For instance, OpenVMS uses this slot to - designate "condition handlers" with very different arguments than what we - would be providing. Such cases are typically identified from OS specific - bits in the unwind information block header, and checked by the target - MD_UNW_COMPATIBLE_PERSONALITY_P macro. - - We just pretend there is no personality from our standpoint in such - situations, and expect GCC not to set the identifying bits itself so that - compatible personalities for GCC compiled code are called. - - Of course, this raises the question of what combinations of native/GCC - calls can be expected to behave properly exception handling-wise. We are - not to provide a magic answer here, merely to prevent crashes assuming - users know what they are doing. - - ??? Perhaps check UNW_VER / UNW_FLAG_OSMASK as well. */ - - if (MD_UNW_COMPATIBLE_PERSONALITY_P (header) - && (UNW_FLAG_EHANDLER (header) | UNW_FLAG_UHANDLER (header))) - { - fs->personality = - *(_Unwind_Personality_Fn *) (unw[length + 1] + context->gp); - context->lsda = unw + length + 2; - } - - insn = (unsigned char *) (unw + 1); - insn_end = (unsigned char *) (unw + 1 + length); - while (!fs->done && insn < insn_end) - insn = unw_decode (insn, fs->in_body, fs); - - free_label_states (fs->labeled_states); - free_state_stack (&fs->curr); - -#ifdef ENABLE_MALLOC_CHECKING - if (reg_state_alloced || labeled_state_alloced) - abort (); -#endif - - /* If we're in the epilogue, sp has been restored and all values - on the memory stack below psp also have been restored. */ - if (fs->when_target > fs->epilogue_start) - { - struct unw_reg_info *r; - - fs->curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE; - fs->curr.reg[UNW_REG_PSP].val = 0; - for (r = fs->curr.reg; r < fs->curr.reg + UNW_NUM_REGS; ++r) - if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10) - || r->where == UNW_WHERE_SPREL) - r->where = UNW_WHERE_NONE; - } - -skip_unwind_info: - /* If RP didn't get saved, generate entry for the return link register. */ - if (fs->curr.reg[UNW_REG_RP].when >= fs->when_target) - { - 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 = fs->return_link_reg; - } - - /* There is a subtlety for the frame after unwinding through a signal - handler: should we restore the cfm as usual or the pfs? We can't - restore both because we use br.ret to resume execution of user code. - For other frames the procedure is by definition non-leaf so the pfs - is saved and restored and thus effectively dead in the body; only - the cfm need therefore be restored. - - Here we have 2 cases: - - either the pfs is saved and restored and thus effectively dead - like in regular frames; then we do nothing special and restore - the cfm. - - or the pfs is not saved and thus live; but in that case the - procedure is necessarily leaf so the cfm is effectively dead - and we restore the pfs. */ - if (context->signal_pfs_loc) - { - if (fs->curr.reg[UNW_REG_PFS].when >= fs->when_target) - context->pfs_loc = context->signal_pfs_loc; - context->signal_pfs_loc = NULL; - } - - return _URC_NO_REASON; -} - -static void -uw_update_reg_address (struct _Unwind_Context *context, - _Unwind_FrameState *fs, - enum unw_register_index regno) -{ - struct unw_reg_info *r = fs->curr.reg + regno; - void *addr; - unsigned long rval; - - if (r->where == UNW_WHERE_NONE || r->when >= fs->when_target) - return; - - rval = r->val; - switch (r->where) - { - case UNW_WHERE_GR: - if (rval >= 32) - addr = ia64_rse_skip_regs ((unsigned long *) context->bsp, rval - 32); - else if (rval >= 2) - addr = context->ireg[rval - 2].loc; - else if (rval == 0) - { - static const unsigned long dummy; - addr = (void *) &dummy; - } - else - abort (); - break; - - case UNW_WHERE_FR: - if (rval >= 2 && rval < 32) - addr = context->fr_loc[rval - 2]; - else - abort (); - break; - - case UNW_WHERE_BR: - /* Note that while RVAL can only be 1-5 from normal descriptors, - we can want to look at B0, B6 and B7 due to having manually unwound a - signal frame. */ - if (rval < 8) - addr = context->br_loc[rval]; - else - abort (); - break; - - case UNW_WHERE_SPREL: - addr = (void *)(context->sp + rval); - break; - - case UNW_WHERE_PSPREL: - addr = (void *)(context->psp + rval); - break; - - default: - abort (); - } - - switch (regno) - { - case UNW_REG_R2 ... UNW_REG_R31: - context->ireg[regno - UNW_REG_R2].loc = addr; - switch (r->where) - { - case UNW_WHERE_GR: - if (rval >= 32) - { - context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK; - context->ireg[regno - UNW_REG_R2].nat.off - = context->pri_unat_loc - (unsigned long *) addr; - } - else if (rval >= 2) - { - context->ireg[regno - UNW_REG_R2].nat - = context->ireg[rval - 2].nat; - } - else if (rval == 0) - { - context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE; - context->ireg[regno - UNW_REG_R2].nat.off = 0; - } - else - abort (); - break; - - case UNW_WHERE_FR: - context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_VAL; - context->ireg[regno - UNW_REG_R2].nat.off = 0; - break; - - case UNW_WHERE_BR: - context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_NONE; - context->ireg[regno - UNW_REG_R2].nat.off = 0; - break; - - case UNW_WHERE_PSPREL: - case UNW_WHERE_SPREL: - context->ireg[regno - UNW_REG_R2].nat.type = UNW_NAT_MEMSTK; - context->ireg[regno - UNW_REG_R2].nat.off - = context->pri_unat_loc - (unsigned long *) addr; - break; - - default: - abort (); - } - break; - - case UNW_REG_F2 ... UNW_REG_F31: - context->fr_loc[regno - UNW_REG_F2] = addr; - break; - - case UNW_REG_B1 ... UNW_REG_B5: - context->br_loc[regno - UNW_REG_B0] = addr; - break; - - case UNW_REG_BSP: - context->bsp_loc = addr; - break; - case UNW_REG_BSPSTORE: - context->bspstore_loc = addr; - break; - case UNW_REG_PFS: - context->pfs_loc = addr; - break; - case UNW_REG_RP: - context->rp = *(unsigned long *)addr; - break; - case UNW_REG_UNAT: - context->unat_loc = addr; - break; - case UNW_REG_PR: - context->pr = *(unsigned long *) addr; - break; - case UNW_REG_LC: - context->lc_loc = addr; - break; - case UNW_REG_FPSR: - context->fpsr_loc = addr; - break; - - case UNW_REG_PSP: - context->psp = *(unsigned long *)addr; - break; - - default: - abort (); - } -} - -static void -uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs) -{ - long i; - -#ifdef MD_HANDLE_UNWABI - MD_HANDLE_UNWABI (context, fs); -#endif - - context->sp = context->psp; - - /* First, set PSP. Subsequent instructions may depend on this value. */ - if (fs->when_target > fs->curr.reg[UNW_REG_PSP].when) - { - if (fs->curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE) - context->psp = context->psp + fs->curr.reg[UNW_REG_PSP].val; - else - uw_update_reg_address (context, fs, UNW_REG_PSP); - } - - /* Determine the location of the primary UNaT. */ - { - int i; - if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_GR].when) - i = UNW_REG_PRI_UNAT_MEM; - else if (fs->when_target < fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when) - i = UNW_REG_PRI_UNAT_GR; - else if (fs->curr.reg[UNW_REG_PRI_UNAT_MEM].when - > fs->curr.reg[UNW_REG_PRI_UNAT_GR].when) - i = UNW_REG_PRI_UNAT_MEM; - else - i = UNW_REG_PRI_UNAT_GR; - uw_update_reg_address (context, fs, i); - } - - /* Compute the addresses of all registers saved in this frame. */ - for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i) - uw_update_reg_address (context, fs, i); - - /* Unwind BSP for the local registers allocated this frame. */ - /* ??? What to do with stored BSP or BSPSTORE registers. */ - /* We assert that we are either at a call site, or we have - just unwound through a signal frame. In either case - pfs_loc is valid. */ - if (!(fs -> no_reg_stack_frame)) - { - unsigned long pfs = *context->pfs_loc; - unsigned long sol = (pfs >> 7) & 0x7f; - context->bsp = (unsigned long) - ia64_rse_skip_regs ((unsigned long *) context->bsp, -sol); - } -} - -static void -uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs) -{ - uw_update_context (context, fs); -} - -/* Fill in CONTEXT for top-of-stack. The only valid registers at this - level will be the return address and the CFA. Note that CFA = SP+16. */ - -#define uw_init_context(CONTEXT) \ - do { \ - /* ??? There is a whole lot o code in uw_install_context that \ - tries to avoid spilling the entire machine state here. We \ - should try to make that work again. */ \ - __builtin_unwind_init(); \ - uw_init_context_1 (CONTEXT, __builtin_ia64_bsp ()); \ - } while (0) - -static void __attribute__((noinline)) -uw_init_context_1 (struct _Unwind_Context *context, void *bsp) -{ - void *rp = __builtin_extract_return_addr (__builtin_return_address (0)); - /* Set psp to the caller's stack pointer. */ - void *psp = __builtin_dwarf_cfa () - 16; - _Unwind_FrameState fs; - unsigned long rnat, tmp1, tmp2; - - /* Flush the register stack to memory so that we can access it. - Get rse nat collection for the last incomplete rbs chunk of - registers at the same time. For this RSE needs to be turned - into the mandatory only mode. */ - asm ("mov.m %1 = ar.rsc;;\n\t" - "and %2 = 0x1c, %1;;\n\t" - "mov.m ar.rsc = %2;;\n\t" - "flushrs;;\n\t" - "mov.m %0 = ar.rnat;;\n\t" - "mov.m ar.rsc = %1\n\t" - : "=r" (rnat), "=r" (tmp1), "=r" (tmp2)); - - memset (context, 0, sizeof (struct _Unwind_Context)); - context->bsp = (unsigned long) bsp; - /* Set context->regstk_top to lowest rbs address which will use - context->rnat collection. */ - context->regstk_top = context->bsp & ~0x1ffULL; - context->rnat = rnat; - context->psp = (unsigned long) psp; - context->rp = (unsigned long) rp; - asm ("mov %0 = sp" : "=r" (context->sp)); - asm ("mov %0 = pr" : "=r" (context->pr)); - context->pri_unat_loc = &context->initial_unat; /* ??? */ - - if (uw_frame_state_for (context, &fs) != _URC_NO_REASON) - abort (); - - uw_update_context (context, &fs); -} - -/* Install (i.e. longjmp to) the contents of TARGET. */ - -static void __attribute__((noreturn)) -uw_install_context (struct _Unwind_Context *current __attribute__((unused)), - struct _Unwind_Context *target) -{ - unsigned long ireg_buf[4], ireg_nat = 0, ireg_pr = 0; - long i; - - /* Copy integer register data from the target context to a - temporary buffer. Do this so that we can frob AR.UNAT - to get the NaT bits for these registers set properly. */ - for (i = 4; i <= 7; ++i) - { - char nat; - void *t = target->ireg[i - 2].loc; - if (t) - { - unw_access_gr (target, i, &ireg_buf[i - 4], &nat, 0); - ireg_nat |= (long)nat << (((size_t)&ireg_buf[i - 4] >> 3) & 0x3f); - /* Set p6 - p9. */ - ireg_pr |= 4L << i; - } - } - - /* The value in uc_bsp that we've computed is that for the - target function. The value that we install below will be - adjusted by the BR.RET instruction based on the contents - of AR.PFS. So we must unadjust that here. */ - target->bsp = (unsigned long) - ia64_rse_skip_regs ((unsigned long *)target->bsp, - (*target->pfs_loc >> 7) & 0x7f); - - if (target->bsp < target->regstk_top) - target->rnat = *ia64_rse_rnat_addr ((unsigned long *) target->bsp); - - /* Provide assembly with the offsets into the _Unwind_Context. */ - asm volatile ("uc_rnat = %0" - : : "i"(offsetof (struct _Unwind_Context, rnat))); - asm volatile ("uc_bsp = %0" - : : "i"(offsetof (struct _Unwind_Context, bsp))); - asm volatile ("uc_psp = %0" - : : "i"(offsetof (struct _Unwind_Context, psp))); - asm volatile ("uc_rp = %0" - : : "i"(offsetof (struct _Unwind_Context, rp))); - asm volatile ("uc_pr = %0" - : : "i"(offsetof (struct _Unwind_Context, pr))); - asm volatile ("uc_gp = %0" - : : "i"(offsetof (struct _Unwind_Context, gp))); - asm volatile ("uc_pfs_loc = %0" - : : "i"(offsetof (struct _Unwind_Context, pfs_loc))); - asm volatile ("uc_unat_loc = %0" - : : "i"(offsetof (struct _Unwind_Context, unat_loc))); - asm volatile ("uc_lc_loc = %0" - : : "i"(offsetof (struct _Unwind_Context, lc_loc))); - asm volatile ("uc_fpsr_loc = %0" - : : "i"(offsetof (struct _Unwind_Context, fpsr_loc))); - asm volatile ("uc_eh_data = %0" - : : "i"(offsetof (struct _Unwind_Context, eh_data))); - asm volatile ("uc_br_loc = %0" - : : "i"(offsetof (struct _Unwind_Context, br_loc))); - asm volatile ("uc_fr_loc = %0" - : : "i"(offsetof (struct _Unwind_Context, fr_loc))); - - asm volatile ( - /* Load up call-saved non-window integer registers from ireg_buf. */ - "add r20 = 8, %1 \n\t" - "mov ar.unat = %2 \n\t" - "mov pr = %3, 0x3c0 \n\t" - ";; \n\t" - "(p6) ld8.fill r4 = [%1] \n\t" - "(p7) ld8.fill r5 = [r20] \n\t" - "add r21 = uc_br_loc + 16, %0 \n\t" - "adds %1 = 16, %1 \n\t" - "adds r20 = 16, r20 \n\t" - ";; \n\t" - "(p8) ld8.fill r6 = [%1] \n\t" - "(p9) ld8.fill r7 = [r20] \n\t" - "add r20 = uc_br_loc + 8, %0 \n\t" - ";; \n\t" - /* Load up call-saved branch registers. */ - "ld8 r22 = [r20], 16 \n\t" - "ld8 r23 = [r21], 16 \n\t" - ";; \n\t" - "ld8 r24 = [r20], 16 \n\t" - "ld8 r25 = [r21], uc_fr_loc - (uc_br_loc + 32)\n\t" - ";; \n\t" - "ld8 r26 = [r20], uc_fr_loc + 8 - (uc_br_loc + 40)\n\t" - "ld8 r27 = [r21], 24 \n\t" - "cmp.ne p6, p0 = r0, r22 \n\t" - ";; \n\t" - "ld8 r28 = [r20], 8 \n\t" - "(p6) ld8 r22 = [r22] \n\t" - "cmp.ne p7, p0 = r0, r23 \n\t" - ";; \n\t" - "(p7) ld8 r23 = [r23] \n\t" - "cmp.ne p8, p0 = r0, r24 \n\t" - ";; \n\t" - "(p8) ld8 r24 = [r24] \n\t" - "(p6) mov b1 = r22 \n\t" - "cmp.ne p9, p0 = r0, r25 \n\t" - ";; \n\t" - "(p9) ld8 r25 = [r25] \n\t" - "(p7) mov b2 = r23 \n\t" - "cmp.ne p6, p0 = r0, r26 \n\t" - ";; \n\t" - "(p6) ld8 r26 = [r26] \n\t" - "(p8) mov b3 = r24 \n\t" - "cmp.ne p7, p0 = r0, r27 \n\t" - ";; \n\t" - /* Load up call-saved fp registers. */ - "(p7) ldf.fill f2 = [r27] \n\t" - "(p9) mov b4 = r25 \n\t" - "cmp.ne p8, p0 = r0, r28 \n\t" - ";; \n\t" - "(p8) ldf.fill f3 = [r28] \n\t" - "(p6) mov b5 = r26 \n\t" - ";; \n\t" - "ld8 r29 = [r20], 16*8 - 4*8 \n\t" - "ld8 r30 = [r21], 17*8 - 5*8 \n\t" - ";; \n\t" - "ld8 r22 = [r20], 16 \n\t" - "ld8 r23 = [r21], 16 \n\t" - ";; \n\t" - "ld8 r24 = [r20], 16 \n\t" - "ld8 r25 = [r21] \n\t" - "cmp.ne p6, p0 = r0, r29 \n\t" - ";; \n\t" - "ld8 r26 = [r20], 8 \n\t" - "(p6) ldf.fill f4 = [r29] \n\t" - "cmp.ne p7, p0 = r0, r30 \n\t" - ";; \n\t" - "ld8 r27 = [r20], 8 \n\t" - "(p7) ldf.fill f5 = [r30] \n\t" - "cmp.ne p6, p0 = r0, r22 \n\t" - ";; \n\t" - "ld8 r28 = [r20], 8 \n\t" - "(p6) ldf.fill f16 = [r22] \n\t" - "cmp.ne p7, p0 = r0, r23 \n\t" - ";; \n\t" - "ld8 r29 = [r20], 8 \n\t" - "(p7) ldf.fill f17 = [r23] \n\t" - "cmp.ne p6, p0 = r0, r24 \n\t" - ";; \n\t" - "ld8 r22 = [r20], 8 \n\t" - "(p6) ldf.fill f18 = [r24] \n\t" - "cmp.ne p7, p0 = r0, r25 \n\t" - ";; \n\t" - "ld8 r23 = [r20], 8 \n\t" - "(p7) ldf.fill f19 = [r25] \n\t" - "cmp.ne p6, p0 = r0, r26 \n\t" - ";; \n\t" - "ld8 r24 = [r20], 8 \n\t" - "(p6) ldf.fill f20 = [r26] \n\t" - "cmp.ne p7, p0 = r0, r27 \n\t" - ";; \n\t" - "ld8 r25 = [r20], 8 \n\t" - "(p7) ldf.fill f21 = [r27] \n\t" - "cmp.ne p6, p0 = r0, r28 \n\t" - ";; \n\t" - "ld8 r26 = [r20], 8 \n\t" - "(p6) ldf.fill f22 = [r28] \n\t" - "cmp.ne p7, p0 = r0, r29 \n\t" - ";; \n\t" - "ld8 r27 = [r20], 8 \n\t" - ";; \n\t" - "ld8 r28 = [r20], 8 \n\t" - "(p7) ldf.fill f23 = [r29] \n\t" - "cmp.ne p6, p0 = r0, r22 \n\t" - ";; \n\t" - "ld8 r29 = [r20], 8 \n\t" - "(p6) ldf.fill f24 = [r22] \n\t" - "cmp.ne p7, p0 = r0, r23 \n\t" - ";; \n\t" - "(p7) ldf.fill f25 = [r23] \n\t" - "cmp.ne p6, p0 = r0, r24 \n\t" - "cmp.ne p7, p0 = r0, r25 \n\t" - ";; \n\t" - "(p6) ldf.fill f26 = [r24] \n\t" - "(p7) ldf.fill f27 = [r25] \n\t" - "cmp.ne p6, p0 = r0, r26 \n\t" - ";; \n\t" - "(p6) ldf.fill f28 = [r26] \n\t" - "cmp.ne p7, p0 = r0, r27 \n\t" - "cmp.ne p6, p0 = r0, r28 \n\t" - ";; \n\t" - "(p7) ldf.fill f29 = [r27] \n\t" - "(p6) ldf.fill f30 = [r28] \n\t" - "cmp.ne p7, p0 = r0, r29 \n\t" - ";; \n\t" - "(p7) ldf.fill f31 = [r29] \n\t" - "add r20 = uc_rnat, %0 \n\t" - "add r21 = uc_bsp, %0 \n\t" - ";; \n\t" - /* Load the balance of the thread state from the context. */ - "ld8 r22 = [r20], uc_psp - uc_rnat \n\t" - "ld8 r23 = [r21], uc_gp - uc_bsp \n\t" - ";; \n\t" - "ld8 r24 = [r20], uc_pfs_loc - uc_psp \n\t" - "ld8 r1 = [r21], uc_rp - uc_gp \n\t" - ";; \n\t" - "ld8 r25 = [r20], uc_unat_loc - uc_pfs_loc\n\t" - "ld8 r26 = [r21], uc_pr - uc_rp \n\t" - ";; \n\t" - "ld8 r27 = [r20], uc_lc_loc - uc_unat_loc\n\t" - "ld8 r28 = [r21], uc_fpsr_loc - uc_pr \n\t" - ";; \n\t" - "ld8 r29 = [r20], uc_eh_data - uc_lc_loc\n\t" - "ld8 r30 = [r21], uc_eh_data + 8 - uc_fpsr_loc\n\t" - ";; \n\t" - /* Load data for the exception handler. */ - "ld8 r15 = [r20], 16 \n\t" - "ld8 r16 = [r21], 16 \n\t" - ";; \n\t" - "ld8 r17 = [r20] \n\t" - "ld8 r18 = [r21] \n\t" - ";; \n\t" - /* Install the balance of the thread state loaded above. */ - "cmp.ne p6, p0 = r0, r25 \n\t" - "cmp.ne p7, p0 = r0, r27 \n\t" - ";; \n\t" - "(p6) ld8 r25 = [r25] \n\t" - "(p7) ld8 r27 = [r27] \n\t" - ";; \n\t" - "(p7) mov.m ar.unat = r27 \n\t" - "(p6) mov.i ar.pfs = r25 \n\t" - "cmp.ne p9, p0 = r0, r29 \n\t" - ";; \n\t" - "(p9) ld8 r29 = [r29] \n\t" - "cmp.ne p6, p0 = r0, r30 \n\t" - ";; \n\t" - "(p6) ld8 r30 = [r30] \n\t" - /* Don't clobber p6-p9, which are in use at present. */ - "mov pr = r28, ~0x3c0 \n\t" - "(p9) mov.i ar.lc = r29 \n\t" - ";; \n\t" - "mov.m r25 = ar.rsc \n\t" - "(p6) mov.m ar.fpsr = r30 \n\t" - ";; \n\t" - "and r29 = 0x1c, r25 \n\t" - "mov b0 = r26 \n\t" - ";; \n\t" - "mov.m ar.rsc = r29 \n\t" - ";; \n\t" - /* This must be done before setting AR.BSPSTORE, otherwise - AR.BSP will be initialized with a random displacement - below the value we want, based on the current number of - dirty stacked registers. */ - "loadrs \n\t" - "invala \n\t" - ";; \n\t" - "mov.m ar.bspstore = r23 \n\t" - ";; \n\t" - "mov.m ar.rnat = r22 \n\t" - ";; \n\t" - "mov.m ar.rsc = r25 \n\t" - "mov sp = r24 \n\t" - "br.ret.sptk.few b0" - : : "r"(target), "r"(ireg_buf), "r"(ireg_nat), "r"(ireg_pr) - : "r15", "r16", "r17", "r18", "r20", "r21", "r22", - "r23", "r24", "r25", "r26", "r27", "r28", "r29", - "r30", "r31"); - /* NOTREACHED */ - while (1); -} - -static inline _Unwind_Ptr -uw_identify_context (struct _Unwind_Context *context) -{ - return _Unwind_GetIP (context); -} - -#include "unwind.inc" - -#if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS) -alias (_Unwind_Backtrace); -alias (_Unwind_DeleteException); -alias (_Unwind_FindEnclosingFunction); -alias (_Unwind_ForcedUnwind); -alias (_Unwind_GetBSP); -alias (_Unwind_GetCFA); -alias (_Unwind_GetGR); -alias (_Unwind_GetIP); -alias (_Unwind_GetLanguageSpecificData); -alias (_Unwind_GetRegionStart); -alias (_Unwind_RaiseException); -alias (_Unwind_Resume); -alias (_Unwind_Resume_or_Rethrow); -alias (_Unwind_SetGR); -alias (_Unwind_SetIP); -#endif - -#endif diff --git a/gcc/config/ia64/unwind-ia64.h b/gcc/config/ia64/unwind-ia64.h deleted file mode 100644 index b98f048..0000000 --- a/gcc/config/ia64/unwind-ia64.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 1999, 2000, 2001, 2007, 2009 Free Software Foundation, Inc. - Contributed by Andrew MacLeod <amacleod@cygnus.com> - Andrew Haley <aph@cygnus.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. - - 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/>. */ - -struct unw_table_entry -{ - unsigned long start_offset; - unsigned long end_offset; - unsigned long info_offset; -}; - -/* Accessors to fields of an unwind info block header. In this common file to - be visible from all the units involved in a target implementation. */ - -#ifndef __USING_SJLJ_EXCEPTIONS__ -#define UNW_VER(x) ((x) >> 48) -#define UNW_FLAG_MASK 0x0000ffff00000000 -#define UNW_FLAG_OSMASK 0x0000f00000000000 -#define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L) -#define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L) -#define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL) -#endif - -extern struct unw_table_entry * -_Unwind_FindTableEntry (void *pc, unsigned long *segment_base, - unsigned long *gp, struct unw_table_entry *ent) - __attribute__ ((__visibility__ ("hidden"))); diff --git a/gcc/config/ia64/vms.h b/gcc/config/ia64/vms.h index 847d79a..853e023 100644 --- a/gcc/config/ia64/vms.h +++ b/gcc/config/ia64/vms.h @@ -139,9 +139,6 @@ STATIC func_ptr __CTOR_LIST__[1] \ /* Define this to be nonzero if static stack checking is supported. */ #define STACK_CHECK_STATIC_BUILTIN 1 -#define UNW_IVMS_MODE(HEADER) (((HEADER) >> 44) & 0x3L) -#define MD_UNW_COMPATIBLE_PERSONALITY_P(HEADER) (!UNW_IVMS_MODE (HEADER)) - /* Minimum amount of stack required to recover from an anticipated stack overflow detection. The default value conveys an estimate of the amount of stack required to propagate an exception. */ diff --git a/gcc/config/picochip/t-picochip b/gcc/config/picochip/t-picochip index ba4394e..4df74a0 100644 --- a/gcc/config/picochip/t-picochip +++ b/gcc/config/picochip/t-picochip @@ -43,9 +43,6 @@ LIB2FUNCS_EXTRA = \ LIB1ASMFUNCS = _mulsc3 _divsc3 LIB1ASMSRC = picochip/libgccExtras/fake_libgcc.asm -# Turn off the building of exception handling libraries. -LIB2ADDEH = - # Turn off ranlib on target libraries. RANLIB_FOR_TARGET = cat diff --git a/gcc/config/rs6000/aix.h b/gcc/config/rs6000/aix.h index 13d317f..2c678a3 100644 --- a/gcc/config/rs6000/aix.h +++ b/gcc/config/rs6000/aix.h @@ -209,40 +209,6 @@ /* And similarly for general purpose registers. */ #define GP_SAVE_INLINE(FIRST_REG) ((FIRST_REG) < 32) -/* 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 R_LR 65 - -#ifdef __64BIT__ -#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \ - do { \ - if ((FS)->regs.reg[2].how == REG_UNSAVED) \ - { \ - unsigned int *insn \ - = (unsigned int *) \ - _Unwind_GetGR ((CTX), R_LR); \ - if (*insn == 0xE8410028) \ - _Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 40); \ - } \ - } while (0) -#else -#define MD_FROB_UPDATE_CONTEXT(CTX, FS) \ - do { \ - if ((FS)->regs.reg[2].how == REG_UNSAVED) \ - { \ - unsigned int *insn \ - = (unsigned int *) \ - _Unwind_GetGR ((CTX), R_LR); \ - if (*insn == 0x80410014) \ - _Unwind_SetGRPtr ((CTX), 2, (CTX)->cfa + 20); \ - } \ - } while (0) -#endif - #define PROFILE_HOOK(LABEL) output_profile_hook (LABEL) /* No version of AIX fully supports AltiVec or 64-bit instructions in diff --git a/gcc/config/rs6000/darwin-fallback.c b/gcc/config/rs6000/darwin-fallback.c deleted file mode 100644 index 4591071..0000000 --- a/gcc/config/rs6000/darwin-fallback.c +++ /dev/null @@ -1,487 +0,0 @@ -/* Fallback frame-state unwinder for Darwin. - Copyright (C) 2004, 2005, 2007, 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/>. */ - -#ifdef __ppc__ - -#include "tconfig.h" -#include "tsystem.h" -#include "coretypes.h" -#include "tm.h" -#include "dwarf2.h" -#include "unwind.h" -#include "unwind-dw2.h" -#include <stdint.h> -#include <stdbool.h> -#include <sys/types.h> -#include <signal.h> - -#define R_LR 65 -#define R_CTR 66 -#define R_CR2 70 -#define R_XER 76 -#define R_VR0 77 -#define R_VRSAVE 109 -#define R_VSCR 110 -#define R_SPEFSCR 112 - -typedef unsigned long reg_unit; - -/* Place in GPRS the parameters to the first 'sc' instruction that would - have been executed if we were returning from this CONTEXT, or - return false if an unexpected instruction is encountered. */ - -static bool -interpret_libc (reg_unit gprs[32], struct _Unwind_Context *context) -{ - uint32_t *pc = (uint32_t *)_Unwind_GetIP (context); - uint32_t cr; - reg_unit lr = (reg_unit) pc; - reg_unit ctr = 0; - uint32_t *invalid_address = NULL; - - int i; - - for (i = 0; i < 13; i++) - gprs[i] = 1; - gprs[1] = _Unwind_GetCFA (context); - for (; i < 32; i++) - gprs[i] = _Unwind_GetGR (context, i); - cr = _Unwind_GetGR (context, R_CR2); - - /* For each supported Libc, we have to track the code flow - all the way back into the kernel. - - This code is believed to support all released Libc/Libsystem builds since - Jaguar 6C115, including all the security updates. To be precise, - - Libc Libsystem Build(s) - 262~1 60~37 6C115 - 262~1 60.2~4 6D52 - 262~1 61~3 6F21-6F22 - 262~1 63~24 6G30-6G37 - 262~1 63~32 6I34-6I35 - 262~1 63~64 6L29-6L60 - 262.4.1~1 63~84 6L123-6R172 - - 320~1 71~101 7B85-7D28 - 320~1 71~266 7F54-7F56 - 320~1 71~288 7F112 - 320~1 71~289 7F113 - 320.1.3~1 71.1.1~29 7H60-7H105 - 320.1.3~1 71.1.1~30 7H110-7H113 - 320.1.3~1 71.1.1~31 7H114 - - That's a big table! It would be insane to try to keep track of - every little detail, so we just read the code itself and do what - it would do. - */ - - for (;;) - { - uint32_t ins = *pc++; - - if ((ins & 0xFC000003) == 0x48000000) /* b instruction */ - { - pc += ((((int32_t) ins & 0x3FFFFFC) ^ 0x2000000) - 0x2000004) / 4; - continue; - } - if ((ins & 0xFC600000) == 0x2C000000) /* cmpwi */ - { - int32_t val1 = (int16_t) ins; - int32_t val2 = gprs[ins >> 16 & 0x1F]; - /* Only beq and bne instructions are supported, so we only - need to set the EQ bit. */ - uint32_t mask = 0xF << ((ins >> 21 & 0x1C) ^ 0x1C); - if (val1 == val2) - cr |= mask; - else - cr &= ~mask; - continue; - } - if ((ins & 0xFEC38003) == 0x40820000) /* forwards beq/bne */ - { - if ((cr >> ((ins >> 16 & 0x1F) ^ 0x1F) & 1) == (ins >> 24 & 1)) - pc += (ins & 0x7FFC) / 4 - 1; - continue; - } - if ((ins & 0xFC0007FF) == 0x7C000378) /* or, including mr */ - { - gprs [ins >> 16 & 0x1F] = (gprs [ins >> 11 & 0x1F] - | gprs [ins >> 21 & 0x1F]); - continue; - } - if (ins >> 26 == 0x0E) /* addi, including li */ - { - reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; - gprs [ins >> 21 & 0x1F] = src + (int16_t) ins; - continue; - } - if (ins >> 26 == 0x0F) /* addis, including lis */ - { - reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; - gprs [ins >> 21 & 0x1F] = src + ((int16_t) ins << 16); - continue; - } - if (ins >> 26 == 0x20) /* lwz */ - { - reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; - uint32_t *p = (uint32_t *)(src + (int16_t) ins); - if (p == invalid_address) - return false; - gprs [ins >> 21 & 0x1F] = *p; - continue; - } - if (ins >> 26 == 0x21) /* lwzu */ - { - uint32_t *p = (uint32_t *)(gprs [ins >> 16 & 0x1F] += (int16_t) ins); - if (p == invalid_address) - return false; - gprs [ins >> 21 & 0x1F] = *p; - continue; - } - if (ins >> 26 == 0x24) /* stw */ - /* What we hope this is doing is '--in_sigtramp'. We don't want - to actually store to memory, so just make a note of the - address and refuse to load from it. */ - { - reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; - uint32_t *p = (uint32_t *)(src + (int16_t) ins); - if (p == NULL || invalid_address != NULL) - return false; - invalid_address = p; - continue; - } - if (ins >> 26 == 0x2E) /* lmw */ - { - reg_unit src = (ins >> 16 & 0x1F) == 0 ? 0 : gprs [ins >> 16 & 0x1F]; - uint32_t *p = (uint32_t *)(src + (int16_t) ins); - int i; - - for (i = (ins >> 21 & 0x1F); i < 32; i++) - { - if (p == invalid_address) - return false; - gprs[i] = *p++; - } - continue; - } - if ((ins & 0xFC1FFFFF) == 0x7c0803a6) /* mtlr */ - { - lr = gprs [ins >> 21 & 0x1F]; - continue; - } - if ((ins & 0xFC1FFFFF) == 0x7c0802a6) /* mflr */ - { - gprs [ins >> 21 & 0x1F] = lr; - continue; - } - if ((ins & 0xFC1FFFFF) == 0x7c0903a6) /* mtctr */ - { - ctr = gprs [ins >> 21 & 0x1F]; - continue; - } - /* The PowerPC User's Manual says that bit 11 of the mtcrf - instruction is reserved and should be set to zero, but it - looks like the Darwin assembler doesn't do that... */ - if ((ins & 0xFC000FFF) == 0x7c000120) /* mtcrf */ - { - int i; - uint32_t mask = 0; - for (i = 0; i < 8; i++) - mask |= ((-(ins >> (12 + i) & 1)) & 0xF) << 4 * i; - cr = (cr & ~mask) | (gprs [ins >> 21 & 0x1F] & mask); - continue; - } - if (ins == 0x429f0005) /* bcl- 20,4*cr7+so,.+4, loads pc into LR */ - { - lr = (reg_unit) pc; - continue; - } - if (ins == 0x4e800420) /* bctr */ - { - pc = (uint32_t *) ctr; - continue; - } - if (ins == 0x44000002) /* sc */ - return true; - - return false; - } -} - -/* We used to include <ucontext.h> and <mach/thread_status.h>, - but they change so much between different Darwin system versions - that it's much easier to just write the structures involved here - directly. */ - -/* These defines are from the kernel's bsd/dev/ppc/unix_signal.c. */ -#define UC_TRAD 1 -#define UC_TRAD_VEC 6 -#define UC_TRAD64 20 -#define UC_TRAD64_VEC 25 -#define UC_FLAVOR 30 -#define UC_FLAVOR_VEC 35 -#define UC_FLAVOR64 40 -#define UC_FLAVOR64_VEC 45 -#define UC_DUAL 50 -#define UC_DUAL_VEC 55 - -struct gcc_ucontext -{ - int onstack; - sigset_t sigmask; - void * stack_sp; - size_t stack_sz; - int stack_flags; - struct gcc_ucontext *link; - size_t mcsize; - struct gcc_mcontext32 *mcontext; -}; - -struct gcc_float_vector_state -{ - double fpregs[32]; - uint32_t fpscr_pad; - uint32_t fpscr; - uint32_t save_vr[32][4]; - uint32_t save_vscr[4]; -}; - -struct gcc_mcontext32 { - uint32_t dar; - uint32_t dsisr; - uint32_t exception; - uint32_t padding1[5]; - uint32_t srr0; - uint32_t srr1; - uint32_t gpr[32]; - uint32_t cr; - uint32_t xer; - uint32_t lr; - uint32_t ctr; - uint32_t mq; - uint32_t vrsave; - struct gcc_float_vector_state fvs; -}; - -/* These are based on /usr/include/ppc/ucontext.h and - /usr/include/mach/ppc/thread_status.h, but rewritten to be more - convenient, to compile on Jaguar, and to work around Radar 3712064 - on Panther, which is that the 'es' field of 'struct mcontext64' has - the wrong type (doh!). */ - -struct gcc_mcontext64 { - uint64_t dar; - uint32_t dsisr; - uint32_t exception; - uint32_t padding1[4]; - uint64_t srr0; - uint64_t srr1; - uint32_t gpr[32][2]; - uint32_t cr; - uint32_t xer[2]; /* These are arrays because the original structure has them misaligned. */ - uint32_t lr[2]; - uint32_t ctr[2]; - uint32_t vrsave; - struct gcc_float_vector_state fvs; -}; - -#define UC_FLAVOR_SIZE \ - (sizeof (struct gcc_mcontext32) - 33*16) - -#define UC_FLAVOR_VEC_SIZE (sizeof (struct gcc_mcontext32)) - -#define UC_FLAVOR64_SIZE \ - (sizeof (struct gcc_mcontext64) - 33*16) - -#define UC_FLAVOR64_VEC_SIZE (sizeof (struct gcc_mcontext64)) - -/* Given GPRS as input to a 'sc' instruction, and OLD_CFA, update FS - to represent the execution of a signal return; or, if not a signal - return, return false. */ - -static bool -handle_syscall (_Unwind_FrameState *fs, const reg_unit gprs[32], - _Unwind_Ptr old_cfa) -{ - struct gcc_ucontext *uctx; - bool is_64, is_vector; - struct gcc_float_vector_state * float_vector_state; - _Unwind_Ptr new_cfa; - int i; - static _Unwind_Ptr return_addr; - - /* Yay! We're in a Libc that we understand, and it's made a - system call. In Jaguar, this is a direct system call with value 103; - in Panther and Tiger it is a SYS_syscall call for system call number 184, - and in Leopard it is a direct syscall with number 184. */ - - if (gprs[0] == 0x67 /* SYS_SIGRETURN */) - { - uctx = (struct gcc_ucontext *) gprs[3]; - is_vector = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE - || uctx->mcsize == UC_FLAVOR_VEC_SIZE); - is_64 = (uctx->mcsize == UC_FLAVOR64_VEC_SIZE - || uctx->mcsize == UC_FLAVOR64_SIZE); - } - else if (gprs[0] == 0 /* SYS_syscall */ && gprs[3] == 184) - { - int ctxstyle = gprs[5]; - uctx = (struct gcc_ucontext *) gprs[4]; - is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC - || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC); - is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC - || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64); - } - else if (gprs[0] == 184 /* SYS_sigreturn */) - { - int ctxstyle = gprs[4]; - uctx = (struct gcc_ucontext *) gprs[3]; - is_vector = (ctxstyle == UC_FLAVOR_VEC || ctxstyle == UC_FLAVOR64_VEC - || ctxstyle == UC_TRAD_VEC || ctxstyle == UC_TRAD64_VEC); - is_64 = (ctxstyle == UC_FLAVOR64_VEC || ctxstyle == UC_TRAD64_VEC - || ctxstyle == UC_FLAVOR64 || ctxstyle == UC_TRAD64); - } - else - return false; - -#define set_offset(r, addr) \ - (fs->regs.reg[r].how = REG_SAVED_OFFSET, \ - fs->regs.reg[r].loc.offset = (_Unwind_Ptr)(addr) - new_cfa) - - /* Restore even the registers that are not call-saved, since they - might be being used in the prologue to save other registers, - for instance GPR0 is sometimes used to save LR. */ - - /* Handle the GPRs, and produce the information needed to do the rest. */ - if (is_64) - { - /* The context is 64-bit, but it doesn't carry any extra information - for us because only the low 32 bits of the registers are - call-saved. */ - struct gcc_mcontext64 *m64 = (struct gcc_mcontext64 *)uctx->mcontext; - int i; - - float_vector_state = &m64->fvs; - - new_cfa = m64->gpr[1][1]; - - set_offset (R_CR2, &m64->cr); - for (i = 0; i < 32; i++) - set_offset (i, m64->gpr[i] + 1); - set_offset (R_XER, m64->xer + 1); - set_offset (R_LR, m64->lr + 1); - set_offset (R_CTR, m64->ctr + 1); - if (is_vector) - set_offset (R_VRSAVE, &m64->vrsave); - - /* Sometimes, srr0 points to the instruction that caused the exception, - and sometimes to the next instruction to be executed; we want - the latter. */ - if (m64->exception == 3 || m64->exception == 4 - || m64->exception == 6 - || (m64->exception == 7 && !(m64->srr1 & 0x10000))) - return_addr = m64->srr0 + 4; - else - return_addr = m64->srr0; - } - else - { - struct gcc_mcontext32 *m = uctx->mcontext; - int i; - - float_vector_state = &m->fvs; - - new_cfa = m->gpr[1]; - - set_offset (R_CR2, &m->cr); - for (i = 0; i < 32; i++) - set_offset (i, m->gpr + i); - set_offset (R_XER, &m->xer); - set_offset (R_LR, &m->lr); - set_offset (R_CTR, &m->ctr); - - if (is_vector) - set_offset (R_VRSAVE, &m->vrsave); - - /* Sometimes, srr0 points to the instruction that caused the exception, - and sometimes to the next instruction to be executed; we want - the latter. */ - if (m->exception == 3 || m->exception == 4 - || m->exception == 6 - || (m->exception == 7 && !(m->srr1 & 0x10000))) - return_addr = m->srr0 + 4; - else - return_addr = m->srr0; - } - - fs->regs.cfa_how = CFA_REG_OFFSET; - fs->regs.cfa_reg = STACK_POINTER_REGNUM; - fs->regs.cfa_offset = new_cfa - old_cfa;; - - /* The choice of column for the return address is somewhat tricky. - Fortunately, the actual choice is private to this file, and - the space it's reserved from is the GCC register space, not the - DWARF2 numbering. So any free element of the right size is an OK - choice. Thus: */ - fs->retaddr_column = ARG_POINTER_REGNUM; - /* FIXME: this should really be done using a DWARF2 location expression, - not using a static variable. In fact, this entire file should - be implemented in DWARF2 expressions. */ - set_offset (ARG_POINTER_REGNUM, &return_addr); - - for (i = 0; i < 32; i++) - set_offset (32 + i, float_vector_state->fpregs + i); - set_offset (R_SPEFSCR, &float_vector_state->fpscr); - - if (is_vector) - { - for (i = 0; i < 32; i++) - set_offset (R_VR0 + i, float_vector_state->save_vr + i); - set_offset (R_VSCR, float_vector_state->save_vscr); - } - - return true; -} - -/* This is also prototyped in rs6000/darwin.h, inside the - MD_FALLBACK_FRAME_STATE_FOR macro. */ -extern bool _Unwind_fallback_frame_state_for (struct _Unwind_Context *context, - _Unwind_FrameState *fs); - -/* Implement the MD_FALLBACK_FRAME_STATE_FOR macro, - returning true iff the frame was a sigreturn() frame that we - can understand. */ - -bool -_Unwind_fallback_frame_state_for (struct _Unwind_Context *context, - _Unwind_FrameState *fs) -{ - reg_unit gprs[32]; - - if (!interpret_libc (gprs, context)) - return false; - return handle_syscall (fs, gprs, _Unwind_GetCFA (context)); -} -#endif diff --git a/gcc/config/rs6000/t-darwin b/gcc/config/rs6000/t-darwin index 8113b9e..27fc07b 100644 --- a/gcc/config/rs6000/t-darwin +++ b/gcc/config/rs6000/t-darwin @@ -1,5 +1,5 @@ # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, -# 2007 Free Software Foundation, Inc. +# 2007, 2011 Free Software Foundation, Inc. # # This file is part of GCC. # @@ -40,7 +40,5 @@ TARGET_LIBGCC2_CFLAGS = -Wa,-force_cpusubtype_ALL -pipe -mmacosx-version-min=10. # Export the _xlq* symbols from darwin-ldouble.c. SHLIB_MAPFILES += $(srcdir)/config/rs6000/libgcc-ppc64.ver -LIB2ADDEH += $(srcdir)/config/rs6000/darwin-fallback.c - darwin-fpsave.o: $(srcdir)/config/rs6000/darwin-asm.h darwin-tramp.o: $(srcdir)/config/rs6000/darwin-asm.h diff --git a/gcc/config/sh/t-sh b/gcc/config/sh/t-sh index a897bff..27cbd3d 100644 --- a/gcc/config/sh/t-sh +++ b/gcc/config/sh/t-sh @@ -1,5 +1,5 @@ # Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2006, 2008, 2009 Free Software Foundation, Inc. +# 2003, 2004, 2006, 2008, 2009, 2011 Free Software Foundation, Inc. # # This file is part of GCC. # @@ -149,7 +149,7 @@ $(T)sdivsi3_i4i-Os-4-200.o: $(srcdir)/config/sh/lib1funcs-Os-4-200.asm $(GCC_PAS $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $@ -DL_sdivsi3_i4i -x assembler-with-cpp $< $(T)udivsi3_i4i-Os-4-200.o: $(srcdir)/config/sh/lib1funcs-Os-4-200.asm $(GCC_PASSES) $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) -c -o $@ -DL_udivsi3_i4i -x assembler-with-cpp $< -$(T)unwind-dw2-Os-4-200.o: $(srcdir)/unwind-dw2.c $(srcdir)/unwind-generic.h unwind-pe.h unwind.inc unwind-dw2-fde.h unwind-dw2.h $(CONFIG_H) coretypes.h $(TM_H) $(MACHMODE_H) longlong.h config.status stmp-int-hdrs tsystem.h $(GCC_PASSES) +$(T)unwind-dw2-Os-4-200.o: $(srcdir)/../libgcc/unwind-dw2.c $(srcdir)/../libgcc/unwind-generic.h $(srcdir)/../libgcc/unwind-pe.h $(srcdir)/../libgcc/unwind.inc $(srcdir)/../libgcc/unwind-dw2-fde.h $(srcdir)/../libgcc/unwind-dw2.h $(CONFIG_H) coretypes.h $(TM_H) $(MACHMODE_H) longlong.h config.status stmp-int-hdrs tsystem.h $(GCC_PASSES) $(GCC_FOR_TARGET) $(MULTILIB_CFLAGS) $(LIBGCC2_CFLAGS) $(INCLUDES) $(vis_hide) -fexceptions -Os -c -o $@ $< OBJS_Os_4_200=$(T)sdivsi3_i4i-Os-4-200.o $(T)udivsi3_i4i-Os-4-200.o $(T)unwind-dw2-Os-4-200.o $(T)libgcc-Os-4-200.a: $(OBJS_Os_4_200) $(GCC_PASSES) diff --git a/gcc/config/spu/t-spu-elf b/gcc/config/spu/t-spu-elf index 5189f28..ab680f5 100644 --- a/gcc/config/spu/t-spu-elf +++ b/gcc/config/spu/t-spu-elf @@ -47,9 +47,6 @@ LIB2FUNCS_STATIC_EXTRA = $(srcdir)/config/spu/float_unssidf.c \ $(srcdir)/config/spu/divmodti4.c \ $(srcdir)/config/spu/divv2df3.c -LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde.c \ - $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c - # We want fine grained libraries, so use the new code to build the # floating point emulation libraries. FPBIT = fp-bit.c diff --git a/gcc/config/t-darwin b/gcc/config/t-darwin index 9e77395..d952bd3 100644 --- a/gcc/config/t-darwin +++ b/gcc/config/t-darwin @@ -42,10 +42,6 @@ darwin-driver.o: $(srcdir)/config/darwin-driver.c \ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/darwin-driver.c -# Use unwind-dw2-fde-darwin -LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-darwin.c \ - $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c - # -pipe because there's an assembler bug, 4077127, which causes # it to not properly process the first # directive, causing temporary # file names to appear in stabs, causing the bootstrap to fail. Using -pipe diff --git a/gcc/config/t-freebsd b/gcc/config/t-freebsd index af2df24..0680618 100644 --- a/gcc/config/t-freebsd +++ b/gcc/config/t-freebsd @@ -3,7 +3,3 @@ CRTSTUFF_T_CFLAGS_S = $(CRTSTUFF_T_CFLAGS) -fPIC # Compile libgcc.a with pic. TARGET_LIBGCC2_CFLAGS += -fPIC - -# Use unwind-dw2-fde-glibc -LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \ - $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c diff --git a/gcc/config/t-libunwind b/gcc/config/t-libunwind index 6fdaf67..6b8d2dd 100644 --- a/gcc/config/t-libunwind +++ b/gcc/config/t-libunwind @@ -1,4 +1,4 @@ -# Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2004, 2011 Free Software Foundation, Inc. # # This file is part of GCC. # @@ -22,9 +22,6 @@ # so that the resulting libgcc_s.so has the necessary DT_NEEDED entry for # libunwind. SHLIB_LC = -lunwind -lc -LIB2ADDEH = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c \ - $(srcdir)/unwind-compat.c $(srcdir)/unwind-dw2-fde-compat.c -LIB2ADDEHSTATIC = $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c T_CFLAGS += -DUSE_LIBUNWIND_EXCEPTIONS TARGET_LIBGCC2_CFLAGS += -DUSE_GAS_SYMVER diff --git a/gcc/config/t-libunwind-elf b/gcc/config/t-libunwind-elf deleted file mode 100644 index 5ae0d62..0000000 --- a/gcc/config/t-libunwind-elf +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright (C) 2004, 2005 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/>. - -# Build libunwind for ELF with the GNU linker. - -# Use unwind-dw2-fde-glibc -LIBUNWIND = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c -LIBUNWINDDEP = unwind.inc unwind-dw2-fde.h unwind-dw2-fde.c - -SHLIBUNWIND_SOVERSION = 7 -SHLIBUNWIND_SONAME = @shlib_base_name@.so.$(SHLIBUNWIND_SOVERSION) - -SHLIBUNWIND_LINK = $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) -shared \ - -nodefaultlibs -Wl,-h,$(SHLIBUNWIND_SONAME) \ - -Wl,-z,text -Wl,-z,defs -o $(SHLIB_DIR)/$(SHLIBUNWIND_SONAME).tmp \ - @multilib_flags@ $(SHLIB_OBJS) -lc && \ - rm -f $(SHLIB_DIR)/$(SHLIB_SOLINK) && \ - if [ -f $(SHLIB_DIR)/$(SHLIBUNWIND_SONAME) ]; then \ - mv -f $(SHLIB_DIR)/$(SHLIBUNWIND_SONAME) \ - $(SHLIB_DIR)/$(SHLIBUNWIND_SONAME).backup; \ - else true; fi && \ - mv $(SHLIB_DIR)/$(SHLIBUNWIND_SONAME).tmp \ - $(SHLIB_DIR)/$(SHLIBUNWIND_SONAME) && \ - $(LN_S) $(SHLIBUNWIND_SONAME) $(SHLIB_DIR)/$(SHLIB_SOLINK) - -# $(slibdir) double quoted to protect it from expansion while building -# libgcc.mk. We want this delayed until actual install time. -SHLIBUNWIND_INSTALL = \ - $$(SHELL) $$(srcdir)/mkinstalldirs $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL); \ - $(INSTALL_DATA) $(SHLIB_DIR)/$(SHLIBUNWIND_SONAME) \ - $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIBUNWIND_SONAME); \ - rm -f $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK); \ - $(LN_S) $(SHLIBUNWIND_SONAME) \ - $$(DESTDIR)$$(slibdir)$(SHLIB_SLIBDIR_QUAL)/$(SHLIB_SOLINK) diff --git a/gcc/config/t-linux b/gcc/config/t-linux index 039fa27..64d19ca 100644 --- a/gcc/config/t-linux +++ b/gcc/config/t-linux @@ -25,7 +25,3 @@ TARGET_LIBGCC2_CFLAGS = -fPIC # Override t-slibgcc-elf-ver to export some libgcc symbols with # the symbol versions that glibc used. SHLIB_MAPFILES += $(srcdir)/config/libgcc-glibc.ver - -# Use unwind-dw2-fde-glibc -LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \ - $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c diff --git a/gcc/config/t-sol2 b/gcc/config/t-sol2 index 73fd8eb..f53da4d 100644 --- a/gcc/config/t-sol2 +++ b/gcc/config/t-sol2 @@ -31,8 +31,3 @@ sol2.o: $(srcdir)/config/sol2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ # This is required by gcc/ada/gcc-interface/Makefile.in. TARGET_LIBGCC2_CFLAGS = -fPIC - -# Use unwind-dw2-fde-glibc.c. Unless linker support and dl_iterate_phdr -# are present, automatically falls back to unwind-dw2-fde.c. -LIB2ADDEH = $(srcdir)/unwind-dw2.c $(srcdir)/unwind-dw2-fde-glibc.c \ - $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c diff --git a/gcc/config/xtensa/t-xtensa b/gcc/config/xtensa/t-xtensa index c3d98ae..641e6fe 100644 --- a/gcc/config/xtensa/t-xtensa +++ b/gcc/config/xtensa/t-xtensa @@ -1,4 +1,5 @@ -# Copyright (C) 2002, 2003, 2006, 2007, 2008 Free Software Foundation, Inc. +# Copyright (C) 2002, 2003, 2006, 2007, 2008, 2011 +# Free Software Foundation, Inc. # # This file is part of GCC. # @@ -29,8 +30,6 @@ LIB1ASMFUNCS = _mulsi3 _divsi3 _modsi3 _udivsi3 _umodsi3 \ _truncdfsf2 _extendsfdf2 LIB2FUNCS_EXTRA = $(srcdir)/config/xtensa/lib2funcs.S -LIB2ADDEH = $(srcdir)/config/xtensa/unwind-dw2-xtensa.c \ - $(srcdir)/unwind-dw2-fde.c $(srcdir)/unwind-sjlj.c $(srcdir)/unwind-c.c $(T)crti.o: $(srcdir)/config/xtensa/crti.asm $(GCC_PASSES) $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \ diff --git a/gcc/config/xtensa/unwind-dw2-xtensa.c b/gcc/config/xtensa/unwind-dw2-xtensa.c deleted file mode 100644 index 54daf76..0000000 --- a/gcc/config/xtensa/unwind-dw2-xtensa.c +++ /dev/null @@ -1,544 +0,0 @@ -/* DWARF2 exception handling and frame unwinding for Xtensa. - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2007, 2008, 2009, 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 "tconfig.h" -#include "tsystem.h" -#include "coretypes.h" -#include "tm.h" -#include "dwarf2.h" -#include "unwind.h" -#ifdef __USING_SJLJ_EXCEPTIONS__ -# define NO_SIZE_OF_ENCODED_VALUE -#endif -#include "unwind-pe.h" -#include "unwind-dw2-fde.h" -#include "unwind-dw2-xtensa.h" - -#ifndef __USING_SJLJ_EXCEPTIONS__ - -/* The standard CIE and FDE structures work fine for Xtensa but the - variable-size register window save areas are not a good fit for the rest - of the standard DWARF unwinding mechanism. Nor is that mechanism - necessary, since the register save areas are always in fixed locations - in each stack frame. This file is a stripped down and customized version - of the standard DWARF unwinding code. It needs to be customized to have - builtin logic for finding the save areas and also to track the stack - pointer value (besides the CFA) while unwinding since the primary save - area is located below the stack pointer. It is stripped down to reduce - code size and ease the maintenance burden of tracking changes in the - standard version of the code. */ - -#ifndef DWARF_REG_TO_UNWIND_COLUMN -#define DWARF_REG_TO_UNWIND_COLUMN(REGNO) (REGNO) -#endif - -#define XTENSA_RA_FIELD_MASK 0x3FFFFFFF - -/* 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. */ -struct _Unwind_Context -{ - /* Track register window save areas of 4 registers each, instead of - keeping separate addresses for the individual registers. */ - _Unwind_Word *reg[4]; - - void *cfa; - void *sp; - void *ra; - - /* Cache the 2 high bits to replace the window size in return addresses. */ - _Unwind_Word ra_high_bits; - - void *lsda; - struct dwarf_eh_bases bases; - /* Signal frame context. */ -#define SIGNAL_FRAME_BIT ((~(_Unwind_Word) 0 >> 1) + 1) - _Unwind_Word flags; - /* 0 for now, can be increased when further fields are added to - struct _Unwind_Context. */ - _Unwind_Word version; -}; - - -/* Read unaligned data from the instruction buffer. */ - -union unaligned -{ - void *p; -} __attribute__ ((packed)); - -static void uw_update_context (struct _Unwind_Context *, _Unwind_FrameState *); -static _Unwind_Reason_Code uw_frame_state_for (struct _Unwind_Context *, - _Unwind_FrameState *); - -static inline void * -read_pointer (const void *p) { const union unaligned *up = p; return up->p; } - -static inline _Unwind_Word -_Unwind_IsSignalFrame (struct _Unwind_Context *context) -{ - return (context->flags & SIGNAL_FRAME_BIT) ? 1 : 0; -} - -static inline void -_Unwind_SetSignalFrame (struct _Unwind_Context *context, int val) -{ - if (val) - context->flags |= SIGNAL_FRAME_BIT; - else - context->flags &= ~SIGNAL_FRAME_BIT; -} - -/* Get the value of register INDEX as saved in CONTEXT. */ - -inline _Unwind_Word -_Unwind_GetGR (struct _Unwind_Context *context, int index) -{ - _Unwind_Word *ptr; - - index = DWARF_REG_TO_UNWIND_COLUMN (index); - ptr = context->reg[index >> 2] + (index & 3); - - return *ptr; -} - -/* Get the value of the CFA as saved in CONTEXT. */ - -_Unwind_Word -_Unwind_GetCFA (struct _Unwind_Context *context) -{ - return (_Unwind_Ptr) context->cfa; -} - -/* Overwrite the saved value for register INDEX in CONTEXT with VAL. */ - -inline void -_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val) -{ - _Unwind_Word *ptr; - - index = DWARF_REG_TO_UNWIND_COLUMN (index); - ptr = context->reg[index >> 2] + (index & 3); - - *ptr = val; -} - -/* Retrieve the return address for CONTEXT. */ - -inline _Unwind_Ptr -_Unwind_GetIP (struct _Unwind_Context *context) -{ - return (_Unwind_Ptr) context->ra; -} - -/* Retrieve the return address and flag whether that IP is before - or after first not yet fully executed instruction. */ - -inline _Unwind_Ptr -_Unwind_GetIPInfo (struct _Unwind_Context *context, int *ip_before_insn) -{ - *ip_before_insn = _Unwind_IsSignalFrame (context); - return (_Unwind_Ptr) context->ra; -} - -/* Overwrite the return address for CONTEXT with VAL. */ - -inline void -_Unwind_SetIP (struct _Unwind_Context *context, _Unwind_Ptr val) -{ - context->ra = (void *) val; -} - -void * -_Unwind_GetLanguageSpecificData (struct _Unwind_Context *context) -{ - return context->lsda; -} - -_Unwind_Ptr -_Unwind_GetRegionStart (struct _Unwind_Context *context) -{ - return (_Unwind_Ptr) context->bases.func; -} - -void * -_Unwind_FindEnclosingFunction (void *pc) -{ - struct dwarf_eh_bases bases; - const struct dwarf_fde *fde = _Unwind_Find_FDE (pc-1, &bases); - if (fde) - return bases.func; - else - return NULL; -} - -_Unwind_Ptr -_Unwind_GetDataRelBase (struct _Unwind_Context *context) -{ - return (_Unwind_Ptr) context->bases.dbase; -} - -_Unwind_Ptr -_Unwind_GetTextRelBase (struct _Unwind_Context *context) -{ - return (_Unwind_Ptr) context->bases.tbase; -} - -#include "md-unwind-support.h" - -/* Extract any interesting information from the CIE for the translation - unit F belongs to. Return a pointer to the byte after the augmentation, - or NULL if we encountered an undecipherable augmentation. */ - -static const unsigned char * -extract_cie_info (const struct dwarf_cie *cie, struct _Unwind_Context *context, - _Unwind_FrameState *fs) -{ - const unsigned char *aug = cie->augmentation; - const unsigned char *p = aug + strlen ((const char *)aug) + 1; - const unsigned char *ret = NULL; - _uleb128_t utmp; - _sleb128_t stmp; - - /* g++ v2 "eh" has pointer immediately following augmentation string, - so it must be handled first. */ - if (aug[0] == 'e' && aug[1] == 'h') - { - fs->eh_ptr = read_pointer (p); - p += sizeof (void *); - aug += 2; - } - - /* Immediately following the augmentation are the code and - data alignment and return address column. */ - p = read_uleb128 (p, &utmp); - p = read_sleb128 (p, &stmp); - if (cie->version == 1) - fs->retaddr_column = *p++; - else - { - p = read_uleb128 (p, &utmp); - fs->retaddr_column = (_Unwind_Word)utmp; - } - fs->lsda_encoding = DW_EH_PE_omit; - - /* If the augmentation starts with 'z', then a uleb128 immediately - follows containing the length of the augmentation field following - the size. */ - if (*aug == 'z') - { - p = read_uleb128 (p, &utmp); - ret = p + utmp; - - fs->saw_z = 1; - ++aug; - } - - /* Iterate over recognized augmentation subsequences. */ - while (*aug != '\0') - { - /* "L" indicates a byte showing how the LSDA pointer is encoded. */ - if (aug[0] == 'L') - { - fs->lsda_encoding = *p++; - aug += 1; - } - - /* "R" indicates a byte indicating how FDE addresses are encoded. */ - else if (aug[0] == 'R') - { - fs->fde_encoding = *p++; - aug += 1; - } - - /* "P" indicates a personality routine in the CIE augmentation. */ - else if (aug[0] == 'P') - { - _Unwind_Ptr personality; - - p = read_encoded_value (context, *p, p + 1, &personality); - fs->personality = (_Unwind_Personality_Fn) personality; - aug += 1; - } - - /* "S" indicates a signal frame. */ - else if (aug[0] == 'S') - { - fs->signal_frame = 1; - aug += 1; - } - - /* Otherwise we have an unknown augmentation string. - Bail unless we saw a 'z' prefix. */ - else - return ret; - } - - return ret ? ret : p; -} - -/* Given the _Unwind_Context CONTEXT for a stack frame, look up the FDE for - its caller and decode it into FS. This function also sets the - lsda member of CONTEXT, as it is really information - about the caller's frame. */ - -static _Unwind_Reason_Code -uw_frame_state_for (struct _Unwind_Context *context, _Unwind_FrameState *fs) -{ - const struct dwarf_fde *fde; - const struct dwarf_cie *cie; - const unsigned char *aug; - int window_size; - _Unwind_Word *ra_ptr; - - memset (fs, 0, sizeof (*fs)); - context->lsda = 0; - - fde = _Unwind_Find_FDE (context->ra + _Unwind_IsSignalFrame (context) - 1, - &context->bases); - if (fde == NULL) - { -#ifdef MD_FALLBACK_FRAME_STATE_FOR - _Unwind_Reason_Code reason; - /* 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. */ - reason = MD_FALLBACK_FRAME_STATE_FOR (context, fs); - if (reason != _URC_END_OF_STACK) - return reason; -#endif - /* The frame was not recognized and handled by the fallback function, - but it is not really the end of the stack. Fall through here and - unwind it anyway. */ - } - else - { - cie = get_cie (fde); - if (extract_cie_info (cie, context, fs) == NULL) - /* CIE contained unknown augmentation. */ - return _URC_FATAL_PHASE1_ERROR; - - /* Locate augmentation for the fde. */ - aug = (const unsigned char *) fde + sizeof (*fde); - aug += 2 * size_of_encoded_value (fs->fde_encoding); - if (fs->saw_z) - { - _uleb128_t i; - aug = read_uleb128 (aug, &i); - } - if (fs->lsda_encoding != DW_EH_PE_omit) - { - _Unwind_Ptr lsda; - - aug = read_encoded_value (context, fs->lsda_encoding, aug, &lsda); - context->lsda = (void *) lsda; - } - } - - /* Check for the end of the stack. This needs to be checked after - the MD_FALLBACK_FRAME_STATE_FOR check for signal frames because - the contents of context->reg[0] are undefined at a signal frame, - and register a0 may appear to be zero. (The return address in - context->ra comes from register a4 or a8). */ - ra_ptr = context->reg[0]; - if (ra_ptr && *ra_ptr == 0) - return _URC_END_OF_STACK; - - /* Find the window size from the high bits of the return address. */ - if (ra_ptr) - window_size = (*ra_ptr >> 30) * 4; - else - window_size = 8; - - fs->retaddr_column = window_size; - - return _URC_NO_REASON; -} - -static void -uw_update_context_1 (struct _Unwind_Context *context, _Unwind_FrameState *fs) -{ - struct _Unwind_Context orig_context = *context; - _Unwind_Word *sp, *cfa, *next_cfa; - int i; - - if (fs->signal_regs) - { - cfa = (_Unwind_Word *) fs->signal_regs[1]; - next_cfa = (_Unwind_Word *) cfa[-3]; - - for (i = 0; i < 4; i++) - context->reg[i] = fs->signal_regs + (i << 2); - } - else - { - int window_size = fs->retaddr_column >> 2; - - sp = (_Unwind_Word *) orig_context.sp; - cfa = (_Unwind_Word *) orig_context.cfa; - next_cfa = (_Unwind_Word *) cfa[-3]; - - /* Registers a0-a3 are in the save area below sp. */ - context->reg[0] = sp - 4; - - /* Find the extra save area below next_cfa. */ - for (i = 1; i < window_size; i++) - context->reg[i] = next_cfa - 4 * (1 + window_size - i); - - /* Remaining registers rotate from previous save areas. */ - for (i = window_size; i < 4; i++) - context->reg[i] = orig_context.reg[i - window_size]; - } - - context->sp = cfa; - context->cfa = next_cfa; - - _Unwind_SetSignalFrame (context, fs->signal_frame); -} - -/* CONTEXT describes the unwind state for a frame, and FS describes the FDE - of its caller. Update CONTEXT to refer to the caller as well. Note - that the lsda member is not updated here, but later in - uw_frame_state_for. */ - -static void -uw_update_context (struct _Unwind_Context *context, _Unwind_FrameState *fs) -{ - uw_update_context_1 (context, fs); - - /* Compute the return address now, since the return address column - can change from frame to frame. */ - if (fs->signal_ra != 0) - context->ra = (void *) fs->signal_ra; - else - context->ra = (void *) ((_Unwind_GetGR (context, fs->retaddr_column) - & XTENSA_RA_FIELD_MASK) | context->ra_high_bits); -} - -static void -uw_advance_context (struct _Unwind_Context *context, _Unwind_FrameState *fs) -{ - uw_update_context (context, fs); -} - -/* Fill in CONTEXT for top-of-stack. The only valid registers at this - level will be the return address and the CFA. */ - -#define uw_init_context(CONTEXT) \ - do \ - { \ - __builtin_unwind_init (); \ - uw_init_context_1 (CONTEXT, __builtin_dwarf_cfa (), \ - __builtin_return_address (0)); \ - } \ - while (0) - -static void __attribute__((noinline)) -uw_init_context_1 (struct _Unwind_Context *context, void *outer_cfa, - void *outer_ra) -{ - void *ra = __builtin_return_address (0); - void *cfa = __builtin_dwarf_cfa (); - _Unwind_FrameState fs; - - memset (context, 0, sizeof (struct _Unwind_Context)); - context->ra = ra; - - memset (&fs, 0, sizeof (fs)); - fs.retaddr_column = 8; - context->sp = cfa; - context->cfa = outer_cfa; - context->ra_high_bits = - ((_Unwind_Word) uw_init_context_1) & ~XTENSA_RA_FIELD_MASK; - uw_update_context_1 (context, &fs); - - context->ra = outer_ra; -} - - -/* Install TARGET into CURRENT so that we can return to it. This is a - macro because __builtin_eh_return must be invoked in the context of - our caller. */ - -#define uw_install_context(CURRENT, TARGET) \ - do \ - { \ - long offset = uw_install_context_1 ((CURRENT), (TARGET)); \ - void *handler = __builtin_frob_return_addr ((TARGET)->ra); \ - __builtin_eh_return (offset, handler); \ - } \ - while (0) - -static long -uw_install_context_1 (struct _Unwind_Context *current, - struct _Unwind_Context *target) -{ - long i; - - /* The eh_return insn assumes a window size of 8, so don't bother copying - the save areas for registers a8-a15 since they won't be reloaded. */ - for (i = 0; i < 2; ++i) - { - void *c = current->reg[i]; - void *t = target->reg[i]; - - if (t && c && t != c) - memcpy (c, t, 4 * sizeof (_Unwind_Word)); - } - - return 0; -} - -static inline _Unwind_Ptr -uw_identify_context (struct _Unwind_Context *context) -{ - return _Unwind_GetCFA (context); -} - - -#include "unwind.inc" - -#if defined (USE_GAS_SYMVER) && defined (SHARED) && defined (USE_LIBUNWIND_EXCEPTIONS) -alias (_Unwind_Backtrace); -alias (_Unwind_DeleteException); -alias (_Unwind_FindEnclosingFunction); -alias (_Unwind_ForcedUnwind); -alias (_Unwind_GetDataRelBase); -alias (_Unwind_GetTextRelBase); -alias (_Unwind_GetCFA); -alias (_Unwind_GetGR); -alias (_Unwind_GetIP); -alias (_Unwind_GetLanguageSpecificData); -alias (_Unwind_GetRegionStart); -alias (_Unwind_RaiseException); -alias (_Unwind_Resume); -alias (_Unwind_Resume_or_Rethrow); -alias (_Unwind_SetGR); -alias (_Unwind_SetIP); -#endif - -#endif /* !USING_SJLJ_EXCEPTIONS */ diff --git a/gcc/config/xtensa/unwind-dw2-xtensa.h b/gcc/config/xtensa/unwind-dw2-xtensa.h deleted file mode 100644 index d13b326..0000000 --- a/gcc/config/xtensa/unwind-dw2-xtensa.h +++ /dev/null @@ -1,50 +0,0 @@ -/* DWARF2 frame unwind data structure for Xtensa. - Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2007, 2008, - 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/>. */ - -/* A target can override (perhaps for backward compatibility) how - many dwarf2 columns are unwound. */ -#ifndef DWARF_FRAME_REGISTERS -#define DWARF_FRAME_REGISTERS FIRST_PSEUDO_REGISTER -#endif - -/* Xtensa's variable-size register window save areas can be unwound without - any unwind info. This is a stripped down version of the standard DWARF - _Unwind_FrameState. */ -typedef struct -{ - /* The information we care about from the CIE/FDE. */ - _Unwind_Personality_Fn personality; - _Unwind_Word retaddr_column; - unsigned char fde_encoding; - unsigned char lsda_encoding; - unsigned char saw_z; - unsigned char signal_frame; - void *eh_ptr; - - /* Saved registers for a signal frame. */ - _Unwind_Word *signal_regs; - _Unwind_Word signal_ra; -} _Unwind_FrameState; - |