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 defined(__riscv) 108#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) 109#define _LIBUNWIND_BUILD_ZERO_COST_APIS 110#endif 111#endif 112 113#if defined(__powerpc64__) && defined(_ARCH_PWR8) 114#define PPC64_HAS_VMX 115#endif 116 117#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 118#define _LIBUNWIND_ABORT(msg) \ 119 do { \ 120 abort(); \ 121 } while (0) 122#else 123#define _LIBUNWIND_ABORT(msg) \ 124 do { \ 125 fprintf(stderr, "libunwind: %s %s:%d - %s\n", __func__, __FILE__, \ 126 __LINE__, 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 199template <typename _Type, typename _Mem> 200struct 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