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