diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 6290cbcb4e6..54d56f4e148 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3416,7 +3416,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknow WINE_MODREF *wm; LPCWSTR load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer; - if (process_detaching) return; + if (process_detaching) NtTerminateThread( GetCurrentThread(), 0 ); RtlEnterCriticalSection( &loader_section ); @@ -3486,6 +3486,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknow } RtlLeaveCriticalSection( &loader_section ); + signal_start_thread( context ); } diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index a97dadb2a5f..63ceac42e94 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -65,6 +65,7 @@ extern void init_unix_codepage(void) DECLSPEC_HIDDEN; extern void init_locale( HMODULE module ) DECLSPEC_HIDDEN; extern void init_user_process_params(void) DECLSPEC_HIDDEN; extern NTSTATUS restart_process( RTL_USER_PROCESS_PARAMETERS *params, NTSTATUS status ) DECLSPEC_HIDDEN; +extern void CDECL DECLSPEC_NORETURN signal_start_thread( CONTEXT *ctx ) DECLSPEC_HIDDEN; /* server support */ extern BOOL is_wow64 DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index ba455ea71e7..1041dadf867 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -263,6 +263,17 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, return 0; } +/*********************************************************************** + * signal_start_thread + */ +__ASM_GLOBAL_FUNC( signal_start_thread, + "mov sp, r0\n\t" /* context */ + "and r0, #~0xff0\n\t" /* round down to page size */ + "bl " __ASM_NAME("virtual_clear_thread_stack") "\n\t" + "mov r1, #1\n\t" + "mov r0, sp\n\t" + "b " __ASM_NAME("NtContinue") ) + /********************************************************************** * DbgBreakPoint (NTDLL.@) */ diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index a35e48c1d60..e3102f7bdfb 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -1188,6 +1188,17 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, return 0; } +/*********************************************************************** + * signal_start_thread + */ +__ASM_GLOBAL_FUNC( signal_start_thread, + "mov sp, x0\n\t" /* context */ + "and x0, x0, #~0xfff\n\t" /* round down to page size */ + "bl " __ASM_NAME("virtual_clear_thread_stack") "\n\t" + "mov x0, sp\n\t" + "mov x1, #1\n\t" + "b " __ASM_NAME("NtContinue") ) + /********************************************************************** * DbgBreakPoint (NTDLL.@) */ diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index b65beb7215b..8cdce3384ac 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -498,6 +498,22 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, } +/*********************************************************************** + * signal_start_thread + */ +__ASM_GLOBAL_FUNC( signal_start_thread, + "movl 4(%esp),%esi\n\t" /* context */ + "leal -12(%esi),%eax\n\t" + "movl %eax,%esp\n\t" + /* clear the stack */ + "andl $~0xfff,%eax\n\t" /* round down to page size */ + "movl %eax,(%esp)\n\t" + "call " __ASM_NAME("virtual_clear_thread_stack") "\n\t" + /* switch to the initial context */ + "movl $1,4(%esp)\n\t" + "movl %esi,(%esp)\n\t" + "call " __ASM_STDCALL("NtContinue", 8) ) + /********************************************************************** * DbgBreakPoint (NTDLL.@) */ diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index 40ed53c10d1..e1cf7f3e013 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -1477,6 +1477,20 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, } +/*********************************************************************** + * signal_start_thread + */ +__ASM_GLOBAL_FUNC( signal_start_thread, + "movq %rcx,%rbx\n\t" /* context */ + "leaq -32(%rcx),%rcx\n\t" + "movq %rcx,%rsp\n\t" + "andq $~0xfff,%rcx\n\t" /* round down to page size */ + "call " __ASM_NAME("virtual_clear_thread_stack") "\n\t" + "movl $1,%edx\n\t" + "movq %rbx,%rcx\n\t" + "call " __ASM_NAME("NtContinue") ) + + /********************************************************************** * DbgBreakPoint (NTDLL.@) */ diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 3ba4b8afbcb..64eef6aa843 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -106,6 +106,22 @@ void WINAPI RtlFreeUserStack( void *stack ) NtFreeVirtualMemory( NtCurrentProcess(), &stack, &size, MEM_RELEASE ); } + +/*********************************************************************** + * virtual_clear_thread_stack + * + * Clear the stack contents before calling the main entry point, some broken apps need that. + */ +void CDECL virtual_clear_thread_stack( void *stack_end ) +{ + void *stack = NtCurrentTeb()->Tib.StackLimit; + SIZE_T size = (char *)stack_end - (char *)stack; + + NtFreeVirtualMemory( GetCurrentProcess(), &stack, &size, MEM_DECOMMIT ); + NtAllocateVirtualMemory( GetCurrentProcess(), &stack, 0, &size, MEM_COMMIT, PAGE_READWRITE ); +} + + /*********************************************************************** * __wine_locked_recvmsg */