ntdll: Don't expect LdrInitializeThunk() to return to the Unix side.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-08-20 15:30:08 +02:00
parent 4a7cd0f492
commit 53e0bf2f9f
8 changed files with 45 additions and 99 deletions

View File

@ -1486,7 +1486,7 @@ void CDECL server_init_process_done( void *relay )
SERVER_END_REQ; SERVER_END_REQ;
assert( !status ); assert( !status );
signal_start_thread( entry, peb, suspend, relay, NtCurrentTeb() ); signal_start_thread( entry, peb, suspend, relay, pLdrInitializeThunk, NtCurrentTeb() );
} }

View File

@ -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, PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg,
BOOL suspend, void *relay ) BOOL suspend, void *relay )
{ {
CONTEXT *ctx; 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 ); pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
ctx->ContextFlags = CONTEXT_FULL; ctx->ContextFlags = CONTEXT_FULL;
pLdrInitializeThunk( ctx, (void **)&ctx->R0, 0, 0 );
return ctx; return ctx;
} }
@ -940,22 +939,18 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg,
__ASM_GLOBAL_FUNC( signal_start_thread, __ASM_GLOBAL_FUNC( signal_start_thread,
".arm\n\t" ".arm\n\t"
"push {r4-r12,lr}\n\t" "push {r4-r12,lr}\n\t"
"ldr r5, [sp, #40]\n\t" /* thunk */
/* store exit frame */ /* 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 */ "str sp, [r4, #0x1d4]\n\t" /* teb->GdiTebBatch */
/* switch to thread stack */ /* switch to thread stack */
"ldr r4, [r4, #4]\n\t" /* teb->Tib.StackBase */ "ldr r4, [r4, #4]\n\t" /* teb->Tib.StackBase */
"sub sp, r4, #0x1000\n\t" "sub sp, r4, #0x1000\n\t"
/* attach dlls */ /* attach dlls */
"bl " __ASM_NAME("attach_thread") "\n\t" "bl " __ASM_NAME("get_initial_context") "\n\t"
"mov sp, r0\n\t" "add r1, r0, #4\n\t" /* &context->R0 */
/* clear the stack */ "mov lr, #0\n\t"
"and r0, #~0xff0\n\t" /* round down to page size */ "bx r5" )
"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") )
extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), TEB *teb ); extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), TEB *teb );

View File

@ -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, PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg,
BOOL suspend, void *relay ) BOOL suspend, void *relay )
{ {
CONTEXT *ctx; CONTEXT *ctx;
@ -1012,8 +1012,7 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg,
init_thread_context( ctx, entry, arg, relay ); init_thread_context( ctx, entry, arg, relay );
} }
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL ); pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
ctx->ContextFlags = CONTEXT_FULL; ctx->ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT;
pLdrInitializeThunk( ctx, (void **)&ctx->u.s.X0, 0, 0 );
return ctx; return ctx;
} }
@ -1023,43 +1022,19 @@ PCONTEXT DECLSPEC_HIDDEN attach_thread( LPTHREAD_START_ROUTINE entry, void *arg,
*/ */
__ASM_GLOBAL_FUNC( signal_start_thread, __ASM_GLOBAL_FUNC( signal_start_thread,
"stp x29, x30, [sp,#-16]!\n\t" "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 */ /* store exit frame */
"mov x29, sp\n\t" "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 */ /* 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" "sub sp, x5, #0x1000\n\t"
/* attach dlls */ /* attach dlls */
"bl " __ASM_NAME("attach_thread") "\n\t" "bl " __ASM_NAME("get_initial_context") "\n\t"
"mov sp, x0\n\t" "add x1, x0, #4\n\t" /* &context->X0 */
/* clear the stack */ "mov lr, #0\n\t"
"and x0, x0, #~0xfff\n\t" /* round down to page size */ "br x19" )
"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") )
extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), TEB *teb ); extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), TEB *teb );

View File

@ -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, PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg,
BOOL suspend, void *relay ) BOOL suspend, void *relay )
{ {
CONTEXT *ctx; 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 ); pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
ctx->ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS; ctx->ContextFlags = CONTEXT_FULL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS;
pLdrInitializeThunk( ctx, (void **)&ctx->Eax, 0, 0 );
return ctx; return ctx;
} }
@ -2293,18 +2292,14 @@ __ASM_GLOBAL_FUNC( signal_start_thread,
"pushl 16(%ebp)\n\t" /* suspend */ "pushl 16(%ebp)\n\t" /* suspend */
"pushl 12(%ebp)\n\t" /* arg */ "pushl 12(%ebp)\n\t" /* arg */
"pushl 8(%ebp)\n\t" /* entry */ "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" "xorl %ebp,%ebp\n\t"
"call " __ASM_NAME("attach_thread") "\n\t" "pushl $0\n\t"
"movl %eax,%esi\n\t" "jmp *%edx" )
"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") )
/*********************************************************************** /***********************************************************************

View File

@ -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, PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg,
BOOL suspend, void *relay ) BOOL suspend, void *relay )
{ {
CONTEXT *ctx; 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 ); pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
ctx->ContextFlags = CONTEXT_FULL; ctx->ContextFlags = CONTEXT_FULL;
pLdrInitializeThunk( ctx, (void **)&ctx->Rcx, 0, 0 );
return ctx; return ctx;
} }
@ -2521,19 +2520,15 @@ __ASM_GLOBAL_FUNC( signal_start_thread,
"movq %rsp,0x320(%rax)\n\t" /* amd64_thread_data()->exit_frame */ "movq %rsp,0x320(%rax)\n\t" /* amd64_thread_data()->exit_frame */
/* switch to thread stack */ /* switch to thread stack */
"movq 8(%rax),%rax\n\t" /* NtCurrentTeb()->Tib.StackBase */ "movq 8(%rax),%rax\n\t" /* NtCurrentTeb()->Tib.StackBase */
"movq %r8,%rbx\n\t" /* thunk */
"leaq -0x1000(%rax),%rsp\n\t" "leaq -0x1000(%rax),%rsp\n\t"
/* attach dlls */ /* attach dlls */
"call " __ASM_NAME("attach_thread") "\n\t" "call " __ASM_NAME("get_initial_context") "\n\t"
"movq %rax,%rbx\n\t" "movq %rax,%rcx\n\t" /* context */
"leaq -32(%rax),%rsp\n\t" "leaq 0x80(%rcx),%rdx\n\t" /* &context->Rcx */
/* clear the stack */ "xorq %rax,%rax\n\t"
"andq $~0xfff,%rax\n\t" /* round down to page size */ "pushq %rax\n\t"
"movq %rax,%rdi\n\t" "jmp *%rbx" )
"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") )
/*********************************************************************** /***********************************************************************

View File

@ -99,7 +99,8 @@ static void start_thread( TEB *teb )
thread_data->pthread_id = pthread_self(); thread_data->pthread_id = pthread_self();
signal_init_thread( teb ); signal_init_thread( teb );
server_init_thread( thread_data->start, &suspend ); 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 );
} }

View File

@ -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_thread( TEB *teb ) DECLSPEC_HIDDEN;
extern void signal_init_process(void) DECLSPEC_HIDDEN; extern void signal_init_process(void) DECLSPEC_HIDDEN;
extern void DECLSPEC_NORETURN signal_start_thread( PRTL_THREAD_START_ROUTINE entry, void *arg, 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 DECLSPEC_NORETURN signal_exit_thread( int status, void (*func)(int) ) DECLSPEC_HIDDEN;
extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN; extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN;
extern void fill_vm_counters( VM_COUNTERS_EX *pvmi, int unix_pid ) DECLSPEC_HIDDEN; extern void fill_vm_counters( VM_COUNTERS_EX *pvmi, int unix_pid ) DECLSPEC_HIDDEN;

View File

@ -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 * virtual_map_user_shared_data
*/ */