Index: src/cxa_default_handlers.cpp =================================================================== --- src/cxa_default_handlers.cpp +++ src/cxa_default_handlers.cpp @@ -35,10 +35,7 @@ { _Unwind_Exception* unwind_exception = reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; - bool native_exception = - (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); - if (native_exception) + if (__isOurExceptionClass(unwind_exception)) { void* thrown_object = unwind_exception->exception_class == kOurDependentExceptionClass ? Index: src/cxa_exception.hpp =================================================================== --- src/cxa_exception.hpp +++ src/cxa_exception.hpp @@ -24,6 +24,8 @@ static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1 static const uint64_t get_vendor_and_language = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++ +bool __isOurExceptionClass(const _Unwind_Exception*); + struct _LIBCXXABI_HIDDEN __cxa_exception { #if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI) // This is a new field to support C++ 0x exception_ptr. Index: src/cxa_exception.cpp =================================================================== --- src/cxa_exception.cpp +++ src/cxa_exception.cpp @@ -87,9 +87,15 @@ } // Is it one of ours? -static bool isOurExceptionClass(const _Unwind_Exception* unwind_exception) { - return (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); +bool __isOurExceptionClass(const _Unwind_Exception* unwind_exception) { +// On x86 and some ARM unwinders, unwind_exception->exception_class is +// a uint64_t. On other ARM unwinders, it is a char[8] +// See: http://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf +// So we just copy it into a uint64_t to be sure. + uint64_t exClass; + ::memcpy(&exClass, &unwind_exception->exception_class, sizeof(exClass)); + return (exClass & get_vendor_and_language) == + (kOurExceptionClass & get_vendor_and_language); } static bool isDependentException(_Unwind_Exception* unwind_exception) { @@ -299,7 +305,7 @@ __cxa_exception* exception_header = cxa_exception_from_exception_unwind_exception(unwind_exception); - if (isOurExceptionClass(unwind_exception)) + if (__isOurExceptionClass(unwind_exception)) { if (0 == exception_header->propagationCount) { @@ -342,7 +348,7 @@ std::terminate(); } - if (isOurExceptionClass(&exception_header->unwindHeader)) + if (__isOurExceptionClass(&exception_header->unwindHeader)) { --exception_header->propagationCount; if (0 == exception_header->propagationCount) @@ -407,7 +413,7 @@ __cxa_begin_catch(void* unwind_arg) throw() { _Unwind_Exception* unwind_exception = static_cast<_Unwind_Exception*>(unwind_arg); - bool native_exception = isOurExceptionClass(unwind_exception); + bool native_exception = __isOurExceptionClass(unwind_exception); __cxa_eh_globals* globals = __cxa_get_globals(); // exception_header is a hackish offset from a foreign exception, but it // works as long as we're careful not to try to access any __cxa_exception @@ -484,7 +490,7 @@ // nothing more to be done. Do nothing! if (NULL != exception_header) { - bool native_exception = isOurExceptionClass(&exception_header->unwindHeader); + bool native_exception = __isOurExceptionClass(&exception_header->unwindHeader); if (native_exception) { // This is a native exception @@ -549,7 +555,7 @@ __cxa_exception *exception_header = globals->caughtExceptions; if (NULL == exception_header) return NULL; // No current exception - if (!isOurExceptionClass(&exception_header->unwindHeader)) + if (!__isOurExceptionClass(&exception_header->unwindHeader)) return NULL; return exception_header->exceptionType; } @@ -571,7 +577,7 @@ __cxa_exception* exception_header = globals->caughtExceptions; if (NULL == exception_header) std::terminate(); // throw; called outside of a exception handler - bool native_exception = isOurExceptionClass(&exception_header->unwindHeader); + bool native_exception = __isOurExceptionClass(&exception_header->unwindHeader); if (native_exception) { // Mark the exception as being rethrown (reverse the effects of __cxa_begin_catch) @@ -660,7 +666,7 @@ __cxa_exception* exception_header = globals->caughtExceptions; if (NULL == exception_header) return NULL; // No current exception - if (!isOurExceptionClass(&exception_header->unwindHeader)) + if (!__isOurExceptionClass(&exception_header->unwindHeader)) return NULL; // Can't capture a foreign exception (no way to refcount it) if (isDependentException(&exception_header->unwindHeader)) { __cxa_dependent_exception* dep_exception_header = Index: src/cxa_handlers.cpp =================================================================== --- src/cxa_handlers.cpp +++ src/cxa_handlers.cpp @@ -89,10 +89,7 @@ { _Unwind_Exception* unwind_exception = reinterpret_cast<_Unwind_Exception*>(exception_header + 1) - 1; - bool native_exception = - (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); - if (native_exception) + if (__isOurExceptionClass(unwind_exception)) __terminate(exception_header->terminateHandler); } } Index: src/cxa_personality.cpp =================================================================== --- src/cxa_personality.cpp +++ src/cxa_personality.cpp @@ -1073,8 +1073,7 @@ if (unwind_exception == 0 || context == 0) return _URC_FATAL_PHASE1_ERROR; - bool native_exception = (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); + bool native_exception = __isOurExceptionClass(unwind_exception); #if !defined(LIBCXXABI_USE_LLVM_UNWINDER) // Copy the address of _Unwind_Control_Block to r12 so that @@ -1178,9 +1177,7 @@ if (unwind_exception == 0) call_terminate(false, unwind_exception); __cxa_begin_catch(unwind_exception); - bool native_old_exception = - (unwind_exception->exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); + bool native_old_exception = __isOurExceptionClass(unwind_exception); std::unexpected_handler u_handler; std::terminate_handler t_handler; __cxa_exception* old_exception_header = 0; @@ -1242,9 +1239,7 @@ if (new_exception_header == 0) // This shouldn't be able to happen! std::__terminate(t_handler); - bool native_new_exception = - (new_exception_header->unwindHeader.exception_class & get_vendor_and_language) == - (kOurExceptionClass & get_vendor_and_language); + bool native_new_exception = __isOurExceptionClass(&new_exception_header->unwindHeader); void* adjustedPtr; if (native_new_exception && (new_exception_header != old_exception_header)) {