From: Rémi Bernon rbernon@codeweavers.com
--- dlls/ntdll/unix/signal_x86_64.c | 93 ++++++++++++++++++--------------- 1 file changed, 52 insertions(+), 41 deletions(-)
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 0c291633ac6..d69c0fbf78d 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1596,14 +1596,14 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, "movl %r14d,0xb0(%rsp)\n\t" /* frame->syscall_flags */ "movq %r10,0xa0(%rsp)\n\t" /* frame->prev_frame */ "movq %rsp,0x328(%r8)\n\t" /* amd64_thread_data()->syscall_frame */ + /* switch to user stack */ + "movq %rdi,%rsp\n\t" /* user_rsp */ #ifdef __linux__ "testl $12,%r14d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB | SYSCALL_HAVE_WRFSGSBASE */ "jz 1f\n\t" "movw 0x338(%r8),%fs\n" /* amd64_thread_data()->fs */ "1:\n\t" #endif - /* switch to user stack */ - "movq %rdi,%rsp\n\t" /* user_rsp */ "jmpq *%rcx" ) /* func */
@@ -2666,20 +2666,6 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, __ASM_CFI_REG_IS_AT1(r14, rbp, 0x48) __ASM_CFI_REG_IS_AT1(r15, rbp, 0x50) __ASM_CFI_REG_IS_AT1(rbp, rbp, 0x00) -#ifdef __linux__ - "testl $12,%r14d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB | SYSCALL_HAVE_WRFSGSBASE */ - "jz 2f\n\t" - "movq %gs:0x320,%rsi\n\t" /* amd64_thread_data()->pthread_teb */ - "testl $8,%r14d\n\t" /* SYSCALL_HAVE_WRFSGSBASE */ - "jz 1f\n\t" - "wrfsbase %rsi\n\t" - "jmp 2f\n" - "1:\tmov $0x1002,%edi\n\t" /* ARCH_SET_FS */ - "mov $158,%eax\n\t" /* SYS_arch_prctl */ - "syscall\n\t" - "leaq -0x98(%rbp),%rcx\n" - "2:\n\t" -#endif "movq 0x28(%rsp),%r12\n\t" /* 5th argument */ "movq 0x30(%rsp),%r13\n\t" /* 6th argument */ "leaq 0x38(%rsp),%rsi\n\t" /* 7th argument */ @@ -2696,6 +2682,22 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, __ASM_CFI(".cfi_offset %r15,-0x38\n\t") __ASM_CFI(".cfi_undefined %rdi\n\t") __ASM_CFI(".cfi_undefined %rsi\n\t") +#ifdef __linux__ + "mov %rsi,%r15\n\t" + "testl $12,%r14d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB | SYSCALL_HAVE_WRFSGSBASE */ + "jz 2f\n\t" + "movq %gs:0x320,%rsi\n\t" /* amd64_thread_data()->pthread_teb */ + "testl $8,%r14d\n\t" /* SYSCALL_HAVE_WRFSGSBASE */ + "jz 1f\n\t" + "wrfsbase %rsi\n\t" + "jmp 2f\n" + "1:\tmov $0x1002,%edi\n\t" /* ARCH_SET_FS */ + "mov $158,%eax\n\t" /* SYS_arch_prctl */ + "syscall\n\t" + "leaq -0x98(%rbp),%rcx\n" + "2:\n\t" + "mov %r15,%rsi\n\t" +#endif "movq 0x00(%rcx),%rax\n\t" "movq 0x18(%rcx),%r11\n\t" /* 2nd argument */ "movl %eax,%ebx\n\t" @@ -2732,12 +2734,6 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "leaq -0x98(%rbp),%rcx\n\t" __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") ":\n\t" "movl 0xb4(%rcx),%edx\n\t" /* frame->restore_flags */ -#ifdef __linux__ - "testl $12,%r14d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB | SYSCALL_HAVE_WRFSGSBASE */ - "jz 1f\n\t" - "movw %gs:0x338,%fs\n" /* amd64_thread_data()->fs */ - "1:\n\t" -#endif "testl $0x48,%edx\n\t" /* CONTEXT_FLOATING_POINT | CONTEXT_XSTATE */ "jnz 2f\n\t" "movaps 0x1c0(%rcx),%xmm6\n\t" @@ -2792,6 +2788,13 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, __ASM_CFI(".cfi_same_value %r15\n\t") __ASM_CFI(".cfi_same_value %rdi\n\t") __ASM_CFI(".cfi_same_value %rsi\n\t") +#ifdef __linux__ + "movl 0xb0(%rcx),%r9d\n\t" /* frame->syscall_flags */ + "testl $12,%r9d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB | SYSCALL_HAVE_WRFSGSBASE */ + "jz 2f\n\t" + "movw %gs:0x338,%fs\n" /* amd64_thread_data()->fs */ + "2:\n\t" +#endif "movq 0x70(%rcx),%rcx\n\t" /* frame->rip */ __ASM_CFI(".cfi_register rip, rcx\n\t") "pushq %rcx\n\t" @@ -2801,6 +2804,13 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, __ASM_CFI("\t.cfi_restore_state\n")
"1:\tleaq 0x70(%rcx),%rsp\n\t" +#ifdef __linux__ + "movl 0xb0(%rcx),%r9d\n\t" /* frame->syscall_flags */ + "testl $12,%r9d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB | SYSCALL_HAVE_WRFSGSBASE */ + "jz 1f\n\t" + "movw %gs:0x338,%fs\n" /* amd64_thread_data()->fs */ + "1:\n\t" +#endif "testl $0x2,%edx\n\t" /* CONTEXT_INTEGER */ "jnz 1f\n\t" "movq 0x10(%rsp),%r11\n\t" /* frame->eflags */ @@ -2873,6 +2883,19 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "movdqa %xmm14,0x240(%rcx)\n\t" "movdqa %xmm15,0x250(%rcx)\n\t" "movl 0xb0(%rcx),%r14d\n\t" /* frame->syscall_flags */ + /* switch to kernel stack */ + "movq %rcx,%rsp\n" + /* we're now on the kernel stack, stitch unwind info with previous frame */ + __ASM_CFI_CFA_IS_AT2(rsp, 0xa8, 0x01) /* frame->syscall_cfa */ + __ASM_CFI(".cfi_offset %rip,-0x08\n\t") + __ASM_CFI(".cfi_offset %rbp,-0x10\n\t") + __ASM_CFI(".cfi_offset %rbx,-0x18\n\t") + __ASM_CFI(".cfi_offset %r12,-0x20\n\t") + __ASM_CFI(".cfi_offset %r13,-0x28\n\t") + __ASM_CFI(".cfi_offset %r14,-0x30\n\t") + __ASM_CFI(".cfi_offset %r15,-0x38\n\t") + __ASM_CFI(".cfi_undefined %rdi\n\t") + __ASM_CFI(".cfi_undefined %rsi\n\t") #ifdef __linux__ "testl $12,%r14d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB | SYSCALL_HAVE_WRFSGSBASE */ "jz 2f\n\t" @@ -2888,19 +2911,6 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "mov %r9,%rcx\n\t" "2:\n\t" #endif - /* switch to kernel stack */ - "movq %rcx,%rsp\n" - /* we're now on the kernel stack, stitch unwind info with previous frame */ - __ASM_CFI_CFA_IS_AT2(rsp, 0xa8, 0x01) /* frame->syscall_cfa */ - __ASM_CFI(".cfi_offset %rip,-0x08\n\t") - __ASM_CFI(".cfi_offset %rbp,-0x10\n\t") - __ASM_CFI(".cfi_offset %rbx,-0x18\n\t") - __ASM_CFI(".cfi_offset %r12,-0x20\n\t") - __ASM_CFI(".cfi_offset %r13,-0x28\n\t") - __ASM_CFI(".cfi_offset %r14,-0x30\n\t") - __ASM_CFI(".cfi_offset %r15,-0x38\n\t") - __ASM_CFI(".cfi_undefined %rdi\n\t") - __ASM_CFI(".cfi_undefined %rsi\n\t") "movq %r8,%rdi\n\t" /* args */ "callq *(%r10,%rdx,8)\n\t" "movq %rsp,%rcx\n" @@ -2916,12 +2926,6 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "movdqa 0x250(%rcx),%xmm15\n\t" "testl $0xffff,0xb4(%rcx)\n\t" /* frame->restore_flags */ "jnz " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t" -#ifdef __linux__ - "testl $12,%r14d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB | SYSCALL_HAVE_WRFSGSBASE */ - "jz 1f\n\t" - "movw %gs:0x338,%fs\n" /* amd64_thread_data()->fs */ - "1:\n\t" -#endif "movq 0x60(%rcx),%r14\n\t" "movq 0x28(%rcx),%rdi\n\t" "movq 0x20(%rcx),%rsi\n\t" @@ -2937,6 +2941,13 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, __ASM_CFI(".cfi_undefined %r15\n\t") __ASM_CFI(".cfi_same_value %rdi\n\t") __ASM_CFI(".cfi_same_value %rsi\n\t") +#ifdef __linux__ + "movl 0xb0(%rcx),%r9d\n\t" /* frame->syscall_flags */ + "testl $12,%r9d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB | SYSCALL_HAVE_WRFSGSBASE */ + "jz 1f\n\t" + "movw %gs:0x338,%fs\n" /* amd64_thread_data()->fs */ + "1:\n\t" +#endif "pushq 0x70(%rcx)\n\t" /* frame->rip */ __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") "ret" )