Module: wine Branch: master Commit: bedfb31d7cfe0f1683e142ab6b0c1575cfc4c933 URL: https://source.winehq.org/git/wine.git/?a=commit;h=bedfb31d7cfe0f1683e142ab6...
Author: Alexandre Julliard julliard@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@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;