From 53e0bf2f9f0f9876ca89e4c9133d9d5265b3e9dd Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 20 Aug 2020 15:30:08 +0200 Subject: [PATCH] ntdll: Don't expect LdrInitializeThunk() to return to the Unix side. Signed-off-by: Alexandre Julliard --- dlls/ntdll/unix/server.c | 2 +- dlls/ntdll/unix/signal_arm.c | 23 ++++++---------- dlls/ntdll/unix/signal_arm64.c | 49 ++++++++------------------------- dlls/ntdll/unix/signal_i386.c | 25 +++++++---------- dlls/ntdll/unix/signal_x86_64.c | 25 +++++++---------- dlls/ntdll/unix/thread.c | 3 +- dlls/ntdll/unix/unix_private.h | 2 +- dlls/ntdll/unix/virtual.c | 15 ---------- 8 files changed, 45 insertions(+), 99 deletions(-) diff --git a/dlls/ntdll/unix/server.c b/dlls/ntdll/unix/server.c index d867a7fb462..0fd8f537b25 100644 --- a/dlls/ntdll/unix/server.c +++ b/dlls/ntdll/unix/server.c @@ -1486,7 +1486,7 @@ void CDECL server_init_process_done( void *relay ) SERVER_END_REQ; assert( !status ); - signal_start_thread( entry, peb, suspend, relay, NtCurrentTeb() ); + signal_start_thread( entry, peb, suspend, relay, pLdrInitializeThunk, NtCurrentTeb() ); } diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index e619dbd9755..fe54b9d68fd 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -906,10 +906,10 @@ static void init_thread_context( CONTEXT *context, LPTHREAD_START_ROUTINE entry, /*********************************************************************** - * attach_thread + * get_initial_context */ -PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, - BOOL suspend, void *relay ) +PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg, + BOOL suspend, void *relay ) { CONTEXT *ctx; @@ -929,7 +929,6 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, } pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); ctx->ContextFlags = CONTEXT_FULL; - pLdrInitializeThunk( ctx, (void **)&ctx->R0, 0, 0 ); return ctx; } @@ -940,22 +939,18 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, __ASM_GLOBAL_FUNC( signal_start_thread, ".arm\n\t" "push {r4-r12,lr}\n\t" + "ldr r5, [sp, #40]\n\t" /* thunk */ /* store exit frame */ - "ldr r4, [sp, #40]\n\t" /* teb */ + "ldr r4, [sp, #44]\n\t" /* teb */ "str sp, [r4, #0x1d4]\n\t" /* teb->GdiTebBatch */ /* switch to thread stack */ "ldr r4, [r4, #4]\n\t" /* teb->Tib.StackBase */ "sub sp, r4, #0x1000\n\t" /* attach dlls */ - "bl " __ASM_NAME("attach_thread") "\n\t" - "mov sp, r0\n\t" - /* clear the stack */ - "and r0, #~0xff0\n\t" /* round down to page size */ - "bl " __ASM_NAME("virtual_clear_thread_stack") "\n\t" - /* switch to the initial context */ - "mov r1, #1\n\t" - "mov r0, sp\n\t" - "b " __ASM_NAME("NtContinue") ) + "bl " __ASM_NAME("get_initial_context") "\n\t" + "add r1, r0, #4\n\t" /* &context->R0 */ + "mov lr, #0\n\t" + "bx r5" ) extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), TEB *teb ); diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index 7fe40d4ea12..7a68fa2a472 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -990,10 +990,10 @@ static void init_thread_context( CONTEXT *context, LPTHREAD_START_ROUTINE entry, /*********************************************************************** - * attach_thread + * get_initial_context */ -PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, - BOOL suspend, void *relay ) +PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg, + BOOL suspend, void *relay ) { CONTEXT *ctx; @@ -1012,8 +1012,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, init_thread_context( ctx, entry, arg, relay ); } pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); - ctx->ContextFlags = CONTEXT_FULL; - pLdrInitializeThunk( ctx, (void **)&ctx->u.s.X0, 0, 0 ); + ctx->ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT; return ctx; } @@ -1023,43 +1022,19 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, */ __ASM_GLOBAL_FUNC( signal_start_thread, "stp x29, x30, [sp,#-16]!\n\t" - "mov x18, x4\n\t" /* teb */ + "mov x19, x4\n\t" /* thunk */ + "mov x18, x5\n\t" /* teb */ /* store exit frame */ "mov x29, sp\n\t" - "str x29, [x4, #0x2f0]\n\t" /* arm64_thread_data()->exit_frame */ + "str x29, [x5, #0x2f0]\n\t" /* arm64_thread_data()->exit_frame */ /* switch to thread stack */ - "ldr x5, [x4, #8]\n\t" /* teb->Tib.StackBase */ + "ldr x5, [x5, #8]\n\t" /* teb->Tib.StackBase */ "sub sp, x5, #0x1000\n\t" /* attach dlls */ - "bl " __ASM_NAME("attach_thread") "\n\t" - "mov sp, x0\n\t" - /* clear the stack */ - "and x0, x0, #~0xfff\n\t" /* round down to page size */ - "bl " __ASM_NAME("virtual_clear_thread_stack") "\n\t" - /* switch to the initial context */ - "mov x0, sp\n\t" - "ldp q0, q1, [x0, #0x110]\n\t" /* context->V[0,1] */ - "ldp q2, q3, [x0, #0x130]\n\t" /* context->V[2,3] */ - "ldp q4, q5, [x0, #0x150]\n\t" /* context->V[4,5] */ - "ldp q6, q7, [x0, #0x170]\n\t" /* context->V[6,7] */ - "ldp q8, q9, [x0, #0x190]\n\t" /* context->V[8,9] */ - "ldp q10, q11, [x0, #0x1b0]\n\t" /* context->V[10,11] */ - "ldp q12, q13, [x0, #0x1d0]\n\t" /* context->V[12,13] */ - "ldp q14, q15, [x0, #0x1f0]\n\t" /* context->V[14,15] */ - "ldp q16, q17, [x0, #0x210]\n\t" /* context->V[16,17] */ - "ldp q18, q19, [x0, #0x230]\n\t" /* context->V[18,19] */ - "ldp q20, q21, [x0, #0x250]\n\t" /* context->V[20,21] */ - "ldp q22, q23, [x0, #0x270]\n\t" /* context->V[22,23] */ - "ldp q24, q25, [x0, #0x290]\n\t" /* context->V[24,25] */ - "ldp q26, q27, [x0, #0x2b0]\n\t" /* context->V[26,27] */ - "ldp q28, q29, [x0, #0x2d0]\n\t" /* context->V[28,29] */ - "ldp q30, q31, [x0, #0x2f0]\n\t" /* context->V[30,31] */ - "ldr w1, [x0, #0x310]\n\t" /* context->Fpcr */ - "msr fpcr, x1\n\t" - "ldr w1, [x0, #0x314]\n\t" /* context->Fpsr */ - "msr fpsr, x1\n\t" - "mov x1, #1\n\t" - "b " __ASM_NAME("NtContinue") ) + "bl " __ASM_NAME("get_initial_context") "\n\t" + "add x1, x0, #4\n\t" /* &context->X0 */ + "mov lr, #0\n\t" + "br x19" ) extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), TEB *teb ); diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 39c154ebbc1..a65f4d60cc7 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -2240,10 +2240,10 @@ static void init_thread_context( CONTEXT *context, LPTHREAD_START_ROUTINE entry, /*********************************************************************** - * attach_thread + * get_initial_context */ -PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, - BOOL suspend, void *relay ) +PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg, + BOOL suspend, void *relay ) { CONTEXT *ctx; @@ -2263,7 +2263,6 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, } pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); ctx->ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS; - pLdrInitializeThunk( ctx, (void **)&ctx->Eax, 0, 0 ); return ctx; } @@ -2293,18 +2292,14 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "pushl 16(%ebp)\n\t" /* suspend */ "pushl 12(%ebp)\n\t" /* arg */ "pushl 8(%ebp)\n\t" /* entry */ + "call " __ASM_NAME("get_initial_context") "\n\t" + "movl %eax,(%esp)\n\t" /* context */ + "leal 0xb0(%eax),%eax\n\t" /* &context->Eax */ + "movl %eax,4(%esp)\n\t" + "movl 24(%ebp),%edx\n\t" /* thunk */ "xorl %ebp,%ebp\n\t" - "call " __ASM_NAME("attach_thread") "\n\t" - "movl %eax,%esi\n\t" - "leal -12(%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_NAME("NtContinue") ) + "pushl $0\n\t" + "jmp *%edx" ) /*********************************************************************** diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 6f01b76c5ae..3a929d70f11 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2467,10 +2467,10 @@ static void init_thread_context( CONTEXT *context, LPTHREAD_START_ROUTINE entry, /*********************************************************************** - * attach_thread + * get_initial_context */ -PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, - BOOL suspend, void *relay ) +PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg, + BOOL suspend, void *relay ) { CONTEXT *ctx; @@ -2491,7 +2491,6 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg, } pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); ctx->ContextFlags = CONTEXT_FULL; - pLdrInitializeThunk( ctx, (void **)&ctx->Rcx, 0, 0 ); return ctx; } @@ -2521,19 +2520,15 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "movq %rsp,0x320(%rax)\n\t" /* amd64_thread_data()->exit_frame */ /* switch to thread stack */ "movq 8(%rax),%rax\n\t" /* NtCurrentTeb()->Tib.StackBase */ + "movq %r8,%rbx\n\t" /* thunk */ "leaq -0x1000(%rax),%rsp\n\t" /* attach dlls */ - "call " __ASM_NAME("attach_thread") "\n\t" - "movq %rax,%rbx\n\t" - "leaq -32(%rax),%rsp\n\t" - /* clear the stack */ - "andq $~0xfff,%rax\n\t" /* round down to page size */ - "movq %rax,%rdi\n\t" - "call " __ASM_NAME("virtual_clear_thread_stack") "\n\t" - /* switch to the initial context */ - "movl $1,%edx\n\t" - "movq %rbx,%rcx\n\t" - "call " __ASM_NAME("NtContinue") ) + "call " __ASM_NAME("get_initial_context") "\n\t" + "movq %rax,%rcx\n\t" /* context */ + "leaq 0x80(%rcx),%rdx\n\t" /* &context->Rcx */ + "xorq %rax,%rax\n\t" + "pushq %rax\n\t" + "jmp *%rbx" ) /*********************************************************************** diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index cb7377017b8..28c7d816b72 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -99,7 +99,8 @@ static void start_thread( TEB *teb ) thread_data->pthread_id = pthread_self(); signal_init_thread( teb ); server_init_thread( thread_data->start, &suspend ); - signal_start_thread( thread_data->start, thread_data->param, suspend, pRtlUserThreadStart, teb ); + signal_start_thread( thread_data->start, thread_data->param, suspend, + pRtlUserThreadStart, pLdrInitializeThunk, teb ); } diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 397211957bd..f7619964a2d 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -231,7 +231,7 @@ extern void signal_free_thread( TEB *teb ) DECLSPEC_HIDDEN; extern void signal_init_thread( TEB *teb ) DECLSPEC_HIDDEN; extern void signal_init_process(void) DECLSPEC_HIDDEN; extern void DECLSPEC_NORETURN signal_start_thread( PRTL_THREAD_START_ROUTINE entry, void *arg, - BOOL suspend, void *relay, TEB *teb ) DECLSPEC_HIDDEN; + BOOL suspend, void *relay, void *thunk, TEB *teb ) DECLSPEC_HIDDEN; extern void DECLSPEC_NORETURN signal_exit_thread( int status, void (*func)(int) ) DECLSPEC_HIDDEN; extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN; extern void fill_vm_counters( VM_COUNTERS_EX *pvmi, int unix_pid ) DECLSPEC_HIDDEN; diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index a2fea588834..fa46ec09668 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -2817,21 +2817,6 @@ done: } -/*********************************************************************** - * virtual_clear_thread_stack - * - * Clear the stack contents before calling the main entry point, some broken apps need that. - */ -void virtual_clear_thread_stack( void *stack_end ) -{ - void *stack = NtCurrentTeb()->Tib.StackLimit; - size_t size = (char *)stack_end - (char *)stack; - - wine_anon_mmap( stack, size, PROT_READ | PROT_WRITE, MAP_FIXED ); - if (force_exec_prot) mprotect( stack, size, PROT_READ | PROT_WRITE | PROT_EXEC ); -} - - /*********************************************************************** * virtual_map_user_shared_data */