annotate gcc/ada/sigtramp-vxworks.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /****************************************************************************
kono
parents:
diff changeset
2 * *
kono
parents:
diff changeset
3 * GNAT COMPILER COMPONENTS *
kono
parents:
diff changeset
4 * *
kono
parents:
diff changeset
5 * S I G T R A M P *
kono
parents:
diff changeset
6 * *
kono
parents:
diff changeset
7 * Asm Implementation File *
kono
parents:
diff changeset
8 * *
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 * Copyright (C) 2011-2019, Free Software Foundation, Inc. *
111
kono
parents:
diff changeset
10 * *
kono
parents:
diff changeset
11 * GNAT is free software; you can redistribute it and/or modify it under *
kono
parents:
diff changeset
12 * terms of the GNU General Public License as published by the Free Soft- *
kono
parents:
diff changeset
13 * ware Foundation; either version 3, or (at your option) any later ver- *
kono
parents:
diff changeset
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
kono
parents:
diff changeset
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
kono
parents:
diff changeset
16 * or FITNESS FOR A PARTICULAR PURPOSE. *
kono
parents:
diff changeset
17 * *
kono
parents:
diff changeset
18 * As a special exception under Section 7 of GPL version 3, you are granted *
kono
parents:
diff changeset
19 * additional permissions described in the GCC Runtime Library Exception, *
kono
parents:
diff changeset
20 * version 3.1, as published by the Free Software Foundation. *
kono
parents:
diff changeset
21 * *
kono
parents:
diff changeset
22 * In particular, you can freely distribute your programs built with the *
kono
parents:
diff changeset
23 * GNAT Pro compiler, including any required library run-time units, using *
kono
parents:
diff changeset
24 * any licensing terms of your choosing. See the AdaCore Software License *
kono
parents:
diff changeset
25 * for full details. *
kono
parents:
diff changeset
26 * *
kono
parents:
diff changeset
27 * GNAT was originally developed by the GNAT team at New York University. *
kono
parents:
diff changeset
28 * Extensive contributions were provided by Ada Core Technologies Inc. *
kono
parents:
diff changeset
29 * *
kono
parents:
diff changeset
30 ****************************************************************************/
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 /**************************************************
kono
parents:
diff changeset
33 * VxWorks version of the __gnat_sigtramp service *
kono
parents:
diff changeset
34 **************************************************/
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 #include "sigtramp.h"
kono
parents:
diff changeset
37 /* See sigtramp.h for a general explanation of functionality. */
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 #include <vxWorks.h>
kono
parents:
diff changeset
40 #include <arch/../regs.h>
kono
parents:
diff changeset
41 #ifndef __RTP__
kono
parents:
diff changeset
42 #if defined(__i386__)
kono
parents:
diff changeset
43 #include <version.h>
kono
parents:
diff changeset
44 #endif
kono
parents:
diff changeset
45 #include <sigLib.h>
kono
parents:
diff changeset
46 #else
kono
parents:
diff changeset
47 #include <signal.h>
kono
parents:
diff changeset
48 #include <regs.h>
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 typedef struct mcontext
kono
parents:
diff changeset
51 {
kono
parents:
diff changeset
52 REG_SET regs;
kono
parents:
diff changeset
53 } mcontext_t;
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 typedef struct ucontext
kono
parents:
diff changeset
56 {
kono
parents:
diff changeset
57 mcontext_t uc_mcontext; /* register set */
kono
parents:
diff changeset
58 struct ucontext * uc_link; /* not used */
kono
parents:
diff changeset
59 sigset_t uc_sigmask; /* set of signals blocked */
kono
parents:
diff changeset
60 stack_t uc_stack; /* stack of context signaled */
kono
parents:
diff changeset
61 } ucontext_t;
kono
parents:
diff changeset
62 #endif
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 /* ----------------------
kono
parents:
diff changeset
65 -- General comments --
kono
parents:
diff changeset
66 ----------------------
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 Stubs are generated from toplevel asms and .cfi directives, much simpler
kono
parents:
diff changeset
69 to use and check for correctness than manual encodings of CFI byte
kono
parents:
diff changeset
70 sequences. The general idea is to establish CFA as sigcontext->sc_pregs
kono
parents:
diff changeset
71 (for DKM) and mcontext (for RTP) and state where to find the registers as
kono
parents:
diff changeset
72 offsets from there.
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 As of today, we support a stub providing CFI info for common
kono
parents:
diff changeset
75 registers (GPRs, LR, ...). We might need variants with support for floating
kono
parents:
diff changeset
76 point or altivec registers as well at some point.
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 Checking which variant should apply and getting at sc_pregs / mcontext
kono
parents:
diff changeset
79 is simpler to express in C (we can't use offsetof in toplevel asms and
kono
parents:
diff changeset
80 hardcoding constants is not workable with the flurry of VxWorks variants),
kono
parents:
diff changeset
81 so this is the choice for our toplevel interface.
kono
parents:
diff changeset
82
kono
parents:
diff changeset
83 Note that the registers we "restore" here are those to which we have
kono
parents:
diff changeset
84 direct access through the system sigcontext structure, which includes
kono
parents:
diff changeset
85 only a partial set of the non-volatiles ABI-wise. */
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 /* -------------------------------------------
kono
parents:
diff changeset
88 -- Prototypes for our internal asm stubs --
kono
parents:
diff changeset
89 -------------------------------------------
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 Eventhough our symbols will remain local, the prototype claims "extern"
kono
parents:
diff changeset
92 and not "static" to prevent compiler complaints about a symbol used but
kono
parents:
diff changeset
93 never defined. */
kono
parents:
diff changeset
94
kono
parents:
diff changeset
95 #define TRAMP_COMMON __gnat_sigtramp_common
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 /* sigtramp stub providing CFI info for common registers. */
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 extern void
kono
parents:
diff changeset
100 TRAMP_COMMON (int signo, void *siginfo, void *sigcontext,
kono
parents:
diff changeset
101 __sigtramphandler_t * handler, REG_SET * sc_pregs);
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 /* -------------------------------------
kono
parents:
diff changeset
104 -- Common interface implementation --
kono
parents:
diff changeset
105 -------------------------------------
kono
parents:
diff changeset
106
kono
parents:
diff changeset
107 We enforce optimization to minimize the overhead of the extra layer. */
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 #if defined(__vxworks) && (defined (__i386__) || defined (__x86_64__)) && !defined (VTHREADS)
kono
parents:
diff changeset
110 static int __gnat_is_vxsim = 0;
kono
parents:
diff changeset
111
kono
parents:
diff changeset
112 void __gnat_set_is_vxsim(int val) {
kono
parents:
diff changeset
113 __gnat_is_vxsim = val;
kono
parents:
diff changeset
114 }
kono
parents:
diff changeset
115 #endif
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 void __gnat_sigtramp (int signo, void *si, void *sc,
kono
parents:
diff changeset
118 __sigtramphandler_t * handler)
kono
parents:
diff changeset
119 __attribute__((optimize(2)));
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 void __gnat_sigtramp (int signo, void *si, void *sc,
kono
parents:
diff changeset
122 __sigtramphandler_t * handler)
kono
parents:
diff changeset
123 {
kono
parents:
diff changeset
124 REG_SET *pregs;
kono
parents:
diff changeset
125
kono
parents:
diff changeset
126 /* VXSIM uses a different signal context structure than the regular x86
kono
parents:
diff changeset
127 targets:
kono
parents:
diff changeset
128 * on x86-vx6: two 32-bit values are added at the end of the REG_SET, plus
kono
parents:
diff changeset
129 an explicit padding of 0xc8 characters (200 characters). The sigcontext
kono
parents:
diff changeset
130 containing a complete REG_SET just before the field 'sc_pregs', this
kono
parents:
diff changeset
131 adds a 208 bytes offset to get the value of 'sc_pregs'.
kono
parents:
diff changeset
132 * on x86-vx7: the same offset is used on vx7: 3 32-bit values are present
kono
parents:
diff changeset
133 at the end of the reg set, but the padding is then of 0xc4 characters.
kono
parents:
diff changeset
134 * on x86_64-vx7: two 64-bit values are added at the beginning of the
kono
parents:
diff changeset
135 REG_SET. This adds a 16 bytes offset to get the value of 'sc_pregs',
kono
parents:
diff changeset
136 and another 16 bytes offset within the pregs structure to retrieve the
kono
parents:
diff changeset
137 registers list.
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 * See header file regsSimlinux.h.
kono
parents:
diff changeset
140 */
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 /* Retrieve the registers to restore : */
kono
parents:
diff changeset
143 #ifndef __RTP__
kono
parents:
diff changeset
144 #ifdef __HANDLE_VXSIM_SC
kono
parents:
diff changeset
145 #if defined(__i386__)
kono
parents:
diff changeset
146 /* move sctx 208 bytes further, so that the vxsim's sc_pregs field coincide
kono
parents:
diff changeset
147 with the expected x86 one */
kono
parents:
diff changeset
148 struct sigcontext * sctx =
kono
parents:
diff changeset
149 (struct sigcontext *) (sc + (__gnat_is_vxsim ?
kono
parents:
diff changeset
150 (_WRS_VXWORKS_MAJOR == 7 ? 204 : 208)
kono
parents:
diff changeset
151 : 0));
kono
parents:
diff changeset
152 #elif defined(__x86_64__)
kono
parents:
diff changeset
153 /* move sctx 16 bytes further, so that the vxsim's sc_pregs field coincide
kono
parents:
diff changeset
154 with the expected x86_64 one */
kono
parents:
diff changeset
155 struct sigcontext * sctx =
kono
parents:
diff changeset
156 (struct sigcontext *) (sc + (__gnat_is_vxsim ? 16 : 0));
kono
parents:
diff changeset
157 #endif /* __i386__ || __x86_64__ */
kono
parents:
diff changeset
158 #else /* __HANDLE_VXSIM_SC__ */
kono
parents:
diff changeset
159 struct sigcontext * sctx = (struct sigcontext *) sc;
kono
parents:
diff changeset
160 #endif
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162 pregs = sctx->sc_pregs;
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 #else /* !defined(__RTP__) */
kono
parents:
diff changeset
165
kono
parents:
diff changeset
166 mcontext_t *mcontext = &((ucontext_t *) sc)->uc_mcontext;
kono
parents:
diff changeset
167 /* No specific offset in this case for vxsim */
kono
parents:
diff changeset
168 pregs = &(mcontext->regs);
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 #endif /* !defined(__RTP__) */
kono
parents:
diff changeset
171
kono
parents:
diff changeset
172 #if defined (__HANDLE_VXSIM_SC) && defined (__x86_64__)
kono
parents:
diff changeset
173 /* Ignore the first two values, that are not registers in case of
kono
parents:
diff changeset
174 vxsim */
kono
parents:
diff changeset
175 pregs = (REG_SET *) ((void *)pregs + (__gnat_is_vxsim ? 16 : 0));
kono
parents:
diff changeset
176 #endif
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 /* And now call the real signal trampoline with the list of registers */
kono
parents:
diff changeset
179 __gnat_sigtramp_common (signo, si, sc, handler, pregs);
kono
parents:
diff changeset
180 }
kono
parents:
diff changeset
181
kono
parents:
diff changeset
182 /* Include the target specific bits. */
kono
parents:
diff changeset
183 #include "sigtramp-vxworks-target.inc"
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 /* sigtramp stub for common registers. */
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 asm (SIGTRAMP_START(TRAMP_COMMON));
kono
parents:
diff changeset
188 asm (CFI_DEF_CFA);
kono
parents:
diff changeset
189 asm (CFI_COMMON_REGS);
kono
parents:
diff changeset
190 asm (SIGTRAMP_BODY);
kono
parents:
diff changeset
191 asm (SIGTRAMP_END(TRAMP_COMMON));