From c3dd077d34232611c8b2ee38789114da45e71ef4 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 1 Dec 2017 19:24:21 +0100 Subject: [PATCH] ntdll: Run the entire thread initialization code on the thread stack on remaining platforms. Signed-off-by: Alexandre Julliard --- dlls/ntdll/ntdll_misc.h | 1 - dlls/ntdll/signal_arm.c | 117 ++++++++++++++++++++-------------------- dlls/ntdll/signal_arm64.c | 126 +++++++++++++++++++++----------------------- dlls/ntdll/signal_powerpc.c | 126 +++++++++++++++++++++----------------------- 4 files changed, 177 insertions(+), 193 deletions(-) diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index a17c5d9afb1..1393bbf6c66 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -57,7 +57,6 @@ extern NTSTATUS context_to_server( context_t *to, const CONTEXT *from ) DECLSPEC extern NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) DECLSPEC_HIDDEN; extern NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self ) DECLSPEC_HIDDEN; extern NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self ) DECLSPEC_HIDDEN; -extern void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) DECLSPEC_NORETURN DECLSPEC_HIDDEN; /* debug helpers */ extern LPCSTR debugstr_us( const UNICODE_STRING *str ) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index 0cdda2c4695..e1aa94f0728 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -1013,63 +1013,6 @@ void signal_init_process(void) } -struct startup_info -{ - LPTHREAD_START_ROUTINE entry; - void *arg; -}; - -static void thread_startup( void *param ) -{ - struct startup_info *info = param; - call_thread_entry_point( info->entry, info->arg ); -} - - -/*********************************************************************** - * signal_start_thread - */ -void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) -{ - CONTEXT context = { 0 }; - struct startup_info info = { entry, arg }; - - /* build the initial context */ - context.ContextFlags = CONTEXT_FULL; - context.R0 = (DWORD)entry; - context.R1 = (DWORD)arg; - context.Sp = (DWORD)NtCurrentTeb()->Tib.StackBase; - context.Pc = (DWORD)call_thread_entry_point; - - if (suspend) wait_suspend( &context ); - - wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase ); - TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg ); - wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); -} - - -/********************************************************************** - * signal_start_process - */ -void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) -{ - CONTEXT context = { 0 }; - - /* build the initial context */ - context.ContextFlags = CONTEXT_FULL; - context.R0 = (DWORD)kernel32_start_process; - context.R1 = (DWORD)entry; - context.Sp = (DWORD)NtCurrentTeb()->Tib.StackBase; - context.Pc = (DWORD)call_thread_entry_point; - - if (suspend) wait_suspend( &context ); - - wine_call_on_stack( attach_dlls, (void *)1, (char *)NtCurrentTeb()->Tib.StackBase ); - set_cpu_context( &context ); -} - - /********************************************************************** * __wine_enter_vm86 (NTDLL.@) */ @@ -1250,10 +1193,11 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, /*********************************************************************** * call_thread_entry_point */ -void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) +static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) { __TRY { + TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg ); exit_thread( entry( arg )); } __EXCEPT(unhandled_exception_filter) @@ -1264,6 +1208,63 @@ void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) abort(); /* should not be reached */ } +struct startup_info +{ + LPTHREAD_START_ROUTINE entry; + void *arg; + BOOL suspend; +}; + +/*********************************************************************** + * thread_startup + */ +static void thread_startup( void *param ) +{ + CONTEXT context = { 0 }; + struct startup_info *info = param; + + /* build the initial context */ + context.ContextFlags = CONTEXT_FULL; + context.R0 = (DWORD)info->entry; + context.R1 = (DWORD)info->arg; + context.Sp = (DWORD)NtCurrentTeb()->Tib.StackBase; + context.Pc = (DWORD)call_thread_entry_point; + + if (info->suspend) wait_suspend( &context ); + attach_dlls( &context ); + + set_cpu_context( &context ); +} + +/*********************************************************************** + * signal_start_thread + * + * Thread startup sequence: + * signal_start_thread() + * -> thread_startup() + * -> call_thread_entry_point() + */ +void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) +{ + struct startup_info info = { entry, arg, suspend }; + wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); +} + +/********************************************************************** + * signal_start_process + * + * Process startup sequence: + * signal_start_process() + * -> thread_startup() + * -> call_thread_entry_point() + * -> kernel32_start_process() + */ +void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) +{ + struct startup_info info = { kernel32_start_process, entry, suspend }; + wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); +} + /*********************************************************************** * RtlExitUserThread (NTDLL.@) */ diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index 537bd08aad1..3dc92ad2dbb 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -884,72 +884,6 @@ void signal_init_process(void) } -struct startup_info -{ - LPTHREAD_START_ROUTINE entry; - void *arg; -}; - -static void thread_startup( void *param ) -{ - struct startup_info *info = param; - call_thread_entry_point( info->entry, info->arg ); -} - - -/*********************************************************************** - * signal_start_thread - */ -void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) -{ - CONTEXT context = { 0 }; - struct startup_info info = { entry, arg }; - - /* build the initial context */ - context.ContextFlags = CONTEXT_FULL; - context.X0 = (DWORD_PTR)entry; - context.X1 = (DWORD_PTR)arg; - context.Sp = (DWORD_PTR)NtCurrentTeb()->Tib.StackBase; - context.Pc = (DWORD_PTR)call_thread_entry_point; - - if (suspend) wait_suspend( &context ); - - wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase ); - TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg ); - wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); -} - - -/*********************************************************************** - * start_process - */ -static void start_process( void *arg ) -{ - CONTEXT *context = arg; - call_thread_entry_point( (LPTHREAD_START_ROUTINE)context->X0, (void *)context->X1 ); -} - -/********************************************************************** - * signal_start_process - */ -void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) -{ - CONTEXT context = { 0 }; - - /* build the initial context */ - context.ContextFlags = CONTEXT_FULL; - context.X0 = (DWORD_PTR)kernel32_start_process; - context.X1 = (DWORD_PTR)entry; - context.Sp = (DWORD_PTR)NtCurrentTeb()->Tib.StackBase; - context.Pc = (DWORD_PTR)call_thread_entry_point; - - if (suspend) wait_suspend( &context ); - - wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Sp ); - wine_switch_to_stack( start_process, &context, (void *)context.Sp ); -} - - /********************************************************************** * __wine_enter_vm86 (NTDLL.@) */ @@ -1002,10 +936,11 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, /*********************************************************************** * call_thread_entry_point */ -void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) +static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) { __TRY { + TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg ); exit_thread( entry( arg )); } __EXCEPT(unhandled_exception_filter) @@ -1016,6 +951,63 @@ void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) abort(); /* should not be reached */ } +struct startup_info +{ + LPTHREAD_START_ROUTINE entry; + void *arg; + BOOL suspend; +}; + +/*********************************************************************** + * thread_startup + */ +static void thread_startup( void *param ) +{ + CONTEXT context = { 0 }; + struct startup_info *info = param; + + /* build the initial context */ + context.ContextFlags = CONTEXT_FULL; + context.X0 = (DWORD_PTR)info->entry; + context.X1 = (DWORD_PTR)info->arg; + context.Sp = (DWORD_PTR)NtCurrentTeb()->Tib.StackBase; + context.Pc = (DWORD_PTR)call_thread_entry_point; + + if (info->suspend) wait_suspend( &context ); + attach_dlls( &context ); + + call_thread_entry_point( (LPTHREAD_START_ROUTINE)context.X0, (void *)context.X1 ); +} + +/*********************************************************************** + * signal_start_thread + * + * Thread startup sequence: + * signal_start_thread() + * -> thread_startup() + * -> call_thread_entry_point() + */ +void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) +{ + struct startup_info info = { entry, arg, suspend }; + wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); +} + +/********************************************************************** + * signal_start_process + * + * Process startup sequence: + * signal_start_process() + * -> thread_startup() + * -> call_thread_entry_point() + * -> kernel32_start_process() + */ +void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) +{ + struct startup_info info = { kernel32_start_process, entry, suspend }; + wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); +} + /*********************************************************************** * RtlExitUserThread (NTDLL.@) */ diff --git a/dlls/ntdll/signal_powerpc.c b/dlls/ntdll/signal_powerpc.c index 53667cf1f0e..b0124975f35 100644 --- a/dlls/ntdll/signal_powerpc.c +++ b/dlls/ntdll/signal_powerpc.c @@ -1086,72 +1086,6 @@ void signal_init_process(void) } -struct startup_info -{ - LPTHREAD_START_ROUTINE entry; - void *arg; -}; - -static void thread_startup( void *param ) -{ - struct startup_info *info = param; - call_thread_entry_point( info->entry, info->arg ); -} - - -/*********************************************************************** - * signal_start_thread - */ -void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) -{ - CONTEXT context = { 0 }; - struct startup_info info = { entry, arg }; - - /* build the initial context */ - context.ContextFlags = CONTEXT_FULL; - context.Gpr1 = (DWORD)NtCurrentTeb()->Tib.StackBase; - context.Gpr3 = (DWORD)entry; - context.Gpr4 = (DWORD)arg; - context.Iar = (DWORD)call_thread_entry_point; - - if (suspend) wait_suspend( &context ); - - wine_call_on_stack( attach_dlls, (void *)1, NtCurrentTeb()->Tib.StackBase ); - TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg ); - wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); -} - - -/*********************************************************************** - * start_process - */ -static void start_process( void *arg ) -{ - CONTEXT *context = arg; - call_thread_entry_point( (LPTHREAD_START_ROUTINE)context->Gpr3, (void *)context->Gpr4 ); -} - -/********************************************************************** - * signal_start_process - */ -void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) -{ - CONTEXT context = { 0 }; - - /* build the initial context */ - context.ContextFlags = CONTEXT_FULL; - context.Gpr1 = (DWORD)NtCurrentTeb()->Tib.StackBase; - context.Gpr3 = (DWORD)kernel32_start_process; - context.Gpr4 = (DWORD)entry; - context.Iar = (DWORD)call_thread_entry_point; - - if (suspend) wait_suspend( &context ); - - wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Gpr1 ); - wine_switch_to_stack( start_process, &context, (void *)context.Gpr1 ); -} - - /********************************************************************** * __wine_enter_vm86 (NTDLL.@) */ @@ -1204,10 +1138,11 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, /*********************************************************************** * call_thread_entry_point */ -void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) +static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) { __TRY { + TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", entry, arg ); exit_thread( entry( arg )); } __EXCEPT(unhandled_exception_filter) @@ -1218,6 +1153,63 @@ void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) abort(); /* should not be reached */ } +struct startup_info +{ + LPTHREAD_START_ROUTINE entry; + void *arg; + BOOL suspend; +}; + +/*********************************************************************** + * thread_startup + */ +static void thread_startup( void *param ) +{ + CONTEXT context = { 0 }; + struct startup_info *info = param; + + /* build the initial context */ + context.ContextFlags = CONTEXT_FULL; + context.Gpr1 = (DWORD)NtCurrentTeb()->Tib.StackBase; + context.Gpr3 = (DWORD)info->entry; + context.Gpr4 = (DWORD)info->arg; + context.Iar = (DWORD)call_thread_entry_point; + + if (info->suspend) wait_suspend( &context ); + attach_dlls( &context ); + + call_thread_entry_point( (LPTHREAD_START_ROUTINE)context.Gpr3, (void *)context.Gpr4 ); +} + +/*********************************************************************** + * signal_start_thread + * + * Thread startup sequence: + * signal_start_thread() + * -> thread_startup() + * -> call_thread_entry_point() + */ +void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) +{ + struct startup_info info = { entry, arg, suspend }; + wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); +} + +/********************************************************************** + * signal_start_process + * + * Process startup sequence: + * signal_start_process() + * -> thread_startup() + * -> call_thread_entry_point() + * -> kernel32_start_process() + */ +void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) +{ + struct startup_info info = { kernel32_start_process, entry, suspend }; + wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); +} + /*********************************************************************** * RtlExitUserThread (NTDLL.@) */ -- 2.11.4.GIT