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 commits 0ee0dbfb0d and
d2b3fadf2d, 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 commit 3c4fd2463b
("libcxxrt: add padding in __cxa_allocate_* to fix alignment").

PR:		253840
This commit is contained in:
Dimitry Andric 2021-03-13 14:54:24 +01:00
parent 653ed678c7
commit 9097e3cbca
3 changed files with 28 additions and 13 deletions

View File

@ -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
* 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)
{
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);
return buffer+sizeof(__cxa_exception);
return buffer + exception_alignment_padding + sizeof(__cxa_exception);
}
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);
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)
@ -644,7 +661,8 @@ void __cxa_free_dependent_exception(void *thrown_exception)
{
releaseException(realExceptionFromException(reinterpret_cast<__cxa_exception*>(ex)));
}
free_exception(reinterpret_cast<char*>(ex));
free_exception(reinterpret_cast<char*>(ex) -
exception_alignment_padding);
}
/**

View File

@ -97,7 +97,7 @@ struct _Unwind_Exception
} pr_cache;
/** Force alignment of next item to 8-byte boundary */
long long int :0;
} __attribute__((__aligned__(8)));
};
/* Unwinding functions */
_Unwind_Reason_Code _Unwind_RaiseException(struct _Unwind_Exception *ucbp);

View File

@ -79,12 +79,9 @@ struct _Unwind_Exception
{
uint64_t exception_class;
_Unwind_Exception_Cleanup_Fn exception_cleanup;
uintptr_t private_1;
uintptr_t private_2;
#if __SIZEOF_POINTER__ == 4
uint32_t reserved[3];
#endif
} __attribute__((__aligned__));
unsigned long private_1;
unsigned long private_2;
} ;
extern _Unwind_Reason_Code _Unwind_RaiseException (struct _Unwind_Exception *);
extern _Unwind_Reason_Code _Unwind_ForcedUnwind (struct _Unwind_Exception *,