master
  1//===----------------------------------------------------------------------===//
  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#include <__libunwind_config.h>
 22
 23// Platform specific configuration defines.
 24#ifdef __APPLE__
 25  #if defined(FOR_DYLD)
 26    #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
 27  #else
 28    #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND 1
 29    #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
 30  #endif
 31#elif defined(_WIN32)
 32  #ifdef __SEH__
 33    #define _LIBUNWIND_SUPPORT_SEH_UNWIND 1
 34  #else
 35    #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
 36  #endif
 37#elif defined(_LIBUNWIND_IS_BAREMETAL)
 38  #if !defined(_LIBUNWIND_ARM_EHABI)
 39    #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
 40    #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1
 41  #endif
 42#elif defined(__BIONIC__) && defined(_LIBUNWIND_ARM_EHABI)
 43  // For ARM EHABI, Bionic didn't implement dl_iterate_phdr until API 21. After
 44  // API 21, dl_iterate_phdr exists, but dl_unwind_find_exidx is much faster.
 45  #define _LIBUNWIND_USE_DL_UNWIND_FIND_EXIDX 1
 46#elif defined(_AIX)
 47// The traceback table at the end of each function is used for unwinding.
 48#define _LIBUNWIND_SUPPORT_TBTAB_UNWIND 1
 49#elif defined(__HAIKU__)
 50  #if defined(_LIBUNWIND_USE_HAIKU_BSD_LIB)
 51    #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1
 52  #endif
 53  #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
 54  #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1
 55#else
 56  // Assume an ELF system with a dl_iterate_phdr function.
 57  #define _LIBUNWIND_USE_DL_ITERATE_PHDR 1
 58  #if !defined(_LIBUNWIND_ARM_EHABI)
 59    #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
 60    #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1
 61  #endif
 62#endif
 63
 64#if defined(_LIBUNWIND_HIDE_SYMBOLS)
 65  // The CMake file passes -fvisibility=hidden to control ELF/Mach-O visibility.
 66  #define _LIBUNWIND_EXPORT
 67  #define _LIBUNWIND_HIDDEN
 68#else
 69  #if !defined(__ELF__) && !defined(__MACH__) && !defined(_AIX)
 70    #define _LIBUNWIND_EXPORT __declspec(dllexport)
 71    #define _LIBUNWIND_HIDDEN
 72  #else
 73    #define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
 74    #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
 75  #endif
 76#endif
 77
 78#define STR(a) #a
 79#define XSTR(a) STR(a)
 80#define SYMBOL_NAME(name) XSTR(__USER_LABEL_PREFIX__) #name
 81
 82#if defined(__APPLE__)
 83#if defined(_LIBUNWIND_HIDE_SYMBOLS)
 84#define _LIBUNWIND_ALIAS_VISIBILITY(name) __asm__(".private_extern " name);
 85#else
 86#define _LIBUNWIND_ALIAS_VISIBILITY(name)
 87#endif
 88#define _LIBUNWIND_WEAK_ALIAS(name, aliasname)                                 \
 89  __asm__(".globl " SYMBOL_NAME(aliasname));                                   \
 90  __asm__(SYMBOL_NAME(aliasname) " = " SYMBOL_NAME(name));                     \
 91  _LIBUNWIND_ALIAS_VISIBILITY(SYMBOL_NAME(aliasname))
 92#elif defined(__ELF__) || defined(_AIX) || defined(__wasm__)
 93#define _LIBUNWIND_WEAK_ALIAS(name, aliasname)                                 \
 94  extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname                        \
 95      __attribute__((weak, alias(#name)));
 96#elif defined(_WIN32)
 97#if defined(__MINGW32__)
 98#define _LIBUNWIND_WEAK_ALIAS(name, aliasname)                                 \
 99  extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname                        \
100      __attribute__((alias(#name)));
101#else
102#define _LIBUNWIND_WEAK_ALIAS(name, aliasname)                                 \
103  __pragma(comment(linker, "/alternatename:" SYMBOL_NAME(aliasname) "="        \
104                                             SYMBOL_NAME(name)))               \
105  extern "C" _LIBUNWIND_EXPORT __typeof(name) aliasname;
106#endif
107#else
108#error Unsupported target
109#endif
110
111// Apple/armv7k defaults to DWARF/Compact unwinding, but its libunwind also
112// needs to include the SJLJ APIs.
113#if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__)
114#define _LIBUNWIND_BUILD_SJLJ_APIS
115#endif
116
117#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) ||        \
118    (!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) ||       \
119    defined(__mips__) || defined(__riscv) || defined(__hexagon__) ||           \
120    defined(__sparc__) || defined(__s390x__) || defined(__loongarch__)
121#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
122#define _LIBUNWIND_BUILD_ZERO_COST_APIS
123#endif
124#endif
125
126#ifndef _LIBUNWIND_REMEMBER_HEAP_ALLOC
127#if defined(_LIBUNWIND_REMEMBER_STACK_ALLOC) || defined(__APPLE__) ||          \
128    defined(__linux__) || defined(__ANDROID__) || defined(__MINGW32__) ||      \
129    defined(_LIBUNWIND_IS_BAREMETAL)
130#define _LIBUNWIND_REMEMBER_ALLOC(_size) __builtin_alloca(_size)
131#define _LIBUNWIND_REMEMBER_FREE(_ptr)                                         \
132  do {                                                                         \
133  } while (0)
134#elif defined(_WIN32)
135#define _LIBUNWIND_REMEMBER_ALLOC(_size) _malloca(_size)
136#define _LIBUNWIND_REMEMBER_FREE(_ptr) _freea(_ptr)
137#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED
138#else
139#define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size)
140#define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr)
141#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED
142#endif
143#else /* _LIBUNWIND_REMEMBER_HEAP_ALLOC */
144#define _LIBUNWIND_REMEMBER_ALLOC(_size) malloc(_size)
145#define _LIBUNWIND_REMEMBER_FREE(_ptr) free(_ptr)
146#define _LIBUNWIND_REMEMBER_CLEANUP_NEEDED
147#endif
148
149#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)
150#define _LIBUNWIND_ABORT(msg)                                                  \
151  do {                                                                         \
152    abort();                                                                   \
153  } while (0)
154#else
155#define _LIBUNWIND_ABORT(msg)                                                  \
156  do {                                                                         \
157    fprintf(stderr, "libunwind: %s - %s\n", __func__, msg);                    \
158    fflush(stderr);                                                            \
159    abort();                                                                   \
160  } while (0)
161#endif
162
163#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)
164#define _LIBUNWIND_LOG0(msg)
165#define _LIBUNWIND_LOG(msg, ...)
166#else
167#define _LIBUNWIND_LOG0(msg) do {                                              \
168    fprintf(stderr, "libunwind: " msg "\n");                                   \
169    fflush(stderr);                                                            \
170  } while (0)
171#define _LIBUNWIND_LOG(msg, ...) do {                                          \
172    fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__);                      \
173    fflush(stderr);                                                            \
174  } while (0)
175#endif
176
177#if defined(NDEBUG)
178  #define _LIBUNWIND_LOG_IF_FALSE(x) x
179#else
180  #define _LIBUNWIND_LOG_IF_FALSE(x)                                           \
181    do {                                                                       \
182      bool _ret = x;                                                           \
183      if (!_ret)                                                               \
184        _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__);                   \
185    } while (0)
186#endif
187
188// Macros that define away in non-Debug builds
189#ifdef NDEBUG
190  #define _LIBUNWIND_DEBUG_LOG(msg, ...)
191  #define _LIBUNWIND_TRACE_API(msg, ...)
192  #define _LIBUNWIND_TRACING_UNWINDING (0)
193  #define _LIBUNWIND_TRACING_DWARF (0)
194  #define _LIBUNWIND_TRACE_UNWINDING(msg, ...)
195  #define _LIBUNWIND_TRACE_DWARF(...)
196#else
197  #ifdef __cplusplus
198    extern "C" {
199  #endif
200    extern  bool logAPIs(void);
201    extern  bool logUnwinding(void);
202    extern  bool logDWARF(void);
203  #ifdef __cplusplus
204    }
205  #endif
206  #define _LIBUNWIND_DEBUG_LOG(msg, ...)  _LIBUNWIND_LOG(msg, __VA_ARGS__)
207  #define _LIBUNWIND_TRACE_API(msg, ...)                                       \
208    do {                                                                       \
209      if (logAPIs())                                                           \
210        _LIBUNWIND_LOG(msg, __VA_ARGS__);                                      \
211    } while (0)
212  #define _LIBUNWIND_TRACING_UNWINDING logUnwinding()
213  #define _LIBUNWIND_TRACING_DWARF logDWARF()
214  #define _LIBUNWIND_TRACE_UNWINDING(msg, ...)                                 \
215    do {                                                                       \
216      if (logUnwinding())                                                      \
217        _LIBUNWIND_LOG(msg, __VA_ARGS__);                                      \
218    } while (0)
219  #define _LIBUNWIND_TRACE_DWARF(...)                                          \
220    do {                                                                       \
221      if (logDWARF())                                                          \
222        fprintf(stderr, __VA_ARGS__);                                          \
223    } while (0)
224#endif
225
226#ifdef __cplusplus
227// Used to fit UnwindCursor and Registers_xxx types against unw_context_t /
228// unw_cursor_t sized memory blocks.
229#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
230# define COMP_OP ==
231#else
232# define COMP_OP <=
233#endif
234template <typename _Type, typename _Mem>
235struct check_fit {
236  template <typename T>
237  struct blk_count {
238    static const size_t count =
239      (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t);
240  };
241  static const bool does_fit =
242    (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count);
243};
244#undef COMP_OP
245#endif // __cplusplus
246
247#endif // LIBUNWIND_CONFIG_H