Mercurial > hg > CbC > CbC_gcc
comparison gcc/ada/sigtramp-qnx.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /**************************************************************************** | |
2 * * | |
3 * GNAT COMPILER COMPONENTS * | |
4 * * | |
5 * S I G T R A M P * | |
6 * * | |
7 * Asm Implementation File * | |
8 * * | |
9 * Copyright (C) 2017-2018, Free Software Foundation, Inc. * | |
10 * * | |
11 * GNAT is free software; you can redistribute it and/or modify it under * | |
12 * terms of the GNU General Public License as published by the Free Soft- * | |
13 * ware Foundation; either version 3, or (at your option) any later ver- * | |
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- * | |
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * | |
16 * or FITNESS FOR A PARTICULAR PURPOSE. * | |
17 * * | |
18 * As a special exception under Section 7 of GPL version 3, you are granted * | |
19 * additional permissions described in the GCC Runtime Library Exception, * | |
20 * version 3.1, as published by the Free Software Foundation. * | |
21 * * | |
22 * In particular, you can freely distribute your programs built with the * | |
23 * GNAT Pro compiler, including any required library run-time units, using * | |
24 * any licensing terms of your choosing. See the AdaCore Software License * | |
25 * for full details. * | |
26 * * | |
27 * GNAT was originally developed by the GNAT team at New York University. * | |
28 * Extensive contributions were provided by Ada Core Technologies Inc. * | |
29 * * | |
30 ****************************************************************************/ | |
31 | |
32 /********************************************** | |
33 * QNX version of the __gnat_sigtramp service * | |
34 **********************************************/ | |
35 | |
36 #include <ucontext.h> | |
37 | |
38 #include "sigtramp.h" | |
39 /* See sigtramp.h for a general explanation of functionality. */ | |
40 | |
41 extern void __gnat_sigtramp_common | |
42 (int signo, void *siginfo, void *sigcontext, | |
43 __sigtramphandler_t * handler); | |
44 | |
45 void __gnat_sigtramp (int signo, void *si, void *sc, | |
46 __sigtramphandler_t * handler) | |
47 __attribute__((optimize(2))); | |
48 | |
49 void __gnat_sigtramp (int signo, void *si, void *ucontext, | |
50 __sigtramphandler_t * handler) | |
51 { | |
52 struct sigcontext *mcontext = &((ucontext_t *) ucontext)->uc_mcontext; | |
53 | |
54 __gnat_sigtramp_common (signo, si, mcontext, handler); | |
55 } | |
56 | |
57 /* asm string construction helpers. */ | |
58 | |
59 #define STR(TEXT) #TEXT | |
60 /* stringify expanded TEXT, surrounding it with double quotes. */ | |
61 | |
62 #define S(E) STR(E) | |
63 /* stringify E, which will resolve as text but may contain macros | |
64 still to be expanded. */ | |
65 | |
66 /* asm (TEXT) outputs <tab>TEXT. These facilitate the output of | |
67 multiline contents: */ | |
68 #define TAB(S) "\t" S | |
69 #define CR(S) S "\n" | |
70 | |
71 #undef TCR | |
72 #define TCR(S) TAB(CR(S)) | |
73 | |
74 /* Trampoline body block | |
75 --------------------- */ | |
76 | |
77 #define COMMON_CFI(REG) \ | |
78 ".cfi_offset " S(REGNO_##REG) "," S(REG_OFFSET_##REG) | |
79 | |
80 #ifdef __x86_64__ | |
81 /***************************************** | |
82 * x86-64 * | |
83 *****************************************/ | |
84 | |
85 // CFI register numbers | |
86 #define REGNO_RAX 0 | |
87 #define REGNO_RDX 1 | |
88 #define REGNO_RCX 2 | |
89 #define REGNO_RBX 3 | |
90 #define REGNO_RSI 4 | |
91 #define REGNO_RDI 5 | |
92 #define REGNO_RBP 6 | |
93 #define REGNO_RSP 7 | |
94 #define REGNO_R8 8 | |
95 #define REGNO_R9 9 | |
96 #define REGNO_R10 10 | |
97 #define REGNO_R11 11 | |
98 #define REGNO_R12 12 | |
99 #define REGNO_R13 13 | |
100 #define REGNO_R14 14 | |
101 #define REGNO_R15 15 /* Used as CFA */ | |
102 #define REGNO_RPC 16 /* aka %rip */ | |
103 | |
104 // Registers offset from the regset structure | |
105 #define REG_OFFSET_RDI 0x00 | |
106 #define REG_OFFSET_RSI 0x08 | |
107 #define REG_OFFSET_RDX 0x10 | |
108 #define REG_OFFSET_R10 0x18 | |
109 #define REG_OFFSET_R8 0x20 | |
110 #define REG_OFFSET_R9 0x28 | |
111 #define REG_OFFSET_RAX 0x30 | |
112 #define REG_OFFSET_RBX 0x38 | |
113 #define REG_OFFSET_RBP 0x40 | |
114 #define REG_OFFSET_RCX 0x48 | |
115 #define REG_OFFSET_R11 0x50 | |
116 #define REG_OFFSET_R12 0x58 | |
117 #define REG_OFFSET_R13 0x60 | |
118 #define REG_OFFSET_R14 0x68 | |
119 #define REG_OFFSET_R15 0x70 | |
120 #define REG_OFFSET_RPC 0x78 /* RIP */ | |
121 #define REG_OFFSET_RSP 0x90 | |
122 | |
123 #define CFI_COMMON_REGS \ | |
124 CR("# CFI for common registers\n") \ | |
125 TCR(COMMON_CFI(RSP)) \ | |
126 TCR(COMMON_CFI(R15)) \ | |
127 TCR(COMMON_CFI(R14)) \ | |
128 TCR(COMMON_CFI(R13)) \ | |
129 TCR(COMMON_CFI(R12)) \ | |
130 TCR(COMMON_CFI(R11)) \ | |
131 TCR(COMMON_CFI(RCX)) \ | |
132 TCR(COMMON_CFI(RBP)) \ | |
133 TCR(COMMON_CFI(RBX)) \ | |
134 TCR(COMMON_CFI(RAX)) \ | |
135 TCR(COMMON_CFI(R9)) \ | |
136 TCR(COMMON_CFI(R8)) \ | |
137 TCR(COMMON_CFI(R10)) \ | |
138 TCR(COMMON_CFI(RSI)) \ | |
139 TCR(COMMON_CFI(RDI)) \ | |
140 TCR(COMMON_CFI(RDX)) \ | |
141 TCR(COMMON_CFI(RPC)) \ | |
142 TCR(".cfi_return_column " S(REGNO_RPC)) | |
143 | |
144 #define SIGTRAMP_BODY \ | |
145 TCR(".cfi_def_cfa 15, 0") \ | |
146 CFI_COMMON_REGS \ | |
147 CR("") \ | |
148 TCR("# Allocate frame and save the non-volatile") \ | |
149 TCR("# registers we're going to modify") \ | |
150 TCR("subq $8, %rsp") \ | |
151 TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \ | |
152 TCR("movq %rdx, %r15") \ | |
153 TCR("# Call the real handler. The signo, siginfo and sigcontext") \ | |
154 TCR("# arguments are the same as those we received") \ | |
155 TCR("call *%rcx") \ | |
156 TCR("# This part should never be executed") \ | |
157 TCR("addq $8, %rsp") \ | |
158 TCR("ret") | |
159 #endif | |
160 | |
161 #ifdef __aarch64__ | |
162 /***************************************** | |
163 * Aarch64 * | |
164 *****************************************/ | |
165 | |
166 /* CFA reg: any callee saved register will do */ | |
167 #define CFA_REG 19 | |
168 | |
169 /* General purpose registers */ | |
170 #define REG_OFFSET_GR(n) (n * 8) | |
171 #define REGNO_GR(n) n | |
172 | |
173 /* ELR value offset withing the mcontext registers list */ | |
174 #define REG_OFFSET_ELR (32 * 8) | |
175 /* The register used to hold the PC value to restore. We need a scratch | |
176 register. */ | |
177 #define REGNO_PC 9 | |
178 | |
179 #define CFI_DEF_CFA \ | |
180 TCR(".cfi_def_cfa " S(CFA_REG) ", 0") | |
181 | |
182 /* This restores the callee-saved registers, the FP, the LR, and the SP. | |
183 A scratch register is used as return column to indicate the new value | |
184 for PC */ | |
185 #define CFI_COMMON_REGS \ | |
186 CR("# CFI for common registers\n") \ | |
187 TCR(COMMON_CFI(GR(18))) \ | |
188 TCR(COMMON_CFI(GR(19))) \ | |
189 TCR(COMMON_CFI(GR(20))) \ | |
190 TCR(COMMON_CFI(GR(21))) \ | |
191 TCR(COMMON_CFI(GR(22))) \ | |
192 TCR(COMMON_CFI(GR(23))) \ | |
193 TCR(COMMON_CFI(GR(24))) \ | |
194 TCR(COMMON_CFI(GR(25))) \ | |
195 TCR(COMMON_CFI(GR(26))) \ | |
196 TCR(COMMON_CFI(GR(27))) \ | |
197 TCR(COMMON_CFI(GR(28))) \ | |
198 TCR(COMMON_CFI(GR(29))) \ | |
199 TCR(COMMON_CFI(GR(30))) \ | |
200 TCR(COMMON_CFI(GR(31))) \ | |
201 TCR(".cfi_offset " S(REGNO_PC) "," S(REG_OFFSET_ELR)) \ | |
202 TCR(".cfi_return_column " S(REGNO_PC)) | |
203 | |
204 #define SIGTRAMP_BODY \ | |
205 CFI_DEF_CFA \ | |
206 CFI_COMMON_REGS \ | |
207 TCR("# Allocate the frame (16bytes aligned) and push FP and LR") \ | |
208 TCR("stp x29, x30, [sp, #-32]!") \ | |
209 TCR("add x29, sp, 0") \ | |
210 TCR("# Push register used to hold the CFA on stack") \ | |
211 TCR("str x" S(CFA_REG) ", [sp, 16]") \ | |
212 TCR("# Set the CFA: x2 value") \ | |
213 TCR("mov x" S(CFA_REG) ", x2") \ | |
214 TCR("# Call the handler") \ | |
215 TCR("blr x3") \ | |
216 TCR("# Release our frame and return (should never get here!).") \ | |
217 TCR("ldr x" S(CFA_REG) ", [sp, 16]") \ | |
218 TCR("ldp x29, x30, [sp], 32") \ | |
219 TCR("ret") | |
220 | |
221 #endif /* AARCH64 */ | |
222 | |
223 /* Symbol definition block | |
224 ----------------------- */ | |
225 | |
226 #if defined (__x86_64__) || defined (__aarch64__) | |
227 #define FUNC_ALIGN TCR(".p2align 4,,15") | |
228 #else | |
229 #define FUNC_ALIGN | |
230 #endif | |
231 | |
232 #define SIGTRAMP_START(SYM) \ | |
233 CR("# " S(SYM) " cfi trampoline") \ | |
234 TCR(".type " S(SYM) ", @function") \ | |
235 CR("") \ | |
236 FUNC_ALIGN \ | |
237 CR(S(SYM) ":") \ | |
238 TCR(".cfi_startproc") \ | |
239 TCR(".cfi_signal_frame") | |
240 | |
241 /* Symbol termination block | |
242 ------------------------ */ | |
243 | |
244 #define SIGTRAMP_END(SYM) \ | |
245 CR(".cfi_endproc") \ | |
246 TCR(".size " S(SYM) ", .-" S(SYM)) | |
247 | |
248 /*---------------------------- | |
249 -- And now, the real code -- | |
250 ---------------------------- */ | |
251 | |
252 /* Text section start. The compiler isn't aware of that switch. */ | |
253 | |
254 asm (".text\n" | |
255 TCR(".align 2")); | |
256 | |
257 /* sigtramp stub for common registers. */ | |
258 | |
259 #define TRAMP_COMMON __gnat_sigtramp_common | |
260 | |
261 asm (SIGTRAMP_START(TRAMP_COMMON)); | |
262 asm (SIGTRAMP_BODY); | |
263 asm (SIGTRAMP_END(TRAMP_COMMON)); |