1 //===----------------------------- config.h -------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 // 9 // Defines macros used within libunwind project. 10 // 11 //===----------------------------------------------------------------------===// 12 13 14 #ifndef LIBUNWIND_CONFIG_H 15 #define LIBUNWIND_CONFIG_H 16 17 #include <assert.h> 18 #include <stdio.h> 19 #include <stdint.h> 20 #include <stdlib.h> 21 22 // Define static_assert() unless already defined by compiler. 23 #ifndef __has_feature 24 #define __has_feature(__x) 0 25 #endif 26 #if !(__has_feature(cxx_static_assert)) && !defined(static_assert) 27 #define static_assert(__b, __m) \ 28 extern int compile_time_assert_failed[ ( __b ) ? 1 : -1 ] \ 29 __attribute__( ( unused ) ); 30 #endif 31 32 // Platform specific configuration defines. 33 #ifdef __APPLE__ 34 #if defined(FOR_DYLD) 35 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 36 #else 37 #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 38 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 39 #endif 40 #else 41 #if defined(__ARM_DWARF_EH__) || !defined(__arm__) 42 #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 43 #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 44 #endif 45 #endif 46 47 // FIXME: these macros are not correct for COFF targets 48 #define _LIBUNWIND_EXPORT __attribute__((visibility("default"))) 49 #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden"))) 50 51 #if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__) 52 #define _LIBUNWIND_BUILD_SJLJ_APIS 53 #endif 54 55 #if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__) 56 #define _LIBUNWIND_SUPPORT_FRAME_APIS 57 #endif 58 59 #if defined(__i386__) || defined(__x86_64__) || \ 60 defined(__ppc__) || defined(__ppc64__) || \ 61 (!defined(__APPLE__) && defined(__arm__)) || \ 62 (defined(__arm64__) || defined(__aarch64__)) || \ 63 (defined(__APPLE__) && defined(__mips__)) 64 #define _LIBUNWIND_BUILD_ZERO_COST_APIS 65 #endif 66 67 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 68 #define _LIBUNWIND_ABORT(msg) \ 69 do { \ 70 abort(); \ 71 } while (0) 72 #else 73 #define _LIBUNWIND_ABORT(msg) \ 74 do { \ 75 fprintf(stderr, "libunwind: %s %s:%d - %s\n", __func__, __FILE__, \ 76 __LINE__, msg); \ 77 fflush(stderr); \ 78 abort(); \ 79 } while (0) 80 #endif 81 82 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 83 #define _LIBUNWIND_LOG(msg, ...) 84 #else 85 #define _LIBUNWIND_LOG(msg, ...) \ 86 fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) 87 #endif 88 89 #if defined(_LIBUNWIND_HAS_NO_THREADS) 90 // only used with pthread calls, not needed for the single-threaded builds 91 #define _LIBUNWIND_LOG_NON_ZERO(x) 92 #else 93 #if defined(NDEBUG) 94 #define _LIBUNWIND_LOG_NON_ZERO(x) x 95 #else 96 #define _LIBUNWIND_LOG_NON_ZERO(x) \ 97 do { \ 98 int _err = x; \ 99 if (_err != 0) \ 100 _LIBUNWIND_LOG("" #x "=%d in %s", _err, __FUNCTION__); \ 101 } while (0) 102 #endif 103 #endif 104 105 // Macros that define away in non-Debug builds 106 #ifdef NDEBUG 107 #define _LIBUNWIND_DEBUG_LOG(msg, ...) 108 #define _LIBUNWIND_TRACE_API(msg, ...) 109 #define _LIBUNWIND_TRACING_UNWINDING (0) 110 #define _LIBUNWIND_TRACING_DWARF (0) 111 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) 112 #define _LIBUNWIND_TRACE_DWARF(...) 113 #else 114 #ifdef __cplusplus 115 extern "C" { 116 #endif 117 extern bool logAPIs(); 118 extern bool logUnwinding(); 119 extern bool logDWARF(); 120 #ifdef __cplusplus 121 } 122 #endif 123 #define _LIBUNWIND_DEBUG_LOG(msg, ...) _LIBUNWIND_LOG(msg, __VA_ARGS__) 124 #define _LIBUNWIND_TRACE_API(msg, ...) \ 125 do { \ 126 if (logAPIs()) \ 127 _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 128 } while (0) 129 #define _LIBUNWIND_TRACING_UNWINDING logUnwinding() 130 #define _LIBUNWIND_TRACING_DWARF logDWARF() 131 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \ 132 do { \ 133 if (logUnwinding()) \ 134 _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 135 } while (0) 136 #define _LIBUNWIND_TRACE_DWARF(...) \ 137 do { \ 138 if (logDWARF()) \ 139 fprintf(stderr, __VA_ARGS__); \ 140 } while (0) 141 #endif 142 143 #ifdef __cplusplus 144 // Used to fit UnwindCursor and Registers_xxx types against unw_context_t / 145 // unw_cursor_t sized memory blocks. 146 #if defined(_LIBUNWIND_IS_NATIVE_ONLY) 147 # define COMP_OP == 148 #else 149 # define COMP_OP < 150 #endif 151 template <typename _Type, typename _Mem> 152 struct check_fit { 153 template <typename T> 154 struct blk_count { 155 static const size_t count = 156 (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t); 157 }; 158 static const bool does_fit = 159 (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count); 160 }; 161 #undef COMP_OP 162 #endif // __cplusplus 163 164 #endif // LIBUNWIND_CONFIG_H 165