Alexandre Julliard : wow64cpu: Restore the full 32-bit context when changed externally.
Alexandre Julliard
julliard at winehq.org
Wed Aug 4 16:41:37 CDT 2021
Module: wine
Branch: master
Commit: e30f091f3b2acbd133edb599a72b4bea381c0b55
URL: https://source.winehq.org/git/wine.git/?a=commit;h=e30f091f3b2acbd133edb599a72b4bea381c0b55
Author: Alexandre Julliard <julliard at winehq.org>
Date: Wed Aug 4 12:13:21 2021 +0200
wow64cpu: Restore the full 32-bit context when changed externally.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/unix/signal_x86_64.c | 3 +++
dlls/wow64cpu/cpu.c | 40 +++++++++++++++++++++++++++++++++++++++-
dlls/wow64cpu/wow64cpu.spec | 4 ++--
include/winternl.h | 2 ++
4 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index bfc5b34a464..d02a7946945 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -1957,12 +1957,15 @@ NTSTATUS set_thread_wow64_context( HANDLE handle, const void *ctx, ULONG size )
}
if (flags & CONTEXT_I386_CONTROL)
{
+ WOW64_CPURESERVED *cpu = NtCurrentTeb()->TlsSlots[WOW64_TLS_CPURESERVED];
+
wow_frame->Esp = context->Esp;
wow_frame->Ebp = context->Ebp;
wow_frame->Eip = context->Eip;
wow_frame->EFlags = context->EFlags;
wow_frame->SegCs = cs32_sel;
wow_frame->SegSs = ds64_sel;
+ cpu->Flags |= WOW64_CPURESERVED_FLAG_RESET_STATE;
}
if (flags & CONTEXT_I386_SEGMENTS)
{
diff --git a/dlls/wow64cpu/cpu.c b/dlls/wow64cpu/cpu.c
index df292221117..8293d596ec4 100644
--- a/dlls/wow64cpu/cpu.c
+++ b/dlls/wow64cpu/cpu.c
@@ -82,13 +82,33 @@ __ASM_GLOBAL_FUNC( syscall_32to64,
"movl 0xa0(%r13),%esi\n\t" /* context->Esi */
"movl 0xa4(%r13),%ebx\n\t" /* context->Ebx */
"movl 0xb4(%r13),%ebp\n\t" /* context->Ebp */
+ "btrl $0,-4(%r13)\n\t" /* cpu->Flags & WOW64_CPURESERVED_FLAG_RESET_STATE */
+ "jc 1f\n\t"
"movl 0xb8(%r13),%edx\n\t" /* context->Eip */
"movl %edx,(%rsp)\n\t"
"movl 0xbc(%r13),%edx\n\t" /* context->SegCs */
"movl %edx,4(%rsp)\n\t"
"movl 0xc4(%r13),%r14d\n\t" /* context->Esp */
"xchgq %r14,%rsp\n\t"
- "ljmp *(%r14)" )
+ "ljmp *(%r14)\n"
+ "1:\tmovq %rsp,%r14\n\t"
+ "movl 0xa8(%r13),%edx\n\t" /* context->Edx */
+ "movl 0xac(%r13),%ecx\n\t" /* context->Ecx */
+ "movl 0xc8(%r13),%eax\n\t" /* context->SegSs */
+ "movq %rax,0x20(%rsp)\n\t"
+ "mov %ax,%ds\n\t"
+ "mov %ax,%es\n\t"
+ "mov 0x90(%r13),%fs\n\t" /* context->SegFs */
+ "movl 0xc4(%r13),%eax\n\t" /* context->Esp */
+ "movq %rax,0x18(%rsp)\n\t"
+ "movl 0xc0(%r13),%eax\n\t" /* context->EFlags */
+ "movq %rax,0x10(%rsp)\n\t"
+ "movl 0xbc(%r13),%eax\n\t" /* context->SegCs */
+ "movq %rax,0x8(%rsp)\n\t"
+ "movl 0xb8(%r13),%eax\n\t" /* context->Eip */
+ "movq %rax,(%rsp)\n\t"
+ "movl 0xb0(%r13),%eax\n\t" /* context->Eax */
+ "iretq" )
/**********************************************************************
@@ -137,3 +157,21 @@ void * WINAPI BTCpuGetBopCode(void)
{
return code_buffer;
}
+
+
+/**********************************************************************
+ * BTCpuGetContext (wow64cpu.@)
+ */
+NTSTATUS WINAPI BTCpuGetContext( HANDLE thread, HANDLE process, void *unknown, I386_CONTEXT *ctx )
+{
+ return NtQueryInformationThread( thread, ThreadWow64Context, ctx, sizeof(*ctx), NULL );
+}
+
+
+/**********************************************************************
+ * BTCpuSetContext (wow64cpu.@)
+ */
+NTSTATUS WINAPI BTCpuSetContext( HANDLE thread, HANDLE process, void *unknown, I386_CONTEXT *ctx )
+{
+ return NtSetInformationThread( thread, ThreadWow64Context, ctx, sizeof(*ctx) );
+}
diff --git a/dlls/wow64cpu/wow64cpu.spec b/dlls/wow64cpu/wow64cpu.spec
index ba0abb7a8ed..b86481563f2 100644
--- a/dlls/wow64cpu/wow64cpu.spec
+++ b/dlls/wow64cpu/wow64cpu.spec
@@ -1,8 +1,8 @@
@ stdcall BTCpuGetBopCode()
-#@ stub BTCpuGetContext
+@ stdcall BTCpuGetContext(long long ptr ptr)
@ stdcall BTCpuProcessInit()
#@ stub BTCpuResetToConsistentState
-#@ stub BTCpuSetContext
+@ stdcall BTCpuSetContext(long long ptr ptr)
@ stdcall BTCpuSimulate()
#@ stub BTCpuTurboThunkControl
#@ stub TurboDispatchJumpAddressEnd
diff --git a/include/winternl.h b/include/winternl.h
index 9dff3a98bed..a048b9546ee 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -3727,6 +3727,8 @@ typedef struct _WOW64_CPURESERVED
/* CONTEXT_EX *context_ex */
} WOW64_CPURESERVED, *PWOW64_CPURESERVED;
+#define WOW64_CPURESERVED_FLAG_RESET_STATE 1
+
typedef struct _WOW64_CPU_AREA_INFO
{
void *Context;
More information about the wine-cvs
mailing list