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