mclow.lists created this revision.
mclow.lists added a reviewer: EricWF.
Herald added subscribers: kristof.beyls, aemerson.
See https://bugs.llvm.org/show_bug.cgi?id=35945, which reports that libc++
doesn't build for the Raspberry PI.
The problem is that the exception class is defined as a `char[8]` in that
library, rather than `uint64_t`, as in other libraries.
Same size, same values, different type.
Solution: Pull the code to check the exception class into a routine, and memcpy
the field into a `uint64_t` and call the routine everywhere we were previously
checking directly.
https://reviews.llvm.org/D42242
Files:
src/cxa_default_handlers.cpp
src/cxa_exception.cpp
src/cxa_exception.hpp
src/cxa_handlers.cpp
src/cxa_personality.cpp
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))
{
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_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_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 ?
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits