Alexandre Julliard : ntdll: Add a helper function to retrieve the CPU area context on the Unix side.

Alexandre Julliard julliard at winehq.org
Thu Jul 1 15:53:49 CDT 2021


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu Jul  1 11:16:27 2021 +0200

ntdll: Add a helper function to retrieve the CPU area context on the Unix side.

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

---

 dlls/ntdll/unix/signal_arm.c   |  6 +-----
 dlls/ntdll/unix/signal_i386.c  |  6 +-----
 dlls/ntdll/unix/thread.c       | 29 +++++++++++++++++++++++++++++
 dlls/ntdll/unix/unix_private.h |  1 +
 4 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index e3ad240c718..a86805b113c 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -921,11 +921,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
     context.Sp = (DWORD)teb->Tib.StackBase;
     context.Pc = (DWORD)pRtlUserThreadStart;
     if (context.Pc & 1) context.Cpsr |= 0x20; /* thumb mode */
-    if (NtCurrentTeb64())
-    {
-        WOW64_CPURESERVED *cpu = ULongToPtr( NtCurrentTeb64()->TlsSlots[WOW64_TLS_CPURESERVED] );
-        memcpy( cpu + 1, &context, sizeof(context) );
-    }
+    if ((ctx = get_cpu_area( IMAGE_FILE_MACHINE_ARMNT ))) *ctx = context;
 
     if (suspend) wait_suspend( &context );
 
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index 1560251e3a1..72aff4614ca 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -2337,11 +2337,7 @@ void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, B
     context.FloatSave.ControlWord = 0x27f;
     ((XSAVE_FORMAT *)context.ExtendedRegisters)->ControlWord = 0x27f;
     ((XSAVE_FORMAT *)context.ExtendedRegisters)->MxCsr = 0x1f80;
-    if (NtCurrentTeb64())
-    {
-        WOW64_CPURESERVED *cpu = ULongToPtr( NtCurrentTeb64()->TlsSlots[WOW64_TLS_CPURESERVED] );
-        memcpy( cpu + 1, &context, sizeof(context) );
-    }
+    if ((ctx = get_cpu_area( IMAGE_FILE_MACHINE_I386 ))) *ctx = context;
 
     if (suspend) wait_suspend( &context );
 
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index 05c412620f6..4383a4779be 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -1097,6 +1097,35 @@ static SIZE_T get_machine_context_size( USHORT machine )
 }
 
 
+/***********************************************************************
+ *           get_cpu_area
+ *
+ * cf. RtlWow64GetCurrentCpuArea
+ */
+void *get_cpu_area( USHORT machine )
+{
+    WOW64_CPURESERVED *cpu;
+    ULONG align;
+
+    if (!NtCurrentTeb()->WowTebOffset) return NULL;
+#ifdef _WIN64
+    cpu = NtCurrentTeb()->TlsSlots[WOW64_TLS_CPURESERVED];
+#else
+    cpu = ULongToPtr( NtCurrentTeb64()->TlsSlots[WOW64_TLS_CPURESERVED] );
+#endif
+    if (cpu->Machine != machine) return NULL;
+    switch (cpu->Machine)
+    {
+    case IMAGE_FILE_MACHINE_I386: align = TYPE_ALIGNMENT(I386_CONTEXT); break;
+    case IMAGE_FILE_MACHINE_AMD64: align = TYPE_ALIGNMENT(ARM_CONTEXT); break;
+    case IMAGE_FILE_MACHINE_ARMNT: align = TYPE_ALIGNMENT(AMD64_CONTEXT); break;
+    case IMAGE_FILE_MACHINE_ARM64: align = TYPE_ALIGNMENT(ARM64_NT_CONTEXT); break;
+    default: return NULL;
+    }
+    return (void *)(((ULONG_PTR)(cpu + 1) + align - 1) & ~(align - 1));
+}
+
+
 /***********************************************************************
  *           set_thread_id
  */
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 20b78e2a266..3ab546eb254 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -181,6 +181,7 @@ extern int server_pipe( int fd[2] ) DECLSPEC_HIDDEN;
 
 extern void fpux_to_fpu( I386_FLOATING_SAVE_AREA *fpu, const XSAVE_FORMAT *fpux ) DECLSPEC_HIDDEN;
 extern void fpu_to_fpux( XSAVE_FORMAT *fpux, const I386_FLOATING_SAVE_AREA *fpu ) DECLSPEC_HIDDEN;
+extern void *get_cpu_area( USHORT machine ) DECLSPEC_HIDDEN;
 extern void set_thread_id( TEB *teb, DWORD pid, DWORD tid ) DECLSPEC_HIDDEN;
 extern NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR zero_bits, SIZE_T reserve_size, SIZE_T commit_size ) DECLSPEC_HIDDEN;
 extern void DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN;




More information about the wine-cvs mailing list