ntdll: Simulate a syscall return when starting a thread.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
db26df5934
commit
fed7e7a78b
|
@ -1600,7 +1600,7 @@ void server_init_process_done(void)
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
assert( !status );
|
assert( !status );
|
||||||
signal_start_thread( entry, peb, suspend, pLdrInitializeThunk, NtCurrentTeb() );
|
signal_start_thread( entry, peb, suspend, NtCurrentTeb() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -894,48 +894,39 @@ void signal_init_process(void)
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* init_thread_context
|
* call_init_thunk
|
||||||
*/
|
*/
|
||||||
static void init_thread_context( CONTEXT *context, LPTHREAD_START_ROUTINE entry, void *arg, TEB *teb )
|
void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb )
|
||||||
{
|
{
|
||||||
context->R0 = (DWORD)entry;
|
struct arm_thread_data *thread_data = (struct arm_thread_data *)&teb->GdiTebBatch;
|
||||||
context->R1 = (DWORD)arg;
|
struct syscall_frame *frame = thread_data->syscall_frame;
|
||||||
context->Sp = (DWORD)teb->Tib.StackBase;
|
CONTEXT *ctx, context = { CONTEXT_ALL };
|
||||||
context->Pc = (DWORD)pRtlUserThreadStart;
|
|
||||||
if (context->Pc & 1) context->Cpsr |= 0x20; /* thumb mode */
|
context.R0 = (DWORD)entry;
|
||||||
|
context.R1 = (DWORD)arg;
|
||||||
|
context.Sp = (DWORD)teb->Tib.StackBase;
|
||||||
|
context.Pc = (DWORD)pRtlUserThreadStart;
|
||||||
|
if (context.Pc & 1) context.Cpsr |= 0x20; /* thumb mode */
|
||||||
if (NtCurrentTeb64())
|
if (NtCurrentTeb64())
|
||||||
{
|
{
|
||||||
WOW64_CPURESERVED *cpu = ULongToPtr( NtCurrentTeb64()->TlsSlots[WOW64_TLS_CPURESERVED] );
|
WOW64_CPURESERVED *cpu = ULongToPtr( NtCurrentTeb64()->TlsSlots[WOW64_TLS_CPURESERVED] );
|
||||||
memcpy( cpu + 1, context, sizeof(*context) );
|
memcpy( cpu + 1, &context, sizeof(context) );
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if (suspend) wait_suspend( &context );
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* get_initial_context
|
|
||||||
*/
|
|
||||||
PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg,
|
|
||||||
BOOL suspend, TEB *teb )
|
|
||||||
{
|
|
||||||
CONTEXT *ctx;
|
|
||||||
|
|
||||||
if (suspend)
|
|
||||||
{
|
|
||||||
CONTEXT context = { CONTEXT_ALL };
|
|
||||||
|
|
||||||
init_thread_context( &context, entry, arg, teb );
|
|
||||||
wait_suspend( &context );
|
|
||||||
ctx = (CONTEXT *)((ULONG_PTR)context.Sp & ~15) - 1;
|
ctx = (CONTEXT *)((ULONG_PTR)context.Sp & ~15) - 1;
|
||||||
*ctx = context;
|
*ctx = context;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ctx = (CONTEXT *)teb->Tib.StackBase - 1;
|
|
||||||
init_thread_context( ctx, entry, arg, teb );
|
|
||||||
}
|
|
||||||
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
|
|
||||||
ctx->ContextFlags = CONTEXT_FULL;
|
ctx->ContextFlags = CONTEXT_FULL;
|
||||||
return ctx;
|
NtSetContextThread( GetCurrentThread(), ctx );
|
||||||
|
|
||||||
|
frame->sp = (DWORD)ctx;
|
||||||
|
frame->pc = (DWORD)pLdrInitializeThunk;
|
||||||
|
frame->r0 = (DWORD)ctx;
|
||||||
|
frame->restore_flags |= CONTEXT_INTEGER;
|
||||||
|
|
||||||
|
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
|
||||||
|
__wine_syscall_dispatcher_return( frame, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -944,23 +935,15 @@ PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void
|
||||||
*/
|
*/
|
||||||
__ASM_GLOBAL_FUNC( signal_start_thread,
|
__ASM_GLOBAL_FUNC( signal_start_thread,
|
||||||
"push {r4-r12,lr}\n\t"
|
"push {r4-r12,lr}\n\t"
|
||||||
"mov r5, r3\n\t" /* thunk */
|
|
||||||
/* store exit frame */
|
/* store exit frame */
|
||||||
"ldr r3, [sp, #40]\n\t" /* teb */
|
|
||||||
"str sp, [r3, #0x1d4]\n\t" /* arm_thread_data()->exit_frame */
|
"str sp, [r3, #0x1d4]\n\t" /* arm_thread_data()->exit_frame */
|
||||||
/* set syscall frame */
|
/* set syscall frame */
|
||||||
"ldr r6, [r3, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */
|
"ldr r6, [r3, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */
|
||||||
"cbnz r6, 1f\n\t"
|
"cbnz r6, 1f\n\t"
|
||||||
"sub r6, sp, #0x150\n\t" /* sizeof(struct syscall_frame) */
|
"sub r6, sp, #0x150\n\t" /* sizeof(struct syscall_frame) */
|
||||||
"str r6, [r3, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */
|
"str r6, [r3, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */
|
||||||
/* switch to thread stack */
|
"1:\tmov sp, r6\n\t"
|
||||||
"1:\tldr r4, [r3, #4]\n\t" /* teb->Tib.StackBase */
|
"bl " __ASM_NAME("call_init_thunk") )
|
||||||
"sub r4, #0x1000\n\t"
|
|
||||||
"mov sp, r4\n\t"
|
|
||||||
/* attach dlls */
|
|
||||||
"bl " __ASM_NAME("get_initial_context") "\n\t"
|
|
||||||
"mov lr, #0\n\t"
|
|
||||||
"bx r5" )
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -1079,43 +1079,35 @@ void signal_init_process(void)
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* init_thread_context
|
* call_init_thunk
|
||||||
*/
|
*/
|
||||||
static void init_thread_context( CONTEXT *context, LPTHREAD_START_ROUTINE entry, void *arg, TEB *teb )
|
void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb )
|
||||||
{
|
{
|
||||||
context->u.s.X0 = (DWORD64)entry;
|
struct arm64_thread_data *thread_data = (struct arm64_thread_data *)&teb->GdiTebBatch;
|
||||||
context->u.s.X1 = (DWORD64)arg;
|
struct syscall_frame *frame = thread_data->syscall_frame;
|
||||||
context->u.s.X18 = (DWORD64)teb;
|
CONTEXT *ctx, context = { CONTEXT_ALL };
|
||||||
context->Sp = (DWORD64)teb->Tib.StackBase;
|
|
||||||
context->Pc = (DWORD64)pRtlUserThreadStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
context.u.s.X0 = (DWORD64)entry;
|
||||||
|
context.u.s.X1 = (DWORD64)arg;
|
||||||
|
context.u.s.X18 = (DWORD64)teb;
|
||||||
|
context.Sp = (DWORD64)teb->Tib.StackBase;
|
||||||
|
context.Pc = (DWORD64)pRtlUserThreadStart;
|
||||||
|
|
||||||
/***********************************************************************
|
if (suspend) wait_suspend( &context );
|
||||||
* get_initial_context
|
|
||||||
*/
|
|
||||||
PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg,
|
|
||||||
BOOL suspend, TEB *teb )
|
|
||||||
{
|
|
||||||
CONTEXT *ctx;
|
|
||||||
|
|
||||||
if (suspend)
|
|
||||||
{
|
|
||||||
CONTEXT context = { CONTEXT_ALL };
|
|
||||||
|
|
||||||
init_thread_context( &context, entry, arg, teb );
|
|
||||||
wait_suspend( &context );
|
|
||||||
ctx = (CONTEXT *)((ULONG_PTR)context.Sp & ~15) - 1;
|
ctx = (CONTEXT *)((ULONG_PTR)context.Sp & ~15) - 1;
|
||||||
*ctx = context;
|
*ctx = context;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ctx = (CONTEXT *)teb->Tib.StackBase - 1;
|
|
||||||
init_thread_context( ctx, entry, arg, teb );
|
|
||||||
}
|
|
||||||
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
|
|
||||||
ctx->ContextFlags = CONTEXT_FULL;
|
ctx->ContextFlags = CONTEXT_FULL;
|
||||||
return ctx;
|
NtSetContextThread( GetCurrentThread(), ctx );
|
||||||
|
|
||||||
|
frame->sp = (ULONG64)ctx;
|
||||||
|
frame->pc = (ULONG64)pLdrInitializeThunk;
|
||||||
|
frame->x[0] = (ULONG64)ctx;
|
||||||
|
frame->x[18] = (ULONG64)teb;
|
||||||
|
frame->restore_flags |= CONTEXT_INTEGER;
|
||||||
|
|
||||||
|
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
|
||||||
|
__wine_syscall_dispatcher_return( frame, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1124,24 +1116,16 @@ PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void
|
||||||
*/
|
*/
|
||||||
__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 x19, x3\n\t" /* thunk */
|
|
||||||
"mov x18, x4\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, [x3, #0x2f0]\n\t" /* arm64_thread_data()->exit_frame */
|
||||||
/* set syscall frame */
|
/* set syscall frame */
|
||||||
"ldr x8, [x4, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */
|
"ldr x8, [x3, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */
|
||||||
"cbnz x8, 1f\n\t"
|
"cbnz x8, 1f\n\t"
|
||||||
"sub x8, sp, #0x320\n\t" /* sizeof(struct syscall_frame) */
|
"sub x8, sp, #0x320\n\t" /* sizeof(struct syscall_frame) */
|
||||||
"str x8, [x4, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */
|
"str x8, [x3, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */
|
||||||
/* switch to thread stack */
|
"1:\tmov sp, x8\n\t"
|
||||||
"1:\tldr x5, [x4, #8]\n\t" /* teb->Tib.StackBase */
|
"bl " __ASM_NAME("call_init_thunk") )
|
||||||
"sub sp, x5, #0x1000\n\t"
|
|
||||||
/* attach dlls */
|
|
||||||
"mov x3, x4\n\t"
|
|
||||||
"bl " __ASM_NAME("get_initial_context") "\n\t"
|
|
||||||
"mov lr, #0\n\t"
|
|
||||||
"br x19" )
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* signal_exit_thread
|
* signal_exit_thread
|
||||||
|
|
|
@ -2369,59 +2369,56 @@ void signal_init_process(void)
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* init_thread_context
|
* call_init_thunk
|
||||||
*/
|
*/
|
||||||
static void init_thread_context( CONTEXT *context, LPTHREAD_START_ROUTINE entry, void *arg, TEB *teb )
|
void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb )
|
||||||
{
|
|
||||||
context->SegCs = get_cs();
|
|
||||||
context->SegDs = get_ds();
|
|
||||||
context->SegEs = get_ds();
|
|
||||||
context->SegFs = get_fs();
|
|
||||||
context->SegGs = get_gs();
|
|
||||||
context->SegSs = get_ds();
|
|
||||||
context->EFlags = 0x202;
|
|
||||||
context->Eax = (DWORD)entry;
|
|
||||||
context->Ebx = (DWORD)arg;
|
|
||||||
context->Esp = (DWORD)teb->Tib.StackBase - 16;
|
|
||||||
context->Eip = (DWORD)pRtlUserThreadStart;
|
|
||||||
context->FloatSave.ControlWord = 0x27f;
|
|
||||||
((XSAVE_FORMAT *)context->ExtendedRegisters)->ControlWord = 0x27f;
|
|
||||||
((XSAVE_FORMAT *)context->ExtendedRegisters)->MxCsr = 0x1f80;
|
|
||||||
if (NtCurrentTeb64())
|
|
||||||
{
|
|
||||||
WOW64_CPURESERVED *cpu = ULongToPtr( NtCurrentTeb64()->TlsSlots[WOW64_TLS_CPURESERVED] );
|
|
||||||
memcpy( cpu + 1, context, sizeof(*context) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* get_initial_context
|
|
||||||
*/
|
|
||||||
PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb )
|
|
||||||
{
|
{
|
||||||
struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch;
|
struct x86_thread_data *thread_data = (struct x86_thread_data *)&teb->GdiTebBatch;
|
||||||
struct syscall_frame *frame = thread_data->syscall_frame;
|
struct syscall_frame *frame = thread_data->syscall_frame;
|
||||||
CONTEXT *ctx;
|
CONTEXT *ctx, context = { CONTEXT_ALL };
|
||||||
|
DWORD *stack;
|
||||||
|
|
||||||
if (suspend)
|
context.SegCs = get_cs();
|
||||||
|
context.SegDs = get_ds();
|
||||||
|
context.SegEs = get_ds();
|
||||||
|
context.SegFs = get_fs();
|
||||||
|
context.SegGs = get_gs();
|
||||||
|
context.SegSs = get_ds();
|
||||||
|
context.EFlags = 0x202;
|
||||||
|
context.Eax = (DWORD)entry;
|
||||||
|
context.Ebx = (DWORD)arg;
|
||||||
|
context.Esp = (DWORD)teb->Tib.StackBase - 16;
|
||||||
|
context.Eip = (DWORD)pRtlUserThreadStart;
|
||||||
|
context.FloatSave.ControlWord = 0x27f;
|
||||||
|
((XSAVE_FORMAT *)context.ExtendedRegisters)->ControlWord = 0x27f;
|
||||||
|
((XSAVE_FORMAT *)context.ExtendedRegisters)->MxCsr = 0x1f80;
|
||||||
|
if (NtCurrentTeb64())
|
||||||
{
|
{
|
||||||
CONTEXT context = { CONTEXT_ALL };
|
WOW64_CPURESERVED *cpu = ULongToPtr( NtCurrentTeb64()->TlsSlots[WOW64_TLS_CPURESERVED] );
|
||||||
|
memcpy( cpu + 1, &context, sizeof(context) );
|
||||||
|
}
|
||||||
|
|
||||||
init_thread_context( &context, entry, arg, teb );
|
if (suspend) wait_suspend( &context );
|
||||||
wait_suspend( &context );
|
|
||||||
ctx = (CONTEXT *)((ULONG_PTR)context.Esp & ~15) - 1;
|
ctx = (CONTEXT *)((ULONG_PTR)context.Esp & ~3) - 1;
|
||||||
*ctx = context;
|
*ctx = context;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ctx = (CONTEXT *)((char *)teb->Tib.StackBase - 16) - 1;
|
|
||||||
init_thread_context( ctx, entry, arg, teb );
|
|
||||||
}
|
|
||||||
frame->syscall_flags = __wine_syscall_flags;
|
|
||||||
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;
|
||||||
return ctx;
|
memset( frame, 0, sizeof(*frame) );
|
||||||
|
NtSetContextThread( GetCurrentThread(), ctx );
|
||||||
|
|
||||||
|
stack = (DWORD *)ctx;
|
||||||
|
*(--stack) = 0;
|
||||||
|
*(--stack) = 0;
|
||||||
|
*(--stack) = 0;
|
||||||
|
*(--stack) = (DWORD)ctx;
|
||||||
|
*(--stack) = 0xdeadbabe;
|
||||||
|
frame->esp = (DWORD)stack;
|
||||||
|
frame->eip = (DWORD)pLdrInitializeThunk;
|
||||||
|
frame->syscall_flags = __wine_syscall_flags;
|
||||||
|
frame->restore_flags |= CONTEXT_INTEGER;
|
||||||
|
|
||||||
|
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
|
||||||
|
__wine_syscall_dispatcher_return( frame, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2441,28 +2438,21 @@ __ASM_GLOBAL_FUNC( signal_start_thread,
|
||||||
"pushl %edi\n\t"
|
"pushl %edi\n\t"
|
||||||
__ASM_CFI(".cfi_rel_offset %edi,-12\n\t")
|
__ASM_CFI(".cfi_rel_offset %edi,-12\n\t")
|
||||||
/* store exit frame */
|
/* store exit frame */
|
||||||
"movl 24(%ebp),%ecx\n\t" /* teb */
|
"movl 20(%ebp),%ecx\n\t" /* teb */
|
||||||
"movl %ebp,0x1f4(%ecx)\n\t" /* x86_thread_data()->exit_frame */
|
"movl %ebp,0x1f4(%ecx)\n\t" /* x86_thread_data()->exit_frame */
|
||||||
/* set syscall frame */
|
/* set syscall frame */
|
||||||
"cmpl $0,0x1f8(%ecx)\n\t" /* x86_thread_data()->syscall_frame */
|
"movl 0x1f8(%ecx),%eax\n\t" /* x86_thread_data()->syscall_frame */
|
||||||
|
"orl %eax,%eax\n\t"
|
||||||
"jnz 1f\n\t"
|
"jnz 1f\n\t"
|
||||||
"leal -0x380(%esp),%eax\n\t" /* sizeof(struct syscall_frame) */
|
"leal -0x380(%esp),%eax\n\t" /* sizeof(struct syscall_frame) */
|
||||||
"andl $~63,%eax\n\t"
|
"andl $~63,%eax\n\t"
|
||||||
"movl %eax,0x1f8(%ecx)\n" /* x86_thread_data()->syscall_frame */
|
"movl %eax,0x1f8(%ecx)\n" /* x86_thread_data()->syscall_frame */
|
||||||
/* switch to thread stack */
|
"1:\tmovl %eax,%esp\n\t"
|
||||||
"1:\tmovl 4(%ecx),%eax\n\t" /* teb->StackBase */
|
|
||||||
"leal -0x1000(%eax),%esp\n\t"
|
|
||||||
/* attach dlls */
|
|
||||||
"pushl %ecx\n\t" /* teb */
|
"pushl %ecx\n\t" /* teb */
|
||||||
"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"
|
"call " __ASM_NAME("call_init_thunk") )
|
||||||
"movl %eax,(%esp)\n\t" /* context */
|
|
||||||
"movl 20(%ebp),%edx\n\t" /* thunk */
|
|
||||||
"xorl %ebp,%ebp\n\t"
|
|
||||||
"pushl $0\n\t"
|
|
||||||
"jmp *%edx" )
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -2626,47 +2626,40 @@ void signal_init_process(void)
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* init_thread_context
|
* call_init_thunk
|
||||||
*/
|
*/
|
||||||
static void init_thread_context( CONTEXT *context, LPTHREAD_START_ROUTINE entry, void *arg, TEB *teb )
|
void DECLSPEC_HIDDEN call_init_thunk( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb )
|
||||||
{
|
{
|
||||||
__asm__( "movw %%cs,%0" : "=m" (context->SegCs) );
|
struct amd64_thread_data *thread_data = (struct amd64_thread_data *)&teb->GdiTebBatch;
|
||||||
__asm__( "movw %%ss,%0" : "=m" (context->SegSs) );
|
struct syscall_frame *frame = thread_data->syscall_frame;
|
||||||
context->Rcx = (ULONG_PTR)entry;
|
CONTEXT *ctx, context = { 0 };
|
||||||
context->Rdx = (ULONG_PTR)arg;
|
|
||||||
context->Rsp = (ULONG_PTR)teb->Tib.StackBase - 0x28;
|
|
||||||
context->Rip = (ULONG_PTR)pRtlUserThreadStart;
|
|
||||||
context->EFlags = 0x200;
|
|
||||||
context->u.FltSave.ControlWord = 0x27f;
|
|
||||||
context->u.FltSave.MxCsr = context->MxCsr = 0x1f80;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* get_initial_context
|
|
||||||
*/
|
|
||||||
PCONTEXT DECLSPEC_HIDDEN get_initial_context( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend, TEB *teb )
|
|
||||||
{
|
|
||||||
CONTEXT *ctx;
|
|
||||||
|
|
||||||
if (suspend)
|
|
||||||
{
|
|
||||||
CONTEXT context = { 0 };
|
|
||||||
|
|
||||||
context.ContextFlags = CONTEXT_ALL;
|
context.ContextFlags = CONTEXT_ALL;
|
||||||
init_thread_context( &context, entry, arg, teb );
|
context.Rcx = (ULONG_PTR)entry;
|
||||||
wait_suspend( &context );
|
context.Rdx = (ULONG_PTR)arg;
|
||||||
|
context.Rsp = (ULONG_PTR)teb->Tib.StackBase - 0x28;
|
||||||
|
context.Rip = (ULONG_PTR)pRtlUserThreadStart;
|
||||||
|
context.EFlags = 0x200;
|
||||||
|
context.u.FltSave.ControlWord = 0x27f;
|
||||||
|
context.u.FltSave.MxCsr = context.MxCsr = 0x1f80;
|
||||||
|
__asm__( "movw %%cs,%0" : "=m" (context.SegCs) );
|
||||||
|
__asm__( "movw %%ss,%0" : "=m" (context.SegSs) );
|
||||||
|
|
||||||
|
if (suspend) wait_suspend( &context );
|
||||||
|
|
||||||
ctx = (CONTEXT *)((ULONG_PTR)context.Rsp & ~15) - 1;
|
ctx = (CONTEXT *)((ULONG_PTR)context.Rsp & ~15) - 1;
|
||||||
*ctx = context;
|
*ctx = context;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ctx = (CONTEXT *)((char *)teb->Tib.StackBase - 0x30) - 1;
|
|
||||||
init_thread_context( ctx, entry, arg, teb );
|
|
||||||
}
|
|
||||||
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
|
|
||||||
ctx->ContextFlags = CONTEXT_FULL;
|
ctx->ContextFlags = CONTEXT_FULL;
|
||||||
return ctx;
|
memset( frame, 0, sizeof(*frame) );
|
||||||
|
NtSetContextThread( GetCurrentThread(), ctx );
|
||||||
|
|
||||||
|
frame->rsp = (ULONG64)ctx - 8;
|
||||||
|
frame->rip = (ULONG64)pLdrInitializeThunk;
|
||||||
|
frame->rcx = (ULONG64)ctx;
|
||||||
|
frame->restore_flags |= CONTEXT_INTEGER;
|
||||||
|
|
||||||
|
pthread_sigmask( SIG_UNBLOCK, &server_block_set, NULL );
|
||||||
|
__wine_syscall_dispatcher_return( frame, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2691,24 +2684,16 @@ __ASM_GLOBAL_FUNC( signal_start_thread,
|
||||||
"movq %r15,8(%rsp)\n\t"
|
"movq %r15,8(%rsp)\n\t"
|
||||||
__ASM_CFI(".cfi_rel_offset %r15,8\n\t")
|
__ASM_CFI(".cfi_rel_offset %r15,8\n\t")
|
||||||
/* store exit frame */
|
/* store exit frame */
|
||||||
"movq %rsp,0x320(%r8)\n\t" /* amd64_thread_data()->exit_frame */
|
"movq %rsp,0x320(%rcx)\n\t" /* amd64_thread_data()->exit_frame */
|
||||||
/* set syscall frame */
|
/* set syscall frame */
|
||||||
"cmpq $0,0x328(%r8)\n\t" /* amd64_thread_data()->syscall_frame */
|
"movq 0x328(%rcx),%rax\n\t" /* amd64_thread_data()->syscall_frame */
|
||||||
|
"orq %rax,%rax\n\t"
|
||||||
"jnz 1f\n\t"
|
"jnz 1f\n\t"
|
||||||
"leaq -0x400(%rsp),%r10\n\t" /* sizeof(struct syscall_frame) */
|
"leaq -0x400(%rsp),%rax\n\t" /* sizeof(struct syscall_frame) */
|
||||||
"andq $~63,%r10\n\t"
|
"andq $~63,%rax\n\t"
|
||||||
"movq %r10,0x328(%r8)\n" /* amd64_thread_data()->syscall_frame */
|
"movq %rax,0x328(%rcx)\n" /* amd64_thread_data()->syscall_frame */
|
||||||
/* switch to thread stack */
|
"1:\tmovq %rax,%rsp\n\t"
|
||||||
"1:\tmovq 8(%r8),%rax\n\t" /* teb->Tib.StackBase */
|
"call " __ASM_NAME("call_init_thunk"))
|
||||||
"movq %rcx,%rbx\n\t" /* thunk */
|
|
||||||
"movq %r8,%rcx\n\t" /* teb */
|
|
||||||
"leaq -0x1000(%rax),%rsp\n\t"
|
|
||||||
/* attach dlls */
|
|
||||||
"call " __ASM_NAME("get_initial_context") "\n\t"
|
|
||||||
"movq %rax,%rcx\n\t" /* context */
|
|
||||||
"xorq %rax,%rax\n\t"
|
|
||||||
"pushq %rax\n\t"
|
|
||||||
"jmp *%rbx" )
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -736,7 +736,7 @@ 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, pLdrInitializeThunk, teb );
|
signal_start_thread( thread_data->start, thread_data->param, suspend, teb );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -236,7 +236,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 *thunk, TEB *teb ) DECLSPEC_HIDDEN;
|
BOOL suspend, TEB *teb ) DECLSPEC_HIDDEN;
|
||||||
extern void DECLSPEC_NORETURN signal_exit_thread( int status, void (*func)(int), TEB *teb ) DECLSPEC_HIDDEN;
|
extern void DECLSPEC_NORETURN signal_exit_thread( int status, void (*func)(int), TEB *teb ) DECLSPEC_HIDDEN;
|
||||||
extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN;
|
extern void __wine_syscall_dispatcher(void) DECLSPEC_HIDDEN;
|
||||||
extern void WINAPI DECLSPEC_NORETURN __wine_syscall_dispatcher_return( void *frame, ULONG_PTR retval ) DECLSPEC_HIDDEN;
|
extern void WINAPI DECLSPEC_NORETURN __wine_syscall_dispatcher_return( void *frame, ULONG_PTR retval ) DECLSPEC_HIDDEN;
|
||||||
|
|
Loading…
Reference in New Issue