diff options
Diffstat (limited to 'gcc/ada/sigtramp-vxworks-target.h')
-rw-r--r-- | gcc/ada/sigtramp-vxworks-target.h | 585 |
1 files changed, 585 insertions, 0 deletions
diff --git a/gcc/ada/sigtramp-vxworks-target.h b/gcc/ada/sigtramp-vxworks-target.h new file mode 100644 index 0000000..8c43451 --- /dev/null +++ b/gcc/ada/sigtramp-vxworks-target.h @@ -0,0 +1,585 @@ +/**************************************************************************** + * * + * GNAT COMPILER COMPONENTS * + * * + * S I G T R A M P - T A R G E T * + * * + * Asm Implementation Include File * + * * + * Copyright (C) 2011-2021, Free Software Foundation, Inc. * + * * + * GNAT is free software; you can redistribute it and/or modify it under * + * terms of the GNU General Public License as published by the Free Soft- * + * ware Foundation; either version 3, or (at your option) any later ver- * + * sion. GNAT is distributed in the hope that it will be useful, but WITH- * + * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * + * or FITNESS FOR A PARTICULAR PURPOSE. * + * * + * As a special exception 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. * + * * + * In particular, you can freely distribute your programs built with the * + * GNAT Pro compiler, including any required library run-time units, using * + * any licensing terms of your choosing. See the AdaCore Software License * + * for full details. * + * * + * GNAT was originally developed by the GNAT team at New York University. * + * Extensive contributions were provided by Ada Core Technologies Inc. * + * * + ****************************************************************************/ + +/*************************************************************** + * VxWorks target specific part of the __gnat_sigtramp service * + ***************************************************************/ + +/* Note: This target specific part is kept in a separate file to avoid + duplication of its code for the vxworks and vxworks-vxsim asm + implementation files. */ + +/* --------------------------- + -- And now the asm stubs -- + --------------------------- + + They all have a common structure with blocks of asm sequences queued one + after the others. Typically: + + SYMBOL_START + + CFI_DIRECTIVES + CFI_DEF_CFA, + CFI_COMMON_REGISTERS, + ... + + STUB_BODY + asm code to establish frame, setup the cfa reg value, + call the real signal handler, ... + + SYMBOL_END +*/ + +/*-------------------------------- + -- Misc constants and helpers -- + -------------------------------- */ + +/* asm string construction helpers. */ + +#define STR(TEXT) #TEXT +/* stringify expanded TEXT, surrounding it with double quotes. */ + +#define S(E) STR(E) +/* stringify E, which will resolve as text but may contain macros + still to be expanded. */ + +/* asm (TEXT) outputs <tab>TEXT. These facilitate the output of + multine contents: */ +#define TAB(S) "\t" S +#define CR(S) S "\n" + +#undef TCR +#define TCR(S) TAB(CR(S)) + +/* REGNO constants, dwarf column numbers for registers of interest. */ + +#if defined (__PPC__) + +#define REGNO_LR 65 +#define REGNO_CTR 66 +#define REGNO_CR 70 +#define REGNO_XER 76 +#define REGNO_GR(N) (N) + +#define REGNO_PC 67 /* ARG_POINTER_REGNUM */ + +#define FUNCTION "@function" + +#elif defined (ARMEL) + +#define REGNO_G_REG_OFFSET(N) (N) + +#define FUNCTION "%function" + +#ifdef __aarch64__ +#define REGNO_PC_OFFSET 96 /* DWARF_ALT_FRAME_RETURN_COLUMN */ +#else +#define REGNO_PC_OFFSET 15 /* PC_REGNUM */ +#endif + +/* Mapping of CFI Column, Gcc Regno, Signal context offset for _LP64 + + Name CFI GCC SCTX + G0-G30 0-30 0-30 0-30 + SP 31 31 31 + PC 32 + V0-V31 64-95 32-63 N/A + +*/ + +#elif defined (i386) + +/* These are the cfi colunm numbers */ + +#define REGNO_EDI 7 +#define REGNO_ESI 6 +#define REGNO_EBP 5 +#define REGNO_ESP 4 +#define REGNO_EBX 3 +#define REGNO_EDX 2 +#define REGNO_ECX 1 +#define REGNO_EAX 0 +#define REGNO_EFLAGS 9 +#define REGNO_SET_PC 8 /* aka %eip */ + +#define FUNCTION "@function" + +/* Mapping of CFI Column, Gcc Regno, Signal context offset for 32bit + + Name CFI GCC SCTX + %eax 0 0 7 + %ecx 1 2 6 + %edx 2 1 5 + %ebx 3 3 4 + %esp 4 7 3 + %ebp 5 6 2 + %esi 6 4 1 + %edi 7 5 0 + %eflags 9 17 8 + %eip 8 n/a 9 + + + In general: + There is no unique numbering for the x86 architecture. It's parameterized + by DWARF_FRAME_REGNUM, which is DBX_REGISTER_NUMBER except for Windows, and + the latter depends on the platform. +*/ + +#elif defined (__x86_64__) + +/* These are the cfi colunm numbers */ + +#define REGNO_RAX 0 +#define REGNO_RDX 1 +#define REGNO_RCX 2 +#define REGNO_RBX 3 +#define REGNO_RSI 4 +#define REGNO_RDI 5 +#define REGNO_RBP 6 +#define REGNO_RSP 7 +#define REGNO_R8 8 +#define REGNO_R9 9 +#define REGNO_R10 10 +#define REGNO_R11 11 +#define REGNO_R12 12 +#define REGNO_R13 13 +#define REGNO_R14 14 +#define REGNO_R15 15 +#define REGNO_RPC 16 /* aka %rip */ +#define REGNO_EFLAGS 49 +#define REGNO_FS 54 + +#define FUNCTION "@function" + +#else +Not_implemented; +#endif /* REGNO constants */ + + +/*------------------------------ + -- Stub construction blocks -- + ------------------------------ */ + +/* CFA setup block + --------------- + Only non-volatile registers are suitable for a CFA base. These are the + only ones we can expect to be able retrieve from the unwinding context + while walking up the chain, saved by at least the bottom-most exception + propagation services. We set a non-volatile register to the value we + need in the stub body that follows. */ + +#if defined (__PPC__) + +/* Use r15 for PPC. Note that r14 is inappropriate here, even though it + is non-volatile according to the ABI, because GCC uses it as an extra + SCRATCH on SPE targets. */ + +#define CFA_REG 15 + +#elif defined (ARMEL) + +#ifdef __aarch64__ +#define CFA_REG 19 +#else +/* Use r8 for ARM. Any of r4-r8 should work. */ +#define CFA_REG 8 +#endif + +#elif defined (i386) + +#define CFA_REG 7 + +#elif defined (__x86_64__) + +/* R15 register */ +#define CFA_REG 15 + +#else +Not_implemented; +#endif /* CFA setup block */ + +#define CFI_DEF_CFA \ +CR(".cfi_def_cfa " S(CFA_REG) ", 0") + +/* Register location blocks + ------------------------ + Rules to find registers of interest from the CFA. This should comprise + all the non-volatile registers relevant to the interrupted context. + + Note that we include r1 in this set, unlike the libgcc unwinding + fallbacks. This is useful for fallbacks to allow the use of r1 in CFI + expressions and the absence of rule for r1 gets compensated by using the + target CFA instead. We don't need the expression facility here and + setup a fake CFA to allow very simple offset expressions, so having a + rule for r1 is the proper thing to do. We for sure have observed + crashes in some cases without it. */ + +#if defined (__PPC__) + +#define COMMON_CFI(REG) \ + ".cfi_offset " S(REGNO_##REG) "," S(REG_SET_##REG) + +#define CFI_COMMON_REGS \ +CR("# CFI for common registers\n") \ +TCR(COMMON_CFI(GR(0))) \ +TCR(COMMON_CFI(GR(1))) \ +TCR(COMMON_CFI(GR(2))) \ +TCR(COMMON_CFI(GR(3))) \ +TCR(COMMON_CFI(GR(4))) \ +TCR(COMMON_CFI(GR(5))) \ +TCR(COMMON_CFI(GR(6))) \ +TCR(COMMON_CFI(GR(7))) \ +TCR(COMMON_CFI(GR(8))) \ +TCR(COMMON_CFI(GR(9))) \ +TCR(COMMON_CFI(GR(10))) \ +TCR(COMMON_CFI(GR(11))) \ +TCR(COMMON_CFI(GR(12))) \ +TCR(COMMON_CFI(GR(13))) \ +TCR(COMMON_CFI(GR(14))) \ +TCR(COMMON_CFI(GR(15))) \ +TCR(COMMON_CFI(GR(16))) \ +TCR(COMMON_CFI(GR(17))) \ +TCR(COMMON_CFI(GR(18))) \ +TCR(COMMON_CFI(GR(19))) \ +TCR(COMMON_CFI(GR(20))) \ +TCR(COMMON_CFI(GR(21))) \ +TCR(COMMON_CFI(GR(22))) \ +TCR(COMMON_CFI(GR(23))) \ +TCR(COMMON_CFI(GR(24))) \ +TCR(COMMON_CFI(GR(25))) \ +TCR(COMMON_CFI(GR(26))) \ +TCR(COMMON_CFI(GR(27))) \ +TCR(COMMON_CFI(GR(28))) \ +TCR(COMMON_CFI(GR(29))) \ +TCR(COMMON_CFI(GR(30))) \ +TCR(COMMON_CFI(GR(31))) \ +TCR(COMMON_CFI(LR)) \ +TCR(COMMON_CFI(CR)) \ +TCR(COMMON_CFI(CTR)) \ +TCR(COMMON_CFI(XER)) \ +TCR(COMMON_CFI(PC)) \ +TCR(".cfi_return_column " S(REGNO_PC)) + +/* Trampoline body block + --------------------- */ + +#if !defined (__PPC64__) +#define SIGTRAMP_BODY \ +CR("") \ +TCR("# Allocate frame and save the non-volatile") \ +TCR("# registers we're going to modify") \ +TCR("stwu %r1,-16(%r1)") \ +TCR("mflr %r0") \ +TCR("stw %r0,20(%r1)") \ +TCR("stw %r" S(CFA_REG) ",8(%r1)") \ +TCR("") \ +TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \ +TCR("mr %r" S(CFA_REG) ", %r7") \ +TCR("") \ +TCR("# Call the real handler. The signo, siginfo and sigcontext") \ +TCR("# arguments are the same as those we received in r3, r4 and r5") \ +TCR("mtctr %r6") \ +TCR("bctrl") \ +TCR("") \ +TCR("# Restore our callee-saved items, release our frame and return") \ +TCR("lwz %r" S(CFA_REG) ",8(%r1)") \ +TCR("lwz %r0,20(%r1)") \ +TCR("mtlr %r0") \ +TCR("") \ +TCR("addi %r1,%r1,16") \ +TCR("blr") +#else +#define SIGTRAMP_BODY \ +CR("") \ +TCR(".LOC_SIGTMP_COM_0:") \ +TCR("addis 2,12,.TOC.-.LOC_SIGTMP_COM_0@ha") \ +TCR("addi 2,2,.TOC.-.LOC_SIGTMP_COM_0@l") \ +TCR(".localentry __gnat_sigtramp_common,.-__gnat_sigtramp_common") \ +TCR("# Allocate frame and save the non-volatile") \ +TCR("# registers we're going to modify") \ +TCR("mflr %r0") \ +TCR("std %r0,16(%r1)") \ +TCR("stdu %r1,-32(%r1)") \ +TCR("std %r2,24(%r1)") \ +TCR("std %r" S(CFA_REG) ",8(%r1)") \ +TCR("") \ +TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \ +TCR("mr %r" S(CFA_REG) ", %r7") \ +TCR("") \ +TCR("# Call the real handler. The signo, siginfo and sigcontext") \ +TCR("# arguments are the same as those we received in r3, r4 and r5") \ +TCR("mr %r12,%r6") \ +TCR("mtctr %r6") \ +TCR("bctrl") \ +TCR("") \ +TCR("# Restore our callee-saved items, release our frame and return") \ +TCR("ld %r" S(CFA_REG) ",8(%r1)") \ +TCR("ld %r2,24(%r1)") \ +TCR("addi %r1,%r1,32") \ +TCR("ld %r0,16(%r1)") \ +TCR("mtlr %r0") \ +TCR("blr") +#endif + +#elif defined (ARMEL) + +#define COMMON_CFI(REG) \ + ".cfi_offset " S(REGNO_##REG) "," S(REG_SET_##REG) + +#ifdef __aarch64__ +#define CFI_COMMON_REGS \ +CR("# CFI for common registers\n") \ +TCR(COMMON_CFI(G_REG_OFFSET(0))) \ +TCR(COMMON_CFI(G_REG_OFFSET(1))) \ +TCR(COMMON_CFI(G_REG_OFFSET(2))) \ +TCR(COMMON_CFI(G_REG_OFFSET(3))) \ +TCR(COMMON_CFI(G_REG_OFFSET(4))) \ +TCR(COMMON_CFI(G_REG_OFFSET(5))) \ +TCR(COMMON_CFI(G_REG_OFFSET(6))) \ +TCR(COMMON_CFI(G_REG_OFFSET(7))) \ +TCR(COMMON_CFI(G_REG_OFFSET(8))) \ +TCR(COMMON_CFI(G_REG_OFFSET(9))) \ +TCR(COMMON_CFI(G_REG_OFFSET(10))) \ +TCR(COMMON_CFI(G_REG_OFFSET(11))) \ +TCR(COMMON_CFI(G_REG_OFFSET(12))) \ +TCR(COMMON_CFI(G_REG_OFFSET(13))) \ +TCR(COMMON_CFI(G_REG_OFFSET(14))) \ +TCR(COMMON_CFI(G_REG_OFFSET(15))) \ +TCR(COMMON_CFI(G_REG_OFFSET(16))) \ +TCR(COMMON_CFI(G_REG_OFFSET(17))) \ +CR("# Leave alone R18, VxWorks reserved\n") \ +TCR(COMMON_CFI(G_REG_OFFSET(19))) \ +TCR(COMMON_CFI(G_REG_OFFSET(20))) \ +TCR(COMMON_CFI(G_REG_OFFSET(21))) \ +TCR(COMMON_CFI(G_REG_OFFSET(22))) \ +TCR(COMMON_CFI(G_REG_OFFSET(23))) \ +TCR(COMMON_CFI(G_REG_OFFSET(24))) \ +TCR(COMMON_CFI(G_REG_OFFSET(25))) \ +TCR(COMMON_CFI(G_REG_OFFSET(26))) \ +TCR(COMMON_CFI(G_REG_OFFSET(27))) \ +TCR(COMMON_CFI(G_REG_OFFSET(28))) \ +TCR(COMMON_CFI(G_REG_OFFSET(29))) \ +TCR(COMMON_CFI(G_REG_OFFSET(30))) \ +TCR(COMMON_CFI(G_REG_OFFSET(31))) \ +TCR(COMMON_CFI(PC_OFFSET)) \ +TCR(".cfi_return_column " S(REGNO_PC_OFFSET)) +#else +#define CFI_COMMON_REGS \ +CR("# CFI for common registers\n") \ +TCR(COMMON_CFI(G_REG_OFFSET(0))) \ +TCR(COMMON_CFI(G_REG_OFFSET(1))) \ +TCR(COMMON_CFI(G_REG_OFFSET(2))) \ +TCR(COMMON_CFI(G_REG_OFFSET(3))) \ +TCR(COMMON_CFI(G_REG_OFFSET(4))) \ +TCR(COMMON_CFI(G_REG_OFFSET(5))) \ +TCR(COMMON_CFI(G_REG_OFFSET(6))) \ +TCR(COMMON_CFI(G_REG_OFFSET(7))) \ +TCR(COMMON_CFI(G_REG_OFFSET(8))) \ +TCR(COMMON_CFI(G_REG_OFFSET(9))) \ +TCR(COMMON_CFI(G_REG_OFFSET(10))) \ +TCR(COMMON_CFI(G_REG_OFFSET(11))) \ +TCR(COMMON_CFI(G_REG_OFFSET(12))) \ +TCR(COMMON_CFI(G_REG_OFFSET(13))) \ +TCR(COMMON_CFI(G_REG_OFFSET(14))) \ +TCR(COMMON_CFI(PC_OFFSET)) \ +TCR(".cfi_return_column " S(REGNO_PC_OFFSET)) +#endif + +/* Trampoline body block + --------------------- */ +#ifdef __aarch64__ +#define SIGTRAMP_BODY \ +CR("") \ +TCR("# Allocate the frame (16bytes aligned) and push FP and LR") \ +TCR("stp x29, x30, [sp, #-32]!") \ +TCR("add x29, sp, 0") \ +TCR("# Store register used to hold the CFA on stack (pro forma)") \ +TCR("str x" S(CFA_REG) ", [sp, 16]") \ +TCR("# Set the CFA reg from the 5th arg") \ +TCR("mov x" S(CFA_REG) ", x4") \ +TCR("# Call the handler") \ +TCR("blr x3") \ +TCR("# Release our frame and return (should never get here!).") \ +TCR("ldr x" S(CFA_REG) ", [sp, 16]") \ +TCR("ldp x29, x30, [sp], 32") \ +TCR("ret") +#else +#define SIGTRAMP_BODY \ +CR("") \ +TCR("# Allocate frame and save the non-volatile") \ +TCR("# registers we're going to modify") \ +TCR("mov ip, sp") \ +TCR("stmfd sp!, {r"S(CFA_REG)", fp, ip, lr, pc}") \ +TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \ +TCR("ldr r"S(CFA_REG)", [ip]") \ +TCR("") \ +TCR("# Call the real handler. The signo, siginfo and sigcontext") \ +TCR("# arguments are the same as those we received in r0, r1 and r2") \ +TCR("sub fp, ip, #4") \ +TCR("blx r3") \ +TCR("# Restore our callee-saved items, release our frame and return") \ +TCR("ldmfd sp, {r"S(CFA_REG)", fp, sp, pc}") +#endif + +#elif defined (i386) + +#if CPU == SIMNT || CPU == SIMPENTIUM || CPU == SIMLINUX +#define COMMON_CFI(REG) \ + ".cfi_offset " S(REGNO_##REG) "," S(REG_SET_##REG) +#else +#define COMMON_CFI(REG) \ + ".cfi_offset " S(REGNO_##REG) "," S(REG_##REG) +#endif + +#define PC_CFI(REG) \ + ".cfi_offset " S(REGNO_##REG) "," S(REG_##REG) + +#define CFI_COMMON_REGS \ +CR("# CFI for common registers\n") \ +TCR(COMMON_CFI(EDI)) \ +TCR(COMMON_CFI(ESI)) \ +TCR(COMMON_CFI(EBP)) \ +TCR(COMMON_CFI(ESP)) \ +TCR(COMMON_CFI(EBX)) \ +TCR(COMMON_CFI(EDX)) \ +TCR(COMMON_CFI(ECX)) \ +TCR(COMMON_CFI(EAX)) \ +TCR(COMMON_CFI(EFLAGS)) \ +TCR(PC_CFI(SET_PC)) \ +TCR(".cfi_return_column " S(REGNO_SET_PC)) + +/* Trampoline body block + --------------------- */ + +#define SIGTRAMP_BODY \ +CR("") \ +TCR("# Allocate frame and save the non-volatile") \ +TCR("# registers we're going to modify") \ +TCR("pushl %ebp") \ +TCR("movl %esp, %ebp") \ +TCR("pushl %edi") \ +TCR("subl $24, %esp") \ +TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \ +TCR("movl 24(%ebp), %edi") \ +TCR("# Call the real handler. The signo, siginfo and sigcontext") \ +TCR("# arguments are the same as those we received") \ +TCR("movl 16(%ebp), %eax") \ +TCR("movl %eax, 8(%esp)") \ +TCR("movl 12(%ebp), %eax") \ +TCR("movl %eax, 4(%esp)") \ +TCR("movl 8(%ebp), %eax") \ +TCR("movl %eax, (%esp)") \ +TCR("call *20(%ebp)") \ +TCR("# Restore our callee-saved items, release our frame and return") \ +TCR("popl %edi") \ +TCR("leave") \ +TCR("ret") + +#elif defined (__x86_64__) + +#define COMMON_CFI(REG) \ + ".cfi_offset " S(REGNO_##REG) "," S(REG_##REG) + +#define CFI_COMMON_REGS \ +CR("# CFI for common registers\n") \ +TCR(COMMON_CFI(R15)) \ +TCR(COMMON_CFI(R14)) \ +TCR(COMMON_CFI(R13)) \ +TCR(COMMON_CFI(R12)) \ +TCR(COMMON_CFI(R11)) \ +TCR(COMMON_CFI(R10)) \ +TCR(COMMON_CFI(R9)) \ +TCR(COMMON_CFI(R8)) \ +TCR(COMMON_CFI(RDI)) \ +TCR(COMMON_CFI(RSI)) \ +TCR(COMMON_CFI(RBP)) \ +TCR(COMMON_CFI(RSP)) \ +TCR(COMMON_CFI(RBX)) \ +TCR(COMMON_CFI(RDX)) \ +TCR(COMMON_CFI(RCX)) \ +TCR(COMMON_CFI(RAX)) \ +TCR(COMMON_CFI(RPC)) \ +TCR(".cfi_return_column " S(REGNO_RPC)) + +/* Trampoline body block + --------------------- */ + +#define SIGTRAMP_BODY \ +CR("") \ +TCR("# Allocate frame and save the non-volatile") \ +TCR("# registers we're going to modify") \ +TCR("subq $8, %rsp") \ +TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \ +TCR("movq %r8, %r15") \ +TCR("# Call the real handler. The signo, siginfo and sigcontext") \ +TCR("# arguments are the same as those we received") \ +TCR("call *%rcx") \ +TCR("# This part should never be executed") \ +TCR("addq $8, %rsp") \ +TCR("ret") + +#else +Not_implemented; +#endif /* CFI_COMMON_REGS and SIGTRAMP_BODY */ + +/* Symbol definition block + ----------------------- */ + +#ifdef __x86_64__ +#define FUNC_ALIGN TCR(".p2align 4,,15") +#else +#define FUNC_ALIGN +#endif + +#define SIGTRAMP_START(SYM) \ +CR("# " S(SYM) " cfi trampoline") \ +TCR(".type " S(SYM) ", "FUNCTION) \ +CR("") \ +FUNC_ALIGN \ +CR(S(SYM) ":") \ +TCR(".cfi_startproc") \ +TCR(".cfi_signal_frame") + +/* Symbol termination block + ------------------------ */ + +#define SIGTRAMP_END(SYM) \ +CR(".cfi_endproc") \ +TCR(".size " S(SYM) ", .-" S(SYM)) + +/*---------------------------- + -- And now, the real code -- + ---------------------------- */ + +/* Text section start. The compiler isn't aware of that switch. */ + +asm (".text\n" + TCR(".align 2")); |