Home | History | Annotate | Download | only in src
      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