diff gcc/ada/sigtramp-qnx.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents
children 1830386684a0
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gcc/ada/sigtramp-qnx.c	Thu Oct 25 07:37:49 2018 +0900
@@ -0,0 +1,263 @@
+/****************************************************************************
+ *                                                                          *
+ *                         GNAT COMPILER COMPONENTS                         *
+ *                                                                          *
+ *                             S I G T R A M P                              *
+ *                                                                          *
+ *                         Asm Implementation File                          *
+ *                                                                          *
+ *           Copyright (C) 2017-2018, 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.      *
+ *                                                                          *
+ ****************************************************************************/
+
+/**********************************************
+ * QNX version of the __gnat_sigtramp service *
+ **********************************************/
+
+#include <ucontext.h>
+
+#include "sigtramp.h"
+/* See sigtramp.h for a general explanation of functionality.  */
+
+extern void __gnat_sigtramp_common
+  (int signo, void *siginfo, void *sigcontext,
+   __sigtramphandler_t * handler);
+
+void __gnat_sigtramp (int signo, void *si, void *sc,
+                      __sigtramphandler_t * handler)
+     __attribute__((optimize(2)));
+
+void __gnat_sigtramp (int signo, void *si, void *ucontext,
+                      __sigtramphandler_t * handler)
+{
+  struct sigcontext *mcontext = &((ucontext_t *) ucontext)->uc_mcontext;
+
+  __gnat_sigtramp_common (signo, si, mcontext, handler);
+}
+
+/* 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
+   multiline contents:  */
+#define TAB(S) "\t" S
+#define CR(S)  S "\n"
+
+#undef TCR
+#define TCR(S) TAB(CR(S))
+
+/* Trampoline body block
+   ---------------------  */
+
+#define COMMON_CFI(REG) \
+  ".cfi_offset " S(REGNO_##REG) "," S(REG_OFFSET_##REG)
+
+#ifdef __x86_64__
+/*****************************************
+ *               x86-64                  *
+ *****************************************/
+
+// CFI register 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 /* Used as CFA */
+#define REGNO_RPC 16 /* aka %rip */
+
+//  Registers offset from the regset structure
+#define REG_OFFSET_RDI 0x00
+#define REG_OFFSET_RSI 0x08
+#define REG_OFFSET_RDX 0x10
+#define REG_OFFSET_R10 0x18
+#define REG_OFFSET_R8  0x20
+#define REG_OFFSET_R9  0x28
+#define REG_OFFSET_RAX 0x30
+#define REG_OFFSET_RBX 0x38
+#define REG_OFFSET_RBP 0x40
+#define REG_OFFSET_RCX 0x48
+#define REG_OFFSET_R11 0x50
+#define REG_OFFSET_R12 0x58
+#define REG_OFFSET_R13 0x60
+#define REG_OFFSET_R14 0x68
+#define REG_OFFSET_R15 0x70
+#define REG_OFFSET_RPC 0x78 /* RIP */
+#define REG_OFFSET_RSP 0x90
+
+#define CFI_COMMON_REGS \
+CR("# CFI for common registers\n") \
+TCR(COMMON_CFI(RSP)) \
+TCR(COMMON_CFI(R15)) \
+TCR(COMMON_CFI(R14)) \
+TCR(COMMON_CFI(R13)) \
+TCR(COMMON_CFI(R12)) \
+TCR(COMMON_CFI(R11)) \
+TCR(COMMON_CFI(RCX)) \
+TCR(COMMON_CFI(RBP)) \
+TCR(COMMON_CFI(RBX)) \
+TCR(COMMON_CFI(RAX)) \
+TCR(COMMON_CFI(R9)) \
+TCR(COMMON_CFI(R8)) \
+TCR(COMMON_CFI(R10)) \
+TCR(COMMON_CFI(RSI)) \
+TCR(COMMON_CFI(RDI)) \
+TCR(COMMON_CFI(RDX)) \
+TCR(COMMON_CFI(RPC)) \
+TCR(".cfi_return_column " S(REGNO_RPC))
+
+#define SIGTRAMP_BODY     \
+TCR(".cfi_def_cfa 15, 0") \
+CFI_COMMON_REGS \
+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	%rdx, %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")
+#endif
+
+#ifdef __aarch64__
+/*****************************************
+ *               Aarch64                 *
+ *****************************************/
+
+/* CFA reg: any callee saved register will do */
+#define CFA_REG  19
+
+/* General purpose registers */
+#define REG_OFFSET_GR(n)     (n * 8)
+#define REGNO_GR(n)   n
+
+/* ELR value offset withing the mcontext registers list */
+#define REG_OFFSET_ELR           (32 * 8)
+/* The register used to hold the PC value to restore. We need a scratch
+   register.  */
+#define REGNO_PC      9
+
+#define CFI_DEF_CFA \
+  TCR(".cfi_def_cfa " S(CFA_REG) ", 0")
+
+/* This restores the callee-saved registers, the FP, the LR, and the SP.
+   A scratch register is used as return column to indicate the new value
+   for PC */
+#define CFI_COMMON_REGS \
+  CR("# CFI for common registers\n") \
+  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(".cfi_offset " S(REGNO_PC) "," S(REG_OFFSET_ELR)) \
+  TCR(".cfi_return_column " S(REGNO_PC))
+
+#define SIGTRAMP_BODY \
+  CFI_DEF_CFA \
+  CFI_COMMON_REGS \
+  TCR("# Allocate the frame (16bytes aligned) and push FP and LR") \
+  TCR("stp x29, x30, [sp, #-32]!") \
+  TCR("add x29, sp, 0") \
+  TCR("# Push register used to hold the CFA on stack") \
+  TCR("str x" S(CFA_REG) ", [sp, 16]")  \
+  TCR("# Set the CFA: x2 value") \
+  TCR("mov x" S(CFA_REG) ", x2") \
+  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")
+
+#endif /* AARCH64 */
+
+/* Symbol definition block
+   -----------------------  */
+
+#if defined (__x86_64__) || defined (__aarch64__)
+#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"));
+
+/* sigtramp stub for common registers.  */
+
+#define TRAMP_COMMON __gnat_sigtramp_common
+
+asm (SIGTRAMP_START(TRAMP_COMMON));
+asm (SIGTRAMP_BODY);
+asm (SIGTRAMP_END(TRAMP_COMMON));