diff --git a/libcxxabi/src/cxa_exception.h b/libcxxabi/src/cxa_exception.h --- a/libcxxabi/src/cxa_exception.h +++ b/libcxxabi/src/cxa_exception.h @@ -29,6 +29,11 @@ struct _LIBCXXABI_HIDDEN __cxa_exception { #if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI) + // Now _Unwind_Exception is marked with __attribute__((aligned)), + // which implies __cxa_exception is also aligned. Insert padding + // in the beginning of the struct, rather than before unwindHeader. + void *reserve; + // This is a new field to support C++ 0x exception_ptr. // For binary compatibility it is at the start of this // struct which is prepended to the object thrown in @@ -71,6 +76,7 @@ // primaryException instead of referenceCount. struct _LIBCXXABI_HIDDEN __cxa_dependent_exception { #if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI) + void* reserve; // padding. void* primaryException; #endif @@ -100,6 +106,45 @@ _Unwind_Exception unwindHeader; }; +// Verify the negative offsets of different fields. +static_assert(sizeof(_Unwind_Exception) + + offsetof(__cxa_exception, unwindHeader) == + sizeof(__cxa_exception), + "unwindHeader has wrong negative offsets"); +static_assert(sizeof(_Unwind_Exception) + + offsetof(__cxa_dependent_exception, unwindHeader) == + sizeof(__cxa_dependent_exception), + "unwindHeader has wrong negative offsets"); + +#if defined(_LIBCXXABI_ARM_EHABI) +static_assert(offsetof(__cxa_exception, propagationCount) + + sizeof(_Unwind_Exception) + sizeof(void*) == + sizeof(__cxa_exception), + "propagationCount has wrong negative offset"); +static_assert(offsetof(__cxa_dependent_exception, propagationCount) + + sizeof(_Unwind_Exception) + sizeof(void*) == + sizeof(__cxa_dependent_exception), + "propagationCount has wrong negative offset"); +#elif defined(__LP64__) +static_assert(offsetof(__cxa_exception, adjustedPtr) + + sizeof(_Unwind_Exception) + sizeof(void*) == + sizeof(__cxa_exception), + "adjustedPtr has wrong negative offset"); +static_assert(offsetof(__cxa_dependent_exception, adjustedPtr) + + sizeof(_Unwind_Exception) + sizeof(void*) == + sizeof(__cxa_dependent_exception), + "adjustedPtr has wrong negative offset"); +#else +static_assert(offsetof(__cxa_exception, referenceCount) + + sizeof(_Unwind_Exception) + sizeof(void*) == + sizeof(__cxa_exception), + "referenceCount has wrong negative offset"); +static_assert(offsetof(__cxa_dependent_exception, primaryException) + + sizeof(_Unwind_Exception) + sizeof(void*) == + sizeof(__cxa_dependent_exception), + "primaryException has wrong negative offset"); +#endif + struct _LIBCXXABI_HIDDEN __cxa_eh_globals { __cxa_exception * caughtExceptions; unsigned int uncaughtExceptions;