Skip to content

Commit f2a4360

Browse files
[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
1 parent e44f4a8 commit f2a4360

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

libcxxabi/src/cxa_exception.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ _LIBCXXABI_HIDDEN bool __isOurExceptionClass(const _Unwind_Exception*);
2929

3030
struct _LIBCXXABI_HIDDEN __cxa_exception {
3131
#if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI)
32+
// Now _Unwind_Exception is marked with __attribute__((aligned)),
33+
// which implies __cxa_exception is also aligned. Insert padding
34+
// in the beginning of the struct, rather than before unwindHeader.
35+
void *reserve;
36+
3237
// This is a new field to support C++ 0x exception_ptr.
3338
// For binary compatibility it is at the start of this
3439
// struct which is prepended to the object thrown in
@@ -71,6 +76,7 @@ struct _LIBCXXABI_HIDDEN __cxa_exception {
7176
// primaryException instead of referenceCount.
7277
struct _LIBCXXABI_HIDDEN __cxa_dependent_exception {
7378
#if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI)
79+
void* reserve; // padding.
7480
void* primaryException;
7581
#endif
7682

@@ -100,6 +106,45 @@ struct _LIBCXXABI_HIDDEN __cxa_dependent_exception {
100106
_Unwind_Exception unwindHeader;
101107
};
102108

109+
// Verify the negative offsets of different fields.
110+
static_assert(sizeof(_Unwind_Exception) +
111+
offsetof(__cxa_exception, unwindHeader) ==
112+
sizeof(__cxa_exception),
113+
"unwindHeader has wrong negative offsets");
114+
static_assert(sizeof(_Unwind_Exception) +
115+
offsetof(__cxa_dependent_exception, unwindHeader) ==
116+
sizeof(__cxa_dependent_exception),
117+
"unwindHeader has wrong negative offsets");
118+
119+
#if defined(_LIBCXXABI_ARM_EHABI)
120+
static_assert(offsetof(__cxa_exception, propagationCount) +
121+
sizeof(_Unwind_Exception) + sizeof(void*) ==
122+
sizeof(__cxa_exception),
123+
"propagationCount has wrong negative offset");
124+
static_assert(offsetof(__cxa_dependent_exception, propagationCount) +
125+
sizeof(_Unwind_Exception) + sizeof(void*) ==
126+
sizeof(__cxa_dependent_exception),
127+
"propagationCount has wrong negative offset");
128+
#elif defined(__LP64__)
129+
static_assert(offsetof(__cxa_exception, adjustedPtr) +
130+
sizeof(_Unwind_Exception) + sizeof(void*) ==
131+
sizeof(__cxa_exception),
132+
"adjustedPtr has wrong negative offset");
133+
static_assert(offsetof(__cxa_dependent_exception, adjustedPtr) +
134+
sizeof(_Unwind_Exception) + sizeof(void*) ==
135+
sizeof(__cxa_dependent_exception),
136+
"adjustedPtr has wrong negative offset");
137+
#else
138+
static_assert(offsetof(__cxa_exception, referenceCount) +
139+
sizeof(_Unwind_Exception) + sizeof(void*) ==
140+
sizeof(__cxa_exception),
141+
"referenceCount has wrong negative offset");
142+
static_assert(offsetof(__cxa_dependent_exception, primaryException) +
143+
sizeof(_Unwind_Exception) + sizeof(void*) ==
144+
sizeof(__cxa_dependent_exception),
145+
"primaryException has wrong negative offset");
146+
#endif
147+
103148
struct _LIBCXXABI_HIDDEN __cxa_eh_globals {
104149
__cxa_exception * caughtExceptions;
105150
unsigned int uncaughtExceptions;

0 commit comments

Comments
 (0)