diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 45d32399adf..ffbc9fabb23 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3819,7 +3819,6 @@ PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule) */ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknown3, ULONG_PTR unknown4 ) { - static const LARGE_INTEGER zero; static int attach_done; int i; NTSTATUS status; @@ -3898,8 +3897,6 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, void **entry, ULONG_PTR unknow } RtlLeaveCriticalSection( &loader_section ); - - NtDelayExecution( TRUE, &zero ); } diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index cd35c23aa91..378c40aa8b1 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -422,8 +422,9 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "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("set_cpu_context") ) + "b " __ASM_NAME("NtContinue") ) 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 add8b4385c4..1f2839844a6 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -88,18 +88,6 @@ static inline struct arm64_thread_data *arm64_thread_data(void) } -/*********************************************************************** - * set_cpu_context - * - * Set the new CPU context. - */ -static void set_cpu_context( const CONTEXT *context ) -{ - InterlockedExchangePointer( (void **)&arm64_thread_data()->context, (void *)context ); - raise( SIGUSR2 ); -} - - /*********************************************************************** * get_server_context_flags * @@ -261,8 +249,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) NTSTATUS ret = STATUS_SUCCESS; BOOL self = (handle == GetCurrentThread()); - if (self && (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_ARM64))) - self = FALSE; + if (self && (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_ARM64))) self = FALSE; if (!self) { @@ -270,7 +257,11 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) context_to_server( &server_context, context ); ret = set_thread_context( handle, &server_context, &self ); } - if (self && ret == STATUS_SUCCESS) set_cpu_context( context ); + if (self && ret == STATUS_SUCCESS) + { + InterlockedExchangePointer( (void **)&arm64_thread_data()->context, (void *)context ); + raise( SIGUSR2 ); + } return ret; } @@ -451,26 +442,8 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "msr fpcr, x1\n\t" "ldr w1, [x0, #0x314]\n\t" /* context->Fpsr */ "msr fpsr, x1\n\t" - "ldp x1, x2, [x0, #0x10]\n\t" /* context->X1,2 */ - "ldp x3, x4, [x0, #0x20]\n\t" /* context->X3,4 */ - "ldp x5, x6, [x0, #0x30]\n\t" /* context->X5,6 */ - "ldp x7, x8, [x0, #0x40]\n\t" /* context->X7,8 */ - "ldp x9, x10, [x0, #0x50]\n\t" /* context->X9,10 */ - "ldp x11, x12, [x0, #0x60]\n\t" /* context->X11,12 */ - "ldp x13, x14, [x0, #0x70]\n\t" /* context->X13,14 */ - "ldp x15, x16, [x0, #0x80]\n\t" /* context->X15,16 */ - "ldp x17, x18, [x0, #0x90]\n\t" /* context->X17,18 */ - "ldp x19, x20, [x0, #0xa0]\n\t" /* context->X19,20 */ - "ldp x21, x22, [x0, #0xb0]\n\t" /* context->X21,22 */ - "ldp x23, x24, [x0, #0xc0]\n\t" /* context->X23,24 */ - "ldp x25, x26, [x0, #0xd0]\n\t" /* context->X25,26 */ - "ldp x27, x28, [x0, #0xe0]\n\t" /* context->X27,28 */ - "ldp x29, x30, [x0, #0xf0]\n\t" /* context->Fp,Lr */ - "ldr x17, [x0, #0x100]\n\t" /* context->Sp */ - "mov sp, x17\n\t" - "ldr x17, [x0, #0x108]\n\t" /* context->Pc */ - "ldr x0, [x0, #0x8]\n\t" /* context->X0 */ - "br x17" ) + "mov x1, #1\n\t" + "b " __ASM_NAME("NtContinue") ) 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 515090d9af8..cbfcdf49db0 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -336,46 +336,6 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context, "iret" ) -/*********************************************************************** - * set_cpu_context - * - * Set the new CPU context. Used by NtSetContextThread. - */ -void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context ) -{ - DWORD flags = context->ContextFlags & ~CONTEXT_i386; - - if (flags & CONTEXT_EXTENDED_REGISTERS) restore_fpux( context ); - else if (flags & CONTEXT_FLOATING_POINT) restore_fpu( context ); - - if (flags & CONTEXT_DEBUG_REGISTERS) - { - x86_thread_data()->dr0 = context->Dr0; - x86_thread_data()->dr1 = context->Dr1; - x86_thread_data()->dr2 = context->Dr2; - x86_thread_data()->dr3 = context->Dr3; - x86_thread_data()->dr6 = context->Dr6; - x86_thread_data()->dr7 = context->Dr7; - } - if (flags & CONTEXT_FULL) - { - if (!(flags & CONTEXT_CONTROL)) - FIXME( "setting partial context (%x) not supported\n", flags ); - else if (flags & CONTEXT_SEGMENTS) - set_full_cpu_context( context ); - else - { - CONTEXT newcontext = *context; - newcontext.SegDs = get_ds(); - newcontext.SegEs = get_ds(); - newcontext.SegFs = get_fs(); - newcontext.SegGs = get_gs(); - set_full_cpu_context( &newcontext ); - } - } -} - - /*********************************************************************** * get_server_context_flags * @@ -545,10 +505,11 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) { NTSTATUS ret = STATUS_SUCCESS; + DWORD flags = context->ContextFlags & ~CONTEXT_i386; BOOL self = (handle == GetCurrentThread()); /* debug registers require a server call */ - if (self && (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_i386))) + if (self && (flags & CONTEXT_DEBUG_REGISTERS)) self = (x86_thread_data()->dr0 == context->Dr0 && x86_thread_data()->dr1 == context->Dr1 && x86_thread_data()->dr2 == context->Dr2 && @@ -561,9 +522,37 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) context_t server_context; context_to_server( &server_context, context ); ret = set_thread_context( handle, &server_context, &self ); + if (ret || !self) return ret; + if (flags & CONTEXT_DEBUG_REGISTERS) + { + x86_thread_data()->dr0 = context->Dr0; + x86_thread_data()->dr1 = context->Dr1; + x86_thread_data()->dr2 = context->Dr2; + x86_thread_data()->dr3 = context->Dr3; + x86_thread_data()->dr6 = context->Dr6; + x86_thread_data()->dr7 = context->Dr7; + } } - if (self && ret == STATUS_SUCCESS) set_cpu_context( context ); + if (flags & CONTEXT_EXTENDED_REGISTERS) restore_fpux( context ); + else if (flags & CONTEXT_FLOATING_POINT) restore_fpu( context ); + + if (flags & CONTEXT_FULL) + { + if (!(flags & CONTEXT_CONTROL)) + FIXME( "setting partial context (%x) not supported\n", flags ); + else if (flags & CONTEXT_SEGMENTS) + set_full_cpu_context( context ); + else + { + CONTEXT newcontext = *context; + newcontext.SegDs = get_ds(); + newcontext.SegEs = get_ds(); + newcontext.SegFs = get_fs(); + newcontext.SegGs = get_gs(); + set_full_cpu_context( &newcontext ); + } + } return ret; } @@ -1044,8 +1033,9 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "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("set_cpu_context") ) + "call " __ASM_NAME("NtContinue") ) /*********************************************************************** diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index aec0228de02..301968f78de 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -191,34 +191,6 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context, "iretq" ); -/*********************************************************************** - * set_cpu_context - * - * Set the new CPU context. Used by NtSetContextThread. - */ -void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context ) -{ - DWORD flags = context->ContextFlags & ~CONTEXT_AMD64; - - if (flags & CONTEXT_DEBUG_REGISTERS) - { - amd64_thread_data()->dr0 = context->Dr0; - amd64_thread_data()->dr1 = context->Dr1; - amd64_thread_data()->dr2 = context->Dr2; - amd64_thread_data()->dr3 = context->Dr3; - amd64_thread_data()->dr6 = context->Dr6; - amd64_thread_data()->dr7 = context->Dr7; - } - if (flags & CONTEXT_FULL) - { - if (!(flags & CONTEXT_CONTROL)) - FIXME( "setting partial context (%x) not supported\n", flags ); - else - set_full_cpu_context( context ); - } -} - - /*********************************************************************** * get_server_context_flags * @@ -437,10 +409,11 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from ) NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) { NTSTATUS ret = STATUS_SUCCESS; + DWORD flags = context->ContextFlags & ~CONTEXT_AMD64; BOOL self = (handle == GetCurrentThread()); /* debug registers require a server call */ - if (self && (context->ContextFlags & (CONTEXT_DEBUG_REGISTERS & ~CONTEXT_AMD64))) + if (self && (flags & CONTEXT_DEBUG_REGISTERS)) self = (amd64_thread_data()->dr0 == context->Dr0 && amd64_thread_data()->dr1 == context->Dr1 && amd64_thread_data()->dr2 == context->Dr2 && @@ -451,10 +424,28 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context ) if (!self) { context_t server_context; + context_to_server( &server_context, context ); ret = set_thread_context( handle, &server_context, &self ); + if (ret || !self) return ret; + if (flags & CONTEXT_DEBUG_REGISTERS) + { + amd64_thread_data()->dr0 = context->Dr0; + amd64_thread_data()->dr1 = context->Dr1; + amd64_thread_data()->dr2 = context->Dr2; + amd64_thread_data()->dr3 = context->Dr3; + amd64_thread_data()->dr6 = context->Dr6; + amd64_thread_data()->dr7 = context->Dr7; + } + } + + if (flags & CONTEXT_FULL) + { + if (!(flags & CONTEXT_CONTROL)) + FIXME( "setting partial context (%x) not supported\n", flags ); + else + set_full_cpu_context( context ); } - if (self && ret == STATUS_SUCCESS) set_cpu_context( context ); return ret; } @@ -724,14 +715,16 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "leaq -0x1000(%rax),%rsp\n\t" /* attach dlls */ "call " __ASM_NAME("attach_thread") "\n\t" - "movq %rax,%rsp\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 */ - "movq %rsp,%rdi\n\t" - "call " __ASM_NAME("set_cpu_context") ) + "movl $1,%edx\n\t" + "movq %rbx,%rcx\n\t" + "call " __ASM_NAME("NtContinue") ) /***********************************************************************