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