From c22aa54e9977785eafcd7cc3811116e5f4dd2da8 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Tue, 1 Feb 2022 22:39:42 +0300 Subject: [PATCH] ntdll: Use .seh handler instead of __TRY in RtlUserThreadStart() on x64. --- dlls/ntdll/thread.c | 36 +++++++++++++++++++++++++++++++++++- include/wine/asm.h | 1 + 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 01733585a75..82a470271d9 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -285,7 +285,41 @@ void DECLSPEC_HIDDEN call_thread_func( PRTL_THREAD_START_ROUTINE entry, void *ar __ENDTRY } -#else /* __i386__ */ +#elif /* __i386__ */ defined(__x86_64__) && defined(__ASM_SEH_SUPPORTED) +EXCEPTION_DISPOSITION WINAPI call_thread_func_handler( EXCEPTION_RECORD *rec, ULONG64 frame, + CONTEXT *context, DISPATCHER_CONTEXT *dispatch ) +{ + EXCEPTION_POINTERS ep = { rec, context }; + + WARN( "Unhandled exception, calling filter.\n" ); + + switch (call_unhandled_exception_filter( &ep )) + { + case EXCEPTION_CONTINUE_SEARCH: + return ExceptionContinueSearch; + case EXCEPTION_CONTINUE_EXECUTION: + return ExceptionContinueExecution; + case EXCEPTION_EXECUTE_HANDLER: + break; + } + NtTerminateProcess( GetCurrentProcess(), rec->ExceptionCode ); + return ExceptionContinueExecution; +} + +extern void WINAPI RtlUserThreadStart( PRTL_THREAD_START_ROUTINE entry, void *arg ); +__ASM_GLOBAL_FUNC( RtlUserThreadStart, + "subq $0x28,%rsp\n\t" + ".seh_stackalloc 0x28\n\t" + ".seh_endprologue\n\t" + "movq %rdx,%r8\n\t" + "movq %rcx,%rdx\n\t" + "xorq %rcx,%rcx\n\t" + "movq " __ASM_NAME( "pBaseThreadInitThunk" ) "(%rip),%r9\n\t" + "call *%r9\n\t" + "int3\n\t" + ".seh_handler call_thread_func_handler, @except\n\t" ) + +#else /* defined(__x86_64__) && defined(__ASM_SEH_SUPPORTED) */ void WINAPI RtlUserThreadStart( PRTL_THREAD_START_ROUTINE entry, void *arg ) { diff --git a/include/wine/asm.h b/include/wine/asm.h index a158449d6a5..2a21bceb55e 100644 --- a/include/wine/asm.h +++ b/include/wine/asm.h @@ -54,6 +54,7 @@ # define __ASM_SEH(str) # else # define __ASM_SEH(str) str +# define __ASM_SEH_SUPPORTED # endif #else # define __ASM_SEH(str)