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" __typeof(name) aliasname __attribute__((weak_import)) _LIBUNWIND_EXPORT;
74#elif defined(__ELF__)
75#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \
76 extern "C" __typeof(name) aliasname __attribute__((weak, alias(#name))) _LIBUNWIND_EXPORT;
77#elif defined(_WIN32)
78#if defined(__MINGW32__)
79#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \
80 extern "C" __typeof(name) aliasname __attribute__((alias(#name))) _LIBUNWIND_EXPORT;
81#else
82#define _LIBUNWIND_WEAK_ALIAS(name, aliasname) \
83 __pragma(comment(linker, "/alternatename:" SYMBOL_NAME(aliasname) "=" \
84 SYMBOL_NAME(name))) \
85 extern "C" __typeof(name) aliasname _LIBUNWIND_EXPORT;
86#endif
87#else
88#error Unsupported target
89#endif
90
91#if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__)
92#define _LIBUNWIND_BUILD_SJLJ_APIS
93#endif
94
95#if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__)
96#define _LIBUNWIND_SUPPORT_FRAME_APIS
97#endif
98
99#if defined(__i386__) || defined(__x86_64__) || \
100 defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) || \
101 (!defined(__APPLE__) && defined(__arm__)) || \
102 (defined(__arm64__) || defined(__aarch64__)) || \
103 defined(__mips__)
104#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
105#define _LIBUNWIND_BUILD_ZERO_COST_APIS
106#endif
107#endif
108
109#if defined(__powerpc64__) && defined(_ARCH_PWR8)
110#define PPC64_HAS_VMX
111#endif
112
113#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)
114#define _LIBUNWIND_ABORT(msg) \
115 do { \
116 abort(); \
117 } while (0)
118#else
119#define _LIBUNWIND_ABORT(msg) \
120 do { \
121 fprintf(stderr, "libunwind: %s %s:%d - %s\n", __func__, __FILE__, \
122 __LINE__, msg); \
123 fflush(stderr); \
124 abort(); \
125 } while (0)
126#endif
127
128#if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)
129#define _LIBUNWIND_LOG0(msg)
130#define _LIBUNWIND_LOG(msg, ...)
131#else
132#define _LIBUNWIND_LOG0(msg) \
133 fprintf(stderr, "libunwind: " msg "\n")
134#define _LIBUNWIND_LOG(msg, ...) \
135 fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__)
136#endif
137
138#if defined(NDEBUG)
139 #define _LIBUNWIND_LOG_IF_FALSE(x) x
140#else
141 #define _LIBUNWIND_LOG_IF_FALSE(x) \
142 do { \
143 bool _ret = x; \
144 if (!_ret) \
145 _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__); \
146 } while (0)
147#endif
148
149// Macros that define away in non-Debug builds
150#ifdef NDEBUG
151 #define _LIBUNWIND_DEBUG_LOG(msg, ...)
152 #define _LIBUNWIND_TRACE_API(msg, ...)
153 #define _LIBUNWIND_TRACING_UNWINDING (0)
154 #define _LIBUNWIND_TRACING_DWARF (0)
155 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...)
156 #define _LIBUNWIND_TRACE_DWARF(...)
157#else
158 #ifdef __cplusplus
159 extern "C" {
160 #endif
161 extern bool logAPIs();
162 extern bool logUnwinding();
163 extern bool logDWARF();
164 #ifdef __cplusplus
165 }
166 #endif
167 #define _LIBUNWIND_DEBUG_LOG(msg, ...) _LIBUNWIND_LOG(msg, __VA_ARGS__)
168 #define _LIBUNWIND_TRACE_API(msg, ...) \
169 do { \
170 if (logAPIs()) \
171 _LIBUNWIND_LOG(msg, __VA_ARGS__); \
172 } while (0)
173 #define _LIBUNWIND_TRACING_UNWINDING logUnwinding()
174 #define _LIBUNWIND_TRACING_DWARF logDWARF()
175 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) \
176 do { \
177 if (logUnwinding()) \
178 _LIBUNWIND_LOG(msg, __VA_ARGS__); \
179 } while (0)
180 #define _LIBUNWIND_TRACE_DWARF(...) \
181 do { \
182 if (logDWARF()) \
183 fprintf(stderr, __VA_ARGS__); \
184 } while (0)
185#endif
186
187#ifdef __cplusplus
188// Used to fit UnwindCursor and Registers_xxx types against unw_context_t /
189// unw_cursor_t sized memory blocks.
190#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
191# define COMP_OP ==
192#else
193# define COMP_OP <=
194#endif
195template <typename _Type, typename _Mem>
196struct check_fit {
197 template <typename T>
198 struct blk_count {
199 static const size_t count =
200 (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t);
201 };
202 static const bool does_fit =
203 (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count);
204};
205#undef COMP_OP
206#endif // __cplusplus
207
208#endif // LIBUNWIND_CONFIG_H
209