PR c++/83897
[official-gcc.git] / gcc / ada / sigtramp-vxworks-target.inc
bloba49a48f8bb3fc319043961599d633808cb6ae961
1 /****************************************************************************
2  *                                                                          *
3  *                         GNAT COMPILER COMPONENTS                         *
4  *                                                                          *
5  *                      S I G T R A M P - T A R G E T                       *
6  *                                                                          *
7  *                     Asm Implementation Include File                      *
8  *                                                                          *
9  *         Copyright (C) 2011-2017, 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  ****************************************************************************/
32 /***************************************************************
33  * VxWorks target specific part of the __gnat_sigtramp service *
34  ***************************************************************/
36 /* Note: This target specific part is kept in a separate file to avoid
37    duplication of its code for the vxworks and vxworks-vxsim asm
38    implementation files.  */
40 /* ---------------------------
41    -- And now the asm stubs --
42    ---------------------------
44    They all have a common structure with blocks of asm sequences queued one
45    after the others.  Typically:
47    SYMBOL_START
49    CFI_DIRECTIVES
50      CFI_DEF_CFA,
51      CFI_COMMON_REGISTERS,
52      ...
54    STUB_BODY
55      asm code to establish frame, setup the cfa reg value,
56      call the real signal handler, ...
58    SYMBOL_END
61 /*--------------------------------
62   -- Misc constants and helpers --
63   -------------------------------- */
65 /* asm string construction helpers.  */
67 #define STR(TEXT) #TEXT
68 /* stringify expanded TEXT, surrounding it with double quotes.  */
70 #define S(E) STR(E)
71 /* stringify E, which will resolve as text but may contain macros
72    still to be expanded.  */
74 /* asm (TEXT) outputs <tab>TEXT. These facilitate the output of
75    multine contents:  */
76 #define TAB(S) "\t" S
77 #define CR(S)  S "\n"
79 #undef TCR
80 #define TCR(S) TAB(CR(S))
82 /* REGNO constants, dwarf column numbers for registers of interest.  */
84 #if defined (__PPC__)
86 #define REGNO_LR  65
87 #define REGNO_CTR 66
88 #define REGNO_CR  70
89 #define REGNO_XER 76
90 #define REGNO_GR(N) (N)
92 #define REGNO_PC  67  /* ARG_POINTER_REGNUM  */
94 #define FUNCTION "@function"
96 #elif defined (ARMEL)
98 #define REGNO_G_REG_OFFSET(N) (N)
100 #define FUNCTION "%function"
102 #ifdef __aarch64__
103 #define REGNO_PC_OFFSET  31  /* PC_REGNUM  */
104 #else
105 #define REGNO_PC_OFFSET  15  /* PC_REGNUM  */
106 #endif
108 /* Mapping of CFI Column, Gcc Regno, Signal context offset for _LP64
110    Name    CFI     GCC     SCTX
111    G0-G30  0-30    0-30
112    PC      31      31
113    V0-V31  64-95   32-63
117 #elif defined (i386)
119 /* These are the cfi colunm numbers */
121 #define REGNO_EDI 7
122 #define REGNO_ESI 6
123 #define REGNO_EBP 5
124 #define REGNO_ESP 4
125 #define REGNO_EBX 3
126 #define REGNO_EDX 2
127 #define REGNO_ECX 1
128 #define REGNO_EAX 0
129 #define REGNO_EFLAGS 9
130 #define REGNO_SET_PC 8 /* aka %eip */
132 #define FUNCTION "@function"
134 /* Mapping of CFI Column, Gcc Regno, Signal context offset for 32bit
136    Name    CFI     GCC     SCTX
137    %eax     0       0       7
138    %ecx     1       2       6
139    %edx     2       1       5
140    %ebx     3       3       4
141    %esp     4       7       3
142    %ebp     5       6       2
143    %esi     6       4       1
144    %edi     7       5       0
145    %eflags  9      17       8
146    %eip     8     n/a       9
149    In general:
150    There is no unique numbering for the x86 architecture.  It's parameterized
151    by DWARF_FRAME_REGNUM, which is DBX_REGISTER_NUMBER except for Windows, and
152    the latter depends on the platform.
155 #elif defined (__x86_64__)
157 /* These are the cfi colunm numbers */
159 #define REGNO_RAX 0
160 #define REGNO_RDX 1
161 #define REGNO_RCX 2
162 #define REGNO_RBX 3
163 #define REGNO_RSI 4
164 #define REGNO_RDI 5
165 #define REGNO_RBP 6
166 #define REGNO_RSP 7
167 #define REGNO_R8 8
168 #define REGNO_R9 9
169 #define REGNO_R10 10
170 #define REGNO_R11 11
171 #define REGNO_R12 12
172 #define REGNO_R13 13
173 #define REGNO_R14 14
174 #define REGNO_R15 15
175 #define REGNO_RPC 16 /* aka %rip */
176 #define REGNO_EFLAGS 49
177 #define REGNO_FS 54
179 #define FUNCTION "@function"
181 #else
182 Not_implemented;
183 #endif /* REGNO constants */
186 /*------------------------------
187   -- Stub construction blocks --
188   ------------------------------ */
190 /* CFA setup block
191    ---------------
192    Only non-volatile registers are suitable for a CFA base. These are the
193    only ones we can expect to be able retrieve from the unwinding context
194    while walking up the chain, saved by at least the bottom-most exception
195    propagation services.  We set a non-volatile register to the value we
196    need in the stub body that follows.  */
198 #if defined (__PPC__)
200 /* Use r15 for PPC.  Note that r14 is inappropriate here, even though it
201    is non-volatile according to the ABI, because GCC uses it as an extra
202    SCRATCH on SPE targets.  */
204 #define CFA_REG 15
206 #elif defined (ARMEL)
208 #ifdef __aarch64__
209 #define CFA_REG 19
210 #else
211 /* Use r8 for ARM.  Any of r4-r8 should work.  */
212 #define CFA_REG 8
213 #endif
215 #elif defined (i386)
217 #define CFA_REG 7
219 #elif defined (__x86_64__)
221 /* R15 register */
222 #define CFA_REG 15
224 #else
225 Not_implemented;
226 #endif /* CFA setup block */
228 #define CFI_DEF_CFA \
229 CR(".cfi_def_cfa " S(CFA_REG) ", 0")
231 /* Register location blocks
232    ------------------------
233    Rules to find registers of interest from the CFA. This should comprise
234    all the non-volatile registers relevant to the interrupted context.
236    Note that we include r1 in this set, unlike the libgcc unwinding
237    fallbacks.  This is useful for fallbacks to allow the use of r1 in CFI
238    expressions and the absence of rule for r1 gets compensated by using the
239    target CFA instead.  We don't need the expression facility here and
240    setup a fake CFA to allow very simple offset expressions, so having a
241    rule for r1 is the proper thing to do.  We for sure have observed
242    crashes in some cases without it.  */
244 #if defined (__PPC__)
246 #define COMMON_CFI(REG) \
247   ".cfi_offset " S(REGNO_##REG) "," S(REG_SET_##REG)
249 #define CFI_COMMON_REGS \
250 CR("# CFI for common registers\n") \
251 TCR(COMMON_CFI(GR(0)))  \
252 TCR(COMMON_CFI(GR(1)))  \
253 TCR(COMMON_CFI(GR(2)))  \
254 TCR(COMMON_CFI(GR(3)))  \
255 TCR(COMMON_CFI(GR(4)))  \
256 TCR(COMMON_CFI(GR(5)))  \
257 TCR(COMMON_CFI(GR(6)))  \
258 TCR(COMMON_CFI(GR(7)))  \
259 TCR(COMMON_CFI(GR(8)))  \
260 TCR(COMMON_CFI(GR(9)))  \
261 TCR(COMMON_CFI(GR(10)))  \
262 TCR(COMMON_CFI(GR(11)))  \
263 TCR(COMMON_CFI(GR(12)))  \
264 TCR(COMMON_CFI(GR(13)))  \
265 TCR(COMMON_CFI(GR(14))) \
266 TCR(COMMON_CFI(GR(15))) \
267 TCR(COMMON_CFI(GR(16))) \
268 TCR(COMMON_CFI(GR(17))) \
269 TCR(COMMON_CFI(GR(18))) \
270 TCR(COMMON_CFI(GR(19))) \
271 TCR(COMMON_CFI(GR(20))) \
272 TCR(COMMON_CFI(GR(21))) \
273 TCR(COMMON_CFI(GR(22))) \
274 TCR(COMMON_CFI(GR(23))) \
275 TCR(COMMON_CFI(GR(24))) \
276 TCR(COMMON_CFI(GR(25))) \
277 TCR(COMMON_CFI(GR(26))) \
278 TCR(COMMON_CFI(GR(27))) \
279 TCR(COMMON_CFI(GR(28))) \
280 TCR(COMMON_CFI(GR(29))) \
281 TCR(COMMON_CFI(GR(30))) \
282 TCR(COMMON_CFI(GR(31))) \
283 TCR(COMMON_CFI(LR)) \
284 TCR(COMMON_CFI(CR)) \
285 TCR(COMMON_CFI(CTR)) \
286 TCR(COMMON_CFI(XER)) \
287 TCR(COMMON_CFI(PC)) \
288 TCR(".cfi_return_column " S(REGNO_PC))
290 /* Trampoline body block
291    ---------------------  */
293 #if !defined (__PPC64__)
294 #define SIGTRAMP_BODY \
295 CR("") \
296 TCR("# Allocate frame and save the non-volatile") \
297 TCR("# registers we're going to modify") \
298 TCR("stwu %r1,-16(%r1)")  \
299 TCR("mflr %r0") \
300 TCR("stw %r0,20(%r1)")  \
301 TCR("stw %r" S(CFA_REG) ",8(%r1)")      \
302 TCR("")                 \
303 TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \
304 TCR("mr %r" S(CFA_REG) ", %r7") \
305 TCR("")                 \
306 TCR("# Call the real handler. The signo, siginfo and sigcontext") \
307 TCR("# arguments are the same as those we received in r3, r4 and r5") \
308 TCR("mtctr %r6") \
309 TCR("bctrl")    \
310 TCR("")         \
311 TCR("# Restore our callee-saved items, release our frame and return") \
312 TCR("lwz %r" S(CFA_REG) ",8(%r1)")      \
313 TCR("lwz %r0,20(%r1)")  \
314 TCR("mtlr %r0")         \
315 TCR("")                 \
316 TCR("addi %r1,%r1,16")  \
317 TCR("blr")
318 #else
319 #define SIGTRAMP_BODY \
320 CR("") \
321 TCR("0:") \
322 TCR("addis 2,12,.TOC.-0@ha") \
323 TCR("addi 2,2,.TOC.-0@l") \
324 TCR(".localentry        __gnat_sigtramp_common,.-__gnat_sigtramp_common") \
325 TCR("# Allocate frame and save the non-volatile") \
326 TCR("# registers we're going to modify") \
327 TCR("mflr %r0") \
328 TCR("std %r0,16(%r1)")  \
329 TCR("stdu %r1,-32(%r1)")  \
330 TCR("std %r2,24(%r1)")  \
331 TCR("std %r" S(CFA_REG) ",8(%r1)")      \
332 TCR("")                 \
333 TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \
334 TCR("mr %r" S(CFA_REG) ", %r7") \
335 TCR("")                 \
336 TCR("# Call the real handler. The signo, siginfo and sigcontext") \
337 TCR("# arguments are the same as those we received in r3, r4 and r5") \
338 TCR("mr %r12,%r6") \
339 TCR("mtctr %r6") \
340 TCR("bctrl")    \
341 TCR("")         \
342 TCR("# Restore our callee-saved items, release our frame and return") \
343 TCR("ld %r" S(CFA_REG) ",8(%r1)")       \
344 TCR("ld %r2,24(%r1)")   \
345 TCR("addi %r1,%r1,32")  \
346 TCR("ld %r0,16(%r1)")   \
347 TCR("mtlr %r0")         \
348 TCR("blr")
349 #endif
351 #elif defined (ARMEL)
353 #define COMMON_CFI(REG) \
354   ".cfi_offset " S(REGNO_##REG) "," S(REG_SET_##REG)
356 #ifdef __aarch64__
357 #define CFI_COMMON_REGS \
358 CR("# CFI for common registers\n") \
359 TCR(COMMON_CFI(G_REG_OFFSET(0)))  \
360 TCR(COMMON_CFI(G_REG_OFFSET(1)))  \
361 TCR(COMMON_CFI(G_REG_OFFSET(2)))  \
362 TCR(COMMON_CFI(G_REG_OFFSET(3)))  \
363 TCR(COMMON_CFI(G_REG_OFFSET(4)))  \
364 TCR(COMMON_CFI(G_REG_OFFSET(5)))  \
365 TCR(COMMON_CFI(G_REG_OFFSET(6)))  \
366 TCR(COMMON_CFI(G_REG_OFFSET(7)))  \
367 TCR(COMMON_CFI(G_REG_OFFSET(8)))  \
368 TCR(COMMON_CFI(G_REG_OFFSET(9)))  \
369 TCR(COMMON_CFI(G_REG_OFFSET(10)))  \
370 TCR(COMMON_CFI(G_REG_OFFSET(11)))  \
371 TCR(COMMON_CFI(G_REG_OFFSET(12)))  \
372 TCR(COMMON_CFI(G_REG_OFFSET(13)))  \
373 TCR(COMMON_CFI(G_REG_OFFSET(14))) \
374 TCR(COMMON_CFI(G_REG_OFFSET(15))) \
375 TCR(COMMON_CFI(G_REG_OFFSET(16))) \
376 TCR(COMMON_CFI(G_REG_OFFSET(17))) \
377 TCR(COMMON_CFI(G_REG_OFFSET(18))) \
378 TCR(COMMON_CFI(G_REG_OFFSET(19))) \
379 TCR(COMMON_CFI(G_REG_OFFSET(20))) \
380 TCR(COMMON_CFI(G_REG_OFFSET(21))) \
381 TCR(COMMON_CFI(G_REG_OFFSET(22))) \
382 TCR(COMMON_CFI(G_REG_OFFSET(23))) \
383 TCR(COMMON_CFI(G_REG_OFFSET(24))) \
384 TCR(COMMON_CFI(G_REG_OFFSET(25))) \
385 TCR(COMMON_CFI(G_REG_OFFSET(26))) \
386 TCR(COMMON_CFI(G_REG_OFFSET(27))) \
387 TCR(COMMON_CFI(G_REG_OFFSET(28))) \
388 TCR(COMMON_CFI(G_REG_OFFSET(29))) \
389 TCR(COMMON_CFI(PC_OFFSET)) \
390 TCR(".cfi_return_column " S(REGNO_PC_OFFSET))
391 #else
392 #define CFI_COMMON_REGS \
393 CR("# CFI for common registers\n") \
394 TCR(COMMON_CFI(G_REG_OFFSET(0)))  \
395 TCR(COMMON_CFI(G_REG_OFFSET(1)))  \
396 TCR(COMMON_CFI(G_REG_OFFSET(2)))  \
397 TCR(COMMON_CFI(G_REG_OFFSET(3)))  \
398 TCR(COMMON_CFI(G_REG_OFFSET(4)))  \
399 TCR(COMMON_CFI(G_REG_OFFSET(5)))  \
400 TCR(COMMON_CFI(G_REG_OFFSET(6)))  \
401 TCR(COMMON_CFI(G_REG_OFFSET(7)))  \
402 TCR(COMMON_CFI(G_REG_OFFSET(8)))  \
403 TCR(COMMON_CFI(G_REG_OFFSET(9)))  \
404 TCR(COMMON_CFI(G_REG_OFFSET(10)))  \
405 TCR(COMMON_CFI(G_REG_OFFSET(11)))  \
406 TCR(COMMON_CFI(G_REG_OFFSET(12)))  \
407 TCR(COMMON_CFI(G_REG_OFFSET(13)))  \
408 TCR(COMMON_CFI(G_REG_OFFSET(14))) \
409 TCR(COMMON_CFI(PC_OFFSET)) \
410 TCR(".cfi_return_column " S(REGNO_PC_OFFSET))
411 #endif
413 /* Trampoline body block
414    ---------------------  */
415 #ifdef __aarch64__
416 #define SIGTRAMP_BODY \
417 CR("") \
418 TCR("# Push FP and LR on stack") \
419 TCR("stp x29, x30, [sp, #-16]!") \
420 TCR("# Push register used to hold the CFA on stack") \
421 TCR("str x" S(CFA_REG) ", [sp, #-8]!")  \
422 TCR("# Set the CFA: x2 value") \
423 TCR("mov x" S(CFA_REG) ", x2") \
424 TCR("# Call the handler") \
425 TCR("blr x3") \
426 TCR("# Release our frame and return (should never get here!).") \
427 TCR("ldr x" S(CFA_REG) " , [sp], 8") \
428 TCR("ldp x29, x30, [sp], 16") \
429 TCR("ret")
430 #else
431 #define SIGTRAMP_BODY \
432 CR("") \
433 TCR("# Allocate frame and save the non-volatile") \
434 TCR("# registers we're going to modify") \
435 TCR("mov        ip, sp") \
436 TCR("stmfd      sp!, {r"S(CFA_REG)", fp, ip, lr, pc}") \
437 TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \
438 TCR("ldr        r"S(CFA_REG)", [ip]") \
439 TCR("")                 \
440 TCR("# Call the real handler. The signo, siginfo and sigcontext") \
441 TCR("# arguments are the same as those we received in r0, r1 and r2") \
442 TCR("sub        fp, ip, #4") \
443 TCR("blx        r3") \
444 TCR("# Restore our callee-saved items, release our frame and return") \
445 TCR("ldmfd      sp, {r"S(CFA_REG)", fp, sp, pc}")
446 #endif
448 #elif defined (i386)
450 #if CPU == SIMNT || CPU == SIMPENTIUM || CPU == SIMLINUX
451 #define COMMON_CFI(REG) \
452   ".cfi_offset " S(REGNO_##REG) "," S(REG_SET_##REG)
453 #else
454 #define COMMON_CFI(REG) \
455   ".cfi_offset " S(REGNO_##REG) "," S(REG_##REG)
456 #endif
458 #define PC_CFI(REG) \
459   ".cfi_offset " S(REGNO_##REG) "," S(REG_##REG)
461 #define CFI_COMMON_REGS \
462 CR("# CFI for common registers\n") \
463 TCR(COMMON_CFI(EDI)) \
464 TCR(COMMON_CFI(ESI)) \
465 TCR(COMMON_CFI(EBP)) \
466 TCR(COMMON_CFI(ESP)) \
467 TCR(COMMON_CFI(EBX)) \
468 TCR(COMMON_CFI(EDX)) \
469 TCR(COMMON_CFI(ECX)) \
470 TCR(COMMON_CFI(EAX)) \
471 TCR(COMMON_CFI(EFLAGS)) \
472 TCR(PC_CFI(SET_PC)) \
473 TCR(".cfi_return_column " S(REGNO_SET_PC))
475 /* Trampoline body block
476    ---------------------  */
478 #define SIGTRAMP_BODY \
479 CR("") \
480 TCR("# Allocate frame and save the non-volatile") \
481 TCR("# registers we're going to modify") \
482 TCR("pushl      %ebp") \
483 TCR("movl       %esp, %ebp") \
484 TCR("pushl      %edi") \
485 TCR("subl       $24, %esp") \
486 TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \
487 TCR("movl       24(%ebp), %edi") \
488 TCR("# Call the real handler. The signo, siginfo and sigcontext") \
489 TCR("# arguments are the same as those we received") \
490 TCR("movl       16(%ebp), %eax") \
491 TCR("movl       %eax, 8(%esp)") \
492 TCR("movl       12(%ebp), %eax") \
493 TCR("movl       %eax, 4(%esp)") \
494 TCR("movl       8(%ebp), %eax") \
495 TCR("movl       %eax, (%esp)") \
496 TCR("call       *20(%ebp)") \
497 TCR("# Restore our callee-saved items, release our frame and return") \
498 TCR("popl       %edi") \
499 TCR("leave") \
500 TCR("ret")
502 #elif defined (__x86_64__)
504 #define COMMON_CFI(REG) \
505   ".cfi_offset " S(REGNO_##REG) "," S(REG_##REG)
507 #define CFI_COMMON_REGS \
508 CR("# CFI for common registers\n") \
509 TCR(COMMON_CFI(R15)) \
510 TCR(COMMON_CFI(R14)) \
511 TCR(COMMON_CFI(R13)) \
512 TCR(COMMON_CFI(R12)) \
513 TCR(COMMON_CFI(R11)) \
514 TCR(COMMON_CFI(R10)) \
515 TCR(COMMON_CFI(R9)) \
516 TCR(COMMON_CFI(R8)) \
517 TCR(COMMON_CFI(RDI)) \
518 TCR(COMMON_CFI(RSI)) \
519 TCR(COMMON_CFI(RBP)) \
520 TCR(COMMON_CFI(RSP)) \
521 TCR(COMMON_CFI(RBX)) \
522 TCR(COMMON_CFI(RDX)) \
523 TCR(COMMON_CFI(RCX)) \
524 TCR(COMMON_CFI(RAX)) \
525 TCR(COMMON_CFI(RPC)) \
526 TCR(".cfi_return_column " S(REGNO_RPC))
528 /* Trampoline body block
529    ---------------------  */
531 #define SIGTRAMP_BODY \
532 CR("") \
533 TCR("# Allocate frame and save the non-volatile") \
534 TCR("# registers we're going to modify") \
535 TCR("subq       $8, %rsp") \
536 TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \
537 TCR("movq       %r8, %r15") \
538 TCR("# Call the real handler. The signo, siginfo and sigcontext") \
539 TCR("# arguments are the same as those we received") \
540 TCR("call       *%rcx") \
541 TCR("# This part should never be executed") \
542 TCR("addq       $8, %rsp") \
543 TCR("ret")
545 #else
546 Not_implemented;
547 #endif /* CFI_COMMON_REGS and SIGTRAMP_BODY */
549 /* Symbol definition block
550    -----------------------  */
552 #ifdef __x86_64__
553 #define FUNC_ALIGN TCR(".p2align 4,,15")
554 #else
555 #define FUNC_ALIGN
556 #endif
558 #define SIGTRAMP_START(SYM) \
559 CR("# " S(SYM) " cfi trampoline") \
560 TCR(".type " S(SYM) ", "FUNCTION) \
561 CR("") \
562 FUNC_ALIGN \
563 CR(S(SYM) ":") \
564 TCR(".cfi_startproc") \
565 TCR(".cfi_signal_frame")
567 /* Symbol termination block
568    ------------------------  */
570 #define SIGTRAMP_END(SYM) \
571 CR(".cfi_endproc") \
572 TCR(".size " S(SYM) ", .-" S(SYM))
574 /*----------------------------
575   -- And now, the real code --
576   ---------------------------- */
578 /* Text section start.  The compiler isn't aware of that switch.  */
580 asm (".text\n"
581      TCR(".align 2"));