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