Commit 23ec3ce2 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Start process execution directly at the kernel32 process entry point.

parent 956a6534
...@@ -57,6 +57,7 @@ ...@@ -57,6 +57,7 @@
#include "winternl.h" #include "winternl.h"
#include "kernel_private.h" #include "kernel_private.h"
#include "psapi.h" #include "psapi.h"
#include "wine/exception.h"
#include "wine/library.h" #include "wine/library.h"
#include "wine/server.h" #include "wine/server.h"
#include "wine/unicode.h" #include "wine/unicode.h"
...@@ -1088,11 +1089,25 @@ __ASM_GLOBAL_FUNC( call_process_entry, ...@@ -1088,11 +1089,25 @@ __ASM_GLOBAL_FUNC( call_process_entry,
__ASM_CFI(".cfi_def_cfa %esp,4\n\t") __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
__ASM_CFI(".cfi_same_value %ebp\n\t") __ASM_CFI(".cfi_same_value %ebp\n\t")
"ret" ) "ret" )
extern void WINAPI start_process( LPTHREAD_START_ROUTINE entry, PEB *peb ) DECLSPEC_HIDDEN;
extern void WINAPI start_process_wrapper(void) DECLSPEC_HIDDEN;
__ASM_GLOBAL_FUNC( start_process_wrapper,
"pushl %ebp\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
"movl %esp,%ebp\n\t"
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
"pushl %ebx\n\t" /* arg */
"pushl %eax\n\t" /* entry */
"call " __ASM_NAME("start_process") )
#else #else
static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry ) static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry )
{ {
return entry( peb ); return entry( peb );
} }
static void WINAPI start_process( LPTHREAD_START_ROUTINE entry, PEB *peb );
#define start_process_wrapper start_process
#endif #endif
/*********************************************************************** /***********************************************************************
...@@ -1100,10 +1115,9 @@ static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry ) ...@@ -1100,10 +1115,9 @@ static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry )
* *
* Startup routine of a new process. Runs on the new process stack. * Startup routine of a new process. Runs on the new process stack.
*/ */
static DWORD WINAPI start_process( LPTHREAD_START_ROUTINE entry ) void WINAPI start_process( LPTHREAD_START_ROUTINE entry, PEB *peb )
{ {
BOOL being_debugged; BOOL being_debugged;
PEB *peb = NtCurrentTeb()->Peb;
if (!entry) if (!entry)
{ {
...@@ -1115,12 +1129,21 @@ static DWORD WINAPI start_process( LPTHREAD_START_ROUTINE entry ) ...@@ -1115,12 +1129,21 @@ static DWORD WINAPI start_process( LPTHREAD_START_ROUTINE entry )
TRACE_(relay)( "\1Starting process %s (entryproc=%p)\n", TRACE_(relay)( "\1Starting process %s (entryproc=%p)\n",
debugstr_w(peb->ProcessParameters->ImagePathName.Buffer), entry ); debugstr_w(peb->ProcessParameters->ImagePathName.Buffer), entry );
__TRY
{
if (!CheckRemoteDebuggerPresent( GetCurrentProcess(), &being_debugged )) if (!CheckRemoteDebuggerPresent( GetCurrentProcess(), &being_debugged ))
being_debugged = FALSE; being_debugged = FALSE;
SetLastError( 0 ); /* clear error code */ SetLastError( 0 ); /* clear error code */
if (being_debugged) DbgBreakPoint(); if (being_debugged) DbgBreakPoint();
return call_process_entry( peb, entry ); ExitThread( call_process_entry( peb, entry ));
}
__EXCEPT(UnhandledExceptionFilter)
{
TerminateThread( GetCurrentThread(), GetExceptionCode() );
}
__ENDTRY
abort(); /* should not be reached */
} }
...@@ -1314,7 +1337,7 @@ void CDECL __wine_kernel_init(void) ...@@ -1314,7 +1337,7 @@ void CDECL __wine_kernel_init(void)
if (!params->CurrentDirectory.Handle) chdir("/"); /* avoid locking removable devices */ if (!params->CurrentDirectory.Handle) chdir("/"); /* avoid locking removable devices */
LdrInitializeThunk( start_process, 0, 0, 0 ); LdrInitializeThunk( start_process_wrapper, 0, 0, 0 );
error: error:
ExitProcess( GetLastError() ); ExitProcess( GetLastError() );
......
...@@ -116,7 +116,7 @@ extern UNICODE_STRING system_dir DECLSPEC_HIDDEN; ...@@ -116,7 +116,7 @@ extern UNICODE_STRING system_dir DECLSPEC_HIDDEN;
typedef LONG (WINAPI *PUNHANDLED_EXCEPTION_FILTER)(PEXCEPTION_POINTERS); typedef LONG (WINAPI *PUNHANDLED_EXCEPTION_FILTER)(PEXCEPTION_POINTERS);
extern PUNHANDLED_EXCEPTION_FILTER unhandled_exception_filter DECLSPEC_HIDDEN; extern PUNHANDLED_EXCEPTION_FILTER unhandled_exception_filter DECLSPEC_HIDDEN;
extern LPTHREAD_START_ROUTINE kernel32_start_process DECLSPEC_HIDDEN; extern void (WINAPI *kernel32_start_process)(LPTHREAD_START_ROUTINE,void*) DECLSPEC_HIDDEN;
/* redefine these to make sure we don't reference kernel symbols */ /* redefine these to make sure we don't reference kernel symbols */
#define GetProcessHeap() (NtCurrentTeb()->Peb->ProcessHeap) #define GetProcessHeap() (NtCurrentTeb()->Peb->ProcessHeap)
......
...@@ -1208,8 +1208,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) ...@@ -1208,8 +1208,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
abort(); /* should not be reached */ abort(); /* should not be reached */
} }
typedef void (WINAPI *thread_start_func)(LPTHREAD_START_ROUTINE,void *);
struct startup_info struct startup_info
{ {
thread_start_func start;
LPTHREAD_START_ROUTINE entry; LPTHREAD_START_ROUTINE entry;
void *arg; void *arg;
BOOL suspend; BOOL suspend;
...@@ -1228,7 +1231,7 @@ static void thread_startup( void *param ) ...@@ -1228,7 +1231,7 @@ static void thread_startup( void *param )
context.R0 = (DWORD)info->entry; context.R0 = (DWORD)info->entry;
context.R1 = (DWORD)info->arg; context.R1 = (DWORD)info->arg;
context.Sp = (DWORD)NtCurrentTeb()->Tib.StackBase; context.Sp = (DWORD)NtCurrentTeb()->Tib.StackBase;
context.Pc = (DWORD)call_thread_entry_point; context.Pc = (DWORD)info->start;
attach_dlls( &context, info->suspend ); attach_dlls( &context, info->suspend );
...@@ -1245,7 +1248,7 @@ static void thread_startup( void *param ) ...@@ -1245,7 +1248,7 @@ static void thread_startup( void *param )
*/ */
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
{ {
struct startup_info info = { entry, arg, suspend }; struct startup_info info = { call_thread_entry_point, entry, arg, suspend };
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
} }
...@@ -1255,12 +1258,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ...@@ -1255,12 +1258,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend
* Process startup sequence: * Process startup sequence:
* signal_start_process() * signal_start_process()
* -> thread_startup() * -> thread_startup()
* -> call_thread_entry_point()
* -> kernel32_start_process() * -> kernel32_start_process()
*/ */
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{ {
struct startup_info info = { kernel32_start_process, entry, suspend }; struct startup_info info = { kernel32_start_process, entry, NtCurrentTeb()->Peb, suspend };
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
} }
......
...@@ -936,7 +936,7 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, ...@@ -936,7 +936,7 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
/*********************************************************************** /***********************************************************************
* call_thread_entry_point * call_thread_entry_point
*/ */
static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) static void WINAPI call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
{ {
__TRY __TRY
{ {
...@@ -951,8 +951,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) ...@@ -951,8 +951,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
abort(); /* should not be reached */ abort(); /* should not be reached */
} }
typedef void (WINAPI *thread_start_func)(LPTHREAD_START_ROUTINE,void *);
struct startup_info struct startup_info
{ {
thread_start_func start;
LPTHREAD_START_ROUTINE entry; LPTHREAD_START_ROUTINE entry;
void *arg; void *arg;
BOOL suspend; BOOL suspend;
...@@ -971,11 +974,11 @@ static void thread_startup( void *param ) ...@@ -971,11 +974,11 @@ static void thread_startup( void *param )
context.X0 = (DWORD_PTR)info->entry; context.X0 = (DWORD_PTR)info->entry;
context.X1 = (DWORD_PTR)info->arg; context.X1 = (DWORD_PTR)info->arg;
context.Sp = (DWORD_PTR)NtCurrentTeb()->Tib.StackBase; context.Sp = (DWORD_PTR)NtCurrentTeb()->Tib.StackBase;
context.Pc = (DWORD_PTR)call_thread_entry_point; context.Pc = (DWORD_PTR)info->start;
attach_dlls( &context, info->suspend ); attach_dlls( &context, info->suspend );
call_thread_entry_point( (LPTHREAD_START_ROUTINE)context.X0, (void *)context.X1 ); ((thread_start_func)context.Pc)( (LPTHREAD_START_ROUTINE)context.X0, (void *)context.X1 );
} }
/*********************************************************************** /***********************************************************************
...@@ -988,7 +991,7 @@ static void thread_startup( void *param ) ...@@ -988,7 +991,7 @@ static void thread_startup( void *param )
*/ */
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
{ {
struct startup_info info = { entry, arg, suspend }; struct startup_info info = { call_thread_entry_point, entry, arg, suspend };
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
} }
...@@ -998,12 +1001,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ...@@ -998,12 +1001,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend
* Process startup sequence: * Process startup sequence:
* signal_start_process() * signal_start_process()
* -> thread_startup() * -> thread_startup()
* -> call_thread_entry_point()
* -> kernel32_start_process() * -> kernel32_start_process()
*/ */
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{ {
struct startup_info info = { kernel32_start_process, entry, suspend }; struct startup_info info = { kernel32_start_process, entry, NtCurrentTeb()->Peb, suspend };
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
} }
......
...@@ -2915,17 +2915,6 @@ __ASM_GLOBAL_FUNC( call_thread_entry, ...@@ -2915,17 +2915,6 @@ __ASM_GLOBAL_FUNC( call_thread_entry,
"pushl %eax\n\t" /* entry */ "pushl %eax\n\t" /* entry */
"call " __ASM_NAME("call_thread_func") ) "call " __ASM_NAME("call_thread_func") )
extern void call_process_entry(void) DECLSPEC_HIDDEN;
__ASM_GLOBAL_FUNC( call_process_entry,
"pushl %ebp\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
__ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
"movl %esp,%ebp\n\t"
__ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
"pushl %ebx\n\t" /* arg */
"pushl %eax\n\t" /* entry */
"call " __ASM_NAME("call_process_func") )
/* wrapper for apps that don't declare the thread function correctly */ /* wrapper for apps that don't declare the thread function correctly */
extern DWORD call_thread_func_wrapper( LPTHREAD_START_ROUTINE entry, void *arg ); extern DWORD call_thread_func_wrapper( LPTHREAD_START_ROUTINE entry, void *arg );
__ASM_GLOBAL_FUNC(call_thread_func_wrapper, __ASM_GLOBAL_FUNC(call_thread_func_wrapper,
...@@ -2962,24 +2951,6 @@ void DECLSPEC_HIDDEN call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg ) ...@@ -2962,24 +2951,6 @@ void DECLSPEC_HIDDEN call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg )
/*********************************************************************** /***********************************************************************
* call_process_func
*/
void DECLSPEC_HIDDEN call_process_func( LPTHREAD_START_ROUTINE entry, void *arg )
{
__TRY
{
RtlExitUserThread( kernel32_start_process( entry ));
}
__EXCEPT(unhandled_exception_filter)
{
NtTerminateThread( GetCurrentThread(), GetExceptionCode() );
}
__ENDTRY
abort(); /* should not be reached */
}
/***********************************************************************
* thread_startup * thread_startup
*/ */
void DECLSPEC_HIDDEN thread_startup( CONTEXT *context, BOOL suspend ) void DECLSPEC_HIDDEN thread_startup( CONTEXT *context, BOOL suspend )
...@@ -3011,14 +2982,12 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ...@@ -3011,14 +2982,12 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend
* signal_start_process() * signal_start_process()
* -> start_thread() * -> start_thread()
* -> thread_startup() * -> thread_startup()
* -> call_process_entry()
* -> call_process_func()
* -> kernel32_start_process() * -> kernel32_start_process()
*/ */
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{ {
start_thread( entry, NtCurrentTeb()->Peb, suspend, start_thread( entry, NtCurrentTeb()->Peb, suspend,
call_process_entry, &x86_thread_data()->exit_frame ); kernel32_start_process, &x86_thread_data()->exit_frame );
} }
......
...@@ -1138,7 +1138,7 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, ...@@ -1138,7 +1138,7 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
/*********************************************************************** /***********************************************************************
* call_thread_entry_point * call_thread_entry_point
*/ */
static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) static void WINAPI call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
{ {
__TRY __TRY
{ {
...@@ -1153,8 +1153,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg ) ...@@ -1153,8 +1153,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
abort(); /* should not be reached */ abort(); /* should not be reached */
} }
typedef void (WINAPI *thread_start_func)(LPTHREAD_START_ROUTINE,void *);
struct startup_info struct startup_info
{ {
thread_start_func start;
LPTHREAD_START_ROUTINE entry; LPTHREAD_START_ROUTINE entry;
void *arg; void *arg;
BOOL suspend; BOOL suspend;
...@@ -1173,11 +1176,11 @@ static void thread_startup( void *param ) ...@@ -1173,11 +1176,11 @@ static void thread_startup( void *param )
context.Gpr1 = (DWORD)NtCurrentTeb()->Tib.StackBase; context.Gpr1 = (DWORD)NtCurrentTeb()->Tib.StackBase;
context.Gpr3 = (DWORD)info->entry; context.Gpr3 = (DWORD)info->entry;
context.Gpr4 = (DWORD)info->arg; context.Gpr4 = (DWORD)info->arg;
context.Iar = (DWORD)call_thread_entry_point; context.Iar = (DWORD)info->start;
attach_dlls( &context, info->suspend ); attach_dlls( &context, info->suspend );
call_thread_entry_point( (LPTHREAD_START_ROUTINE)context.Gpr3, (void *)context.Gpr4 ); ((thread_start_func)context.Iar)( (LPTHREAD_START_ROUTINE)context.Gpr3, (void *)context.Gpr4 );
} }
/*********************************************************************** /***********************************************************************
...@@ -1190,7 +1193,7 @@ static void thread_startup( void *param ) ...@@ -1190,7 +1193,7 @@ static void thread_startup( void *param )
*/ */
void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ) void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
{ {
struct startup_info info = { entry, arg, suspend }; struct startup_info info = { call_thread_entry_point, entry, arg, suspend };
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
} }
...@@ -1200,12 +1203,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ...@@ -1200,12 +1203,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend
* Process startup sequence: * Process startup sequence:
* signal_start_process() * signal_start_process()
* -> thread_startup() * -> thread_startup()
* -> call_thread_entry_point()
* -> kernel32_start_process() * -> kernel32_start_process()
*/ */
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{ {
struct startup_info info = { kernel32_start_process, entry, suspend }; struct startup_info info = { kernel32_start_process, entry, NtCurrentTeb()->Peb, suspend };
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase ); wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
} }
......
...@@ -4073,24 +4073,6 @@ static void WINAPI call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg ) ...@@ -4073,24 +4073,6 @@ static void WINAPI call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg )
} }
/***********************************************************************
* call_process_func
*/
static void WINAPI call_process_func( LPTHREAD_START_ROUTINE entry, void *arg )
{
__TRY
{
RtlExitUserThread( kernel32_start_process( entry ));
}
__EXCEPT(unhandled_exception_filter)
{
NtTerminateThread( GetCurrentThread(), GetExceptionCode() );
}
__ENDTRY
abort(); /* should not be reached */
}
extern void DECLSPEC_NORETURN start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, extern void DECLSPEC_NORETURN start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend,
void *relay, void *stack, void **exit_frame ); void *relay, void *stack, void **exit_frame );
__ASM_GLOBAL_FUNC( start_thread, __ASM_GLOBAL_FUNC( start_thread,
...@@ -4174,12 +4156,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend ...@@ -4174,12 +4156,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend
* signal_start_process() * signal_start_process()
* -> start_thread() * -> start_thread()
* -> thread_startup() * -> thread_startup()
* -> call_process_func()
* -> kernel32_start_process() * -> kernel32_start_process()
*/ */
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend ) void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
{ {
start_thread( entry, NtCurrentTeb()->Peb, suspend, call_process_func, start_thread( entry, NtCurrentTeb()->Peb, suspend, kernel32_start_process,
NtCurrentTeb()->Tib.StackBase, &amd64_thread_data()->exit_frame ); NtCurrentTeb()->Tib.StackBase, &amd64_thread_data()->exit_frame );
} }
......
...@@ -51,7 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(thread); ...@@ -51,7 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(thread);
struct _KUSER_SHARED_DATA *user_shared_data = NULL; struct _KUSER_SHARED_DATA *user_shared_data = NULL;
PUNHANDLED_EXCEPTION_FILTER unhandled_exception_filter = NULL; PUNHANDLED_EXCEPTION_FILTER unhandled_exception_filter = NULL;
LPTHREAD_START_ROUTINE kernel32_start_process = NULL; void (WINAPI *kernel32_start_process)(LPTHREAD_START_ROUTINE,void*) = NULL;
/* info passed to a starting thread */ /* info passed to a starting thread */
struct startup_info struct startup_info
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment