Partially revert libcxxrt changes to avoid _Unwind_Exception change
(Note I am also applying this to main and stable/13, to restore the old libcxxrt ABI and to avoid having to maintain a compat library.) After the recent cherry-picking of libcxxrt commits0ee0dbfb0d
andd2b3fadf2d
, users reported that editors/libreoffice packages from the official package builders did not start anymore. It turns out that the combination of these commits subtly changes the ABI, requiring all applications that depend on internal details of struct _Unwind_Exception (available via unwind-arm.h and unwind-itanium.h) to be recompiled. However, the FreeBSD package builders always use -RELEASE jails, so these still use the old declaration of struct _Unwind_Exception, which is not entirely compatible. In particular, LibreOffice uses this struct in its internal "uno bridge" component, where it attempts to setup its own exception handling mechanism. To fix this incompatibility, go back to the old declarations of struct _Unwind_Exception, and restore the __LP64__ specific workaround we had in place before (which was to cope with yet another, older ABI bug). Effectively, this reverts upstream libcxxrt commits 88bdf6b290da ("Specify double-word alignment for ARM unwind") and b96169641f79 ("Updated Itanium unwind"), and reapplies our commit3c4fd2463b
("libcxxrt: add padding in __cxa_allocate_* to fix alignment"). PR: 253840
This commit is contained in:
parent
653ed678c7
commit
9097e3cbca
@ -572,6 +572,19 @@ static void free_exception(char *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __LP64__
|
||||||
|
/**
|
||||||
|
* There's an ABI bug in __cxa_exception: unwindHeader requires 16-byte
|
||||||
|
* alignment but it was broken by the addition of the referenceCount.
|
||||||
|
* The unwindHeader is at offset 0x58 in __cxa_exception. In order to keep
|
||||||
|
* compatibility with consumers of the broken __cxa_exception, explicitly add
|
||||||
|
* padding on allocation (and account for it on free).
|
||||||
|
*/
|
||||||
|
static const int exception_alignment_padding = 8;
|
||||||
|
#else
|
||||||
|
static const int exception_alignment_padding = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates an exception structure. Returns a pointer to the space that can
|
* Allocates an exception structure. Returns a pointer to the space that can
|
||||||
* be used to store an object of thrown_size bytes. This function will use an
|
* be used to store an object of thrown_size bytes. This function will use an
|
||||||
@ -580,16 +593,19 @@ static void free_exception(char *e)
|
|||||||
*/
|
*/
|
||||||
extern "C" void *__cxa_allocate_exception(size_t thrown_size)
|
extern "C" void *__cxa_allocate_exception(size_t thrown_size)
|
||||||
{
|
{
|
||||||
size_t size = thrown_size + sizeof(__cxa_exception);
|
size_t size = exception_alignment_padding + sizeof(__cxa_exception) +
|
||||||
|
thrown_size;
|
||||||
char *buffer = alloc_or_die(size);
|
char *buffer = alloc_or_die(size);
|
||||||
return buffer+sizeof(__cxa_exception);
|
return buffer + exception_alignment_padding + sizeof(__cxa_exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" void *__cxa_allocate_dependent_exception(void)
|
extern "C" void *__cxa_allocate_dependent_exception(void)
|
||||||
{
|
{
|
||||||
size_t size = sizeof(__cxa_dependent_exception);
|
size_t size = exception_alignment_padding +
|
||||||
|
sizeof(__cxa_dependent_exception);
|
||||||
char *buffer = alloc_or_die(size);
|
char *buffer = alloc_or_die(size);
|
||||||
return buffer+sizeof(__cxa_dependent_exception);
|
return buffer + exception_alignment_padding +
|
||||||
|
sizeof(__cxa_dependent_exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -617,7 +633,8 @@ extern "C" void __cxa_free_exception(void *thrown_exception)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free_exception(reinterpret_cast<char*>(ex));
|
free_exception(reinterpret_cast<char*>(ex) -
|
||||||
|
exception_alignment_padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void releaseException(__cxa_exception *exception)
|
static void releaseException(__cxa_exception *exception)
|
||||||
@ -644,7 +661,8 @@ void __cxa_free_dependent_exception(void *thrown_exception)
|
|||||||
{
|
{
|
||||||
releaseException(realExceptionFromException(reinterpret_cast<__cxa_exception*>(ex)));
|
releaseException(realExceptionFromException(reinterpret_cast<__cxa_exception*>(ex)));
|
||||||
}
|
}
|
||||||
free_exception(reinterpret_cast<char*>(ex));
|
free_exception(reinterpret_cast<char*>(ex) -
|
||||||
|
exception_alignment_padding);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,7 +97,7 @@ struct _Unwind_Exception
|
|||||||
} pr_cache;
|
} pr_cache;
|
||||||
/** Force alignment of next item to 8-byte boundary */
|
/** Force alignment of next item to 8-byte boundary */
|
||||||
long long int :0;
|
long long int :0;
|
||||||
} __attribute__((__aligned__(8)));
|
};
|
||||||
|
|
||||||
/* Unwinding functions */
|
/* Unwinding functions */
|
||||||
_Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *ucbp);
|
_Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *ucbp);
|
||||||
|
@ -79,12 +79,9 @@ struct _Unwind_Exception
|
|||||||
{
|
{
|
||||||
uint64_t exception_class;
|
uint64_t exception_class;
|
||||||
_Unwind_Exception_Cleanup_Fn exception_cleanup;
|
_Unwind_Exception_Cleanup_Fn exception_cleanup;
|
||||||
uintptr_t private_1;
|
unsigned long private_1;
|
||||||
uintptr_t private_2;
|
unsigned long private_2;
|
||||||
#if __SIZEOF_POINTER__ == 4
|
} ;
|
||||||
uint32_t reserved[3];
|
|
||||||
#endif
|
|
||||||
} __attribute__((__aligned__));
|
|
||||||
|
|
||||||
extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
|
extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
|
||||||
extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
|
extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,
|
||||||
|
Loading…
Reference in New Issue
Block a user