1349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric // 80b57cec5SDimitry Andric // Defines macros used within libunwind project. 90b57cec5SDimitry Andric // 100b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LIBUNWIND_CONFIG_H 140b57cec5SDimitry Andric #define LIBUNWIND_CONFIG_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include <assert.h> 170b57cec5SDimitry Andric #include <stdio.h> 180b57cec5SDimitry Andric #include <stdint.h> 190b57cec5SDimitry Andric #include <stdlib.h> 200b57cec5SDimitry Andric 21e8d8bef9SDimitry Andric #include <__libunwind_config.h> 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric // Platform specific configuration defines. 240b57cec5SDimitry Andric #ifdef __APPLE__ 250b57cec5SDimitry Andric #if defined(FOR_DYLD) 26e8d8bef9SDimitry Andric #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1 270b57cec5SDimitry Andric #else 28e8d8bef9SDimitry Andric #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1 290b57cec5SDimitry Andric #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 300b57cec5SDimitry Andric #endif 310b57cec5SDimitry Andric #elif defined(_WIN32) 320b57cec5SDimitry Andric #ifdef __SEH__ 330b57cec5SDimitry Andric #define _LIBUNWIND_SUPPORT_SEH_UNWIND 1 340b57cec5SDimitry Andric #else 350b57cec5SDimitry Andric #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 360b57cec5SDimitry Andric #endif 37e8d8bef9SDimitry Andric #elif defined(_LIBUNWIND_IS_BAREMETAL) 38e8d8bef9SDimitry Andric #if !defined(_LIBUNWIND_ARM_EHABI) 39e8d8bef9SDimitry Andric #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 40e8d8bef9SDimitry Andric #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 41e8d8bef9SDimitry Andric #endif 42e8d8bef9SDimitry Andric #elif defined(__BIONIC__) && defined(_LIBUNWIND_ARM_EHABI) 43e8d8bef9SDimitry Andric // For ARM EHABI, Bionic didn't implement dl_iterate_phdr until API 21. After 44e8d8bef9SDimitry Andric // API 21, dl_iterate_phdr exists, but dl_unwind_find_exidx is much faster. 45e8d8bef9SDimitry Andric #define _LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX 1 4681ad6265SDimitry Andric #elif defined(_AIX) 4781ad6265SDimitry Andric // The traceback table at the end of each function is used for unwinding. 4881ad6265SDimitry Andric #define _LIBUNWIND_SUPPORT_TBTAB_UNWIND 1 49*5f757f3fSDimitry Andric #elif defined(__HAIKU__) 50*5f757f3fSDimitry Andric #if defined(_LIBUNWIND_USE_HAIKU_BSD_LIB) 51*5f757f3fSDimitry Andric #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1 52*5f757f3fSDimitry Andric #endif 53*5f757f3fSDimitry Andric #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 54*5f757f3fSDimitry Andric #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 550b57cec5SDimitry Andric #else 56e8d8bef9SDimitry Andric // Assume an ELF system with a dl_iterate_phdr function. 57e8d8bef9SDimitry Andric #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1 58e8d8bef9SDimitry Andric #if !defined(_LIBUNWIND_ARM_EHABI) 590b57cec5SDimitry Andric #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1 600b57cec5SDimitry Andric #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1 610b57cec5SDimitry Andric #endif 620b57cec5SDimitry Andric #endif 630b57cec5SDimitry Andric 64fe6060f1SDimitry Andric #if defined(_LIBUNWIND_HIDE_SYMBOLS) 65fe6060f1SDimitry Andric // The CMake file passes -fvisibility=hidden to control ELF/Mach-O visibility. 660b57cec5SDimitry Andric #define _LIBUNWIND_EXPORT 670b57cec5SDimitry Andric #define _LIBUNWIND_HIDDEN 680b57cec5SDimitry Andric #else 6981ad6265SDimitry Andric #if !defined(__ELF__) && !defined(__MACH__) && !defined(_AIX) 700b57cec5SDimitry Andric #define _LIBUNWIND_EXPORT __declspec(dllexport) 710b57cec5SDimitry Andric #define _LIBUNWIND_HIDDEN 720b57cec5SDimitry Andric #else 730b57cec5SDimitry Andric #define _LIBUNWIND_EXPORT __attribute__((visibility("default"))) 740b57cec5SDimitry Andric #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden"))) 750b57cec5SDimitry Andric #endif 760b57cec5SDimitry Andric #endif 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric #define STR(a) #a 790b57cec5SDimitry Andric #define XSTR(a) STR(a) 800b57cec5SDimitry Andric #define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric #if defined(__APPLE__) 83fe6060f1SDimitry Andric #if defined(_LIBUNWIND_HIDE_SYMBOLS) 84fe6060f1SDimitry Andric #define _LIBUNWIND_ALIAS_VISIBILITY(name) __asm__(".private_extern " name); 85fe6060f1SDimitry Andric #else 86fe6060f1SDimitry Andric #define _LIBUNWIND_ALIAS_VISIBILITY(name) 87fe6060f1SDimitry Andric #endif 880b57cec5SDimitry Andric #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ 890b57cec5SDimitry Andric __asm__(".globl " SYMBOL_NAME(aliasname)); \ 900b57cec5SDimitry Andric __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name)); \ 91fe6060f1SDimitry Andric _LIBUNWIND_ALIAS_VISIBILITY(SYMBOL_NAME(aliasname)) 92*5f757f3fSDimitry Andric #elif defined(__ELF__) || defined(_AIX) || defined(__wasm__) 930b57cec5SDimitry Andric #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ 940b57cec5SDimitry Andric extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ 950b57cec5SDimitry Andric __attribute__((weak, alias(#name))); 960b57cec5SDimitry Andric #elif defined(_WIN32) 970b57cec5SDimitry Andric #if defined(__MINGW32__) 980b57cec5SDimitry Andric #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ 990b57cec5SDimitry Andric extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname \ 1000b57cec5SDimitry Andric __attribute__((alias(#name))); 1010b57cec5SDimitry Andric #else 1020b57cec5SDimitry Andric #define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \ 1030b57cec5SDimitry Andric __pragma(comment(linker, "/alternatename:" SYMBOL_NAME(aliasname) "=" \ 1040b57cec5SDimitry Andric SYMBOL_NAME(name))) \ 1050b57cec5SDimitry Andric extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname; 1060b57cec5SDimitry Andric #endif 1070b57cec5SDimitry Andric #else 1080b57cec5SDimitry Andric #error Unsupported target 1090b57cec5SDimitry Andric #endif 1100b57cec5SDimitry Andric 111e8d8bef9SDimitry Andric // Apple/armv7k defaults to DWARF/Compact unwinding, but its libunwind also 112e8d8bef9SDimitry Andric // needs to include the SJLJ APIs. 1130b57cec5SDimitry Andric #if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__) 1140b57cec5SDimitry Andric #define _LIBUNWIND_BUILD_SJLJ_APIS 1150b57cec5SDimitry Andric #endif 1160b57cec5SDimitry Andric 117d56accc7SDimitry Andric #if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \ 118d56accc7SDimitry Andric (!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \ 119d56accc7SDimitry Andric defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \ 120bdd1243dSDimitry Andric defined(__sparc__) || defined(__s390x__) || defined(__loongarch__) 1210b57cec5SDimitry Andric #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS) 1220b57cec5SDimitry Andric #define _LIBUNWIND_BUILD_ZERO_COST_APIS 1230b57cec5SDimitry Andric #endif 1240b57cec5SDimitry Andric #endif 1250b57cec5SDimitry Andric 126e8d8bef9SDimitry Andric #ifndef _LIBUNWIND_REMEMBER_HEAP_ALLOC 127e8d8bef9SDimitry Andric #if defined(_LIBUNWIND_REMEMBER_STACK_ALLOC) || defined(__APPLE__) || \ 128e8d8bef9SDimitry Andric defined(__linux__) || defined(__ANDROID__) || defined(__MINGW32__) || \ 129e8d8bef9SDimitry Andric defined(_LIBUNWIND_IS_BAREMETAL) 130*5f757f3fSDimitry Andric #define _LIBUNWIND_REMEMBER_ALLOC(_size) __builtin_alloca(_size) 131e8d8bef9SDimitry Andric #define _LIBUNWIND_REMEMBER_FREE(_ptr) \ 132e8d8bef9SDimitry Andric do { \ 133e8d8bef9SDimitry Andric } while (0) 134e8d8bef9SDimitry Andric #elif defined(_WIN32) 135e8d8bef9SDimitry Andric #define _LIBUNWIND_REMEMBER_ALLOC(_size) _malloca(_size) 136e8d8bef9SDimitry Andric #define _LIBUNWIND_REMEMBER_FREE(_ptr) _freea(_ptr) 137e8d8bef9SDimitry Andric #define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED 138e8d8bef9SDimitry Andric #else 139e8d8bef9SDimitry Andric #define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size) 140e8d8bef9SDimitry Andric #define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr) 141e8d8bef9SDimitry Andric #define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED 142e8d8bef9SDimitry Andric #endif 143e8d8bef9SDimitry Andric #else /* _LIBUNWIND_REMEMBER_HEAP_ALLOC */ 144e8d8bef9SDimitry Andric #define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size) 145e8d8bef9SDimitry Andric #define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr) 146e8d8bef9SDimitry Andric #define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED 1470b57cec5SDimitry Andric #endif 1480b57cec5SDimitry Andric 1490b57cec5SDimitry Andric #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 1500b57cec5SDimitry Andric #define _LIBUNWIND_ABORT(msg) \ 1510b57cec5SDimitry Andric do { \ 1520b57cec5SDimitry Andric abort(); \ 1530b57cec5SDimitry Andric } while (0) 1540b57cec5SDimitry Andric #else 1550b57cec5SDimitry Andric #define _LIBUNWIND_ABORT(msg) \ 1560b57cec5SDimitry Andric do { \ 1575ffd83dbSDimitry Andric fprintf(stderr, "libunwind: %s - %s\n", __func__, msg); \ 1580b57cec5SDimitry Andric fflush(stderr); \ 1590b57cec5SDimitry Andric abort(); \ 1600b57cec5SDimitry Andric } while (0) 1610b57cec5SDimitry Andric #endif 1620b57cec5SDimitry Andric 1630b57cec5SDimitry Andric #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL) 1640b57cec5SDimitry Andric #define _LIBUNWIND_LOG0(msg) 1650b57cec5SDimitry Andric #define _LIBUNWIND_LOG(msg, ...) 1660b57cec5SDimitry Andric #else 16706c3fb27SDimitry Andric #define _LIBUNWIND_LOG0(msg) do { \ 16806c3fb27SDimitry Andric fprintf(stderr, "libunwind: " msg "\n"); \ 16906c3fb27SDimitry Andric fflush(stderr); \ 17006c3fb27SDimitry Andric } while (0) 17106c3fb27SDimitry Andric #define _LIBUNWIND_LOG(msg, ...) do { \ 17206c3fb27SDimitry Andric fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__); \ 17306c3fb27SDimitry Andric fflush(stderr); \ 17406c3fb27SDimitry Andric } while (0) 1750b57cec5SDimitry Andric #endif 1760b57cec5SDimitry Andric 1770b57cec5SDimitry Andric #if defined(NDEBUG) 1780b57cec5SDimitry Andric #define _LIBUNWIND_LOG_IF_FALSE(x) x 1790b57cec5SDimitry Andric #else 1800b57cec5SDimitry Andric #define _LIBUNWIND_LOG_IF_FALSE(x) \ 1810b57cec5SDimitry Andric do { \ 1820b57cec5SDimitry Andric bool _ret = x; \ 1830b57cec5SDimitry Andric if (!_ret) \ 1840b57cec5SDimitry Andric _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__); \ 1850b57cec5SDimitry Andric } while (0) 1860b57cec5SDimitry Andric #endif 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric // Macros that define away in non-Debug builds 1890b57cec5SDimitry Andric #ifdef NDEBUG 1900b57cec5SDimitry Andric #define _LIBUNWIND_DEBUG_LOG(msg, ...) 1910b57cec5SDimitry Andric #define _LIBUNWIND_TRACE_API(msg, ...) 1920b57cec5SDimitry Andric #define _LIBUNWIND_TRACING_UNWINDING (0) 1930b57cec5SDimitry Andric #define _LIBUNWIND_TRACING_DWARF (0) 1940b57cec5SDimitry Andric #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) 1950b57cec5SDimitry Andric #define _LIBUNWIND_TRACE_DWARF(...) 1960b57cec5SDimitry Andric #else 1970b57cec5SDimitry Andric #ifdef __cplusplus 1980b57cec5SDimitry Andric extern "C" { 1990b57cec5SDimitry Andric #endif 20081ad6265SDimitry Andric extern bool logAPIs(void); 20181ad6265SDimitry Andric extern bool logUnwinding(void); 20281ad6265SDimitry Andric extern bool logDWARF(void); 2030b57cec5SDimitry Andric #ifdef __cplusplus 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric #endif 2060b57cec5SDimitry Andric #define _LIBUNWIND_DEBUG_LOG(msg, ...) _LIBUNWIND_LOG(msg, __VA_ARGS__) 2070b57cec5SDimitry Andric #define _LIBUNWIND_TRACE_API(msg, ...) \ 2080b57cec5SDimitry Andric do { \ 2090b57cec5SDimitry Andric if (logAPIs()) \ 2100b57cec5SDimitry Andric _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 2110b57cec5SDimitry Andric } while (0) 2120b57cec5SDimitry Andric #define _LIBUNWIND_TRACING_UNWINDING logUnwinding() 2130b57cec5SDimitry Andric #define _LIBUNWIND_TRACING_DWARF logDWARF() 2140b57cec5SDimitry Andric #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \ 2150b57cec5SDimitry Andric do { \ 2160b57cec5SDimitry Andric if (logUnwinding()) \ 2170b57cec5SDimitry Andric _LIBUNWIND_LOG(msg, __VA_ARGS__); \ 2180b57cec5SDimitry Andric } while (0) 2190b57cec5SDimitry Andric #define _LIBUNWIND_TRACE_DWARF(...) \ 2200b57cec5SDimitry Andric do { \ 2210b57cec5SDimitry Andric if (logDWARF()) \ 2220b57cec5SDimitry Andric fprintf(stderr, __VA_ARGS__); \ 2230b57cec5SDimitry Andric } while (0) 2240b57cec5SDimitry Andric #endif 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric #ifdef __cplusplus 2270b57cec5SDimitry Andric // Used to fit UnwindCursor and Registers_xxx types against unw_context_t / 2280b57cec5SDimitry Andric // unw_cursor_t sized memory blocks. 2290b57cec5SDimitry Andric #if defined(_LIBUNWIND_IS_NATIVE_ONLY) 2300b57cec5SDimitry Andric # define COMP_OP == 2310b57cec5SDimitry Andric #else 2320b57cec5SDimitry Andric # define COMP_OP <= 2330b57cec5SDimitry Andric #endif 2340b57cec5SDimitry Andric template <typename _Type, typename _Mem> 2350b57cec5SDimitry Andric struct check_fit { 2360b57cec5SDimitry Andric template <typename T> 2370b57cec5SDimitry Andric struct blk_count { 2380b57cec5SDimitry Andric static const size_t count = 2390b57cec5SDimitry Andric (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t); 2400b57cec5SDimitry Andric }; 2410b57cec5SDimitry Andric static const bool does_fit = 2420b57cec5SDimitry Andric (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count); 2430b57cec5SDimitry Andric }; 2440b57cec5SDimitry Andric #undef COMP_OP 2450b57cec5SDimitry Andric #endif // __cplusplus 2460b57cec5SDimitry Andric 2470b57cec5SDimitry Andric #endif // LIBUNWIND_CONFIG_H 248