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:
parent
32c2cfb861
commit
c3dd077d34
|
@ -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;
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue