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