Alexandre Julliard : ntdll: Add support for dispatching exception from 32-bit code in Wow64 mode.

Alexandre Julliard julliard at winehq.org
Wed Dec 1 15:23:48 CST 2021


Module: wine
Branch: master
Commit: e5e857c290352f41ce48935c3925aba68e87e873
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=e5e857c290352f41ce48935c3925aba68e87e873

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Dec  1 11:27:51 2021 +0100

ntdll: Add support for dispatching exception from 32-bit code in Wow64 mode.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/loader.c             |  3 +++
 dlls/ntdll/ntdll_misc.h         |  1 +
 dlls/ntdll/signal_x86_64.c      | 25 ++++++++++++++++++++++++-
 dlls/ntdll/unix/signal_x86_64.c |  1 +
 4 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 3cc522af4d8..86aec79dbfc 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -3855,6 +3855,8 @@ static void load_global_options(void)
 
 static void (WINAPI *pWow64LdrpInitialize)( CONTEXT *ctx );
 
+void (WINAPI *pWow64PrepareForException)( EXCEPTION_RECORD *rec, CONTEXT *context ) = NULL;
+
 static void init_wow64( CONTEXT *context )
 {
     if (!imports_fixup_done)
@@ -3874,6 +3876,7 @@ static void init_wow64( CONTEXT *context )
         if (!(p ## name = RtlFindExportedRoutineByName( wow64, #name ))) ERR( "failed to load %s\n", #name )
 
         GET_PTR( Wow64LdrpInitialize );
+        GET_PTR( Wow64PrepareForException );
 #undef GET_PTR
         imports_fixup_done = TRUE;
     }
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 34af6b780cf..d7c5ade5bc1 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -52,6 +52,7 @@ extern void WINAPI LdrInitializeThunk(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR) DE
 extern NTSTATUS WINAPI KiUserExceptionDispatcher(EXCEPTION_RECORD*,CONTEXT*) DECLSPEC_HIDDEN;
 extern void WINAPI KiUserApcDispatcher(CONTEXT*,ULONG_PTR,ULONG_PTR,ULONG_PTR,PNTAPCFUNC) DECLSPEC_HIDDEN;
 extern void WINAPI KiUserCallbackDispatcher(ULONG,void*,ULONG) DECLSPEC_HIDDEN;
+extern void (WINAPI *pWow64PrepareForException)( EXCEPTION_RECORD *rec, CONTEXT *context ) DECLSPEC_HIDDEN;
 
 #if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
 extern RUNTIME_FUNCTION *lookup_function_info( ULONG_PTR pc, ULONG_PTR *base, LDR_DATA_TABLE_ENTRY **module ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index ef32eba68b7..e0372b111fd 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -566,12 +566,35 @@ NTSTATUS WINAPI dispatch_exception( EXCEPTION_RECORD *rec, CONTEXT *context )
 }
 
 
+NTSTATUS WINAPI dispatch_wow_exception( EXCEPTION_RECORD *rec_ptr, CONTEXT *context_ptr )
+{
+    char buffer[sizeof(CONTEXT) + sizeof(CONTEXT_EX) + sizeof(XSTATE) + 128];
+    CONTEXT *context;
+    CONTEXT_EX *context_ex;
+    EXCEPTION_RECORD rec = *rec_ptr;
+
+    RtlInitializeExtendedContext( buffer, context_ptr->ContextFlags, &context_ex );
+    context = RtlLocateLegacyContext( context_ex, NULL );
+    RtlCopyContext( context, context_ptr->ContextFlags, context_ptr );
+    pWow64PrepareForException( &rec, context );
+    return dispatch_exception( &rec, context );
+}
+
+
 /*******************************************************************
  *		KiUserExceptionDispatcher (NTDLL.@)
  */
 __ASM_GLOBAL_FUNC( KiUserExceptionDispatcher,
                   "mov 0x98(%rsp),%rcx\n\t" /* context->Rsp */
-                  "mov 0xf8(%rsp),%rdx\n\t" /* context->Rip */
+                  "movw %cs,%ax\n\t"
+                  "cmpw %ax,0x38(%rsp)\n\t" /* context->SegCs */
+                  "je 1f\n\t"
+                  "mov %rsp,%rdx\n\t" /* context */
+                  "lea 0x4f0(%rsp),%rcx\n\t" /* rec */
+                  "movq %r14,%rsp\n\t"  /* switch to 64-bit stack */
+                  "call " __ASM_NAME("dispatch_wow_exception") "\n\t"
+                  "int3\n"
+                  "1:\tmov 0xf8(%rsp),%rdx\n\t" /* context->Rip */
                   "mov %rdx,-0x8(%rcx)\n\t"
                   "mov %rbp,-0x10(%rcx)\n\t"
                   "mov %rdi,-0x18(%rcx)\n\t"
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 0085bd42410..9972faf799c 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -2171,6 +2171,7 @@ static void setup_raise_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec
         }
     }
 
+    CS_sig(sigcontext)  = cs64_sel;
     RIP_sig(sigcontext) = (ULONG_PTR)pKiUserExceptionDispatcher;
     RSP_sig(sigcontext) = (ULONG_PTR)stack;
     /* clear single-step, direction, and align check flag */




More information about the wine-cvs mailing list