Index: libunwind/trunk/CMakeLists.txt =================================================================== --- libunwind/trunk/CMakeLists.txt +++ libunwind/trunk/CMakeLists.txt @@ -107,6 +107,7 @@ option(LIBUNWIND_ENABLE_STATIC "Build libunwind as a static library." ON) option(LIBUNWIND_ENABLE_CROSS_UNWINDING "Enable cross-platform unwinding support." OFF) option(LIBUNWIND_ENABLE_ARM_WMMX "Enable unwinding support for ARM WMMX registers." OFF) +option(LIBUNWIND_ENABLE_THREADS "Build libunwind with threading support." ON) set(LIBUNWIND_TARGET_TRIPLE "" CACHE STRING "Target triple for cross compiling.") set(LIBUNWIND_GCC_TOOLCHAIN "" CACHE PATH "GCC toolchain for cross compiling.") @@ -242,6 +243,11 @@ list(APPEND LIBUNWIND_COMPILE_FLAGS -D_LIBUNWIND_IS_NATIVE_ONLY) endif() +# Threading-support +if (NOT LIBUNWIND_ENABLE_THREADS) + list(APPEND LIBUNWIND_COMPILE_FLAGS -D_LIBUNWIND_HAS_NO_THREADS) +endif() + # ARM WMMX register support if (LIBUNWIND_ENABLE_ARM_WMMX) # __ARM_WMMX is a compiler pre-define (as per the ACLE 2.0). Clang does not Index: libunwind/trunk/src/CMakeLists.txt =================================================================== --- libunwind/trunk/src/CMakeLists.txt +++ libunwind/trunk/src/CMakeLists.txt @@ -53,7 +53,9 @@ set(libraries ${LIBUNWINDCXX_ABI_LIBRARIES}) append_if(libraries LIBUNWIND_HAS_C_LIB c) append_if(libraries LIBUNWIND_HAS_DL_LIB dl) -append_if(libraries LIBUNWIND_HAS_PTHREAD_LIB pthread) +if (LIBUNWIND_ENABLE_THREADS) + append_if(libraries LIBUNWIND_HAS_PTHREAD_LIB pthread) +endif() # Setup flags. append_if(LIBUNWIND_COMPILE_FLAGS LIBUNWIND_HAS_FPIC_FLAG -fPIC) Index: libunwind/trunk/src/UnwindCursor.hpp =================================================================== --- libunwind/trunk/src/UnwindCursor.hpp +++ libunwind/trunk/src/UnwindCursor.hpp @@ -16,7 +16,9 @@ #include #include #include -#include +#ifndef _LIBUNWIND_HAS_NO_THREADS + #include +#endif #include #ifdef __APPLE__ @@ -60,7 +62,9 @@ // These fields are all static to avoid needing an initializer. // There is only one instance of this class per process. +#ifndef _LIBUNWIND_HAS_NO_THREADS static pthread_rwlock_t _lock; +#endif #ifdef __APPLE__ static void dyldUnloadHook(const struct mach_header *mh, intptr_t slide); static bool _registeredForDyldUnloads; @@ -87,8 +91,10 @@ template typename DwarfFDECache::entry DwarfFDECache::_initialBuffer[64]; +#ifndef _LIBUNWIND_HAS_NO_THREADS template pthread_rwlock_t DwarfFDECache::_lock = PTHREAD_RWLOCK_INITIALIZER; +#endif #ifdef __APPLE__ template Index: libunwind/trunk/src/Unwind_AppleExtras.cpp =================================================================== --- libunwind/trunk/src/Unwind_AppleExtras.cpp +++ libunwind/trunk/src/Unwind_AppleExtras.cpp @@ -185,21 +185,29 @@ #if !defined(FOR_DYLD) && _LIBUNWIND_BUILD_SJLJ_APIS -#include +#ifndef _LIBUNWIND_HAS_NO_THREADS + #include +#else + _Unwind_FunctionContext *fc_ = nullptr; +#endif // Accessors to get get/set linked list of frames for sjlj based execeptions. _LIBUNWIND_HIDDEN struct _Unwind_FunctionContext *__Unwind_SjLj_GetTopOfFunctionStack() { +#ifndef _LIBUNWIND_HAS_NO_THREADS return (struct _Unwind_FunctionContext *) _pthread_getspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key); +#else + return fc_; +#endif } _LIBUNWIND_HIDDEN void __Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext *fc) { +#ifndef _LIBUNWIND_HAS_NO_THREADS _pthread_setspecific_direct(__PTK_LIBC_DYLD_Unwind_SjLj_Key, fc); +#else + fc_ = fc; +#endif } #endif - - - - Index: libunwind/trunk/src/config.h =================================================================== --- libunwind/trunk/src/config.h +++ libunwind/trunk/src/config.h @@ -85,13 +85,20 @@ } while (0) #define _LIBUNWIND_LOG(msg, ...) fprintf(stderr, "libunwind: " msg "\n", __VA_ARGS__) +#if defined(_LIBUNWIND_HAS_NO_THREADS) + // only used with pthread calls, not needed for the single-threaded builds + #define _LIBUNWIND_LOG_NON_ZERO(x) +#endif + // Macros that define away in non-Debug builds #ifdef NDEBUG #define _LIBUNWIND_DEBUG_LOG(msg, ...) #define _LIBUNWIND_TRACE_API(msg, ...) #define _LIBUNWIND_TRACING_UNWINDING 0 #define _LIBUNWIND_TRACE_UNWINDING(msg, ...) - #define _LIBUNWIND_LOG_NON_ZERO(x) x + #ifndef _LIBUNWIND_LOG_NON_ZERO + #define _LIBUNWIND_LOG_NON_ZERO(x) x + #endif #else #ifdef __cplusplus extern "C" { @@ -102,12 +109,14 @@ } #endif #define _LIBUNWIND_DEBUG_LOG(msg, ...) _LIBUNWIND_LOG(msg, __VA_ARGS__) - #define _LIBUNWIND_LOG_NON_ZERO(x) \ - do { \ - int _err = x; \ - if ( _err != 0 ) \ - _LIBUNWIND_LOG("" #x "=%d in %s", _err, __FUNCTION__); \ - } while (0) + #ifndef _LIBUNWIND_LOG_NON_ZERO + #define _LIBUNWIND_LOG_NON_ZERO(x) \ + do { \ + int _err = x; \ + if ( _err != 0 ) \ + _LIBUNWIND_LOG("" #x "=%d in %s", _err, __FUNCTION__); \ + } while (0) + #endif #define _LIBUNWIND_TRACE_API(msg, ...) \ do { \ if ( logAPIs() ) _LIBUNWIND_LOG(msg, __VA_ARGS__); \