ntdll: Add a platform-specific helper for starting a process.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2017-11-29 17:11:10 +01:00
parent f8e0bd1b0d
commit afb16abc0f
8 changed files with 165 additions and 64 deletions

View File

@ -3028,6 +3028,7 @@ NTSTATUS attach_dlls( void *reserved )
goto done;
}
attach_implicitly_loaded_dlls( reserved );
virtual_release_address_space();
}
else
{
@ -3094,14 +3095,6 @@ static void load_global_options(void)
}
/***********************************************************************
* start_process
*/
static void start_process( void *arg )
{
call_thread_entry_point( kernel32_start_process, arg );
}
/******************************************************************
* LdrInitializeThunk (NTDLL.@)
*
@ -3113,7 +3106,6 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2,
NTSTATUS status;
WINE_MODREF *wm;
PEB *peb = NtCurrentTeb()->Peb;
CONTEXT context = { 0 };
kernel32_start_process = kernel_start;
if (main_exe_file) NtClose( main_exe_file ); /* at this point the main module is created */
@ -3145,15 +3137,7 @@ void WINAPI LdrInitializeThunk( void *kernel_start, ULONG_PTR unknown2,
InsertHeadList( &peb->LdrData->InMemoryOrderModuleList, &wm->ldr.InMemoryOrderModuleList );
if ((status = virtual_alloc_thread_stack( NtCurrentTeb(), 0, 0, 0 )) != STATUS_SUCCESS) goto error;
if ((status = server_init_process_done( &context )) != STATUS_SUCCESS) goto error;
status = wine_call_on_stack( attach_dlls, (void *)1, (char *)NtCurrentTeb()->Tib.StackBase - page_size );
if (status != STATUS_SUCCESS) goto error;
virtual_release_address_space();
virtual_clear_thread_stack();
if (context.ContextFlags) NtSetContextThread( GetCurrentThread(), &context );
wine_switch_to_stack( start_process, wm->ldr.EntryPoint, NtCurrentTeb()->Tib.StackBase );
status = server_init_process_done();
error:
ERR( "Main exe initialization for %s failed, status %x\n",

View File

@ -67,7 +67,8 @@ extern LPCSTR debugstr_ObjectAttributes(const OBJECT_ATTRIBUTES *oa) DECLSPEC_HI
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( CONTEXT *context, LPTHREAD_START_ROUTINE entry ) DECLSPEC_HIDDEN;
extern void signal_init_process(void) 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;
extern HANDLE thread_init(void) DECLSPEC_HIDDEN;
@ -82,7 +83,7 @@ extern timeout_t server_start_time DECLSPEC_HIDDEN;
extern unsigned int server_cpus DECLSPEC_HIDDEN;
extern BOOL is_wow64 DECLSPEC_HIDDEN;
extern void server_init_process(void) DECLSPEC_HIDDEN;
extern NTSTATUS server_init_process_done( CONTEXT *context ) DECLSPEC_HIDDEN;
extern NTSTATUS server_init_process_done(void) DECLSPEC_HIDDEN;
extern size_t server_init_thread( void *entry_point ) DECLSPEC_HIDDEN;
extern void DECLSPEC_NORETURN abort_thread( int status ) DECLSPEC_HIDDEN;
extern void DECLSPEC_NORETURN terminate_thread( int status ) DECLSPEC_HIDDEN;

View File

@ -1430,7 +1430,7 @@ void server_init_process(void)
/***********************************************************************
* server_init_process_done
*/
NTSTATUS server_init_process_done( CONTEXT *context )
NTSTATUS server_init_process_done(void)
{
PEB *peb = NtCurrentTeb()->Peb;
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
@ -1444,7 +1444,7 @@ NTSTATUS server_init_process_done( CONTEXT *context )
* We do need the handlers in place by the time the request is over, so
* we set them up here. If we segfault between here and the server call
* something is very wrong... */
signal_init_process( context, entry );
signal_init_process();
/* Signal the parent process to continue */
SERVER_START_REQ( init_process_done )
@ -1460,7 +1460,7 @@ NTSTATUS server_init_process_done( CONTEXT *context )
}
SERVER_END_REQ;
if (suspend) wait_suspend( context );
if (!status) status = signal_start_process( entry, suspend );
return status;
}

View File

@ -975,7 +975,7 @@ void signal_init_thread( TEB *teb )
/**********************************************************************
* signal_init_process
*/
void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
void signal_init_process(void)
{
struct sigaction sig_act;
@ -1004,13 +1004,6 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
sig_act.sa_sigaction = trap_handler;
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
#endif
/* set 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;
return;
error:
@ -1019,6 +1012,29 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
}
/**********************************************************************
* signal_start_process
*/
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{
CONTEXT context = { 0 };
NTSTATUS status;
/* 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 );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1, (char *)NtCurrentTeb()->Tib.StackBase )))
set_cpu_context( &context );
return status;
}
/**********************************************************************
* __wine_enter_vm86 (NTDLL.@)
*/

View File

@ -846,7 +846,7 @@ void signal_init_thread( TEB *teb )
/**********************************************************************
* signal_init_process
*/
void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
void signal_init_process(void)
{
struct sigaction sig_act;
@ -875,8 +875,6 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
sig_act.sa_sigaction = trap_handler;
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
#endif
/* FIXME: set the initial context */
return;
error:
@ -885,6 +883,38 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
}
/***********************************************************************
* 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
*/
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{
CONTEXT context = { 0 };
NTSTATUS status;
/* 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 );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Sp )))
wine_switch_to_stack( start_process, &context, (void *)context.Sp );
return status;
}
/**********************************************************************
* __wine_enter_vm86 (NTDLL.@)
*/

View File

@ -2551,7 +2551,7 @@ void signal_init_thread( TEB *teb )
/**********************************************************************
* signal_init_process
*/
void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
void signal_init_process(void)
{
struct sigaction sig_act;
@ -2593,21 +2593,6 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
#endif
wine_ldt_init_locking( ldt_lock, ldt_unlock );
/* build the initial context */
context->ContextFlags = CONTEXT_FULL;
context->SegCs = wine_get_cs();
context->SegDs = wine_get_ds();
context->SegEs = wine_get_es();
context->SegFs = wine_get_fs();
context->SegGs = wine_get_gs();
context->SegSs = wine_get_ss();
context->Eax = (DWORD)entry;
context->Ebx = (DWORD)NtCurrentTeb()->Peb;
context->Esp = (DWORD)NtCurrentTeb()->Tib.StackBase - 16;
context->Eip = (DWORD)call_thread_entry_point;
((void **)context->Esp)[1] = kernel32_start_process;
((void **)context->Esp)[2] = entry;
return;
error:
@ -2616,6 +2601,41 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
}
/**********************************************************************
* signal_start_process
*/
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{
CONTEXT context = { 0 };
NTSTATUS status;
/* build the initial context */
context.ContextFlags = CONTEXT_FULL;
context.SegCs = wine_get_cs();
context.SegDs = wine_get_ds();
context.SegEs = wine_get_es();
context.SegFs = wine_get_fs();
context.SegGs = wine_get_gs();
context.SegSs = wine_get_ss();
context.Eax = (DWORD)entry;
context.Ebx = (DWORD)NtCurrentTeb()->Peb;
context.Esp = (DWORD)NtCurrentTeb()->Tib.StackBase - 16;
context.Eip = (DWORD)call_thread_entry_point;
((void **)context.Esp)[1] = kernel32_start_process;
((void **)context.Esp)[2] = entry;
if (suspend) wait_suspend( &context );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1,
(char *)NtCurrentTeb()->Tib.StackBase - page_size )))
{
virtual_clear_thread_stack();
set_cpu_context( &context );
}
return status;
}
#ifdef __HAVE_VM86
/**********************************************************************
* __wine_enter_vm86 (NTDLL.@)

View File

@ -1048,7 +1048,7 @@ void signal_init_thread( TEB *teb )
/**********************************************************************
* signal_init_process
*/
void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
void signal_init_process(void)
{
struct sigaction sig_act;
@ -1077,8 +1077,6 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
sig_act.sa_sigaction = trap_handler;
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
#endif
/* FIXME: set the initial context */
return;
error:
@ -1087,6 +1085,38 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
}
/***********************************************************************
* 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
*/
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{
CONTEXT context = { 0 };
NTSTATUS status;
/* 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 );
if (!(wine_call_on_stack( attach_dlls, (void *)1, (void *)context.Gpr1 )))
wine_switch_to_stack( start_process, &context, (void *)context.Gpr1 );
return status;
}
/**********************************************************************
* __wine_enter_vm86 (NTDLL.@)
*/

View File

@ -3106,7 +3106,7 @@ void signal_init_thread( TEB *teb )
/**********************************************************************
* signal_init_process
*/
void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
void signal_init_process(void)
{
struct sigaction sig_act;
@ -3135,16 +3135,6 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
sig_act.sa_sigaction = trap_handler;
if (sigaction( SIGTRAP, &sig_act, NULL ) == -1) goto error;
#endif
/* build the initial context */
context->ContextFlags = CONTEXT_FULL;
__asm__( "movw %%cs,%0" : "=m" (context->SegCs) );
__asm__( "movw %%ss,%0" : "=m" (context->SegSs) );
__asm__( "fxsave %0" : "=m" (context->u.FltSave) );
context->Rcx = (ULONG_PTR)entry;
context->Rdx = (ULONG_PTR)NtCurrentTeb()->Peb;
context->Rsp = (ULONG_PTR)NtCurrentTeb()->Tib.StackBase - 0x28;
context->Rip = (ULONG_PTR)start_process;
return;
error:
@ -3153,6 +3143,36 @@ void signal_init_process( CONTEXT *context, LPTHREAD_START_ROUTINE entry )
}
/**********************************************************************
* signal_start_process
*/
NTSTATUS signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{
CONTEXT context = { 0 };
NTSTATUS status;
/* build the initial context */
context.ContextFlags = CONTEXT_FULL;
__asm__( "movw %%cs,%0" : "=m" (context.SegCs) );
__asm__( "movw %%ss,%0" : "=m" (context.SegSs) );
__asm__( "fxsave %0" : "=m" (context.u.FltSave) );
context.Rcx = (ULONG_PTR)entry;
context.Rdx = (ULONG_PTR)NtCurrentTeb()->Peb;
context.Rsp = (ULONG_PTR)NtCurrentTeb()->Tib.StackBase - 0x28;
context.Rip = (ULONG_PTR)start_process;
if (suspend) wait_suspend( &context );
if (!(status = wine_call_on_stack( attach_dlls, (void *)1,
(char *)NtCurrentTeb()->Tib.StackBase - page_size )))
{
virtual_clear_thread_stack();
set_cpu_context( &context );
}
return status;
}
/**********************************************************************
* RtlAddFunctionTable (NTDLL.@)
*/