mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-21 16:12:47 -05:00
fix(exceptions): interpose libstdc++ ABI on Linux so the project's own unwinder drives it
On native Linux these PRX shared libraries and their test executables dynamically link real libstdc++/libgcc, so a plain throw went through the system's __cxa_throw/_Unwind_RaiseException. That still invoked this project's own __gxx_personality_v0_nid_postfix (the CIE's personality pointer is a raw function address, agnostic to which unwinder is walking the stack), but handed it libgcc's incompatible private _Unwind_Context layout, corrupting every field Personality.cpp reads and aborting with no exception message. Fix: OwnPersonality() now recognises the bare __gxx_personality_v0 wrapper on Linux too (previously Windows-only), and Exports.cpp exports the real ABI names (__cxa_throw, __cxa_begin_catch/end_catch, __cxa_rethrow, __cxa_allocate/free_exception, __cxa_call_terminate, __cxa_get_exception_ptr, __cxa_current_exception_type, __cxa_init_primary_exception, the std:: terminate/uncaught_exception(s) mangled names, and the core _Unwind_* entry points) via the existing GCC_GLOBAL_ALIAS assembler-alias mechanism, so ELF symbol interposition makes this project's own implementation win process-wide over libgcc_s.so.1/libstdc++.so.6. __cxa_init_primary_exception is newly implemented; GCC 13's inline std::make_exception_ptr needs it and nothing provided it before. Fixes 7 previously-aborting tests: guest_rendering_wait, guest_buffer_reuse, guest_shader_link, guest_system_exit_parameters, guest_once, guest_memory, guest_search. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1a0ebbc849
commit
a4c519b262
3 files changed
+33
-5
No files matched your search
@@ -20,9 +20,25 @@ GCC_GLOBAL_ALIAS(__cxa_end_catch_nid_no_patch_cut, __cxa_end_catch_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__cxa_rethrow_nid_no_patch_cut, __cxa_rethrow_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__gxx_personality_v0_nid_no_patch_cut, __gxx_personality_v0_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(_Unwind_Resume_nid_no_patch_cut, _Unwind_Resume_nid_postfix);
|
||||
GCC_LOCAL_ALIAS(__cxa_free_exception, __cxa_free_exception_nid_postfix);
|
||||
GCC_LOCAL_ALIAS(_ZSt9terminatev, _ZSt9terminatev_nid_postfix);
|
||||
GCC_LOCAL_ALIAS(__cxa_call_terminate, __cxa_call_terminate_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__cxa_free_exception, __cxa_free_exception_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(_ZSt9terminatev, _ZSt9terminatev_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__cxa_call_terminate, __cxa_call_terminate_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__cxa_allocate_exception, __cxa_allocate_exception_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__cxa_throw, __cxa_throw_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__cxa_init_primary_exception, __cxa_init_primary_exception_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__cxa_begin_catch, __cxa_begin_catch_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__cxa_end_catch, __cxa_end_catch_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__cxa_rethrow, __cxa_rethrow_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__cxa_get_exception_ptr, __cxa_get_exception_ptr_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(__cxa_current_exception_type, __cxa_current_exception_type_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(_ZSt13set_terminatePFvvE, _ZSt13set_terminatePFvvE_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(_ZSt13get_terminatev, _ZSt13get_terminatev_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(_ZSt18uncaught_exceptionv, __cxa_uncaught_exception_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(_ZSt19uncaught_exceptionsv, __cxa_uncaught_exceptions_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(_Unwind_Resume, _Unwind_Resume_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(_Unwind_RaiseException, _Unwind_RaiseException_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(_Unwind_Resume_or_Rethrow, _Unwind_Resume_or_Rethrow_nid_postfix);
|
||||
GCC_GLOBAL_ALIAS(_Unwind_DeleteException, _Unwind_DeleteException_nid_postfix);
|
||||
|
||||
#ifdef _WIN32
|
||||
extern "C" {
|
||||
|
||||
@@ -221,6 +221,18 @@ void APS5_VABI __cxa_free_exception_nid_postfix(void* object) {
|
||||
InvokeTerminate(header->terminate);
|
||||
}
|
||||
|
||||
LibcException::Header* __cxa_init_primary_exception_nid_postfix(void* object, std::type_info* type, void (*destructor)(void*)) {
|
||||
using namespace LibcException;
|
||||
auto* header = FromObject(object);
|
||||
header->type = type;
|
||||
header->destructor = destructor;
|
||||
header->terminate = terminateHandler.load(std::memory_order_acquire);
|
||||
header->adjusted = object;
|
||||
header->unwind.exception_class = PrimaryClass;
|
||||
header->unwind.exception_cleanup = Cleanup;
|
||||
return header;
|
||||
}
|
||||
|
||||
void* APS5_VABI __cxa_begin_catch_nid_postfix(void* exception) {
|
||||
using namespace LibcException;
|
||||
auto* unwind = static_cast<_Unwind_Exception*>(exception);
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#if defined(__linux__) || defined(_WIN32)
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) || defined(__linux__)
|
||||
extern "C" _Unwind_Reason_Code __gxx_personality_v0(int, _Unwind_Action, std::uint64_t, _Unwind_Exception*, _Unwind_Context*);
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,7 @@ bool OwnPersonality(Word personality) {
|
||||
}
|
||||
#endif
|
||||
if (personality == reinterpret_cast<Word>(__gxx_personality_v0_nid_postfix)) return true;
|
||||
#ifdef _WIN32
|
||||
#if defined(_WIN32) || defined(__linux__)
|
||||
if (personality == reinterpret_cast<Word>(__gxx_personality_v0)) return true;
|
||||
#endif
|
||||
return false;
|
||||
|
||||
Reference in new issue
Block a user