From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/ntdll/unix/loader.c | 2 +- dlls/ntdll/unix/signal_x86_64.c | 42 ++++++++++++++++++++++++--------- dlls/ntdll/unix/thread.c | 6 +++-- dlls/ntdll/unix/unix_private.h | 2 +- 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index bfa9121e813..e3316b5a138 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1868,7 +1868,7 @@ static void start_main_thread(void) init_startup_info( info_size ); *(ULONG_PTR *)&peb->CloudFileFlags = get_image_address(); set_load_order_app_name( main_wargv[0] ); - init_thread_stack( teb, 0, 0, 0 ); + init_thread_stack( teb, 0, 0, 0, TRUE ); NtCreateKeyedEvent( &keyed_event, GENERIC_READ | GENERIC_WRITE, NULL, 0 ); load_ntdll(); load_wow64_ntdll( main_image_info.Machine ); diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 62be4809aaa..9e4b0c65f90 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2825,13 +2825,42 @@ static void *mac_thread_gsbase(void) #endif +static void init_wow_sel(void) +{ + INITIAL_TEB stack; + WOW_TEB *wow_teb; + NTSTATUS status; + SIZE_T size = 0; + + if (!(wow_teb = get_wow_teb( NtCurrentTeb() ))) return; + + /* main thread doesn't have a user stack, create a temporary one to please alloc_fs_sel */ + + if ((status = virtual_alloc_thread_stack( &stack, 0, 0, 0x1000, 0x1000, TRUE ))) return; + wow_teb->Tib.StackBase = PtrToUlong( stack.StackBase ); + wow_teb->Tib.StackLimit = PtrToUlong( stack.StackLimit ); + wow_teb->DeallocationStack = PtrToUlong( stack.DeallocationStack ); + +#ifdef __linux__ + cs32_sel = 0x23; + fs32_sel = alloc_fs_sel( -1, wow_teb ); +#elif defined(__APPLE__) + cs32_sel = ldt_alloc_entry( ldt_make_cs32_entry() ); +#endif + + NtFreeVirtualMemory( GetCurrentProcess(), &stack.DeallocationStack, &size, MEM_RELEASE ); + wow_teb->Tib.StackBase = 0; + wow_teb->Tib.StackLimit = 0; + wow_teb->DeallocationStack = 0; +} + + /********************************************************************** * signal_init_process */ void signal_init_process(void) { struct sigaction sig_act; - WOW_TEB *wow_teb = get_wow_teb( NtCurrentTeb() ); struct ntdll_thread_data *thread_data = ntdll_get_thread_data(); void *ptr, *kernel_stack = (char *)thread_data->kernel_stack + kernel_stack_size; @@ -2847,16 +2876,7 @@ void signal_init_process(void) xstate_extended_features = user_shared_data->XState.EnabledFeatures & ~(UINT64)3; - if (wow_teb) - { -#ifdef __linux__ - cs32_sel = 0x23; - fs32_sel = alloc_fs_sel( -1, wow_teb ); -#elif defined(__APPLE__) - cs32_sel = ldt_alloc_entry( ldt_make_cs32_entry() ); -#endif - } - + init_wow_sel(); signal_alloc_thread( NtCurrentTeb() ); sig_act.sa_mask = server_block_set; diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 1c458c61dae..ea48daf026a 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -1199,7 +1199,7 @@ void set_thread_id( TEB *teb, DWORD pid, DWORD tid ) /*********************************************************************** * init_thread_stack */ -NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR limit, SIZE_T reserve_size, SIZE_T commit_size ) +NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR limit, SIZE_T reserve_size, SIZE_T commit_size, BOOL only_kernel ) { struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch; WOW_TEB *wow_teb = get_wow_teb( teb ); @@ -1211,6 +1211,8 @@ NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR limit, SIZE_T reserve_size, SIZE return status; thread_data->kernel_stack = stack.DeallocationStack; + if (only_kernel) return STATUS_SUCCESS; + if (wow_teb) { WOW64_CPURESERVED *cpu; @@ -1420,7 +1422,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle, ACCESS_MASK access, OBJECT_ATT if ((status = virtual_alloc_teb( &teb ))) goto done; - if ((status = init_thread_stack( teb, get_zero_bits_limit( zero_bits ), stack_reserve, stack_commit ))) + if ((status = init_thread_stack( teb, get_zero_bits_limit( zero_bits ), stack_reserve, stack_commit, FALSE ))) { virtual_free_teb( teb ); goto done; diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index ff705312515..46565b37ac7 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -262,7 +262,7 @@ extern void set_process_instrumentation_callback( void *callback ); extern void *get_cpu_area( USHORT machine ); extern void set_thread_id( TEB *teb, DWORD pid, DWORD tid ); -extern NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR limit, SIZE_T reserve_size, SIZE_T commit_size ); +extern NTSTATUS init_thread_stack( TEB *teb, ULONG_PTR limit, SIZE_T reserve_size, SIZE_T commit_size, BOOL only_kernel ); extern void DECLSPEC_NORETURN abort_thread( int status ); extern void DECLSPEC_NORETURN abort_process( int status ); extern void DECLSPEC_NORETURN exit_process( int status ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10058