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(__powerpc64__)
19#define SEPARATOR ;
20#define PPC64_OFFS_SRR0   0
21#define PPC64_OFFS_CR     272
22#define PPC64_OFFS_XER    280
23#define PPC64_OFFS_LR     288
24#define PPC64_OFFS_CTR    296
25#define PPC64_OFFS_VRSAVE 304
26#define PPC64_OFFS_FP     312
27#define PPC64_OFFS_V      824
28#ifdef _ARCH_PWR8
29#define PPC64_HAS_VMX
30#endif
31#elif defined(__arm64__)
32#define SEPARATOR %%
33#else
34#define SEPARATOR ;
35#endif
36
37#if defined(__powerpc64__) && (!defined(_CALL_ELF) || _CALL_ELF == 1)
38#define PPC64_OPD1 .section .opd,"aw",@progbits SEPARATOR
39#define PPC64_OPD2 SEPARATOR \
40  .p2align 3 SEPARATOR \
41  .quad .Lfunc_begin0 SEPARATOR \
42  .quad .TOC.@tocbase SEPARATOR \
43  .quad 0 SEPARATOR \
44  .text SEPARATOR \
45.Lfunc_begin0:
46#else
47#define PPC64_OPD1
48#define PPC64_OPD2
49#endif
50
51#define GLUE2(a, b) a ## b
52#define GLUE(a, b) GLUE2(a, b)
53#define SYMBOL_NAME(name) GLUE(__USER_LABEL_PREFIX__, name)
54
55#if defined(__APPLE__)
56
57#define SYMBOL_IS_FUNC(name)
58#define EXPORT_SYMBOL(name)
59#define HIDDEN_SYMBOL(name) .private_extern name
60#define WEAK_SYMBOL(name) .weak_reference name
61#define WEAK_ALIAS(name, aliasname)                                            \
62  .globl SYMBOL_NAME(aliasname) SEPARATOR                                      \
63  WEAK_SYMBOL(aliasname) SEPARATOR                                             \
64  SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
65
66#define NO_EXEC_STACK_DIRECTIVE
67
68#elif defined(__ELF__)
69
70#if defined(__arm__)
71#define SYMBOL_IS_FUNC(name) .type name,%function
72#else
73#define SYMBOL_IS_FUNC(name) .type name,@function
74#endif
75#define EXPORT_SYMBOL(name)
76#define HIDDEN_SYMBOL(name) .hidden name
77#define WEAK_SYMBOL(name) .weak name
78#define WEAK_ALIAS(name, aliasname)                                            \
79  WEAK_SYMBOL(aliasname) SEPARATOR                                             \
80  SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
81
82#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
83    defined(__linux__)
84#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits
85#else
86#define NO_EXEC_STACK_DIRECTIVE
87#endif
88
89#elif defined(_WIN32)
90
91#define SYMBOL_IS_FUNC(name)                                                   \
92  .def name SEPARATOR                                                          \
93    .scl 2 SEPARATOR                                                           \
94    .type 32 SEPARATOR                                                         \
95  .endef
96#define EXPORT_SYMBOL2(name)                                                   \
97  .section .drectve,"yn" SEPARATOR                                             \
98  .ascii "-export:", #name, "\0" SEPARATOR                                     \
99  .text
100#if defined(_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS)
101#define EXPORT_SYMBOL(name)
102#else
103#define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name)
104#endif
105#define HIDDEN_SYMBOL(name)
106
107#if defined(__MINGW32__)
108#define WEAK_ALIAS(name, aliasname)                                            \
109  .globl SYMBOL_NAME(aliasname) SEPARATOR                                      \
110  EXPORT_SYMBOL(aliasname) SEPARATOR                                           \
111  SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
112#else
113#define WEAK_ALIAS3(name, aliasname)                                           \
114  .section .drectve,"yn" SEPARATOR                                             \
115  .ascii "-alternatename:", #aliasname, "=", #name, "\0" SEPARATOR             \
116  .text
117#define WEAK_ALIAS2(name, aliasname)                                           \
118  WEAK_ALIAS3(name, aliasname)
119#define WEAK_ALIAS(name, aliasname)                                            \
120  EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
121  WEAK_ALIAS2(SYMBOL_NAME(name), SYMBOL_NAME(aliasname))
122#endif
123
124#define NO_EXEC_STACK_DIRECTIVE
125
126#elif defined(__sparc__)
127
128#else
129
130#error Unsupported target
131
132#endif
133
134#define DEFINE_LIBUNWIND_FUNCTION(name)                                        \
135  .globl SYMBOL_NAME(name) SEPARATOR                                           \
136  HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR                                   \
137  SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
138  PPC64_OPD1                                                                   \
139  SYMBOL_NAME(name):                                                           \
140  PPC64_OPD2
141
142#if defined(__arm__)
143#if !defined(__ARM_ARCH)
144#define __ARM_ARCH 4
145#endif
146
147#if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
148#define ARM_HAS_BX
149#endif
150
151#ifdef ARM_HAS_BX
152#define JMP(r) bx r
153#else
154#define JMP(r) mov pc, r
155#endif
156#endif /* __arm__ */
157
158#endif /* UNWIND_ASSEMBLY_H */
159