2022-11-21 15:32:11 -08:00
|
|
|
From ed725c78b5deb6c482a60ac26eda5f5d58ab531c Mon Sep 17 00:00:00 2001
|
2022-08-11 20:34:16 -07:00
|
|
|
From: Paul Gofman <pgofman@codeweavers.com>
|
|
|
|
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
|
2022-11-21 15:32:11 -08:00
|
|
|
index ac543338893..f2c7cad5675 100644
|
2022-08-11 20:34:16 -07:00
|
|
|
--- a/dlls/ntdll/signal_x86_64.c
|
|
|
|
+++ b/dlls/ntdll/signal_x86_64.c
|
2022-11-21 15:32:11 -08:00
|
|
|
@@ -348,15 +348,32 @@ __ASM_GLOBAL_FUNC( RtlCaptureContext,
|
2022-08-11 20:34:16 -07:00
|
|
|
"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
|
|
|
|
*
|
2022-11-21 15:32:11 -08:00
|
|
|
@@ -365,19 +382,19 @@ static DWORD __cdecl nested_exception_handler( EXCEPTION_RECORD *rec, EXCEPTION_
|
2022-08-11 20:34:16 -07:00
|
|
|
*/
|
|
|
|
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 );
|
2022-11-21 15:32:11 -08:00
|
|
|
TRACE_(seh)( "handler at %p returned %lu\n", dispatch->LanguageHandler, res );
|
2022-08-11 20:34:16 -07:00
|
|
|
|
|
|
|
rec->ExceptionFlags &= EH_NONCONTINUABLE;
|
|
|
|
- __wine_pop_frame( &frame );
|
|
|
|
+ if (res == ExceptionNestedException)
|
|
|
|
+ {
|
|
|
|
+ rec->ExceptionFlags |= EH_NESTED_CALL;
|
|
|
|
+ res = ExceptionContinueSearch;
|
|
|
|
+ }
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2022-11-21 15:32:11 -08:00
|
|
|
@@ -992,7 +1009,8 @@ PVOID WINAPI RtlVirtualUnwind( ULONG type, ULONG64 base, ULONG64 pc,
|
2022-08-11 20:34:16 -07:00
|
|
|
|
|
|
|
struct unwind_exception_frame
|
|
|
|
{
|
|
|
|
- EXCEPTION_REGISTRATION_RECORD frame;
|
|
|
|
+ BYTE dummy[0x28];
|
|
|
|
+ void *rip;
|
|
|
|
DISPATCHER_CONTEXT *dispatch;
|
|
|
|
};
|
|
|
|
|
2022-11-21 15:32:11 -08:00
|
|
|
@@ -1001,7 +1019,7 @@ struct unwind_exception_frame
|
2022-08-11 20:34:16 -07:00
|
|
|
*
|
|
|
|
* 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;
|
2022-11-21 15:32:11 -08:00
|
|
|
@@ -1021,27 +1039,36 @@ static DWORD __cdecl unwind_exception_handler( EXCEPTION_RECORD *rec, EXCEPTION_
|
2022-08-11 20:34:16 -07:00
|
|
|
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 );
|
2022-11-21 15:32:11 -08:00
|
|
|
TRACE( "handler %p returned %lx\n", dispatch->LanguageHandler, res );
|
2022-08-11 20:34:16 -07:00
|
|
|
|
|
|
|
- __wine_pop_frame( &frame.frame );
|
|
|
|
-
|
|
|
|
switch (res)
|
|
|
|
{
|
|
|
|
case ExceptionContinueSearch:
|
|
|
|
--
|
2022-11-21 15:32:11 -08:00
|
|
|
2.38.1
|
2022-08-11 20:34:16 -07:00
|
|
|
|