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(__APPLE__) && defined(__aarch64__)
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 
79 #if defined(__hexagon__)
80 #define WEAK_ALIAS(name, aliasname) \
81   WEAK_SYMBOL(aliasname) SEPARATOR                                             \
82   .equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name)
83 #else
84 #define WEAK_ALIAS(name, aliasname)                                            \
85   WEAK_SYMBOL(aliasname) SEPARATOR                                             \
86   SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
87 #endif
88 
89 #if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
90     defined(__linux__)
91 #define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits
92 #else
93 #define NO_EXEC_STACK_DIRECTIVE
94 #endif
95 
96 #elif defined(_WIN32)
97 
98 #define SYMBOL_IS_FUNC(name)                                                   \
99   .def name SEPARATOR                                                          \
100     .scl 2 SEPARATOR                                                           \
101     .type 32 SEPARATOR                                                         \
102   .endef
103 #define EXPORT_SYMBOL2(name)                                                   \
104   .section .drectve,"yn" SEPARATOR                                             \
105   .ascii "-export:", #name, "\0" SEPARATOR                                     \
106   .text
107 #if defined(_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS)
108 #define EXPORT_SYMBOL(name)
109 #else
110 #define EXPORT_SYMBOL(name) EXPORT_SYMBOL2(name)
111 #endif
112 #define HIDDEN_SYMBOL(name)
113 
114 #if defined(__MINGW32__)
115 #define WEAK_ALIAS(name, aliasname)                                            \
116   .globl SYMBOL_NAME(aliasname) SEPARATOR                                      \
117   EXPORT_SYMBOL(aliasname) SEPARATOR                                           \
118   SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
119 #else
120 #define WEAK_ALIAS3(name, aliasname)                                           \
121   .section .drectve,"yn" SEPARATOR                                             \
122   .ascii "-alternatename:", #aliasname, "=", #name, "\0" SEPARATOR             \
123   .text
124 #define WEAK_ALIAS2(name, aliasname)                                           \
125   WEAK_ALIAS3(name, aliasname)
126 #define WEAK_ALIAS(name, aliasname)                                            \
127   EXPORT_SYMBOL(SYMBOL_NAME(aliasname)) SEPARATOR                              \
128   WEAK_ALIAS2(SYMBOL_NAME(name), SYMBOL_NAME(aliasname))
129 #endif
130 
131 #define NO_EXEC_STACK_DIRECTIVE
132 
133 #elif defined(__sparc__)
134 
135 #else
136 
137 #error Unsupported target
138 
139 #endif
140 
141 #define DEFINE_LIBUNWIND_FUNCTION(name)                                        \
142   .globl SYMBOL_NAME(name) SEPARATOR                                           \
143   HIDDEN_SYMBOL(SYMBOL_NAME(name)) SEPARATOR                                   \
144   SYMBOL_IS_FUNC(SYMBOL_NAME(name)) SEPARATOR                                  \
145   PPC64_OPD1                                                                   \
146   SYMBOL_NAME(name):                                                           \
147   PPC64_OPD2
148 
149 #if defined(__arm__)
150 #if !defined(__ARM_ARCH)
151 #define __ARM_ARCH 4
152 #endif
153 
154 #if defined(__ARM_ARCH_4T__) || __ARM_ARCH >= 5
155 #define ARM_HAS_BX
156 #endif
157 
158 #ifdef ARM_HAS_BX
159 #define JMP(r) bx r
160 #else
161 #define JMP(r) mov pc, r
162 #endif
163 #endif /* __arm__ */
164 
165 #endif /* UNWIND_ASSEMBLY_H */
166