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