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(__hexagon__) 109 #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) 110 #define _LIBUNWIND_BUILD_ZERO_COST_APIS 111 #endif 112 #endif 113 114 #if defined(__powerpc64__) && defined(_ARCH_PWR8) 115 #define PPC64_HAS_VMX 116 #endif 117 118 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 119 #define _LIBUNWIND_ABORT(msg) \ 120 do { \ 121 abort(); \ 122 } while (0) 123 #else 124 #define _LIBUNWIND_ABORT(msg) \ 125 do { \ 126 fprintf(stderr, "libunwind: %s - %s\n", __func__, msg); \ 127 fflush(stderr); \ 128 abort(); \ 129 } while (0) 130 #endif 131 132 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 133 #define _LIBUNWIND_LOG0(msg) 134 #define _LIBUNWIND_LOG(msg, ...) 135 #else 136 #define _LIBUNWIND_LOG0(msg) \ 137 fprintf(stderr, "libunwind: " msg "\n") 138 #define _LIBUNWIND_LOG(msg, ...) \ 139 fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) 140 #endif 141 142 #if defined(NDEBUG) 143 #define _LIBUNWIND_LOG_IF_FALSE(x) x 144 #else 145 #define _LIBUNWIND_LOG_IF_FALSE(x) \ 146 do { \ 147 bool _ret = x; \ 148 if (!_ret) \ 149 _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__); \ 150 } while (0) 151 #endif 152 153 // Macros that define away in non-Debug builds 154 #ifdef NDEBUG 155 #define _LIBUNWIND_DEBUG_LOG(msg, ...) 156 #define _LIBUNWIND_TRACE_API(msg, ...) 157 #define _LIBUNWIND_TRACING_UNWINDING (0) 158 #define _LIBUNWIND_TRACING_DWARF (0) 159 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) 160 #define _LIBUNWIND_TRACE_DWARF(...) 161 #else 162 #ifdef __cplusplus 163 extern "C" { 164 #endif 165 extern bool logAPIs(); 166 extern bool logUnwinding(); 167 extern bool logDWARF(); 168 #ifdef __cplusplus 169 } 170 #endif 171 #define _LIBUNWIND_DEBUG_LOG(msg, ...) _LIBUNWIND_LOG(msg, __VA_ARGS__) 172 #define _LIBUNWIND_TRACE_API(msg, ...) \ 173 do { \ 174 if (logAPIs()) \ 175 _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 176 } while (0) 177 #define _LIBUNWIND_TRACING_UNWINDING logUnwinding() 178 #define _LIBUNWIND_TRACING_DWARF logDWARF() 179 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \ 180 do { \ 181 if (logUnwinding()) \ 182 _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 183 } while (0) 184 #define _LIBUNWIND_TRACE_DWARF(...) \ 185 do { \ 186 if (logDWARF()) \ 187 fprintf(stderr, __VA_ARGS__); \ 188 } while (0) 189 #endif 190 191 #ifdef __cplusplus 192 // Used to fit UnwindCursor and Registers_xxx types against unw_context_t / 193 // unw_cursor_t sized memory blocks. 194 #if defined(_LIBUNWIND_IS_NATIVE_ONLY) 195 # define COMP_OP == 196 #else 197 # define COMP_OP <= 198 #endif 199 template <typename _Type, typename _Mem> 200 struct check_fit { 201 template <typename T> 202 struct blk_count { 203 static const size_t count = 204 (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t); 205 }; 206 static const bool does_fit = 207 (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count); 208 }; 209 #undef COMP_OP 210 #endif // __cplusplus 211 212 #endif // LIBUNWIND_CONFIG_H 213