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