[libcxx-commits] [libcxxabi] f2a4360 - [libcxxabi] Insert padding in __cxa_exception struct for compatibility

Steven Wu via libcxx-commits libcxx-commits at lists.llvm.org
Thu Jan 30 10:04:02 PST 2020


Author: Steven Wu
Date: 2020-01-30T10:03:22-08:00
New Revision: f2a436058fcbc11291e73badb44e243f61046183

URL: https://github.com/llvm/llvm-project/commit/f2a436058fcbc11291e73badb44e243f61046183
DIFF: https://github.com/llvm/llvm-project/commit/f2a436058fcbc11291e73badb44e243f61046183.diff

LOG: [libcxxabi] Insert padding in __cxa_exception struct for compatibility

Summary:
Preserve the old ABI for __cxa_exception and __cxa_dependent_exception
on 64 bit platforms or ARM_EHABI platforms.

After r276215, libunwind in llvm-project labels _Unwind_Exception to be
double word aligned. That change implictly adds a padding before
unwindHeader field in __cxa_exception and __cxa_dependent_exception.
Preserve the same negative offsets in those struct by moving the padding
to the beginning of the field.

The assumption here is that if the ABI is not aware of the padding before
unwindHeader and put the referenceCount/primaryException in there, no padding
should exist before unwindHeader.

Reviewers: EricWF, mclow.lists, ldionne, jroelofs, dexonsmith, rjmccall, compnerd, phosek, ahatanak

Reviewed By: rjmccall

Subscribers: hans, smeenai, kristof.beyls, christof, jkorous, ributzka, libcxx-commits

Tags: #libc

Differential Revision: https://reviews.llvm.org/D72543

Added: 
    

Modified: 
    libcxxabi/src/cxa_exception.h

Removed: 
    


################################################################################
diff  --git a/libcxxabi/src/cxa_exception.h b/libcxxabi/src/cxa_exception.h
index c94621d56852..7e3a19fe2212 100644
--- a/libcxxabi/src/cxa_exception.h
+++ b/libcxxabi/src/cxa_exception.h
@@ -29,6 +29,11 @@ _LIBCXXABI_HIDDEN bool     __isOurExceptionClass(const _Unwind_Exception*);
 
 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 @@ struct _LIBCXXABI_HIDDEN __cxa_exception {
 // 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 @@ struct _LIBCXXABI_HIDDEN __cxa_dependent_exception {
     _Unwind_Exception unwindHeader;
 };
 
+// Verify the negative offsets of 
diff erent 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;


        


More information about the libcxx-commits mailing list