Alexandre Julliard : wow64cpu: Implement BTCpuResetToConsistentState().

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


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

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

wow64cpu: Implement BTCpuResetToConsistentState().

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

---

 dlls/wow64cpu/cpu.c         | 76 ++++++++++++++++++++++++++++++++++++++++++++-
 dlls/wow64cpu/wow64cpu.spec |  2 +-
 2 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/dlls/wow64cpu/cpu.c b/dlls/wow64cpu/cpu.c
index da6fa42894c..3da5b78f55a 100644
--- a/dlls/wow64cpu/cpu.c
+++ b/dlls/wow64cpu/cpu.c
@@ -41,6 +41,9 @@ struct thunk_32to64
 
 static BYTE DECLSPEC_ALIGN(4096) code_buffer[0x1000];
 
+static USHORT cs64_sel;
+static USHORT ds64_sel;
+static USHORT fs32_sel;
 
 BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, void *reserved )
 {
@@ -48,6 +51,53 @@ BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, void *reserved )
     return TRUE;
 }
 
+/**********************************************************************
+ *           copy_context_64to32
+ *
+ * Copy a 64-bit context corresponding to an exception happening in 32-bit mode
+ * into the corresponding 32-bit context.
+ */
+static void copy_context_64to32( I386_CONTEXT *ctx32, DWORD flags, AMD64_CONTEXT *ctx64 )
+{
+    ctx32->ContextFlags = flags;
+    flags &= ~CONTEXT_i386;
+    if (flags & CONTEXT_I386_INTEGER)
+    {
+        ctx32->Eax = ctx64->Rax;
+        ctx32->Ebx = ctx64->Rbx;
+        ctx32->Ecx = ctx64->Rcx;
+        ctx32->Edx = ctx64->Rdx;
+        ctx32->Esi = ctx64->Rsi;
+        ctx32->Edi = ctx64->Rdi;
+    }
+    if (flags & CONTEXT_I386_CONTROL)
+    {
+        ctx32->Esp    = ctx64->Rsp;
+        ctx32->Ebp    = ctx64->Rbp;
+        ctx32->Eip    = ctx64->Rip;
+        ctx32->EFlags = ctx64->EFlags;
+        ctx32->SegCs  = ctx64->SegCs;
+        ctx32->SegSs  = ds64_sel;
+    }
+    if (flags & CONTEXT_I386_SEGMENTS)
+    {
+        ctx32->SegDs = ds64_sel;
+        ctx32->SegEs = ds64_sel;
+        ctx32->SegFs = fs32_sel;
+        ctx32->SegGs = ds64_sel;
+    }
+    if (flags & CONTEXT_I386_DEBUG_REGISTERS)
+    {
+        ctx32->Dr0 = ctx64->Dr0;
+        ctx32->Dr1 = ctx64->Dr1;
+        ctx32->Dr2 = ctx64->Dr2;
+        ctx32->Dr3 = ctx64->Dr3;
+        ctx32->Dr6 = ctx64->Dr6;
+        ctx32->Dr7 = ctx64->Dr7;
+    }
+    /* FIXME: floating point + xstate */
+}
+
 
 /**********************************************************************
  *           syscall_32to64
@@ -141,9 +191,13 @@ NTSTATUS WINAPI BTCpuProcessInit(void)
     }
 
     RtlCaptureContext( &context );
+    cs64_sel = context.SegCs;
+    ds64_sel = context.SegDs;
+    fs32_sel = context.SegFs;
+
     thunk->ljmp = 0xea;
     thunk->addr = PtrToUlong( syscall_32to64 );
-    thunk->cs   = context.SegCs;
+    thunk->cs   = cs64_sel;
     NtProtectVirtualMemory( GetCurrentProcess(), (void **)&thunk, &size, PAGE_EXECUTE_READ, &old_prot );
     return STATUS_SUCCESS;
 }
@@ -174,3 +228,23 @@ NTSTATUS WINAPI BTCpuSetContext( HANDLE thread, HANDLE process, void *unknown, I
 {
     return NtSetInformationThread( thread, ThreadWow64Context, ctx, sizeof(*ctx) );
 }
+
+
+/**********************************************************************
+ *           BTCpuResetToConsistentState  (wow64cpu.@)
+ */
+NTSTATUS WINAPI BTCpuResetToConsistentState( EXCEPTION_POINTERS *ptrs )
+{
+    CONTEXT *context = ptrs->ContextRecord;
+    I386_CONTEXT wow_context;
+
+    copy_context_64to32( &wow_context, CONTEXT_I386_ALL, context );
+    wow_context.EFlags &= ~(0x100|0x40000);
+    BTCpuSetContext( GetCurrentThread(), GetCurrentProcess(), NULL, &wow_context );
+
+    /* fixup context to pretend that we jumped to 64-bit mode */
+    context->Rip = (ULONG64)syscall_32to64;
+    context->SegCs = cs64_sel;
+    context->Rsp = context->R14;
+    return STATUS_SUCCESS;
+}
diff --git a/dlls/wow64cpu/wow64cpu.spec b/dlls/wow64cpu/wow64cpu.spec
index b86481563f2..d6c5a0bfee3 100644
--- a/dlls/wow64cpu/wow64cpu.spec
+++ b/dlls/wow64cpu/wow64cpu.spec
@@ -1,7 +1,7 @@
 @ stdcall BTCpuGetBopCode()
 @ stdcall BTCpuGetContext(long long ptr ptr)
 @ stdcall BTCpuProcessInit()
-#@ stub BTCpuResetToConsistentState
+@ stdcall BTCpuResetToConsistentState(ptr)
 @ stdcall BTCpuSetContext(long long ptr ptr)
 @ stdcall BTCpuSimulate()
 #@ stub BTCpuTurboThunkControl




More information about the wine-cvs mailing list