ntdll: Always put the pthread stack at the top of the 64-bit stack if there's one.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5c1be1dbae
commit
118bd9fee3
|
@ -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);
|
||||
teb64->Tib.StackBase = teb64->TlsSlots[WOW64_TLS_CPURESERVED] = PtrToUlong( cpu );
|
||||
teb64->Tib.StackLimit = PtrToUlong( stack64.StackLimit );
|
||||
teb64->DeallocationStack = PtrToUlong( stack64.DeallocationStack );
|
||||
#endif
|
||||
|
||||
/* 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( stack.StackLimit );
|
||||
teb64->DeallocationStack = PtrToUlong( stack.DeallocationStack );
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue