xref: /freebsd/contrib/llvm-project/libunwind/src/assembly.h (revision 415efcecd8b80f68e76376ef2b854cb6f5c84b5a)
1 /* ===-- assembly.h - libUnwind 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 libUnwind assembler source.
10  * This file is not part of the interface of this library.
11  *
12  * ===----------------------------------------------------------------------===
13  */
14 
15 #ifndef UNWIND_ASSEMBLY_H
16 #define UNWIND_ASSEMBLY_H
17 
18 #if defined(__linux__) && defined(__CET__)
19 #include <cet.h>
20 #define _LIBUNWIND_CET_ENDBR _CET_ENDBR
21 #else
22 #define _LIBUNWIND_CET_ENDBR
23 #endif
24 
25 #if defined(__powerpc64__)
26 #define SEPARATOR ;
27 #define PPC64_OFFS_SRR0   0
28 #define PPC64_OFFS_CR     272
29 #define PPC64_OFFS_XER    280
30 #define PPC64_OFFS_LR     288
31 #define PPC64_OFFS_CTR    296
32 #define PPC64_OFFS_VRSAVE 304
33 #define PPC64_OFFS_FP     312
34 #define PPC64_OFFS_V      824
35 #elif defined(__APPLE__) && defined(__aarch64__)
36 #define SEPARATOR %%
37 #elif defined(__riscv)
38 # define RISCV_ISIZE (__riscv_xlen / 8)
39 # define RISCV_FOFFSET (RISCV_ISIZE * 32)
40 # if defined(__riscv_flen)
41 #  define RISCV_FSIZE (__riscv_flen / 8)
42 # endif
43 
44 # if __riscv_xlen == 64
45 #  define ILOAD ld
46 #  define ISTORE sd
47 # elif __riscv_xlen == 32
48 #  define ILOAD lw
49 #  define ISTORE sw
50 # else
51 #  error "Unsupported __riscv_xlen"
52 # endif
53 
54 # if defined(__riscv_flen)
55 #  if __riscv_flen == 64
56 #   define FLOAD fld
57 #   define FSTORE fsd
58 #  elif __riscv_flen == 32
59 #   define FLOAD flw
60 #   define FSTORE fsw
61 #  else
62 #   error "Unsupported __riscv_flen"
63 #  endif
64 # endif
65 # define SEPARATOR ;
66 #else
67 #define SEPARATOR ;
68 #endif
69 
70 #if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) &&       \
71     !defined(_AIX)
72 #define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR
73 #define PPC64_OPD2 SEPARATOR \
74   .p2align 3 SEPARATOR \
75   .quad .Lfunc_begin0 SEPARATOR \
76   .quad .TOC.@tocbase SEPARATOR \
77   .quad 0 SEPARATOR \
78   .text SEPARATOR \
79 .Lfunc_begin0:
80 #else
81 #define PPC64_OPD1
82 #define PPC64_OPD2
83 #endif
84 
85 #if defined(__aarch64__)
86 #if defined(__ARM_FEATURE_GCS_DEFAULT) && defined(__ARM_FEATURE_BTI_DEFAULT)
87 // Set BTI, PAC, and GCS gnu property bits
88 #define GNU_PROPERTY 7
89 // We indirectly branch to __libunwind_Registers_arm64_jumpto from
90 // __unw_phase2_resume, so we need to use bti jc.
91 #define AARCH64_BTI bti jc
92 #elif defined(__ARM_FEATURE_GCS_DEFAULT)
93 // Set GCS gnu property bit
94 #define GNU_PROPERTY 4
95 #elif defined(__ARM_FEATURE_BTI_DEFAULT)
96 // Set BTI and PAC gnu property bits
97 #define GNU_PROPERTY 3
98 #define AARCH64_BTI bti c
99 #endif
100 #ifdef GNU_PROPERTY
101   .pushsection ".note.gnu.property", "a" SEPARATOR                             \
102   .balign 8 SEPARATOR                                                          \
103   .long 4 SEPARATOR                                                            \
104   .long 0x10 SEPARATOR                                                         \
105   .long 0x5 SEPARATOR                                                          \
106   .asciz "GNU" SEPARATOR                                                       \
107   .long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */          \
108   .long 4 SEPARATOR                                                            \
109   .long GNU_PROPERTY SEPARATOR                                                 \
110   .long 0 SEPARATOR                                                            \
111   .popsection SEPARATOR
112 #endif
113 #endif
114 #if !defined(AARCH64_BTI)
115 #define AARCH64_BTI
116 #endif
117 
118 #if !defined(__aarch64__)
119 #ifdef __ARM_FEATURE_PAC_DEFAULT
120   .eabi_attribute Tag_PAC_extension, 2
121   .eabi_attribute Tag_PACRET_use, 1
122 #endif
123 #ifdef __ARM_FEATURE_BTI_DEFAULT
124   .eabi_attribute Tag_BTI_extension, 1
125   .eabi_attribute Tag_BTI_use, 1
126 #endif
127 #endif
128 
129 #define GLUE2(a, b) a ## b
130 #define GLUE(a, b) GLUE2(a, b)
131 #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
132 
133 #if defined(__APPLE__)
134 
135 #define SYMBOL_IS_FUNC(name)
136 #define HIDDEN_SYMBOL(name) .private_extern name
137 #if defined(_LIBUNWIND_HIDE_SYMBOLS)
138 #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
139 #else
140 #define EXPORT_SYMBOL(name)
141 #endif
142 #define WEAK_ALIAS(name, aliasname)                                            \
143   .globl SYMBOL_NAME(aliasname) SEPARATOR                                      \
144   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
145   SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
146 
147 #define NO_EXEC_STACK_DIRECTIVE
148 
149 #elif defined(__ELF__)
150 
151 #if defined(__arm__)
152 #define SYMBOL_IS_FUNC(name) .type name,%function
153 #else
154 #define SYMBOL_IS_FUNC(name) .type name,@function
155 #endif
156 #define HIDDEN_SYMBOL(name) .hidden name
157 #if defined(_LIBUNWIND_HIDE_SYMBOLS)
158 #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
159 #else
160 #define EXPORT_SYMBOL(name)
161 #endif
162 #define WEAK_SYMBOL(name) .weak name
163 
164 #if defined(__hexagon__)
165 #define WEAK_ALIAS(name, aliasname)                                            \
166   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
167   WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                                \
168   .equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name)
169 #else
170 #define WEAK_ALIAS(name, aliasname)                                            \
171   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
172   WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                                \
173   SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
174 #endif
175 
176 #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
177     defined(__linux__)
178 #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits
179 #else
180 #define NO_EXEC_STACK_DIRECTIVE
181 #endif
182 
183 #elif defined(_WIN32)
184 
185 #define SYMBOL_IS_FUNC(name)                                                   \
186   .def name SEPARATOR                                                          \
187     .scl 2 SEPARATOR                                                           \
188     .type 32 SEPARATOR                                                         \
189   .endef
190 #define EXPORT_SYMBOL2(name)                                                   \
191   .section .drectve,"yn" SEPARATOR                                             \
192   .ascii "-export:", #name, "\0" SEPARATOR                                     \
193   .text
194 #if defined(_LIBUNWIND_HIDE_SYMBOLS)
195 #define EXPORT_SYMBOL(name)
196 #else
197 #define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name)
198 #endif
199 #define HIDDEN_SYMBOL(name)
200 
201 #if defined(__MINGW32__)
202 #define WEAK_ALIAS(name, aliasname)                                            \
203   .globl SYMBOL_NAME(aliasname) SEPARATOR                                      \
204   EXPORT_SYMBOL(aliasname) SEPARATOR                                           \
205   SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
206 #else
207 #define WEAK_ALIAS3(name, aliasname)                                           \
208   .section .drectve,"yn" SEPARATOR                                             \
209   .ascii "-alternatename:", #aliasname, "=", #name, "\0" SEPARATOR             \
210   .text
211 #define WEAK_ALIAS2(name, aliasname)                                           \
212   WEAK_ALIAS3(name, aliasname)
213 #define WEAK_ALIAS(name, aliasname)                                            \
214   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
215   WEAK_ALIAS2(SYMBOL_NAME(name), SYMBOL_NAME(aliasname))
216 #endif
217 
218 #define NO_EXEC_STACK_DIRECTIVE
219 
220 #elif defined(__sparc__)
221 
222 #elif defined(_AIX)
223 
224 #if defined(__powerpc64__)
225 #define VBYTE_LEN 8
226 #define CSECT_ALIGN 3
227 #else
228 #define VBYTE_LEN 4
229 #define CSECT_ALIGN 2
230 #endif
231 
232 // clang-format off
233 #define DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(name, aliasname)              \
234   .csect .text[PR], 2 SEPARATOR                                                \
235   .csect .name[PR], 2 SEPARATOR                                                \
236   .globl name[DS] SEPARATOR                                                    \
237   .globl .name[PR] SEPARATOR                                                   \
238   .align 4 SEPARATOR                                                           \
239   .csect name[DS], CSECT_ALIGN SEPARATOR                                       \
240 aliasname:                                                                     \
241   .vbyte VBYTE_LEN, .name[PR] SEPARATOR                                        \
242   .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR                                         \
243   .vbyte VBYTE_LEN, 0 SEPARATOR                                                \
244   .weak  aliasname SEPARATOR                                                   \
245   .weak  .aliasname SEPARATOR                                                  \
246   .csect .name[PR], 2 SEPARATOR                                                \
247 .aliasname:                                                                    \
248 
249 #define WEAK_ALIAS(name, aliasname)
250 #define NO_EXEC_STACK_DIRECTIVE
251 
252 // clang-format on
253 #else
254 
255 #error Unsupported target
256 
257 #endif
258 
259 #if defined(_AIX)
260   // clang-format off
261 #define DEFINE_LIBUNWIND_FUNCTION(name)                                        \
262   .globl name[DS] SEPARATOR                                                    \
263   .globl .name SEPARATOR                                                       \
264   .align 4 SEPARATOR                                                           \
265   .csect name[DS], CSECT_ALIGN SEPARATOR                                       \
266   .vbyte VBYTE_LEN, .name SEPARATOR                                            \
267   .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR                                         \
268   .vbyte VBYTE_LEN, 0 SEPARATOR                                                \
269   .csect .text[PR], 2 SEPARATOR                                                \
270 .name:
271   // clang-format on
272 #else
273 #define DEFINE_LIBUNWIND_FUNCTION(name)                                        \
274   .globl SYMBOL_NAME(name) SEPARATOR                                           \
275   HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR                                   \
276   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
277   PPC64_OPD1                                                                   \
278   SYMBOL_NAME(name):                                                           \
279   PPC64_OPD2                                                                   \
280   AARCH64_BTI
281 #endif
282 
283 #if defined(__arm__)
284 #if !defined(__ARM_ARCH)
285 #define __ARM_ARCH 4
286 #endif
287 
288 #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
289 #define ARM_HAS_BX
290 #endif
291 
292 #ifdef ARM_HAS_BX
293 #define JMP(r) bx r
294 #else
295 #define JMP(r) mov pc, r
296 #endif
297 #endif /* __arm__ */
298 
299 #if defined(__powerpc__)
300 #define PPC_LEFT_SHIFT(index) << (index)
301 #endif
302 
303 #endif /* UNWIND_ASSEMBLY_H */
304