Alexandre Julliard : ntdll: Always put the pthread stack at the top of the 64-bit stack if there's one.
Alexandre Julliard
julliard at winehq.org
Tue May 25 16:08:15 CDT 2021
Module: wine
Branch: master
Commit: 118bd9fee324c347283de17388055e4cdbd6d493
URL: https://source.winehq.org/git/wine.git/?a=commit;h=118bd9fee324c347283de17388055e4cdbd6d493
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue May 25 11:17:23 2021 +0200
ntdll: Always put the pthread stack at the top of the 64-bit stack if there's one.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/unix/thread.c | 55 +++++++++++++++++++++++++++++++++++++-----------
1 file changed, 43 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c
index b14b441c094..1ac87352b39 100644
--- a/dlls/ntdll/unix/thread.c
+++ b/dlls/ntdll/unix/thread.c
@@ -787,36 +787,67 @@ 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, SIZE_T *pthread_size )
{
- INITIAL_TEB stack, stack64;
+ INITIAL_TEB stack;
NTSTATUS status;
- if ((status = virtual_alloc_thread_stack( &stack, zero_bits, reserve_size, commit_size, pthread_size )))
- return status;
-
- if (teb->WowTebOffset && !(status = virtual_alloc_thread_stack( &stack64, 0, 0x40000, 0x40000, NULL )))
+ if (teb->WowTebOffset)
{
+ WOW64_CPURESERVED *cpu;
SIZE_T cpusize = sizeof(WOW64_CPURESERVED) +
((get_machine_context_size( main_image_info.Machine ) + 7) & ~7) + sizeof(ULONG64);
- WOW64_CPURESERVED *cpu = (WOW64_CPURESERVED *)(((ULONG_PTR)stack64.StackBase - cpusize) & ~15);
+
#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, NULL )))
+ return status;
teb32->Tib.StackBase = PtrToUlong( stack.StackBase );
teb32->Tib.StackLimit = PtrToUlong( stack.StackLimit );
teb32->DeallocationStack = PtrToUlong( stack.DeallocationStack );
- stack64.StackBase = teb->TlsSlots[WOW64_TLS_CPURESERVED] = cpu;
- stack = stack64;
+
+ /* 64-bit stack */
+ if ((status = virtual_alloc_thread_stack( &stack, 0, 0x40000, 0x40000, pthread_size )))
+ return status;
+ cpu = (WOW64_CPURESERVED *)(((ULONG_PTR)stack.StackBase - cpusize) & ~15);
+ cpu->Machine = main_image_info.Machine;
+ teb->Tib.StackBase = teb->TlsSlots[WOW64_TLS_CPURESERVED] = cpu;
+ teb->Tib.StackLimit = stack.StackLimit;
+ teb->DeallocationStack = stack.DeallocationStack;
+
+ if (pthread_size)
+ {
+ struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
+ thread_data->start_stack = stack.StackBase;
+ *pthread_size += (char *)stack.StackBase - (char *)cpu;
+ }
+ return STATUS_SUCCESS;
#else
TEB64 *teb64 = (TEB64 *)((char *)teb + teb->WowTebOffset);
+
+ /* 64-bit stack */
+ if ((status = virtual_alloc_thread_stack( &stack, 0, 0x40000, 0x40000, NULL ))) 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( stack64.StackLimit );
- teb64->DeallocationStack = PtrToUlong( stack64.DeallocationStack );
+ teb64->Tib.StackLimit = PtrToUlong( stack.StackLimit );
+ teb64->DeallocationStack = PtrToUlong( stack.DeallocationStack );
#endif
- cpu->Machine = main_image_info.Machine;
}
+
+ /* native stack */
+ if ((status = virtual_alloc_thread_stack( &stack, zero_bits, reserve_size, commit_size, pthread_size )))
+ return status;
teb->Tib.StackBase = stack.StackBase;
teb->Tib.StackLimit = stack.StackLimit;
teb->DeallocationStack = stack.DeallocationStack;
- return status;
+ if (pthread_size)
+ {
+ struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
+ thread_data->start_stack = stack.StackBase;
+ }
+ return STATUS_SUCCESS;
}
More information about the wine-cvs
mailing list