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   #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
42 #else
43   #if defined(__ARM_DWARF_EH__) || !defined(__arm__)
44     #define _LIBUNWIND_SUPPORT_DWARF_UNWIND 1
45     #define _LIBUNWIND_SUPPORT_DWARF_INDEX 1
46   #endif
47 #endif
48 
49 #if defined(_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS)
50   #define _LIBUNWIND_EXPORT
51   #define _LIBUNWIND_HIDDEN
52 #else
53   // FIXME: these macros are not correct for COFF targets
54   #define _LIBUNWIND_EXPORT __attribute__((visibility("default")))
55   #define _LIBUNWIND_HIDDEN __attribute__((visibility("hidden")))
56 #endif
57 
58 #if (defined(__APPLE__) && defined(__arm__)) || defined(__USING_SJLJ_EXCEPTIONS__)
59 #define _LIBUNWIND_BUILD_SJLJ_APIS
60 #endif
61 
62 #if defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ppc64__)
63 #define _LIBUNWIND_SUPPORT_FRAME_APIS
64 #endif
65 
66 #if defined(__i386__) || defined(__x86_64__) ||                                \
67     defined(__ppc__) || defined(__ppc64__) ||                                  \
68     (!defined(__APPLE__) && defined(__arm__)) ||                               \
69     (defined(__arm64__) || defined(__aarch64__)) ||                            \
70     (defined(__APPLE__) && defined(__mips__))
71 #define _LIBUNWIND_BUILD_ZERO_COST_APIS
72 #endif
73 
74 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)
75 #define _LIBUNWIND_ABORT(msg)                                                  \
76   do {                                                                         \
77     abort();                                                                   \
78   } while (0)
79 #else
80 #define _LIBUNWIND_ABORT(msg)                                                  \
81   do {                                                                         \
82     fprintf(stderr, "libunwind: %s %s:%d - %s\n", __func__, __FILE__,          \
83             __LINE__, msg);                                                    \
84     fflush(stderr);                                                            \
85     abort();                                                                   \
86   } while (0)
87 #endif
88 
89 #if defined(NDEBUG) && defined(_LIBUNWIND_IS_BAREMETAL)
90 #define _LIBUNWIND_LOG(msg, ...)
91 #else
92 #define _LIBUNWIND_LOG(msg, ...)                                               \
93   fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__)
94 #endif
95 
96 #if defined(NDEBUG)
97   #define _LIBUNWIND_LOG_IF_FALSE(x) x
98 #else
99   #define _LIBUNWIND_LOG_IF_FALSE(x)                                           \
100     do {                                                                       \
101       bool _ret = x;                                                           \
102       if (!_ret)                                                               \
103         _LIBUNWIND_LOG("" #x " failed in %s", __FUNCTION__);                   \
104     } while (0)
105 #endif
106 
107 // Macros that define away in non-Debug builds
108 #ifdef NDEBUG
109   #define _LIBUNWIND_DEBUG_LOG(msg, ...)
110   #define _LIBUNWIND_TRACE_API(msg, ...)
111   #define _LIBUNWIND_TRACING_UNWINDING (0)
112   #define _LIBUNWIND_TRACING_DWARF (0)
113   #define _LIBUNWIND_TRACE_UNWINDING(msg, ...)
114   #define _LIBUNWIND_TRACE_DWARF(...)
115 #else
116   #ifdef __cplusplus
117     extern "C" {
118   #endif
119     extern  bool logAPIs();
120     extern  bool logUnwinding();
121     extern  bool logDWARF();
122   #ifdef __cplusplus
123     }
124   #endif
125   #define _LIBUNWIND_DEBUG_LOG(msg, ...)  _LIBUNWIND_LOG(msg, __VA_ARGS__)
126   #define _LIBUNWIND_TRACE_API(msg, ...)                                       \
127     do {                                                                       \
128       if (logAPIs())                                                           \
129         _LIBUNWIND_LOG(msg, __VA_ARGS__);                                      \
130     } while (0)
131   #define _LIBUNWIND_TRACING_UNWINDING logUnwinding()
132   #define _LIBUNWIND_TRACING_DWARF logDWARF()
133   #define _LIBUNWIND_TRACE_UNWINDING(msg, ...)                                 \
134     do {                                                                       \
135       if (logUnwinding())                                                      \
136         _LIBUNWIND_LOG(msg, __VA_ARGS__);                                      \
137     } while (0)
138   #define _LIBUNWIND_TRACE_DWARF(...)                                          \
139     do {                                                                       \
140       if (logDWARF())                                                          \
141         fprintf(stderr, __VA_ARGS__);                                          \
142     } while (0)
143 #endif
144 
145 #ifdef __cplusplus
146 // Used to fit UnwindCursor and Registers_xxx types against unw_context_t /
147 // unw_cursor_t sized memory blocks.
148 #if defined(_LIBUNWIND_IS_NATIVE_ONLY)
149 # define COMP_OP ==
150 #else
151 # define COMP_OP <
152 #endif
153 template <typename _Type, typename _Mem>
154 struct check_fit {
155   template <typename T>
156   struct blk_count {
157     static const size_t count =
158       (sizeof(T) + sizeof(uint64_t) - 1) / sizeof(uint64_t);
159   };
160   static const bool does_fit =
161     (blk_count<_Type>::count COMP_OP blk_count<_Mem>::count);
162 };
163 #undef COMP_OP
164 #endif // __cplusplus
165 
166 #endif // LIBUNWIND_CONFIG_H
167