master
  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                                       \
240aliasname:                                                                     \
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 */