Module: wine Branch: master Commit: 7a5e92124f95d5e2dd50e9862ea050f53573bbb0 URL: https://gitlab.winehq.org/wine/wine/-/commit/7a5e92124f95d5e2dd50e9862ea050f...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Jan 25 17:18:32 2024 +0100
ntdll: Use a .seh handler for nested exceptions.
---
dlls/ntdll/signal_arm.c | 38 ++++++++++++++++++++++++++++++++------ dlls/ntdll/signal_arm64.c | 27 +++++++++++++++++++++------ 2 files changed, 53 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index eb55b883e51..db8955387ae 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -304,6 +304,37 @@ static DWORD call_teb_unwind_handler( EXCEPTION_RECORD *rec, DISPATCHER_CONTEXT }
+/*********************************************************************** + * call_handler_wrapper + */ +#ifdef __WINE_PE_BUILD +extern DWORD WINAPI call_handler_wrapper( EXCEPTION_RECORD *rec, CONTEXT *context, DISPATCHER_CONTEXT *dispatch ); +__ASM_GLOBAL_FUNC( call_handler_wrapper, + "push {r4,lr}\n\t" + ".seh_save_regs {r4,lr}\n\t" + ".seh_endprologue\n\t" + ".seh_handler " __ASM_NAME("nested_exception_handler") ", %except\n\t" + "mov r3, r2\n\t" /* dispatch */ + "mov r2, r1\n\t" /* context */ + "ldr r1, [r3, #0x0c]\n\t" /* dispatch->EstablisherFrame */ + "ldr ip, [r3, #0x18]\n\t" /* dispatch->LanguageHandler */ + "blx ip\n\t" + "pop {r4,pc}\n\t" ) +#else +static DWORD call_handler_wrapper( EXCEPTION_RECORD *rec, CONTEXT *context, DISPATCHER_CONTEXT *dispatch ) +{ + EXCEPTION_REGISTRATION_RECORD frame; + DWORD res; + + frame.Handler = (PEXCEPTION_HANDLER)nested_exception_handler; + __wine_push_frame( &frame ); + res = dispatch->LanguageHandler( rec, (void *)dispatch->EstablisherFrame, context, dispatch ); + __wine_pop_frame( &frame ); + return res; +} +#endif + + /********************************************************************** * call_handler * @@ -311,19 +342,14 @@ static DWORD call_teb_unwind_handler( EXCEPTION_RECORD *rec, DISPATCHER_CONTEXT */ static DWORD call_handler( EXCEPTION_RECORD *rec, CONTEXT *context, DISPATCHER_CONTEXT *dispatch ) { - EXCEPTION_REGISTRATION_RECORD frame; DWORD res;
- frame.Handler = (PEXCEPTION_HANDLER)nested_exception_handler; - __wine_push_frame( &frame ); - TRACE( "calling handler %p (rec=%p, frame=0x%lx context=%p, dispatch=%p)\n", dispatch->LanguageHandler, rec, dispatch->EstablisherFrame, dispatch->ContextRecord, dispatch ); - res = dispatch->LanguageHandler( rec, (void *)dispatch->EstablisherFrame, context, dispatch ); + res = call_handler_wrapper( rec, context, dispatch ); TRACE( "handler at %p returned %lu\n", dispatch->LanguageHandler, res );
rec->ExceptionFlags &= EH_NONCONTINUABLE; - __wine_pop_frame( &frame ); return res; }
diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index 54a1612bd90..bc06aae5aec 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -335,6 +335,26 @@ static DWORD call_teb_unwind_handler( EXCEPTION_RECORD *rec, DISPATCHER_CONTEXT }
+/*********************************************************************** + * call_handler_wrapper + */ +extern DWORD WINAPI call_handler_wrapper( EXCEPTION_RECORD *rec, CONTEXT *context, DISPATCHER_CONTEXT *dispatch ); +__ASM_GLOBAL_FUNC( call_handler_wrapper, + "stp x29, x30, [sp, #-16]!\n\t" + ".seh_save_fplr_x 16\n\t" + "mov x29, sp\n\t" + ".seh_set_fp\n\t" + ".seh_endprologue\n\t" + ".seh_handler " __ASM_NAME("nested_exception_handler") ", @except\n\t" + "mov x3, x2\n\t" /* dispatch */ + "mov x2, x1\n\t" /* context */ + "ldr x1, [x3, #0x18]\n\t" /* dispatch->EstablisherFrame */ + "ldr x15, [x3, #0x30]\n\t" /* dispatch->LanguageHandler */ + "blr x15\n\t" + "ldp x29, x30, [sp], #16\n\t" + "ret" ) + + /********************************************************************** * call_handler * @@ -342,19 +362,14 @@ static DWORD call_teb_unwind_handler( EXCEPTION_RECORD *rec, DISPATCHER_CONTEXT */ static DWORD call_handler( EXCEPTION_RECORD *rec, CONTEXT *context, DISPATCHER_CONTEXT *dispatch ) { - EXCEPTION_REGISTRATION_RECORD frame; DWORD res;
- frame.Handler = (PEXCEPTION_HANDLER)nested_exception_handler; - __wine_push_frame( &frame ); - TRACE( "calling handler %p (rec=%p, frame=%I64x context=%p, dispatch=%p)\n", dispatch->LanguageHandler, rec, dispatch->EstablisherFrame, dispatch->ContextRecord, dispatch ); - res = dispatch->LanguageHandler( rec, (void *)dispatch->EstablisherFrame, context, dispatch ); + res = call_handler_wrapper( rec, context, dispatch ); TRACE( "handler at %p returned %lu\n", dispatch->LanguageHandler, res );
rec->ExceptionFlags &= EH_NONCONTINUABLE; - __wine_pop_frame( &frame ); return res; }