ntdll: Run the entire thread initialization code on the thread stack on remaining platforms.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2017-12-01 19:24:21 +01:00
parent 32c2cfb861
commit c3dd077d34
4 changed files with 177 additions and 193 deletions

View File

@ -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;

View File

@ -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.@)
*/

View File

@ -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.@)
*/

View File

@ -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.@)
*/