From 53e4c36ef8c0720b61b03bb40d5992225c2771f3 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 29 Nov 2017 19:42:53 +0100 Subject: [PATCH] ntdll: Add a platform-specific helper for starting a thread. Signed-off-by: Alexandre Julliard --- dlls/ntdll/ntdll_misc.h | 1 + dlls/ntdll/signal_arm.c | 31 +++++++++++++++++++++++++++++++ dlls/ntdll/signal_arm64.c | 31 +++++++++++++++++++++++++++++++ dlls/ntdll/signal_i386.c | 35 +++++++++++++++++++++++++++++++++-- dlls/ntdll/signal_powerpc.c | 31 +++++++++++++++++++++++++++++++ dlls/ntdll/signal_x86_64.c | 31 +++++++++++++++++++++++++++++++ dlls/ntdll/thread.c | 23 +++-------------------- 7 files changed, 161 insertions(+), 22 deletions(-) diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index cab8d6da371..d3a37e81932 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -68,6 +68,7 @@ extern NTSTATUS signal_alloc_thread( TEB **teb ) DECLSPEC_HIDDEN; extern void signal_free_thread( TEB *teb ) DECLSPEC_HIDDEN; extern void signal_init_thread( TEB *teb ) DECLSPEC_HIDDEN; extern void signal_init_process(void) DECLSPEC_HIDDEN; +extern NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) DECLSPEC_HIDDEN; extern NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) DECLSPEC_HIDDEN; extern void version_init( const WCHAR *appname ) DECLSPEC_HIDDEN; extern void debug_init(void) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index 2a68946277c..3ff8c9124cf 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -62,6 +62,7 @@ #include "winnt.h" WINE_DEFAULT_DEBUG_CHANNEL(seh); +WINE_DECLARE_DEBUG_CHANNEL(relay); static pthread_key_t teb_key; @@ -1012,6 +1013,36 @@ 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 + */ +NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) +{ + NTSTATUS status; + struct startup_info info = { entry, arg }; + + if (!(status = 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 ); + } + return status; +} + + /********************************************************************** * signal_start_process */ diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index d1e40219112..e0e424e9eda 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -59,6 +59,7 @@ #include "winnt.h" WINE_DEFAULT_DEBUG_CHANNEL(seh); +WINE_DECLARE_DEBUG_CHANNEL(relay); static pthread_key_t teb_key; @@ -883,6 +884,36 @@ 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 + */ +NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) +{ + NTSTATUS status; + struct startup_info info = { entry, arg }; + + if (!(status = 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 ); + } + return status; +} + + /*********************************************************************** * start_process */ diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 7914ff520fa..074ad3befde 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -69,6 +69,9 @@ #undef ERR /* Solaris needs to define this */ +WINE_DEFAULT_DEBUG_CHANNEL(seh); +WINE_DECLARE_DEBUG_CHANNEL(relay); + /* not defined for x86, so copy the x86_64 definition */ typedef struct DECLSPEC_ALIGN(16) _M128A { @@ -468,8 +471,6 @@ typedef struct trapframe ucontext_t; #error You must define the signal context functions for your platform #endif /* linux */ -WINE_DEFAULT_DEBUG_CHANNEL(seh); - typedef int (*wine_signal_handler)(unsigned int sig); static const size_t teb_size = 4096; /* we reserve one page for the TEB */ @@ -2601,6 +2602,36 @@ 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 + */ +NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) +{ + NTSTATUS status; + struct startup_info info = { entry, arg }; + + if (!(status = 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 ); + } + return status; +} + + /********************************************************************** * signal_start_process */ diff --git a/dlls/ntdll/signal_powerpc.c b/dlls/ntdll/signal_powerpc.c index 209339a9122..c5b3fdb8829 100644 --- a/dlls/ntdll/signal_powerpc.c +++ b/dlls/ntdll/signal_powerpc.c @@ -59,6 +59,7 @@ #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(seh); +WINE_DECLARE_DEBUG_CHANNEL(relay); static pthread_key_t teb_key; @@ -1085,6 +1086,36 @@ 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 + */ +NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) +{ + NTSTATUS status; + struct startup_info info = { entry, arg }; + + if (!(status = 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 ); + } + return status; +} + + /*********************************************************************** * start_process */ diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index b81bfc0063b..024af8e4878 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -73,6 +73,7 @@ #endif WINE_DEFAULT_DEBUG_CHANNEL(seh); +WINE_DECLARE_DEBUG_CHANNEL(relay); struct _DISPATCHER_CONTEXT; @@ -3143,6 +3144,36 @@ 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 + */ +NTSTATUS signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg ) +{ + NTSTATUS status; + struct startup_info info = { entry, arg }; + + if (!(status = 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 ); + } + return status; +} + + /********************************************************************** * signal_start_process */ diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 80f4780f2f9..18d0fe1b1c4 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -47,7 +47,6 @@ #include "wine/exception.h" WINE_DEFAULT_DEBUG_CHANNEL(thread); -WINE_DECLARE_DEBUG_CHANNEL(relay); struct _KUSER_SHARED_DATA *user_shared_data = NULL; @@ -491,29 +490,13 @@ void exit_thread( int status ) /*********************************************************************** - * thread_startup - */ -static void thread_startup( void *param ) -{ - struct startup_info *info = param; - PRTL_THREAD_START_ROUTINE func = info->entry_point; - void *arg = info->entry_arg; - - attach_dlls( (void *)1 ); - - TRACE_(relay)( "\1Starting thread proc %p (arg=%p)\n", func, arg ); - - call_thread_entry_point( (LPTHREAD_START_ROUTINE)func, arg ); -} - - -/*********************************************************************** * start_thread * * Startup routine for a newly created thread. */ static void start_thread( struct startup_info *info ) { + NTSTATUS status; TEB *teb = info->teb; struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch; struct debug_info debug_info; @@ -525,8 +508,8 @@ static void start_thread( struct startup_info *info ) signal_init_thread( teb ); server_init_thread( info->entry_point ); - - wine_switch_to_stack( thread_startup, info, teb->Tib.StackBase ); + status = signal_start_thread( (LPTHREAD_START_ROUTINE)info->entry_point, info->entry_arg ); + NtTerminateThread( GetCurrentThread(), status ); } -- 2.11.4.GIT