ntdll: Add a platform-specific helper for starting a process.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
f8e0bd1b0d
commit
afb16abc0f
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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.@)
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue