1 //===----------------------------------------------------------------------===// 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 #include <__libunwind_config.h> 22 23 // Platform specific configuration defines. 24 #ifdef __APPLE__ 25 #if defined(FOR_DYLD) 26 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1 27 #else 28 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1 29 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 30 #endif 31 #elif defined(_WIN32) 32 #ifdef __SEH__ 33 #define _LIBUNWIND_SUPPORT_SEH_UNWIND 1 34 #else 35 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 36 #endif 37 #elif defined(_LIBUNWIND_IS_BAREMETAL) 38 #if !defined(_LIBUNWIND_ARM_EHABI) 39 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 40 #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 41 #endif 42 #elif defined(__BIONIC__) && defined(_LIBUNWIND_ARM_EHABI) 43 // For ARM EHABI, Bionic didn't implement dl_iterate_phdr until API 21. After 44 // API 21, dl_iterate_phdr exists, but dl_unwind_find_exidx is much faster. 45 #define _LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX 1 46 #elif defined(_AIX) 47 // The traceback table at the end of each function is used for unwinding. 48 #define _LIBUNWIND_SUPPORT_TBTAB_UNWIND 1 49 #elif defined(__HAIKU__) 50 #if defined(_LIBUNWIND_USE_HAIKU_BSD_LIB) 51 #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1 52 #endif 53 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 54 #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 55 #else 56 // Assume an ELF system with a dl_iterate_phdr function. 57 #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1 58 #if !defined(_LIBUNWIND_ARM_EHABI) 59 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 60 #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 61 #endif 62 #endif 63 64 #if defined(_LIBUNWIND_HIDE_SYMBOLS) 65 // The CMake file passes -fvisibility=hidden to control ELF/Mach-O visibility. 66 #define _LIBUNWIND_EXPORT 67 #define _LIBUNWIND_HIDDEN 68 #else 69 #if !defined(__ELF__) && !defined(__MACH__) && !defined(_AIX) 70 #define _LIBUNWIND_EXPORT __declspec(dllexport) 71 #define _LIBUNWIND_HIDDEN 72 #else 73 #define _LIBUNWIND_EXPORT __attribute__((visibility("default"))) 74 #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden"))) 75 #endif 76 #endif 77 78 #define STR(a) #a 79 #define XSTR(a) STR(a) 80 #define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name 81 82 #if defined(__APPLE__) 83 #if defined(_LIBUNWIND_HIDE_SYMBOLS) 84 #define _LIBUNWIND_ALIAS_VISIBILITY(name) __asm__(".private_extern " name); 85 #else 86 #define _LIBUNWIND_ALIAS_VISIBILITY(name) 87 #endif 88 #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ 89 __asm__(".globl " SYMBOL_NAME(aliasname)); \ 90 __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \ 91 _LIBUNWIND_ALIAS_VISIBILITY(SYMBOL_NAME(aliasname)) 92 #elif defined(__ELF__) || defined(_AIX) || defined(__wasm__) 93 #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ 94 extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ 95 __attribute__((weak, alias(#name))); 96 #elif defined(_WIN32) 97 #if defined(__MINGW32__) 98 #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ 99 extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ 100 __attribute__((alias(#name))); 101 #else 102 #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ 103 __pragma(comment(linker, "/alternatename:" SYMBOL_NAME(aliasname) "=" \ 104 SYMBOL_NAME(name))) \ 105 extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname; 106 #endif 107 #else 108 #error Unsupported target 109 #endif 110 111 // Apple/armv7k defaults to DWARF/Compact unwinding, but its libunwind also 112 // needs to include the SJLJ APIs. 113 #if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__) 114 #define _LIBUNWIND_BUILD_SJLJ_APIS 115 #endif 116 117 #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \ 118 (!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \ 119 defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \ 120 defined(__sparc__) || defined(__s390x__) || defined(__loongarch__) 121 #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) 122 #define _LIBUNWIND_BUILD_ZERO_COST_APIS 123 #endif 124 #endif 125 126 #ifndef _LIBUNWIND_REMEMBER_HEAP_ALLOC 127 #if defined(_LIBUNWIND_REMEMBER_STACK_ALLOC) || defined(__APPLE__) || \ 128 defined(__linux__) || defined(__ANDROID__) || defined(__MINGW32__) || \ 129 defined(_LIBUNWIND_IS_BAREMETAL) 130 #define _LIBUNWIND_REMEMBER_ALLOC(_size) __builtin_alloca(_size) 131 #define _LIBUNWIND_REMEMBER_FREE(_ptr) \ 132 do { \ 133 } while (0) 134 #elif defined(_WIN32) 135 #define _LIBUNWIND_REMEMBER_ALLOC(_size) _malloca(_size) 136 #define _LIBUNWIND_REMEMBER_FREE(_ptr) _freea(_ptr) 137 #define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED 138 #else 139 #define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size) 140 #define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr) 141 #define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED 142 #endif 143 #else /* _LIBUNWIND_REMEMBER_HEAP_ALLOC */ 144 #define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size) 145 #define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr) 146 #define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED 147 #endif 148 149 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 150 #define _LIBUNWIND_ABORT(msg) \ 151 do { \ 152 abort(); \ 153 } while (0) 154 #else 155 #define _LIBUNWIND_ABORT(msg) \ 156 do { \ 157 fprintf(stderr, "libunwind: %s - %s\n", __func__, msg); \ 158 fflush(stderr); \ 159 abort(); \ 160 } while (0) 161 #endif 162 163 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 164 #define _LIBUNWIND_LOG0(msg) 165 #define _LIBUNWIND_LOG(msg, ...) 166 #else 167 #define _LIBUNWIND_LOG0(msg) do { \ 168 fprintf(stderr, "libunwind: " msg "\n"); \ 169 fflush(stderr); \ 170 } while (0) 171 #define _LIBUNWIND_LOG(msg, ...) do { \ 172 fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__); \ 173 fflush(stderr); \ 174 } while (0) 175 #endif 176 177 #if defined(NDEBUG) 178 #define _LIBUNWIND_LOG_IF_FALSE(x) x 179 #else 180 #define _LIBUNWIND_LOG_IF_FALSE(x) \ 181 do { \ 182 bool _ret = x; \ 183 if (!_ret) \ 184 _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__); \ 185 } while (0) 186 #endif 187 188 // Macros that define away in non-Debug builds 189 #ifdef NDEBUG 190 #define _LIBUNWIND_DEBUG_LOG(msg, ...) 191 #define _LIBUNWIND_TRACE_API(msg, ...) 192 #define _LIBUNWIND_TRACING_UNWINDING (0) 193 #define _LIBUNWIND_TRACING_DWARF (0) 194 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) 195 #define _LIBUNWIND_TRACE_DWARF(...) 196 #else 197 #ifdef __cplusplus 198 extern "C" { 199 #endif 200 extern bool logAPIs(void); 201 extern bool logUnwinding(void); 202 extern bool logDWARF(void); 203 #ifdef __cplusplus 204 } 205 #endif 206 #define _LIBUNWIND_DEBUG_LOG(msg, ...) _LIBUNWIND_LOG(msg, __VA_ARGS__) 207 #define _LIBUNWIND_TRACE_API(msg, ...) \ 208 do { \ 209 if (logAPIs()) \ 210 _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 211 } while (0) 212 #define _LIBUNWIND_TRACING_UNWINDING logUnwinding() 213 #define _LIBUNWIND_TRACING_DWARF logDWARF() 214 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \ 215 do { \ 216 if (logUnwinding()) \ 217 _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 218 } while (0) 219 #define _LIBUNWIND_TRACE_DWARF(...) \ 220 do { \ 221 if (logDWARF()) \ 222 fprintf(stderr, __VA_ARGS__); \ 223 } while (0) 224 #endif 225 226 #ifdef __cplusplus 227 // Used to fit UnwindCursor and Registers_xxx types against unw_context_t / 228 // unw_cursor_t sized memory blocks. 229 #if defined(_LIBUNWIND_IS_NATIVE_ONLY) 230 # define COMP_OP == 231 #else 232 # define COMP_OP <= 233 #endif 234 template <typename _Type, typename _Mem> 235 struct check_fit { 236 template <typename T> 237 struct blk_count { 238 static const size_t count = 239 (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t); 240 }; 241 static const bool does_fit = 242 (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count); 243 }; 244 #undef COMP_OP 245 #endif // __cplusplus 246 247 #endif // LIBUNWIND_CONFIG_H 248