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