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

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2017-12-04 13:13:05 +01:00
parent 956a65347b
commit 23ec3ce2a3
8 changed files with 62 additions and 83 deletions

View File

@ -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() );

View File

@ -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)

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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,
@ -2961,24 +2950,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
*/
@ -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 );
}

View File

@ -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 );
}

View File

@ -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 );
}

View File

@ -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