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