1 //===----------------------------- config.h -------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //
9 //  Defines macros used within libunwind project.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 
14 #ifndef LIBUNWIND_CONFIG_H
15 #define LIBUNWIND_CONFIG_H
16 
17 #include <assert.h>
18 #include <stdio.h>
19 #include <stdint.h>
20 #include <stdlib.h>
21 
22 // Define static_assert() unless already defined by compiler.
23 #ifndef __has_feature
24   #define __has_feature(__x) 0
25 #endif
26 #if !(__has_feature(cxx_static_assert)) && !defined(static_assert)
27   #define static_assert(__b, __m) \
28       extern int compile_time_assert_failed[ ( __b ) ? 1 : -1 ]  \
29                                                   __attribute__( ( unused ) );
30 #endif
31 
32 // Platform specific configuration defines.
33 #ifdef __APPLE__
34   #if defined(FOR_DYLD)
35     #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND
36   #else
37     #define _LIBUNWIND_SUPPORT_COMPACT_UNWIND
38     #define _LIBUNWIND_SUPPORT_DWARF_UNWIND   1
39   #endif
40 #elif defined(_WIN32)
41   #ifdef __SEH__
42     #define _LIBUNWIND_SUPPORT_SEH_UNWIND 1
43   #else
44     #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
45   #endif
46 #else
47   #if defined(__ARM_DWARF_EH__) || !defined(__arm__)
48     #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
49     #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1
50   #endif
51 #endif
52 
53 #if defined(_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS)
54   #define _LIBUNWIND_EXPORT
55   #define _LIBUNWIND_HIDDEN
56 #else
57   #if !defined(__ELF__) && !defined(__MACH__)
58     #define _LIBUNWIND_EXPORT __declspec(dllexport)
59     #define _LIBUNWIND_HIDDEN
60   #else
61     #define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
62     #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
63   #endif
64 #endif
65 
66 #if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__)
67 #define _LIBUNWIND_BUILD_SJLJ_APIS
68 #endif
69 
70 #if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__)
71 #define _LIBUNWIND_SUPPORT_FRAME_APIS
72 #endif
73 
74 #if defined(__i386__) || defined(__x86_64__) ||                                \
75     defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) ||        \
76     (!defined(__APPLE__) && defined(__arm__)) ||                               \
77     (defined(__arm64__) || defined(__aarch64__)) ||                            \
78     defined(__mips__)
79 #if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
80 #define _LIBUNWIND_BUILD_ZERO_COST_APIS
81 #endif
82 #endif
83 
84 #if defined(__powerpc64__) && defined(_ARCH_PWR8)
85 #define PPC64_HAS_VMX
86 #endif
87 
88 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)
89 #define _LIBUNWIND_ABORT(msg)                                                  \
90   do {                                                                         \
91     abort();                                                                   \
92   } while (0)
93 #else
94 #define _LIBUNWIND_ABORT(msg)                                                  \
95   do {                                                                         \
96     fprintf(stderr, "libunwind: %s %s:%d - %s\n", __func__, __FILE__,          \
97             __LINE__, msg);                                                    \
98     fflush(stderr);                                                            \
99     abort();                                                                   \
100   } while (0)
101 #endif
102 
103 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)
104 #define _LIBUNWIND_LOG0(msg)
105 #define _LIBUNWIND_LOG(msg, ...)
106 #else
107 #define _LIBUNWIND_LOG0(msg)                                               \
108   fprintf(stderr, "libunwind: " msg "\n")
109 #define _LIBUNWIND_LOG(msg, ...)                                               \
110   fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__)
111 #endif
112 
113 #if defined(NDEBUG)
114   #define _LIBUNWIND_LOG_IF_FALSE(x) x
115 #else
116   #define _LIBUNWIND_LOG_IF_FALSE(x)                                           \
117     do {                                                                       \
118       bool _ret = x;                                                           \
119       if (!_ret)                                                               \
120         _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__);                   \
121     } while (0)
122 #endif
123 
124 // Macros that define away in non-Debug builds
125 #ifdef NDEBUG
126   #define _LIBUNWIND_DEBUG_LOG(msg, ...)
127   #define _LIBUNWIND_TRACE_API(msg, ...)
128   #define _LIBUNWIND_TRACING_UNWINDING (0)
129   #define _LIBUNWIND_TRACING_DWARF (0)
130   #define _LIBUNWIND_TRACE_UNWINDING(msg, ...)
131   #define _LIBUNWIND_TRACE_DWARF(...)
132 #else
133   #ifdef __cplusplus
134     extern "C" {
135   #endif
136     extern  bool logAPIs();
137     extern  bool logUnwinding();
138     extern  bool logDWARF();
139   #ifdef __cplusplus
140     }
141   #endif
142   #define _LIBUNWIND_DEBUG_LOG(msg, ...)  _LIBUNWIND_LOG(msg, __VA_ARGS__)
143   #define _LIBUNWIND_TRACE_API(msg, ...)                                       \
144     do {                                                                       \
145       if (logAPIs())                                                           \
146         _LIBUNWIND_LOG(msg, __VA_ARGS__);                                      \
147     } while (0)
148   #define _LIBUNWIND_TRACING_UNWINDING logUnwinding()
149   #define _LIBUNWIND_TRACING_DWARF logDWARF()
150   #define _LIBUNWIND_TRACE_UNWINDING(msg, ...)                                 \
151     do {                                                                       \
152       if (logUnwinding())                                                      \
153         _LIBUNWIND_LOG(msg, __VA_ARGS__);                                      \
154     } while (0)
155   #define _LIBUNWIND_TRACE_DWARF(...)                                          \
156     do {                                                                       \
157       if (logDWARF())                                                          \
158         fprintf(stderr, __VA_ARGS__);                                          \
159     } while (0)
160 #endif
161 
162 #ifdef __cplusplus
163 // Used to fit UnwindCursor and Registers_xxx types against unw_context_t /
164 // unw_cursor_t sized memory blocks.
165 #if defined(_LIBUNWIND_IS_NATIVE_ONLY)
166 # define COMP_OP ==
167 #else
168 # define COMP_OP <=
169 #endif
170 template <typename _Type, typename _Mem>
171 struct check_fit {
172   template <typename T>
173   struct blk_count {
174     static const size_t count =
175       (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t);
176   };
177   static const bool does_fit =
178     (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count);
179 };
180 #undef COMP_OP
181 #endif // __cplusplus
182 
183 #endif // LIBUNWIND_CONFIG_H
184