1 | //===-- assembly.h - compiler-rt assembler support macros -----------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines macros for use in compiler-rt assembler source. |
10 | // This file is not part of the interface of this library. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef COMPILERRT_ASSEMBLY_H |
15 | #define COMPILERRT_ASSEMBLY_H |
16 | |
17 | #if defined(__linux__) && defined(__CET__) |
18 | #if __has_include(<cet.h>) |
19 | #include <cet.h> |
20 | #endif |
21 | #endif |
22 | |
23 | #if defined(__APPLE__) && defined(__aarch64__) |
24 | #define SEPARATOR %% |
25 | #else |
26 | #define SEPARATOR ; |
27 | #endif |
28 | |
29 | #if defined(__APPLE__) |
30 | #define HIDDEN(name) .private_extern name |
31 | #define LOCAL_LABEL(name) L_##name |
32 | // tell linker it can break up file at label boundaries |
33 | #define FILE_LEVEL_DIRECTIVE .subsections_via_symbols |
34 | #define SYMBOL_IS_FUNC(name) |
35 | #define CONST_SECTION .const |
36 | |
37 | #define NO_EXEC_STACK_DIRECTIVE |
38 | |
39 | #elif defined(__ELF__) |
40 | |
41 | #define HIDDEN(name) .hidden name |
42 | #define LOCAL_LABEL(name) .L_##name |
43 | #define FILE_LEVEL_DIRECTIVE |
44 | #if defined(__arm__) || defined(__aarch64__) |
45 | #define SYMBOL_IS_FUNC(name) .type name,%function |
46 | #else |
47 | #define SYMBOL_IS_FUNC(name) .type name,@function |
48 | #endif |
49 | #define CONST_SECTION .section .rodata |
50 | |
51 | #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ |
52 | defined(__linux__) |
53 | #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits |
54 | #else |
55 | #define NO_EXEC_STACK_DIRECTIVE |
56 | #endif |
57 | |
58 | #else // !__APPLE__ && !__ELF__ |
59 | |
60 | #define HIDDEN(name) |
61 | #define LOCAL_LABEL(name) .L ## name |
62 | #define FILE_LEVEL_DIRECTIVE |
63 | #define SYMBOL_IS_FUNC(name) \ |
64 | .def name SEPARATOR \ |
65 | .scl 2 SEPARATOR \ |
66 | .type 32 SEPARATOR \ |
67 | .endef |
68 | #define CONST_SECTION .section .rdata,"rd" |
69 | |
70 | #define NO_EXEC_STACK_DIRECTIVE |
71 | |
72 | #endif |
73 | |
74 | #if defined(__arm__) || defined(__aarch64__) |
75 | #define FUNC_ALIGN \ |
76 | .text SEPARATOR \ |
77 | .balign 16 SEPARATOR |
78 | #else |
79 | #define FUNC_ALIGN |
80 | #endif |
81 | |
82 | // BTI and PAC gnu property note |
83 | #define NT_GNU_PROPERTY_TYPE_0 5 |
84 | #define GNU_PROPERTY_AARCH64_FEATURE_1_AND 0xc0000000 |
85 | #define GNU_PROPERTY_AARCH64_FEATURE_1_BTI 1 |
86 | #define GNU_PROPERTY_AARCH64_FEATURE_1_PAC 2 |
87 | |
88 | #if defined(__ARM_FEATURE_BTI_DEFAULT) |
89 | #define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI |
90 | #else |
91 | #define BTI_FLAG 0 |
92 | #endif |
93 | |
94 | #if __ARM_FEATURE_PAC_DEFAULT & 3 |
95 | #define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC |
96 | #else |
97 | #define PAC_FLAG 0 |
98 | #endif |
99 | |
100 | #define GNU_PROPERTY(type, value) \ |
101 | .pushsection .note.gnu.property, "a" SEPARATOR \ |
102 | .p2align 3 SEPARATOR \ |
103 | .word 4 SEPARATOR \ |
104 | .word 16 SEPARATOR \ |
105 | .word NT_GNU_PROPERTY_TYPE_0 SEPARATOR \ |
106 | .asciz "GNU" SEPARATOR \ |
107 | .word type SEPARATOR \ |
108 | .word 4 SEPARATOR \ |
109 | .word value SEPARATOR \ |
110 | .word 0 SEPARATOR \ |
111 | .popsection |
112 | |
113 | #if BTI_FLAG != 0 |
114 | #define BTI_C hint #34 |
115 | #define BTI_J hint #36 |
116 | #else |
117 | #define BTI_C |
118 | #define BTI_J |
119 | #endif |
120 | |
121 | #if (BTI_FLAG | PAC_FLAG) != 0 |
122 | #define GNU_PROPERTY_BTI_PAC \ |
123 | GNU_PROPERTY(GNU_PROPERTY_AARCH64_FEATURE_1_AND, BTI_FLAG | PAC_FLAG) |
124 | #else |
125 | #define GNU_PROPERTY_BTI_PAC |
126 | #endif |
127 | |
128 | #if defined(__clang__) || defined(__GCC_HAVE_DWARF2_CFI_ASM) |
129 | #define CFI_START .cfi_startproc |
130 | #define CFI_END .cfi_endproc |
131 | #else |
132 | #define CFI_START |
133 | #define CFI_END |
134 | #endif |
135 | |
136 | #if defined(__arm__) |
137 | |
138 | // Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros: |
139 | // - for '-mthumb -march=armv6' compiler defines '__thumb__' |
140 | // - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__' |
141 | #if defined(__thumb2__) || defined(__thumb__) |
142 | #define DEFINE_CODE_STATE .thumb SEPARATOR |
143 | #define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR |
144 | #if defined(__thumb2__) |
145 | #define USE_THUMB_2 |
146 | #define IT(cond) it cond |
147 | #define ITT(cond) itt cond |
148 | #define ITE(cond) ite cond |
149 | #else |
150 | #define USE_THUMB_1 |
151 | #define IT(cond) |
152 | #define ITT(cond) |
153 | #define ITE(cond) |
154 | #endif // defined(__thumb__2) |
155 | #else // !defined(__thumb2__) && !defined(__thumb__) |
156 | #define DEFINE_CODE_STATE .arm SEPARATOR |
157 | #define DECLARE_FUNC_ENCODING |
158 | #define IT(cond) |
159 | #define ITT(cond) |
160 | #define ITE(cond) |
161 | #endif |
162 | |
163 | #if defined(USE_THUMB_1) && defined(USE_THUMB_2) |
164 | #error "USE_THUMB_1 and USE_THUMB_2 can't be defined together." |
165 | #endif |
166 | |
167 | #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5 |
168 | #define ARM_HAS_BX |
169 | #endif |
170 | #if !defined(__ARM_FEATURE_CLZ) && !defined(USE_THUMB_1) && \ |
171 | (__ARM_ARCH >= 6 || (__ARM_ARCH == 5 && !defined(__ARM_ARCH_5__))) |
172 | #define __ARM_FEATURE_CLZ |
173 | #endif |
174 | |
175 | #ifdef ARM_HAS_BX |
176 | #define JMP(r) bx r |
177 | #define JMPc(r, c) bx##c r |
178 | #else |
179 | #define JMP(r) mov pc, r |
180 | #define JMPc(r, c) mov##c pc, r |
181 | #endif |
182 | |
183 | // pop {pc} can't switch Thumb mode on ARMv4T |
184 | #if __ARM_ARCH >= 5 |
185 | #define POP_PC() pop {pc} |
186 | #else |
187 | #define POP_PC() \ |
188 | pop {ip}; \ |
189 | JMP(ip) |
190 | #endif |
191 | |
192 | #if defined(USE_THUMB_2) |
193 | #define WIDE(op) op.w |
194 | #else |
195 | #define WIDE(op) op |
196 | #endif |
197 | #else // !defined(__arm) |
198 | #define DECLARE_FUNC_ENCODING |
199 | #define DEFINE_CODE_STATE |
200 | #endif |
201 | |
202 | #define GLUE2_(a, b) a##b |
203 | #define GLUE(a, b) GLUE2_(a, b) |
204 | #define GLUE2(a, b) GLUE2_(a, b) |
205 | #define GLUE3_(a, b, c) a##b##c |
206 | #define GLUE3(a, b, c) GLUE3_(a, b, c) |
207 | #define GLUE4_(a, b, c, d) a##b##c##d |
208 | #define GLUE4(a, b, c, d) GLUE4_(a, b, c, d) |
209 | |
210 | #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name) |
211 | |
212 | #ifdef VISIBILITY_HIDDEN |
213 | #define DECLARE_SYMBOL_VISIBILITY(name) \ |
214 | HIDDEN(SYMBOL_NAME(name)) SEPARATOR |
215 | #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) \ |
216 | HIDDEN(name) SEPARATOR |
217 | #else |
218 | #define DECLARE_SYMBOL_VISIBILITY(name) |
219 | #define DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) |
220 | #endif |
221 | |
222 | #define DEFINE_COMPILERRT_FUNCTION(name) \ |
223 | DEFINE_CODE_STATE \ |
224 | FILE_LEVEL_DIRECTIVE SEPARATOR \ |
225 | .globl SYMBOL_NAME(name) SEPARATOR \ |
226 | SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ |
227 | DECLARE_SYMBOL_VISIBILITY(name) \ |
228 | DECLARE_FUNC_ENCODING \ |
229 | SYMBOL_NAME(name): |
230 | |
231 | #define DEFINE_COMPILERRT_THUMB_FUNCTION(name) \ |
232 | DEFINE_CODE_STATE \ |
233 | FILE_LEVEL_DIRECTIVE SEPARATOR \ |
234 | .globl SYMBOL_NAME(name) SEPARATOR \ |
235 | SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ |
236 | DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ |
237 | .thumb_func SEPARATOR \ |
238 | SYMBOL_NAME(name): |
239 | |
240 | #define DEFINE_COMPILERRT_PRIVATE_FUNCTION(name) \ |
241 | DEFINE_CODE_STATE \ |
242 | FILE_LEVEL_DIRECTIVE SEPARATOR \ |
243 | .globl SYMBOL_NAME(name) SEPARATOR \ |
244 | SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ |
245 | HIDDEN(SYMBOL_NAME(name)) SEPARATOR \ |
246 | DECLARE_FUNC_ENCODING \ |
247 | SYMBOL_NAME(name): |
248 | |
249 | #define DEFINE_COMPILERRT_PRIVATE_FUNCTION_UNMANGLED(name) \ |
250 | DEFINE_CODE_STATE \ |
251 | .globl name SEPARATOR \ |
252 | SYMBOL_IS_FUNC(name) SEPARATOR \ |
253 | HIDDEN(name) SEPARATOR \ |
254 | DECLARE_FUNC_ENCODING \ |
255 | name: |
256 | |
257 | #define DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(name) \ |
258 | DEFINE_CODE_STATE \ |
259 | FUNC_ALIGN \ |
260 | .globl name SEPARATOR \ |
261 | SYMBOL_IS_FUNC(name) SEPARATOR \ |
262 | DECLARE_SYMBOL_VISIBILITY_UNMANGLED(name) SEPARATOR \ |
263 | DECLARE_FUNC_ENCODING \ |
264 | name: \ |
265 | SEPARATOR CFI_START \ |
266 | SEPARATOR BTI_C |
267 | |
268 | #define DEFINE_COMPILERRT_FUNCTION_ALIAS(name, target) \ |
269 | .globl SYMBOL_NAME(name) SEPARATOR \ |
270 | SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR \ |
271 | DECLARE_SYMBOL_VISIBILITY(name) SEPARATOR \ |
272 | .set SYMBOL_NAME(name), SYMBOL_NAME(target) SEPARATOR |
273 | |
274 | #if defined(__ARM_EABI__) |
275 | #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) \ |
276 | DEFINE_COMPILERRT_FUNCTION_ALIAS(aeabi_name, name) |
277 | #else |
278 | #define DEFINE_AEABI_FUNCTION_ALIAS(aeabi_name, name) |
279 | #endif |
280 | |
281 | #ifdef __ELF__ |
282 | #define END_COMPILERRT_FUNCTION(name) \ |
283 | .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) |
284 | #define END_COMPILERRT_OUTLINE_FUNCTION(name) \ |
285 | CFI_END SEPARATOR \ |
286 | .size SYMBOL_NAME(name), . - SYMBOL_NAME(name) |
287 | #else |
288 | #define END_COMPILERRT_FUNCTION(name) |
289 | #define END_COMPILERRT_OUTLINE_FUNCTION(name) \ |
290 | CFI_END |
291 | #endif |
292 | |
293 | #endif // COMPILERRT_ASSEMBLY_H |
294 | |