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 @@
#include "winternl.h"
#include "kernel_private.h"
#include "psapi.h"
#include "wine/exception.h"
#include "wine/library.h"
#include "wine/server.h"
#include "wine/unicode.h"
......@@ -1088,11 +1089,25 @@ __ASM_GLOBAL_FUNC( call_process_entry,
__ASM_CFI(".cfi_def_cfa %esp,4\n\t")
__ASM_CFI(".cfi_same_value %ebp\n\t")
"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
static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry )
{
return entry( peb );
}
static void WINAPI start_process( LPTHREAD_START_ROUTINE entry, PEB *peb );
#define start_process_wrapper start_process
#endif
/***********************************************************************
......@@ -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.
*/
static DWORD WINAPI start_process( LPTHREAD_START_ROUTINE entry )
void WINAPI start_process( LPTHREAD_START_ROUTINE entry, PEB *peb )
{
BOOL being_debugged;
PEB *peb = NtCurrentTeb()->Peb;
if (!entry)
{
......@@ -1115,12 +1129,21 @@ static DWORD WINAPI start_process( LPTHREAD_START_ROUTINE entry )
TRACE_(relay)( "\1Starting process %s (entryproc=%p)\n",
debugstr_w(peb->ProcessParameters->ImagePathName.Buffer), entry );
__TRY
{
if (!CheckRemoteDebuggerPresent( GetCurrentProcess(), &being_debugged ))
being_debugged = FALSE;
SetLastError( 0 ); /* clear error code */
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)
if (!params->CurrentDirectory.Handle) chdir("/"); /* avoid locking removable devices */
LdrInitializeThunk( start_process, 0, 0, 0 );
LdrInitializeThunk( start_process_wrapper, 0, 0, 0 );
error:
ExitProcess( GetLastError() );
......
......@@ -116,7 +116,7 @@ extern UNICODE_STRING system_dir DECLSPEC_HIDDEN;
typedef LONG (WINAPI *PUNHANDLED_EXCEPTION_FILTER)(PEXCEPTION_POINTERS);
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 */
#define GetProcessHeap() (NtCurrentTeb()->Peb->ProcessHeap)
......
......@@ -1208,8 +1208,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
abort(); /* should not be reached */
}
typedef void (WINAPI *thread_start_func)(LPTHREAD_START_ROUTINE,void *);
struct startup_info
{
thread_start_func start;
LPTHREAD_START_ROUTINE entry;
void *arg;
BOOL suspend;
......@@ -1228,7 +1231,7 @@ static void thread_startup( void *param )
context.R0 = (DWORD)info->entry;
context.R1 = (DWORD)info->arg;
context.Sp = (DWORD)NtCurrentTeb()->Tib.StackBase;
context.Pc = (DWORD)call_thread_entry_point;
context.Pc = (DWORD)info->start;
attach_dlls( &context, info->suspend );
......@@ -1245,7 +1248,7 @@ static void thread_startup( void *param )
*/
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 );
}
......@@ -1255,12 +1258,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend
* 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 };
struct startup_info info = { kernel32_start_process, entry, NtCurrentTeb()->Peb, suspend };
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
......
......@@ -936,7 +936,7 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer,
/***********************************************************************
* 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
{
......@@ -951,8 +951,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
abort(); /* should not be reached */
}
typedef void (WINAPI *thread_start_func)(LPTHREAD_START_ROUTINE,void *);
struct startup_info
{
thread_start_func start;
LPTHREAD_START_ROUTINE entry;
void *arg;
BOOL suspend;
......@@ -971,11 +974,11 @@ static void thread_startup( void *param )
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;
context.Pc = (DWORD_PTR)info->start;
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 )
*/
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 );
}
......@@ -998,12 +1001,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend
* 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 };
struct startup_info info = { kernel32_start_process, entry, NtCurrentTeb()->Peb, suspend };
wine_switch_to_stack( thread_startup, &info, NtCurrentTeb()->Tib.StackBase );
}
......
......@@ -2915,17 +2915,6 @@ __ASM_GLOBAL_FUNC( call_thread_entry,
"pushl %eax\n\t" /* entry */
"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 */
extern DWORD call_thread_func_wrapper( LPTHREAD_START_ROUTINE entry, void *arg );
__ASM_GLOBAL_FUNC(call_thread_func_wrapper,
......@@ -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
*/
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
* signal_start_process()
* -> start_thread()
* -> thread_startup()
* -> call_process_entry()
* -> call_process_func()
* -> kernel32_start_process()
*/
void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL 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,
/***********************************************************************
* 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
{
......@@ -1153,8 +1153,11 @@ static void call_thread_entry_point( LPTHREAD_START_ROUTINE entry, void *arg )
abort(); /* should not be reached */
}
typedef void (WINAPI *thread_start_func)(LPTHREAD_START_ROUTINE,void *);
struct startup_info
{
thread_start_func start;
LPTHREAD_START_ROUTINE entry;
void *arg;
BOOL suspend;
......@@ -1173,11 +1176,11 @@ static void thread_startup( void *param )
context.Gpr1 = (DWORD)NtCurrentTeb()->Tib.StackBase;
context.Gpr3 = (DWORD)info->entry;
context.Gpr4 = (DWORD)info->arg;
context.Iar = (DWORD)call_thread_entry_point;
context.Iar = (DWORD)info->start;
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 )
*/
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 );
}
......@@ -1200,12 +1203,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend
* 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 };
struct startup_info info = { kernel32_start_process, entry, NtCurrentTeb()->Peb, suspend };
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 )
}
/***********************************************************************
* 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,
void *relay, void *stack, void **exit_frame );
__ASM_GLOBAL_FUNC( start_thread,
......@@ -4174,12 +4156,11 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend
* signal_start_process()
* -> start_thread()
* -> thread_startup()
* -> call_process_func()
* -> kernel32_start_process()
*/
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 );
}
......
......@@ -51,7 +51,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(thread);
struct _KUSER_SHARED_DATA *user_shared_data = 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 */
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