diff --git a/patches/ntdll-wine-frames/0001-ntdll-Don-t-use-Wine-frames-during-exception-process.patch b/patches/ntdll-wine-frames/0001-ntdll-Don-t-use-Wine-frames-during-exception-process.patch new file mode 100644 index 00000000..cb0ec283 --- /dev/null +++ b/patches/ntdll-wine-frames/0001-ntdll-Don-t-use-Wine-frames-during-exception-process.patch @@ -0,0 +1,144 @@ +From b2c573c7d371f760d92b7490fd1aca002e2f18c6 Mon Sep 17 00:00:00 2001 +From: Paul Gofman +Date: Tue, 26 Oct 2021 19:07:26 +0300 +Subject: [PATCH] ntdll: Don't use Wine frames during exception processing on + x64. + +CW-Bug-ID: #19570 +--- + dlls/ntdll/signal_x86_64.c | 65 +++++++++++++++++++++++++++----------- + 1 file changed, 46 insertions(+), 19 deletions(-) + +diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c +index b1ab4933b93..3d163fbc6ea 100644 +--- a/dlls/ntdll/signal_x86_64.c ++++ b/dlls/ntdll/signal_x86_64.c +@@ -347,15 +347,32 @@ __ASM_GLOBAL_FUNC( RtlCaptureContext, + "fxsave 0x100(%rcx)\n\t" /* context->FltSave */ + "ret" ); + +-static DWORD __cdecl nested_exception_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, ++DWORD __cdecl nested_exception_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, + CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) + { ++ TRACE( "exception flags %#x.\n", rec->ExceptionFlags ); ++ + if (!(rec->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))) +- rec->ExceptionFlags |= EH_NESTED_CALL; ++ return ExceptionNestedException; + + return ExceptionContinueSearch; + } + ++/*********************************************************************** ++ * exception_handler_call_wrapper ++ */ ++DWORD exception_handler_call_wrapper( EXCEPTION_RECORD *rec, void *frame, ++ CONTEXT *context, DISPATCHER_CONTEXT *dispatch ); ++__ASM_GLOBAL_FUNC( exception_handler_call_wrapper, ++ __ASM_SEH(".seh_endprologue\n\t") ++ "subq $0x28, %rsp\n\t" ++ __ASM_SEH(".seh_stackalloc 0x28\n\t") ++ __ASM_SEH(".seh_handler nested_exception_handler, @except\n\t") ++ "callq *0x30(%r9)\n\t" /* dispatch->LanguageHandler */ ++ "nop\n\t" ++ "addq $0x28, %rsp\n\t" ++ "ret" ); ++ + /********************************************************************** + * call_handler + * +@@ -364,19 +381,19 @@ static DWORD __cdecl nested_exception_handler( EXCEPTION_RECORD *rec, EXCEPTION_ + */ + static DWORD call_handler( EXCEPTION_RECORD *rec, CONTEXT *context, DISPATCHER_CONTEXT *dispatch ) + { +- EXCEPTION_REGISTRATION_RECORD frame; + DWORD res; + +- frame.Handler = nested_exception_handler; +- __wine_push_frame( &frame ); +- + TRACE_(seh)( "calling handler %p (rec=%p, frame=%p context=%p, dispatch=%p)\n", + dispatch->LanguageHandler, rec, (void *)dispatch->EstablisherFrame, dispatch->ContextRecord, dispatch ); +- res = dispatch->LanguageHandler( rec, (void *)dispatch->EstablisherFrame, context, dispatch ); ++ res = exception_handler_call_wrapper( rec, (void *)dispatch->EstablisherFrame, context, dispatch ); + TRACE_(seh)( "handler at %p returned %u\n", dispatch->LanguageHandler, res ); + + rec->ExceptionFlags &= EH_NONCONTINUABLE; +- __wine_pop_frame( &frame ); ++ if (res == ExceptionNestedException) ++ { ++ rec->ExceptionFlags |= EH_NESTED_CALL; ++ res = ExceptionContinueSearch; ++ } + return res; + } + +@@ -990,7 +1007,8 @@ PVOID WINAPI RtlVirtualUnwind( ULONG type, ULONG64 base, ULONG64 pc, + + struct unwind_exception_frame + { +- EXCEPTION_REGISTRATION_RECORD frame; ++ BYTE dummy[0x28]; ++ void *rip; + DISPATCHER_CONTEXT *dispatch; + }; + +@@ -999,7 +1017,7 @@ struct unwind_exception_frame + * + * Handler for exceptions happening while calling an unwind handler. + */ +-static DWORD __cdecl unwind_exception_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, ++DWORD __cdecl unwind_exception_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame, + CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher ) + { + struct unwind_exception_frame *unwind_frame = (struct unwind_exception_frame *)frame; +@@ -1019,27 +1037,36 @@ static DWORD __cdecl unwind_exception_handler( EXCEPTION_RECORD *rec, EXCEPTION_ + return ExceptionCollidedUnwind; + } + ++/*********************************************************************** ++ * exception_handler_call_wrapper ++ */ ++DWORD unwind_handler_call_wrapper( EXCEPTION_RECORD *rec, void *frame, ++ CONTEXT *context, DISPATCHER_CONTEXT *dispatch ); ++__ASM_GLOBAL_FUNC( unwind_handler_call_wrapper, ++ __ASM_SEH(".seh_endprologue\n\t") ++ "movq %r9, 0x8(%rsp)\n\t" ++ "subq $0x28, %rsp\n\t" ++ __ASM_SEH(".seh_stackalloc 0x28\n\t") ++ __ASM_SEH(".seh_handler unwind_exception_handler, @except, @unwind\n\t") ++ "callq *0x30(%r9)\n\t" /* dispatch->LanguageHandler */ ++ "nop\n\t" ++ "addq $0x28, %rsp\n\t" ++ "ret" ); ++ + /********************************************************************** + * call_unwind_handler + * + * Call a single unwind handler. + */ +-static DWORD call_unwind_handler( EXCEPTION_RECORD *rec, DISPATCHER_CONTEXT *dispatch ) ++DWORD call_unwind_handler( EXCEPTION_RECORD *rec, DISPATCHER_CONTEXT *dispatch ) + { +- struct unwind_exception_frame frame; + DWORD res; + +- frame.frame.Handler = unwind_exception_handler; +- frame.dispatch = dispatch; +- __wine_push_frame( &frame.frame ); +- + TRACE( "calling handler %p (rec=%p, frame=%p context=%p, dispatch=%p)\n", + dispatch->LanguageHandler, rec, (void *)dispatch->EstablisherFrame, dispatch->ContextRecord, dispatch ); +- res = dispatch->LanguageHandler( rec, (void *)dispatch->EstablisherFrame, dispatch->ContextRecord, dispatch ); ++ res = unwind_handler_call_wrapper( rec, (void *)dispatch->EstablisherFrame, dispatch->ContextRecord, dispatch ); + TRACE( "handler %p returned %x\n", dispatch->LanguageHandler, res ); + +- __wine_pop_frame( &frame.frame ); +- + switch (res) + { + case ExceptionContinueSearch: +-- +2.35.1 + diff --git a/patches/ntdll-wine-frames/definition b/patches/ntdll-wine-frames/definition new file mode 100644 index 00000000..829cfb0a --- /dev/null +++ b/patches/ntdll-wine-frames/definition @@ -0,0 +1 @@ +Fixes: [52396] ntdll: Don't use Wine frames during exception processing on x64. diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index bdf7d3e7..6bd06dd9 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -51,7 +51,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "8e27f6c2ef327d6d643e29a271245e76aa6f4792" + echo "b5becc2ee8b70753b9fc538cfdd92c2b4be5911c" } # Show version information @@ -150,6 +150,7 @@ patch_enable_all () enable_ntdll_Syscall_Emulation="$1" enable_ntdll_WRITECOPY="$1" enable_ntdll_ext4_case_folder="$1" + enable_ntdll_wine_frames="$1" enable_nvapi_Stub_DLL="$1" enable_nvcuda_CUDA_Support="$1" enable_nvcuvid_CUDA_Video_Support="$1" @@ -472,6 +473,9 @@ patch_enable () ntdll-ext4-case-folder) enable_ntdll_ext4_case_folder="$2" ;; + ntdll-wine-frames) + enable_ntdll_wine_frames="$2" + ;; nvapi-Stub_DLL) enable_nvapi_Stub_DLL="$2" ;; @@ -2384,6 +2388,18 @@ if test "$enable_ntdll_ext4_case_folder" -eq 1; then patch_apply ntdll-ext4-case-folder/0002-ntdll-server-Mark-drive_c-as-case-insensitive-when-c.patch fi +# Patchset ntdll-wine-frames +# | +# | This patchset fixes the following Wine bugs: +# | * [#52396] ntdll: Don't use Wine frames during exception processing on x64. +# | +# | Modified files: +# | * dlls/ntdll/signal_x86_64.c +# | +if test "$enable_ntdll_wine_frames" -eq 1; then + patch_apply ntdll-wine-frames/0001-ntdll-Don-t-use-Wine-frames-during-exception-process.patch +fi + # Patchset nvcuda-CUDA_Support # | # | This patchset fixes the following Wine bugs: