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 #if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__) 66 #define _LIBUNWIND_BUILD_SJLJ_APIS 67 #endif 68 69 #if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) 70 #define _LIBUNWIND_SUPPORT_FRAME_APIS 71 #endif 72 73 #if defined(__i386__) || defined(__x86_64__) || \ 74 defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \ 75 (!defined(__APPLE__) && defined(__arm__)) || \ 76 (defined(__arm64__) || defined(__aarch64__)) || \ 77 defined(__mips__) 78 #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) 79 #define _LIBUNWIND_BUILD_ZERO_COST_APIS 80 #endif 81 #endif 82 83 #if defined(__powerpc64__) && defined(_ARCH_PWR8) 84 #define PPC64_HAS_VMX 85 #endif 86 87 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 88 #define _LIBUNWIND_ABORT(msg) \ 89 do { \ 90 abort(); \ 91 } while (0) 92 #else 93 #define _LIBUNWIND_ABORT(msg) \ 94 do { \ 95 fprintf(stderr, "libunwind: %s %s:%d - %s\n", __func__, __FILE__, \ 96 __LINE__, msg); \ 97 fflush(stderr); \ 98 abort(); \ 99 } while (0) 100 #endif 101 102 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 103 #define _LIBUNWIND_LOG0(msg) 104 #define _LIBUNWIND_LOG(msg, ...) 105 #else 106 #define _LIBUNWIND_LOG0(msg) \ 107 fprintf(stderr, "libunwind: " msg "\n") 108 #define _LIBUNWIND_LOG(msg, ...) \ 109 fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) 110 #endif 111 112 #if defined(NDEBUG) 113 #define _LIBUNWIND_LOG_IF_FALSE(x) x 114 #else 115 #define _LIBUNWIND_LOG_IF_FALSE(x) \ 116 do { \ 117 bool _ret = x; \ 118 if (!_ret) \ 119 _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__); \ 120 } while (0) 121 #endif 122 123 // Macros that define away in non-Debug builds 124 #ifdef NDEBUG 125 #define _LIBUNWIND_DEBUG_LOG(msg, ...) 126 #define _LIBUNWIND_TRACE_API(msg, ...) 127 #define _LIBUNWIND_TRACING_UNWINDING (0) 128 #define _LIBUNWIND_TRACING_DWARF (0) 129 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) 130 #define _LIBUNWIND_TRACE_DWARF(...) 131 #else 132 #ifdef __cplusplus 133 extern "C" { 134 #endif 135 extern bool logAPIs(); 136 extern bool logUnwinding(); 137 extern bool logDWARF(); 138 #ifdef __cplusplus 139 } 140 #endif 141 #define _LIBUNWIND_DEBUG_LOG(msg, ...) _LIBUNWIND_LOG(msg, __VA_ARGS__) 142 #define _LIBUNWIND_TRACE_API(msg, ...) \ 143 do { \ 144 if (logAPIs()) \ 145 _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 146 } while (0) 147 #define _LIBUNWIND_TRACING_UNWINDING logUnwinding() 148 #define _LIBUNWIND_TRACING_DWARF logDWARF() 149 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \ 150 do { \ 151 if (logUnwinding()) \ 152 _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 153 } while (0) 154 #define _LIBUNWIND_TRACE_DWARF(...) \ 155 do { \ 156 if (logDWARF()) \ 157 fprintf(stderr, __VA_ARGS__); \ 158 } while (0) 159 #endif 160 161 #ifdef __cplusplus 162 // Used to fit UnwindCursor and Registers_xxx types against unw_context_t / 163 // unw_cursor_t sized memory blocks. 164 #if defined(_LIBUNWIND_IS_NATIVE_ONLY) 165 # define COMP_OP == 166 #else 167 # define COMP_OP <= 168 #endif 169 template <typename _Type, typename _Mem> 170 struct check_fit { 171 template <typename T> 172 struct blk_count { 173 static const size_t count = 174 (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t); 175 }; 176 static const bool does_fit = 177 (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count); 178 }; 179 #undef COMP_OP 180 #endif // __cplusplus 181 182 #endif // LIBUNWIND_CONFIG_H 183