From: Rémi Bernon rbernon@codeweavers.com
--- dlls/ntdll/unix/thread.c | 22 +++++++++++++--------- dlls/ntdll/unix/unix_private.h | 2 +- dlls/ntdll/unix/virtual.c | 23 +++-------------------- 3 files changed, 17 insertions(+), 30 deletions(-)
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 029f13dc4f9..c1afbcbabb8 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1155,25 +1155,28 @@ NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR zero_bits, SIZE_T reserve_size, #ifdef _WIN64 /* 32-bit stack */ if ((status = virtual_alloc_thread_stack( &stack, zero_bits ? zero_bits : 0x7fffffff, - reserve_size, commit_size, 0 ))) + reserve_size, commit_size ))) return status; 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 ))) + if ((status = virtual_alloc_thread_stack( &stack, 0, 0x40000, 0x40000 ))) 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; - thread_data->kernel_stack = stack.StackBase; + + if ((status = virtual_alloc_thread_stack( &stack, 0, kernel_stack_size, kernel_stack_size ))) + return status; + thread_data->kernel_stack = stack.DeallocationStack; return STATUS_SUCCESS; #else /* 64-bit stack */ - if ((status = virtual_alloc_thread_stack( &stack, 0, 0x40000, 0x40000, 0 ))) return status; + if ((status = virtual_alloc_thread_stack( &stack, 0, 0x40000, 0x40000 ))) return status;
cpu = (WOW64_CPURESERVED *)(((ULONG_PTR)stack.StackBase - cpusize) & ~15); cpu->Machine = main_image_info.Machine; @@ -1184,13 +1187,15 @@ NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR zero_bits, SIZE_T reserve_size, }
/* native stack */ - if ((status = virtual_alloc_thread_stack( &stack, zero_bits, reserve_size, - commit_size, kernel_stack_size ))) + if ((status = virtual_alloc_thread_stack( &stack, zero_bits, reserve_size, commit_size ))) return status; teb->Tib.StackBase = stack.StackBase; teb->Tib.StackLimit = stack.StackLimit; teb->DeallocationStack = stack.DeallocationStack; - thread_data->kernel_stack = stack.StackBase; + + if ((status = virtual_alloc_thread_stack( &stack, 0, kernel_stack_size, kernel_stack_size ))) + return status; + thread_data->kernel_stack = stack.DeallocationStack; return STATUS_SUCCESS; }
@@ -1341,8 +1346,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT thread_data->param = param;
pthread_attr_init( &pthread_attr ); - pthread_attr_setstack( &pthread_attr, teb->DeallocationStack, - (char *)thread_data->kernel_stack + kernel_stack_size - (char *)teb->DeallocationStack ); + pthread_attr_setstack( &pthread_attr, thread_data->kernel_stack, kernel_stack_size ); pthread_attr_setguardsize( &pthread_attr, 0 ); pthread_attr_setscope( &pthread_attr, PTHREAD_SCOPE_SYSTEM ); /* force creating a kernel thread */ InterlockedIncrement( &nb_threads ); diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 73b9ed76de0..72790605018 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -204,7 +204,7 @@ extern NTSTATUS virtual_alloc_teb( TEB **ret_teb ) DECLSPEC_HIDDEN; extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN; extern NTSTATUS virtual_clear_tls_index( ULONG index ) DECLSPEC_HIDDEN; extern NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, ULONG_PTR zero_bits, SIZE_T reserve_size, - SIZE_T commit_size, SIZE_T extra_size ) DECLSPEC_HIDDEN; + SIZE_T commit_size ) DECLSPEC_HIDDEN; extern void virtual_map_user_shared_data(void) DECLSPEC_HIDDEN; extern NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) DECLSPEC_HIDDEN; extern unsigned int virtual_locked_server_call( void *req_ptr ) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index e80b0ae62dc..8a29687afeb 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -3097,8 +3097,9 @@ NTSTATUS virtual_clear_tls_index( ULONG index ) * virtual_alloc_thread_stack */ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, ULONG_PTR zero_bits, SIZE_T reserve_size, - SIZE_T commit_size, SIZE_T extra_size ) + SIZE_T commit_size ) { + unsigned int vprot = VPROT_READ | VPROT_WRITE | VPROT_COMMITTED; struct file_view *view; NTSTATUS status; sigset_t sigset; @@ -3113,8 +3114,7 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, ULONG_PTR zero_bits, SI
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
- if ((status = map_view( &view, NULL, size + extra_size, FALSE, - VPROT_READ | VPROT_WRITE | VPROT_COMMITTED, zero_bits )) != STATUS_SUCCESS) + if ((status = map_view( &view, NULL, size, FALSE, vprot, zero_bits )) != STATUS_SUCCESS) goto done;
#ifdef VALGRIND_STACK_REGISTER @@ -3128,23 +3128,6 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, ULONG_PTR zero_bits, SI mprotect_range( view->base, 2 * page_size, 0, 0 ); VIRTUAL_DEBUG_DUMP_VIEW( view );
- if (extra_size) - { - struct file_view *extra_view; - - /* shrink the first view and create a second one for the extra size */ - /* this allows the app to free the stack without freeing the thread start portion */ - view->size -= extra_size; - status = create_view( &extra_view, (char *)view->base + view->size, extra_size, - VPROT_READ | VPROT_WRITE | VPROT_COMMITTED ); - if (status != STATUS_SUCCESS) - { - view->size += extra_size; - delete_view( view ); - goto done; - } - } - /* note: limit is lower than base since the stack grows down */ stack->OldStackBase = 0; stack->OldStackLimit = 0;