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" _LIBUNWIND_EXPORT __typeof(name) aliasname \ 74 __attribute__((weak_import)); 75 #elif defined(__ELF__) 76 #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ 77 extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ 78 __attribute__((weak, alias(#name))); 79 #elif defined(_WIN32) 80 #if defined(__MINGW32__) 81 #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ 82 extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ 83 __attribute__((alias(#name))); 84 #else 85 #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ 86 __pragma(comment(linker, "/alternatename:" SYMBOL_NAME(aliasname) "=" \ 87 SYMBOL_NAME(name))) \ 88 extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname; 89 #endif 90 #else 91 #error Unsupported target 92 #endif 93 94 #if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__) 95 #define _LIBUNWIND_BUILD_SJLJ_APIS 96 #endif 97 98 #if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) 99 #define _LIBUNWIND_SUPPORT_FRAME_APIS 100 #endif 101 102 #if defined(__i386__) || defined(__x86_64__) || \ 103 defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \ 104 (!defined(__APPLE__) && defined(__arm__)) || \ 105 defined(__aarch64__) || \ 106 defined(__mips__) || \ 107 defined(__riscv) || \ 108 defined(__sparc64__) || \ 109 defined(__hexagon__) 110 #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) 111 #define _LIBUNWIND_BUILD_ZERO_COST_APIS 112 #endif 113 #endif 114 115 #if defined(__powerpc64__) && defined(_ARCH_PWR8) 116 #define PPC64_HAS_VMX 117 #endif 118 119 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 120 #define _LIBUNWIND_ABORT(msg) \ 121 do { \ 122 abort(); \ 123 } while (0) 124 #else 125 #define _LIBUNWIND_ABORT(msg) \ 126 do { \ 127 fprintf(stderr, "libunwind: %s - %s\n", __func__, msg); \ 128 fflush(stderr); \ 129 abort(); \ 130 } while (0) 131 #endif 132 133 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 134 #define _LIBUNWIND_LOG0(msg) 135 #define _LIBUNWIND_LOG(msg, ...) 136 #else 137 #define _LIBUNWIND_LOG0(msg) \ 138 fprintf(stderr, "libunwind: " msg "\n") 139 #define _LIBUNWIND_LOG(msg, ...) \ 140 fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) 141 #endif 142 143 #if defined(NDEBUG) 144 #define _LIBUNWIND_LOG_IF_FALSE(x) x 145 #else 146 #define _LIBUNWIND_LOG_IF_FALSE(x) \ 147 do { \ 148 bool _ret = x; \ 149 if (!_ret) \ 150 _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__); \ 151 } while (0) 152 #endif 153 154 // Macros that define away in non-Debug builds 155 #ifdef NDEBUG 156 #define _LIBUNWIND_DEBUG_LOG(msg, ...) 157 #define _LIBUNWIND_TRACE_API(msg, ...) 158 #define _LIBUNWIND_TRACING_UNWINDING (0) 159 #define _LIBUNWIND_TRACING_DWARF (0) 160 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) 161 #define _LIBUNWIND_TRACE_DWARF(...) 162 #else 163 #ifdef __cplusplus 164 extern "C" { 165 #endif 166 extern bool logAPIs(); 167 extern bool logUnwinding(); 168 extern bool logDWARF(); 169 #ifdef __cplusplus 170 } 171 #endif 172 #define _LIBUNWIND_DEBUG_LOG(msg, ...) _LIBUNWIND_LOG(msg, __VA_ARGS__) 173 #define _LIBUNWIND_TRACE_API(msg, ...) \ 174 do { \ 175 if (logAPIs()) \ 176 _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 177 } while (0) 178 #define _LIBUNWIND_TRACING_UNWINDING logUnwinding() 179 #define _LIBUNWIND_TRACING_DWARF logDWARF() 180 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \ 181 do { \ 182 if (logUnwinding()) \ 183 _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 184 } while (0) 185 #define _LIBUNWIND_TRACE_DWARF(...) \ 186 do { \ 187 if (logDWARF()) \ 188 fprintf(stderr, __VA_ARGS__); \ 189 } while (0) 190 #endif 191 192 #ifdef __cplusplus 193 // Used to fit UnwindCursor and Registers_xxx types against unw_context_t / 194 // unw_cursor_t sized memory blocks. 195 #if defined(_LIBUNWIND_IS_NATIVE_ONLY) 196 # define COMP_OP == 197 #else 198 # define COMP_OP <= 199 #endif 200 template <typename _Type, typename _Mem> 201 struct check_fit { 202 template <typename T> 203 struct blk_count { 204 static const size_t count = 205 (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t); 206 }; 207 static const bool does_fit = 208 (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count); 209 }; 210 #undef COMP_OP 211 #endif // __cplusplus 212 213 #endif // LIBUNWIND_CONFIG_H 214