1 | //===----------------------------- config.h -------------------------------===// |
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 | // Defines macros used within libunwind project. |
9 | // |
10 | //===----------------------------------------------------------------------===// |
11 | |
12 | |
13 | #ifndef LIBUNWIND_CONFIG_H |
14 | #define LIBUNWIND_CONFIG_H |
15 | |
16 | #include <assert.h> |
17 | #include <stdio.h> |
18 | #include <stdint.h> |
19 | #include <stdlib.h> |
20 | |
21 | // Define static_assert() unless already defined by compiler. |
22 | #ifndef __has_feature |
23 | #define __has_feature(__x) 0 |
24 | #endif |
25 | #if !(__has_feature(cxx_static_assert)) && !defined(static_assert) |
26 | #define static_assert(__b, __m) \ |
27 | extern int compile_time_assert_failed[ ( __b ) ? 1 : -1 ] \ |
28 | __attribute__( ( unused ) ); |
29 | #endif |
30 | |
31 | // Platform specific configuration defines. |
32 | #ifdef __APPLE__ |
33 | #if defined(FOR_DYLD) |
34 | #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND |
35 | #else |
36 | #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND |
37 | #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 |
38 | #endif |
39 | #elif defined(_WIN32) |
40 | #ifdef __SEH__ |
41 | #define _LIBUNWIND_SUPPORT_SEH_UNWIND 1 |
42 | #else |
43 | #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 |
44 | #endif |
45 | #else |
46 | #if defined(__ARM_DWARF_EH__) || !defined(__arm__) |
47 | #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 |
48 | #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 |
49 | #endif |
50 | #endif |
51 | |
52 | #if defined(_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS) |
53 | #define _LIBUNWIND_EXPORT |
54 | #define _LIBUNWIND_HIDDEN |
55 | #else |
56 | #if !defined(__ELF__) && !defined(__MACH__) |
57 | #define _LIBUNWIND_EXPORT __declspec(dllexport) |
58 | #define _LIBUNWIND_HIDDEN |
59 | #else |
60 | #define _LIBUNWIND_EXPORT __attribute__((visibility("default"))) |
61 | #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden"))) |
62 | #endif |
63 | #endif |
64 | |
65 | #define STR(a) #a |
66 | #define XSTR(a) STR(a) |
67 | #define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name |
68 | |
69 | #if defined(__APPLE__) |
70 | #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ |
71 | __asm__(".globl " SYMBOL_NAME(aliasname)); \ |
72 | __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \ |
73 | extern "C" __typeof(name) aliasname __attribute__((weak_import)) _LIBUNWIND_EXPORT; |
74 | #elif defined(__ELF__) |
75 | #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ |
76 | extern "C" __typeof(name) aliasname __attribute__((weak, alias(#name))) _LIBUNWIND_EXPORT; |
77 | #elif defined(_WIN32) |
78 | #if defined(__MINGW32__) |
79 | #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ |
80 | extern "C" __typeof(name) aliasname __attribute__((alias(#name))) _LIBUNWIND_EXPORT; |
81 | #else |
82 | #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ |
83 | __pragma(comment(linker, "/alternatename:" SYMBOL_NAME(aliasname) "=" \ |
84 | SYMBOL_NAME(name))) \ |
85 | extern "C" __typeof(name) aliasname _LIBUNWIND_EXPORT; |
86 | #endif |
87 | #else |
88 | #error Unsupported target |
89 | #endif |
90 | |
91 | #if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__) |
92 | #define _LIBUNWIND_BUILD_SJLJ_APIS |
93 | #endif |
94 | |
95 | #if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) |
96 | #define _LIBUNWIND_SUPPORT_FRAME_APIS |
97 | #endif |
98 | |
99 | #if defined(__i386__) || defined(__x86_64__) || \ |
100 | defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \ |
101 | (!defined(__APPLE__) && defined(__arm__)) || \ |
102 | (defined(__arm64__) || defined(__aarch64__)) || \ |
103 | defined(__mips__) |
104 | #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) |
105 | #define _LIBUNWIND_BUILD_ZERO_COST_APIS |
106 | #endif |
107 | #endif |
108 | |
109 | #if defined(__powerpc64__) && defined(_ARCH_PWR8) |
110 | #define PPC64_HAS_VMX |
111 | #endif |
112 | |
113 | #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) |
114 | #define _LIBUNWIND_ABORT(msg) \ |
115 | do { \ |
116 | abort(); \ |
117 | } while (0) |
118 | #else |
119 | #define _LIBUNWIND_ABORT(msg) \ |
120 | do { \ |
121 | fprintf(stderr, "libunwind: %s %s:%d - %s\n", __func__, __FILE__, \ |
122 | __LINE__, msg); \ |
123 | fflush(stderr); \ |
124 | abort(); \ |
125 | } while (0) |
126 | #endif |
127 | |
128 | #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) |
129 | #define _LIBUNWIND_LOG0(msg) |
130 | #define _LIBUNWIND_LOG(msg, ...) |
131 | #else |
132 | #define _LIBUNWIND_LOG0(msg) \ |
133 | fprintf(stderr, "libunwind: " msg "\n") |
134 | #define _LIBUNWIND_LOG(msg, ...) \ |
135 | fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) |
136 | #endif |
137 | |
138 | #if defined(NDEBUG) |
139 | #define _LIBUNWIND_LOG_IF_FALSE(x) x |
140 | #else |
141 | #define _LIBUNWIND_LOG_IF_FALSE(x) \ |
142 | do { \ |
143 | bool _ret = x; \ |
144 | if (!_ret) \ |
145 | _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__); \ |
146 | } while (0) |
147 | #endif |
148 | |
149 | // Macros that define away in non-Debug builds |
150 | #ifdef NDEBUG |
151 | #define _LIBUNWIND_DEBUG_LOG(msg, ...) |
152 | #define _LIBUNWIND_TRACE_API(msg, ...) |
153 | #define _LIBUNWIND_TRACING_UNWINDING (0) |
154 | #define _LIBUNWIND_TRACING_DWARF (0) |
155 | #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) |
156 | #define _LIBUNWIND_TRACE_DWARF(...) |
157 | #else |
158 | #ifdef __cplusplus |
159 | extern "C" { |
160 | #endif |
161 | extern bool logAPIs(); |
162 | extern bool logUnwinding(); |
163 | extern bool logDWARF(); |
164 | #ifdef __cplusplus |
165 | } |
166 | #endif |
167 | #define _LIBUNWIND_DEBUG_LOG(msg, ...) _LIBUNWIND_LOG(msg, __VA_ARGS__) |
168 | #define _LIBUNWIND_TRACE_API(msg, ...) \ |
169 | do { \ |
170 | if (logAPIs()) \ |
171 | _LIBUNWIND_LOG(msg, __VA_ARGS__); \ |
172 | } while (0) |
173 | #define _LIBUNWIND_TRACING_UNWINDING logUnwinding() |
174 | #define _LIBUNWIND_TRACING_DWARF logDWARF() |
175 | #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \ |
176 | do { \ |
177 | if (logUnwinding()) \ |
178 | _LIBUNWIND_LOG(msg, __VA_ARGS__); \ |
179 | } while (0) |
180 | #define _LIBUNWIND_TRACE_DWARF(...) \ |
181 | do { \ |
182 | if (logDWARF()) \ |
183 | fprintf(stderr, __VA_ARGS__); \ |
184 | } while (0) |
185 | #endif |
186 | |
187 | #ifdef __cplusplus |
188 | // Used to fit UnwindCursor and Registers_xxx types against unw_context_t / |
189 | // unw_cursor_t sized memory blocks. |
190 | #if defined(_LIBUNWIND_IS_NATIVE_ONLY) |
191 | # define COMP_OP == |
192 | #else |
193 | # define COMP_OP <= |
194 | #endif |
195 | template <typename _Type, typename _Mem> |
196 | struct check_fit { |
197 | template <typename T> |
198 | struct blk_count { |
199 | static const size_t count = |
200 | (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t); |
201 | }; |
202 | static const bool does_fit = |
203 | (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count); |
204 | }; |
205 | #undef COMP_OP |
206 | #endif // __cplusplus |
207 | |
208 | #endif // LIBUNWIND_CONFIG_H |
209 | |