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__) && defined(__ARM_FEATURE_BTI_DEFAULT)
86   .pushsection ".note.gnu.property", "a" SEPARATOR                             \
87   .balign 8 SEPARATOR                                                          \
88   .long 4 SEPARATOR                                                            \
89   .long 0x10 SEPARATOR                                                         \
90   .long 0x5 SEPARATOR                                                          \
91   .asciz "GNU" SEPARATOR                                                       \
92   .long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */          \
93   .long 4 SEPARATOR                                                            \
94   .long 3 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_BTI AND */               \
95                     /* GNU_PROPERTY_AARCH64_FEATURE_1_PAC */                   \
96   .long 0 SEPARATOR                                                            \
97   .popsection SEPARATOR
98 #define AARCH64_BTI  bti c
99 #else
100 #define AARCH64_BTI
101 #endif
102 
103 #if !defined(__aarch64__)
104 #ifdef __ARM_FEATURE_PAC_DEFAULT
105   .eabi_attribute Tag_PAC_extension, 2
106   .eabi_attribute Tag_PACRET_use, 1
107 #endif
108 #ifdef __ARM_FEATURE_BTI_DEFAULT
109   .eabi_attribute Tag_BTI_extension, 1
110   .eabi_attribute Tag_BTI_use, 1
111 #endif
112 #endif
113 
114 #define GLUE2(a, b) a ## b
115 #define GLUE(a, b) GLUE2(a, b)
116 #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
117 
118 #if defined(__APPLE__)
119 
120 #define SYMBOL_IS_FUNC(name)
121 #define HIDDEN_SYMBOL(name) .private_extern name
122 #if defined(_LIBUNWIND_HIDE_SYMBOLS)
123 #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
124 #else
125 #define EXPORT_SYMBOL(name)
126 #endif
127 #define WEAK_ALIAS(name, aliasname)                                            \
128   .globl SYMBOL_NAME(aliasname) SEPARATOR                                      \
129   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
130   SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
131 
132 #define NO_EXEC_STACK_DIRECTIVE
133 
134 #elif defined(__ELF__)
135 
136 #if defined(__arm__)
137 #define SYMBOL_IS_FUNC(name) .type name,%function
138 #else
139 #define SYMBOL_IS_FUNC(name) .type name,@function
140 #endif
141 #define HIDDEN_SYMBOL(name) .hidden name
142 #if defined(_LIBUNWIND_HIDE_SYMBOLS)
143 #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
144 #else
145 #define EXPORT_SYMBOL(name)
146 #endif
147 #define WEAK_SYMBOL(name) .weak name
148 
149 #if defined(__hexagon__)
150 #define WEAK_ALIAS(name, aliasname)                                            \
151   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
152   WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                                \
153   .equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name)
154 #else
155 #define WEAK_ALIAS(name, aliasname)                                            \
156   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
157   WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                                \
158   SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
159 #endif
160 
161 #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
162     defined(__linux__)
163 #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits
164 #else
165 #define NO_EXEC_STACK_DIRECTIVE
166 #endif
167 
168 #elif defined(_WIN32)
169 
170 #define SYMBOL_IS_FUNC(name)                                                   \
171   .def name SEPARATOR                                                          \
172     .scl 2 SEPARATOR                                                           \
173     .type 32 SEPARATOR                                                         \
174   .endef
175 #define EXPORT_SYMBOL2(name)                                                   \
176   .section .drectve,"yn" SEPARATOR                                             \
177   .ascii "-export:", #name, "\0" SEPARATOR                                     \
178   .text
179 #if defined(_LIBUNWIND_HIDE_SYMBOLS)
180 #define EXPORT_SYMBOL(name)
181 #else
182 #define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name)
183 #endif
184 #define HIDDEN_SYMBOL(name)
185 
186 #if defined(__MINGW32__)
187 #define WEAK_ALIAS(name, aliasname)                                            \
188   .globl SYMBOL_NAME(aliasname) SEPARATOR                                      \
189   EXPORT_SYMBOL(aliasname) SEPARATOR                                           \
190   SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
191 #else
192 #define WEAK_ALIAS3(name, aliasname)                                           \
193   .section .drectve,"yn" SEPARATOR                                             \
194   .ascii "-alternatename:", #aliasname, "=", #name, "\0" SEPARATOR             \
195   .text
196 #define WEAK_ALIAS2(name, aliasname)                                           \
197   WEAK_ALIAS3(name, aliasname)
198 #define WEAK_ALIAS(name, aliasname)                                            \
199   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
200   WEAK_ALIAS2(SYMBOL_NAME(name), SYMBOL_NAME(aliasname))
201 #endif
202 
203 #define NO_EXEC_STACK_DIRECTIVE
204 
205 #elif defined(__sparc__)
206 
207 #elif defined(_AIX)
208 
209 #if defined(__powerpc64__)
210 #define VBYTE_LEN 8
211 #define CSECT_ALIGN 3
212 #else
213 #define VBYTE_LEN 4
214 #define CSECT_ALIGN 2
215 #endif
216 
217 // clang-format off
218 #define DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(name, aliasname)              \
219   .csect .text[PR], 2 SEPARATOR                                                \
220   .csect .name[PR], 2 SEPARATOR                                                \
221   .globl name[DS] SEPARATOR                                                    \
222   .globl .name[PR] SEPARATOR                                                   \
223   .align 4 SEPARATOR                                                           \
224   .csect name[DS], CSECT_ALIGN SEPARATOR                                       \
225 aliasname:                                                                     \
226   .vbyte VBYTE_LEN, .name[PR] SEPARATOR                                        \
227   .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR                                         \
228   .vbyte VBYTE_LEN, 0 SEPARATOR                                                \
229   .weak  aliasname SEPARATOR                                                   \
230   .weak  .aliasname SEPARATOR                                                  \
231   .csect .name[PR], 2 SEPARATOR                                                \
232 .aliasname:                                                                    \
233 
234 #define WEAK_ALIAS(name, aliasname)
235 #define NO_EXEC_STACK_DIRECTIVE
236 
237 // clang-format on
238 #else
239 
240 #error Unsupported target
241 
242 #endif
243 
244 #if defined(_AIX)
245   // clang-format off
246 #define DEFINE_LIBUNWIND_FUNCTION(name)                                        \
247   .globl name[DS] SEPARATOR                                                    \
248   .globl .name SEPARATOR                                                       \
249   .align 4 SEPARATOR                                                           \
250   .csect name[DS], CSECT_ALIGN SEPARATOR                                       \
251   .vbyte VBYTE_LEN, .name SEPARATOR                                            \
252   .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR                                         \
253   .vbyte VBYTE_LEN, 0 SEPARATOR                                                \
254   .csect .text[PR], 2 SEPARATOR                                                \
255 .name:
256   // clang-format on
257 #else
258 #define DEFINE_LIBUNWIND_FUNCTION(name)                                        \
259   .globl SYMBOL_NAME(name) SEPARATOR                                           \
260   HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR                                   \
261   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
262   PPC64_OPD1                                                                   \
263   SYMBOL_NAME(name):                                                           \
264   PPC64_OPD2                                                                   \
265   AARCH64_BTI
266 #endif
267 
268 #if defined(__arm__)
269 #if !defined(__ARM_ARCH)
270 #define __ARM_ARCH 4
271 #endif
272 
273 #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
274 #define ARM_HAS_BX
275 #endif
276 
277 #ifdef ARM_HAS_BX
278 #define JMP(r) bx r
279 #else
280 #define JMP(r) mov pc, r
281 #endif
282 #endif /* __arm__ */
283 
284 #if defined(__powerpc__)
285 #define PPC_LEFT_SHIFT(index) << (index)
286 #endif
287 
288 #endif /* UNWIND_ASSEMBLY_H */
289