xref: /openbsd-src/gnu/llvm/libunwind/src/assembly.h (revision 94b3843fdd6fbe93c7ca4c27f6f43b9379a31743)
1f6c50668Spatrick /* ===-- assembly.h - libUnwind assembler support macros -------------------===
2f6c50668Spatrick  *
3f6c50668Spatrick  * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4f6c50668Spatrick  * See https://llvm.org/LICENSE.txt for license information.
5f6c50668Spatrick  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f6c50668Spatrick  *
7f6c50668Spatrick  * ===----------------------------------------------------------------------===
8f6c50668Spatrick  *
9f6c50668Spatrick  * This file defines macros for use in libUnwind assembler source.
10f6c50668Spatrick  * This file is not part of the interface of this library.
11f6c50668Spatrick  *
12f6c50668Spatrick  * ===----------------------------------------------------------------------===
13f6c50668Spatrick  */
14f6c50668Spatrick 
15f6c50668Spatrick #ifndef UNWIND_ASSEMBLY_H
16f6c50668Spatrick #define UNWIND_ASSEMBLY_H
17f6c50668Spatrick 
18*94b3843fSkettenis #if defined(__CET__)
19202cdb0eSrobert #include <cet.h>
20202cdb0eSrobert #define _LIBUNWIND_CET_ENDBR _CET_ENDBR
21202cdb0eSrobert #else
22202cdb0eSrobert #define _LIBUNWIND_CET_ENDBR
23202cdb0eSrobert #endif
24202cdb0eSrobert 
25f6c50668Spatrick #if defined(__powerpc64__)
26f6c50668Spatrick #define SEPARATOR ;
27f6c50668Spatrick #define PPC64_OFFS_SRR0   0
28f6c50668Spatrick #define PPC64_OFFS_CR     272
29f6c50668Spatrick #define PPC64_OFFS_XER    280
30f6c50668Spatrick #define PPC64_OFFS_LR     288
31f6c50668Spatrick #define PPC64_OFFS_CTR    296
32f6c50668Spatrick #define PPC64_OFFS_VRSAVE 304
33f6c50668Spatrick #define PPC64_OFFS_FP     312
34f6c50668Spatrick #define PPC64_OFFS_V      824
35f6c50668Spatrick #elif defined(__APPLE__) && defined(__aarch64__)
36f6c50668Spatrick #define SEPARATOR %%
37a0747c9fSpatrick #elif defined(__riscv)
38a0747c9fSpatrick # define RISCV_ISIZE (__riscv_xlen / 8)
39a0747c9fSpatrick # define RISCV_FOFFSET (RISCV_ISIZE * 32)
40a0747c9fSpatrick # if defined(__riscv_flen)
41a0747c9fSpatrick #  define RISCV_FSIZE (__riscv_flen / 8)
42a0747c9fSpatrick # endif
43a0747c9fSpatrick 
44a0747c9fSpatrick # if __riscv_xlen == 64
45a0747c9fSpatrick #  define ILOAD ld
46a0747c9fSpatrick #  define ISTORE sd
47a0747c9fSpatrick # elif __riscv_xlen == 32
48a0747c9fSpatrick #  define ILOAD lw
49a0747c9fSpatrick #  define ISTORE sw
50a0747c9fSpatrick # else
51a0747c9fSpatrick #  error "Unsupported __riscv_xlen"
52a0747c9fSpatrick # endif
53a0747c9fSpatrick 
54a0747c9fSpatrick # if defined(__riscv_flen)
55a0747c9fSpatrick #  if __riscv_flen == 64
56a0747c9fSpatrick #   define FLOAD fld
57a0747c9fSpatrick #   define FSTORE fsd
58a0747c9fSpatrick #  elif __riscv_flen == 32
59a0747c9fSpatrick #   define FLOAD flw
60a0747c9fSpatrick #   define FSTORE fsw
61a0747c9fSpatrick #  else
62a0747c9fSpatrick #   error "Unsupported __riscv_flen"
63a0747c9fSpatrick #  endif
64a0747c9fSpatrick # endif
65a0747c9fSpatrick # define SEPARATOR ;
66f6c50668Spatrick #else
67f6c50668Spatrick #define SEPARATOR ;
68f6c50668Spatrick #endif
69f6c50668Spatrick 
70202cdb0eSrobert #if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1) &&       \
71202cdb0eSrobert     !defined(_AIX)
72f6c50668Spatrick #define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR
73f6c50668Spatrick #define PPC64_OPD2 SEPARATOR \
74f6c50668Spatrick   .p2align 3 SEPARATOR \
75f6c50668Spatrick   .quad .Lfunc_begin0 SEPARATOR \
76f6c50668Spatrick   .quad .TOC.@tocbase SEPARATOR \
77f6c50668Spatrick   .quad 0 SEPARATOR \
78f6c50668Spatrick   .text SEPARATOR \
79f6c50668Spatrick .Lfunc_begin0:
80f6c50668Spatrick #else
81f6c50668Spatrick #define PPC64_OPD1
82f6c50668Spatrick #define PPC64_OPD2
83f6c50668Spatrick #endif
84f6c50668Spatrick 
85202cdb0eSrobert #if defined(__aarch64__) && defined(__ARM_FEATURE_BTI_DEFAULT)
86a0747c9fSpatrick   .pushsection ".note.gnu.property", "a" SEPARATOR                             \
87a0747c9fSpatrick   .balign 8 SEPARATOR                                                          \
88a0747c9fSpatrick   .long 4 SEPARATOR                                                            \
89a0747c9fSpatrick   .long 0x10 SEPARATOR                                                         \
90a0747c9fSpatrick   .long 0x5 SEPARATOR                                                          \
91a0747c9fSpatrick   .asciz "GNU" SEPARATOR                                                       \
92a0747c9fSpatrick   .long 0xc0000000 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_AND */          \
93a0747c9fSpatrick   .long 4 SEPARATOR                                                            \
94a0747c9fSpatrick   .long 3 SEPARATOR /* GNU_PROPERTY_AARCH64_FEATURE_1_BTI AND */               \
95a0747c9fSpatrick                     /* GNU_PROPERTY_AARCH64_FEATURE_1_PAC */                   \
96a0747c9fSpatrick   .long 0 SEPARATOR                                                            \
97a0747c9fSpatrick   .popsection SEPARATOR
98a0747c9fSpatrick #define AARCH64_BTI  bti c
99a0747c9fSpatrick #else
100a0747c9fSpatrick #define AARCH64_BTI
101a0747c9fSpatrick #endif
102a0747c9fSpatrick 
103202cdb0eSrobert #if !defined(__aarch64__)
104202cdb0eSrobert #ifdef __ARM_FEATURE_PAC_DEFAULT
105202cdb0eSrobert   .eabi_attribute Tag_PAC_extension, 2
106202cdb0eSrobert   .eabi_attribute Tag_PACRET_use, 1
107202cdb0eSrobert #endif
108202cdb0eSrobert #ifdef __ARM_FEATURE_BTI_DEFAULT
109202cdb0eSrobert   .eabi_attribute Tag_BTI_extension, 1
110202cdb0eSrobert   .eabi_attribute Tag_BTI_use, 1
111202cdb0eSrobert #endif
112202cdb0eSrobert #endif
113202cdb0eSrobert 
114f6c50668Spatrick #define GLUE2(a, b) a ## b
115f6c50668Spatrick #define GLUE(a, b) GLUE2(a, b)
116f6c50668Spatrick #define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
117f6c50668Spatrick 
118f6c50668Spatrick #if defined(__APPLE__)
119f6c50668Spatrick 
120f6c50668Spatrick #define SYMBOL_IS_FUNC(name)
121f6c50668Spatrick #define HIDDEN_SYMBOL(name) .private_extern name
122a0747c9fSpatrick #if defined(_LIBUNWIND_HIDE_SYMBOLS)
123a0747c9fSpatrick #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
124a0747c9fSpatrick #else
125a0747c9fSpatrick #define EXPORT_SYMBOL(name)
126a0747c9fSpatrick #endif
127f6c50668Spatrick #define WEAK_ALIAS(name, aliasname)                                            \
128f6c50668Spatrick   .globl SYMBOL_NAME(aliasname) SEPARATOR                                      \
129a0747c9fSpatrick   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
130f6c50668Spatrick   SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
131f6c50668Spatrick 
132f6c50668Spatrick #define NO_EXEC_STACK_DIRECTIVE
133f6c50668Spatrick 
134f6c50668Spatrick #elif defined(__ELF__)
135f6c50668Spatrick 
136f6c50668Spatrick #if defined(__arm__)
137f6c50668Spatrick #define SYMBOL_IS_FUNC(name) .type name,%function
138f6c50668Spatrick #else
139f6c50668Spatrick #define SYMBOL_IS_FUNC(name) .type name,@function
140f6c50668Spatrick #endif
141f6c50668Spatrick #define HIDDEN_SYMBOL(name) .hidden name
142a0747c9fSpatrick #if defined(_LIBUNWIND_HIDE_SYMBOLS)
143a0747c9fSpatrick #define EXPORT_SYMBOL(name) HIDDEN_SYMBOL(name)
144a0747c9fSpatrick #else
145a0747c9fSpatrick #define EXPORT_SYMBOL(name)
146a0747c9fSpatrick #endif
147f6c50668Spatrick #define WEAK_SYMBOL(name) .weak name
148f6c50668Spatrick 
149f6c50668Spatrick #if defined(__hexagon__)
150f6c50668Spatrick #define WEAK_ALIAS(name, aliasname)                                            \
151a0747c9fSpatrick   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
152a0747c9fSpatrick   WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                                \
153f6c50668Spatrick   .equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name)
154f6c50668Spatrick #else
155f6c50668Spatrick #define WEAK_ALIAS(name, aliasname)                                            \
156a0747c9fSpatrick   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
157a0747c9fSpatrick   WEAK_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                                \
158f6c50668Spatrick   SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
159f6c50668Spatrick #endif
160f6c50668Spatrick 
161f6c50668Spatrick #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
162f6c50668Spatrick     defined(__linux__)
163f6c50668Spatrick #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits
164f6c50668Spatrick #else
165f6c50668Spatrick #define NO_EXEC_STACK_DIRECTIVE
166f6c50668Spatrick #endif
167f6c50668Spatrick 
168f6c50668Spatrick #elif defined(_WIN32)
169f6c50668Spatrick 
170f6c50668Spatrick #define SYMBOL_IS_FUNC(name)                                                   \
171f6c50668Spatrick   .def name SEPARATOR                                                          \
172f6c50668Spatrick     .scl 2 SEPARATOR                                                           \
173f6c50668Spatrick     .type 32 SEPARATOR                                                         \
174f6c50668Spatrick   .endef
175f6c50668Spatrick #define EXPORT_SYMBOL2(name)                                                   \
176f6c50668Spatrick   .section .drectve,"yn" SEPARATOR                                             \
177f6c50668Spatrick   .ascii "-export:", #name, "\0" SEPARATOR                                     \
178f6c50668Spatrick   .text
179a0747c9fSpatrick #if defined(_LIBUNWIND_HIDE_SYMBOLS)
180f6c50668Spatrick #define EXPORT_SYMBOL(name)
181f6c50668Spatrick #else
182f6c50668Spatrick #define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name)
183f6c50668Spatrick #endif
184f6c50668Spatrick #define HIDDEN_SYMBOL(name)
185f6c50668Spatrick 
186f6c50668Spatrick #if defined(__MINGW32__)
187f6c50668Spatrick #define WEAK_ALIAS(name, aliasname)                                            \
188f6c50668Spatrick   .globl SYMBOL_NAME(aliasname) SEPARATOR                                      \
189f6c50668Spatrick   EXPORT_SYMBOL(aliasname) SEPARATOR                                           \
190f6c50668Spatrick   SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
191f6c50668Spatrick #else
192f6c50668Spatrick #define WEAK_ALIAS3(name, aliasname)                                           \
193f6c50668Spatrick   .section .drectve,"yn" SEPARATOR                                             \
194f6c50668Spatrick   .ascii "-alternatename:", #aliasname, "=", #name, "\0" SEPARATOR             \
195f6c50668Spatrick   .text
196f6c50668Spatrick #define WEAK_ALIAS2(name, aliasname)                                           \
197f6c50668Spatrick   WEAK_ALIAS3(name, aliasname)
198f6c50668Spatrick #define WEAK_ALIAS(name, aliasname)                                            \
199f6c50668Spatrick   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
200f6c50668Spatrick   WEAK_ALIAS2(SYMBOL_NAME(name), SYMBOL_NAME(aliasname))
201f6c50668Spatrick #endif
202f6c50668Spatrick 
203f6c50668Spatrick #define NO_EXEC_STACK_DIRECTIVE
204f6c50668Spatrick 
205f6c50668Spatrick #elif defined(__sparc__)
206f6c50668Spatrick 
207202cdb0eSrobert #elif defined(_AIX)
208202cdb0eSrobert 
209202cdb0eSrobert #if defined(__powerpc64__)
210202cdb0eSrobert #define VBYTE_LEN 8
211202cdb0eSrobert #define CSECT_ALIGN 3
212202cdb0eSrobert #else
213202cdb0eSrobert #define VBYTE_LEN 4
214202cdb0eSrobert #define CSECT_ALIGN 2
215202cdb0eSrobert #endif
216202cdb0eSrobert 
217202cdb0eSrobert // clang-format off
218202cdb0eSrobert #define DEFINE_LIBUNWIND_FUNCTION_AND_WEAK_ALIAS(name, aliasname)              \
219202cdb0eSrobert   .csect .text[PR], 2 SEPARATOR                                                \
220202cdb0eSrobert   .csect .name[PR], 2 SEPARATOR                                                \
221202cdb0eSrobert   .globl name[DS] SEPARATOR                                                    \
222202cdb0eSrobert   .globl .name[PR] SEPARATOR                                                   \
223202cdb0eSrobert   .align 4 SEPARATOR                                                           \
224202cdb0eSrobert   .csect name[DS], CSECT_ALIGN SEPARATOR                                       \
225202cdb0eSrobert aliasname:                                                                     \
226202cdb0eSrobert   .vbyte VBYTE_LEN, .name[PR] SEPARATOR                                        \
227202cdb0eSrobert   .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR                                         \
228202cdb0eSrobert   .vbyte VBYTE_LEN, 0 SEPARATOR                                                \
229202cdb0eSrobert   .weak  aliasname SEPARATOR                                                   \
230202cdb0eSrobert   .weak  .aliasname SEPARATOR                                                  \
231202cdb0eSrobert   .csect .name[PR], 2 SEPARATOR                                                \
232202cdb0eSrobert .aliasname:                                                                    \
233202cdb0eSrobert 
234202cdb0eSrobert #define WEAK_ALIAS(name, aliasname)
235202cdb0eSrobert #define NO_EXEC_STACK_DIRECTIVE
236202cdb0eSrobert 
237202cdb0eSrobert // clang-format on
238f6c50668Spatrick #else
239f6c50668Spatrick 
240f6c50668Spatrick #error Unsupported target
241f6c50668Spatrick 
242f6c50668Spatrick #endif
243f6c50668Spatrick 
244202cdb0eSrobert #if defined(_AIX)
245202cdb0eSrobert   // clang-format off
246202cdb0eSrobert #define DEFINE_LIBUNWIND_FUNCTION(name)                                        \
247202cdb0eSrobert   .globl name[DS] SEPARATOR                                                    \
248202cdb0eSrobert   .globl .name SEPARATOR                                                       \
249202cdb0eSrobert   .align 4 SEPARATOR                                                           \
250202cdb0eSrobert   .csect name[DS], CSECT_ALIGN SEPARATOR                                       \
251202cdb0eSrobert   .vbyte VBYTE_LEN, .name SEPARATOR                                            \
252202cdb0eSrobert   .vbyte VBYTE_LEN, TOC[TC0] SEPARATOR                                         \
253202cdb0eSrobert   .vbyte VBYTE_LEN, 0 SEPARATOR                                                \
254202cdb0eSrobert   .csect .text[PR], 2 SEPARATOR                                                \
255202cdb0eSrobert .name:
256202cdb0eSrobert   // clang-format on
257202cdb0eSrobert #else
258f6c50668Spatrick #define DEFINE_LIBUNWIND_FUNCTION(name)                                        \
259f6c50668Spatrick   .globl SYMBOL_NAME(name) SEPARATOR                                           \
260f6c50668Spatrick   HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR                                   \
261f6c50668Spatrick   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
262f6c50668Spatrick   PPC64_OPD1                                                                   \
263f6c50668Spatrick   SYMBOL_NAME(name):                                                           \
264a0747c9fSpatrick   PPC64_OPD2                                                                   \
265a0747c9fSpatrick   AARCH64_BTI
266202cdb0eSrobert #endif
267f6c50668Spatrick 
268f6c50668Spatrick #if defined(__arm__)
269f6c50668Spatrick #if !defined(__ARM_ARCH)
270f6c50668Spatrick #define __ARM_ARCH 4
271f6c50668Spatrick #endif
272f6c50668Spatrick 
273f6c50668Spatrick #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
274f6c50668Spatrick #define ARM_HAS_BX
275f6c50668Spatrick #endif
276f6c50668Spatrick 
277f6c50668Spatrick #ifdef ARM_HAS_BX
278f6c50668Spatrick #define JMP(r) bx r
279f6c50668Spatrick #else
280f6c50668Spatrick #define JMP(r) mov pc, r
281f6c50668Spatrick #endif
282f6c50668Spatrick #endif /* __arm__ */
283f6c50668Spatrick 
284202cdb0eSrobert #if defined(__powerpc__)
285a0747c9fSpatrick #define PPC_LEFT_SHIFT(index) << (index)
286a0747c9fSpatrick #endif
287a0747c9fSpatrick 
288f6c50668Spatrick #endif /* UNWIND_ASSEMBLY_H */
289