Alexandre Julliard : ntdll: Add a helper to get the Wow64 TEB.
Alexandre Julliard
julliard at winehq.org
Thu Jun 17 15:38:06 CDT 2021
Module: wine
Branch: master
Commit: 7b4ca95ab63c86549bb6fd7a6acbe43b9b28c964
URL: https://source.winehq.org/git/wine.git/?a=commit;h=7b4ca95ab63c86549bb6fd7a6acbe43b9b28c964
Author: Alexandre Julliard <julliard at winehq.org>
Date: Thu Jun 17 09:25:06 2021 +0200
ntdll: Add a helper to get the Wow64 TEB.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/unix/thread.c | 34 +++++++++++++---------------------
dlls/ntdll/unix/unix_private.h | 7 +++++++
dlls/ntdll/unix/virtual.c | 20 ++++++--------------
3 files changed, 26 insertions(+), 35 deletions(-)
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index c7b94eba923..f8ef274db0c 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -761,19 +761,14 @@ static SIZE_T get_machine_context_size( USHORT machine )
*/
void set_thread_id( TEB *teb, DWORD pid, DWORD tid )
{
+ WOW_TEB *wow_teb = get_wow_teb( teb );
+
teb->ClientId.UniqueProcess = ULongToHandle( pid );
teb->ClientId.UniqueThread = ULongToHandle( tid );
- if (teb->WowTebOffset)
+ if (wow_teb)
{
-#ifdef _WIN64
- TEB32 *teb32 = (TEB32 *)((char *)teb + teb->WowTebOffset);
- teb32->ClientId.UniqueProcess = pid;
- teb32->ClientId.UniqueThread = tid;
-#else
- TEB64 *teb64 = (TEB64 *)((char *)teb + teb->WowTebOffset);
- teb64->ClientId.UniqueProcess = pid;
- teb64->ClientId.UniqueThread = tid;
-#endif
+ wow_teb->ClientId.UniqueProcess = pid;
+ wow_teb->ClientId.UniqueThread = tid;
}
}
@@ -784,24 +779,23 @@ void set_thread_id( TEB *teb, DWORD pid, DWORD tid )
NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR zero_bits, SIZE_T reserve_size, SIZE_T commit_size )
{
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
+ WOW_TEB *wow_teb = get_wow_teb( teb );
INITIAL_TEB stack;
NTSTATUS status;
- if (teb->WowTebOffset)
+ if (wow_teb)
{
WOW64_CPURESERVED *cpu;
SIZE_T cpusize = sizeof(WOW64_CPURESERVED) +
((get_machine_context_size( main_image_info.Machine ) + 7) & ~7) + sizeof(ULONG64);
#ifdef _WIN64
- TEB32 *teb32 = (TEB32 *)((char *)teb + teb->WowTebOffset);
-
/* 32-bit stack */
if ((status = virtual_alloc_thread_stack( &stack, zero_bits, reserve_size, commit_size, 0 )))
return status;
- teb32->Tib.StackBase = PtrToUlong( stack.StackBase );
- teb32->Tib.StackLimit = PtrToUlong( stack.StackLimit );
- teb32->DeallocationStack = PtrToUlong( stack.DeallocationStack );
+ wow_teb->Tib.StackBase = PtrToUlong( stack.StackBase );
+ wow_teb->Tib.StackLimit = PtrToUlong( stack.StackLimit );
+ wow_teb->DeallocationStack = PtrToUlong( stack.DeallocationStack );
/* 64-bit stack */
if ((status = virtual_alloc_thread_stack( &stack, 0, 0x40000, 0x40000, kernel_stack_size )))
@@ -814,16 +808,14 @@ NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR zero_bits, SIZE_T reserve_size,
thread_data->kernel_stack = stack.StackBase;
return STATUS_SUCCESS;
#else
- TEB64 *teb64 = (TEB64 *)((char *)teb + teb->WowTebOffset);
-
/* 64-bit stack */
if ((status = virtual_alloc_thread_stack( &stack, 0, 0x40000, 0x40000, 0 ))) return status;
cpu = (WOW64_CPURESERVED *)(((ULONG_PTR)stack.StackBase - cpusize) & ~15);
cpu->Machine = main_image_info.Machine;
- teb64->Tib.StackBase = teb64->TlsSlots[WOW64_TLS_CPURESERVED] = PtrToUlong( cpu );
- teb64->Tib.StackLimit = PtrToUlong( stack.StackLimit );
- teb64->DeallocationStack = PtrToUlong( stack.DeallocationStack );
+ wow_teb->Tib.StackBase = wow_teb->TlsSlots[WOW64_TLS_CPURESERVED] = PtrToUlong( cpu );
+ wow_teb->Tib.StackLimit = PtrToUlong( stack.StackLimit );
+ wow_teb->DeallocationStack = PtrToUlong( stack.DeallocationStack );
#endif
}
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index c8c959029d0..a864604377e 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -321,11 +321,18 @@ static inline void mutex_unlock( pthread_mutex_t *mutex )
}
#ifdef _WIN64
+typedef TEB32 WOW_TEB;
static inline TEB64 *NtCurrentTeb64(void) { return NULL; }
#else
+typedef TEB64 WOW_TEB;
static inline TEB64 *NtCurrentTeb64(void) { return (TEB64 *)NtCurrentTeb()->GdiBatchCount; }
#endif
+static inline WOW_TEB *get_wow_teb( TEB *teb )
+{
+ return teb->WowTebOffset ? (WOW_TEB *)((char *)teb + teb->WowTebOffset) : NULL;
+}
+
enum loadorder
{
LO_INVALID,
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 6c3bc04ace7..c268b66f50c 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -2985,9 +2985,10 @@ NTSTATUS virtual_alloc_teb( TEB **ret_teb )
void virtual_free_teb( TEB *teb )
{
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
- void *ptr = teb;
+ void *ptr;
SIZE_T size;
sigset_t sigset;
+ WOW_TEB *wow_teb = get_wow_teb( teb );
signal_free_thread( teb );
if (teb->DeallocationStack)
@@ -3000,24 +3001,15 @@ void virtual_free_teb( TEB *teb )
size = 0;
NtFreeVirtualMemory( GetCurrentProcess(), &thread_data->kernel_stack, &size, MEM_RELEASE );
}
- if (teb->WowTebOffset)
+ if (wow_teb && (ptr = ULongToPtr( wow_teb->DeallocationStack )))
{
-#ifdef _WIN64
- TEB32 *teb32 = (TEB32 *)((char *)teb + teb->WowTebOffset);
- void *addr = ULongToPtr( teb32->DeallocationStack );
-#else
- TEB64 *teb64 = (TEB64 *)((char *)teb + teb->WowTebOffset);
- void *addr = ULongToPtr( teb64->DeallocationStack );
-#endif
- if (addr)
- {
- size = 0;
- NtFreeVirtualMemory( GetCurrentProcess(), &addr, &size, MEM_RELEASE );
- }
+ size = 0;
+ NtFreeVirtualMemory( GetCurrentProcess(), &ptr, &size, MEM_RELEASE );
}
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
list_remove( &thread_data->entry );
+ ptr = teb;
if (!is_win64) ptr = (char *)ptr - teb_offset;
*(void **)ptr = next_free_teb;
next_free_teb = ptr;
More information about the wine-cvs
mailing list