Commit a5745ba9 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

ntdll: Connect syscall frames across user callbacks on x86-64.

parent 578a730a
...@@ -2641,8 +2641,6 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, ...@@ -2641,8 +2641,6 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"1:\txsave64 0xc0(%rcx)\n\t" "1:\txsave64 0xc0(%rcx)\n\t"
"jmp 3f\n" "jmp 3f\n"
"2:\tfxsave64 0xc0(%rcx)\n" "2:\tfxsave64 0xc0(%rcx)\n"
/* remember state when $rcx is pointing to "frame" */
__ASM_CFI(".cfi_remember_state\n\t")
"3:\tleaq 0x98(%rcx),%rbp\n\t" "3:\tleaq 0x98(%rcx),%rbp\n\t"
__ASM_CFI_CFA_IS_AT1(rbp, 0x70) __ASM_CFI_CFA_IS_AT1(rbp, 0x70)
__ASM_CFI_REG_IS_AT1(rip, rbp, 0x58) __ASM_CFI_REG_IS_AT1(rip, rbp, 0x58)
...@@ -2673,6 +2671,17 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, ...@@ -2673,6 +2671,17 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"leaq 0x38(%rsp),%rsi\n\t" /* 7th argument */ "leaq 0x38(%rsp),%rsi\n\t" /* 7th argument */
/* switch to kernel stack */ /* switch to kernel stack */
"movq %rcx,%rsp\n\t" "movq %rcx,%rsp\n\t"
/* we're now on the kernel stack, stitch unwind info with previous frame */
__ASM_CFI_CFA_IS_AT1(rbp, 0x10) /* 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 0x00(%rcx),%rax\n\t" "movq 0x00(%rcx),%rax\n\t"
"movq 0x18(%rcx),%r11\n\t" /* 2nd argument */ "movq 0x18(%rcx),%r11\n\t" /* 2nd argument */
"movl %eax,%ebx\n\t" "movl %eax,%ebx\n\t"
...@@ -2702,8 +2711,6 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, ...@@ -2702,8 +2711,6 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"movq (%rbx),%r10\n\t" /* table->ServiceTable */ "movq (%rbx),%r10\n\t" /* table->ServiceTable */
"callq *(%r10,%rax,8)\n\t" "callq *(%r10,%rax,8)\n\t"
"leaq -0x98(%rbp),%rcx\n\t" "leaq -0x98(%rbp),%rcx\n\t"
/* $rcx is now pointing to "frame" again */
__ASM_CFI(".cfi_restore_state\n")
__ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") ":\n\t" __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") ":\n\t"
"movl 0xb4(%rcx),%edx\n\t" /* frame->restore_flags */ "movl 0xb4(%rcx),%edx\n\t" /* frame->restore_flags */
#ifdef __linux__ #ifdef __linux__
...@@ -2736,49 +2743,50 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, ...@@ -2736,49 +2743,50 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"jmp 4f\n" "jmp 4f\n"
"3:\tfxrstor64 0xc0(%rcx)\n" "3:\tfxrstor64 0xc0(%rcx)\n"
"4:\tmovq 0x98(%rcx),%rbp\n\t" "4:\tmovq 0x98(%rcx),%rbp\n\t"
__ASM_CFI(".cfi_same_value rbp\n\t") /* push rbp-based kernel stack cfi */
__ASM_CFI("\t.cfi_remember_state\n")
__ASM_CFI_CFA_IS_AT2(rcx, 0xa8, 0x01) /* frame->syscall_cfa */
"movq 0x68(%rcx),%r15\n\t" "movq 0x68(%rcx),%r15\n\t"
__ASM_CFI(".cfi_same_value r15\n\t")
"movq 0x60(%rcx),%r14\n\t" "movq 0x60(%rcx),%r14\n\t"
__ASM_CFI(".cfi_same_value r14\n\t")
"movq 0x58(%rcx),%r13\n\t" "movq 0x58(%rcx),%r13\n\t"
__ASM_CFI(".cfi_same_value r13\n\t")
"movq 0x50(%rcx),%r12\n\t" "movq 0x50(%rcx),%r12\n\t"
__ASM_CFI(".cfi_same_value r12\n\t")
"movq 0x28(%rcx),%rdi\n\t" "movq 0x28(%rcx),%rdi\n\t"
__ASM_CFI(".cfi_same_value rdi\n\t")
"movq 0x20(%rcx),%rsi\n\t" "movq 0x20(%rcx),%rsi\n\t"
__ASM_CFI(".cfi_same_value rsi\n\t")
"movq 0x08(%rcx),%rbx\n\t" "movq 0x08(%rcx),%rbx\n\t"
__ASM_CFI(".cfi_same_value rbx\n\t")
"testl $0x3,%edx\n\t" /* CONTEXT_CONTROL | CONTEXT_INTEGER */ "testl $0x3,%edx\n\t" /* CONTEXT_CONTROL | CONTEXT_INTEGER */
"jnz 1f\n\t" "jnz 1f\n\t"
__ASM_CFI(".cfi_remember_state\n\t")
"movq 0x80(%rcx),%r11\n\t" /* frame->eflags */ "movq 0x80(%rcx),%r11\n\t" /* frame->eflags */
"pushq %r11\n\t" "pushq %r11\n\t"
"popfq\n\t" "popfq\n\t"
/* switch to user stack */ /* switch to user stack */
"movq 0x88(%rcx),%rsp\n\t" "movq 0x88(%rcx),%rsp\n\t"
__ASM_CFI(".cfi_def_cfa rsp, 0\n\t") /* push rcx-based kernel stack cfi */
__ASM_CFI("\t.cfi_remember_state\n")
__ASM_CFI(".cfi_def_cfa %rsp, 0\n\t")
__ASM_CFI_REG_IS_AT2(rip, rcx, 0xf0, 0x00)
__ASM_CFI(".cfi_same_value %rbp\n\t")
__ASM_CFI(".cfi_same_value %rbx\n\t")
__ASM_CFI(".cfi_same_value %r12\n\t")
__ASM_CFI(".cfi_same_value %r13\n\t")
__ASM_CFI(".cfi_same_value %r14\n\t")
__ASM_CFI(".cfi_same_value %r15\n\t")
__ASM_CFI(".cfi_same_value %rdi\n\t")
__ASM_CFI(".cfi_same_value %rsi\n\t")
"movq 0x70(%rcx),%rcx\n\t" /* frame->rip */ "movq 0x70(%rcx),%rcx\n\t" /* frame->rip */
__ASM_CFI(".cfi_register rip, rcx\n\t") __ASM_CFI(".cfi_register rip, rcx\n\t")
"pushq %rcx\n\t" "pushq %rcx\n\t"
__ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
"ret\n\t" "ret\n\t"
/* $rcx is now pointing to "frame" again */ /* pop rcx-based kernel stack cfi */
__ASM_CFI(".cfi_restore_state\n\t") __ASM_CFI("\t.cfi_restore_state\n")
/* remember state when $rcx is pointing to "frame" */
__ASM_CFI(".cfi_remember_state\n\t")
"1:\tleaq 0x70(%rcx),%rsp\n\t" "1:\tleaq 0x70(%rcx),%rsp\n\t"
__ASM_CFI_CFA_IS_AT1(rsp, 0x18)
__ASM_CFI_REG_IS_AT1(rip, rsp, 0x00)
"testl $0x2,%edx\n\t" /* CONTEXT_INTEGER */ "testl $0x2,%edx\n\t" /* CONTEXT_INTEGER */
"jnz 1f\n\t" "jnz 1f\n\t"
"movq 0x10(%rsp),%r11\n\t" /* frame->eflags */ "movq 0x10(%rsp),%r11\n\t" /* frame->eflags */
"movq (%rsp),%rcx\n\t" /* frame->rip */ "movq (%rsp),%rcx\n\t" /* frame->rip */
__ASM_CFI(".cfi_register rip, rcx\n\t")
"iretq\n" "iretq\n"
__ASM_CFI_REG_IS_AT1(rip, rsp, 0x00)
"1:\tmovq 0x00(%rcx),%rax\n\t" "1:\tmovq 0x00(%rcx),%rax\n\t"
"movq 0x18(%rcx),%rdx\n\t" "movq 0x18(%rcx),%rdx\n\t"
"movq 0x30(%rcx),%r8\n\t" "movq 0x30(%rcx),%r8\n\t"
...@@ -2787,20 +2795,11 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, ...@@ -2787,20 +2795,11 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"movq 0x48(%rcx),%r11\n\t" "movq 0x48(%rcx),%r11\n\t"
"movq 0x10(%rcx),%rcx\n" "movq 0x10(%rcx),%rcx\n"
"iretq\n" "iretq\n"
__ASM_CFI_CFA_IS_AT1(rbp, 0x70)
__ASM_CFI_REG_IS_AT1(rip, rbp, 0x58) /* pop rbp-based kernel stack cfi */
__ASM_CFI_REG_IS_AT2(rbx, rbp, 0xf0, 0x7e) __ASM_CFI("\t.cfi_restore_state\n")
__ASM_CFI_REG_IS_AT2(rsi, rbp, 0x88, 0x7f)
__ASM_CFI_REG_IS_AT2(rdi, rbp, 0x90, 0x7f)
__ASM_CFI_REG_IS_AT2(r12, rbp, 0xb8, 0x7f)
__ASM_CFI_REG_IS_AT1(r13, rbp, 0x40)
__ASM_CFI_REG_IS_AT1(r14, rbp, 0x48)
__ASM_CFI_REG_IS_AT1(r15, rbp, 0x50)
__ASM_CFI_REG_IS_AT1(rbp, rbp, 0x00)
"5:\tmovl $0xc000000d,%eax\n\t" /* STATUS_INVALID_PARAMETER */ "5:\tmovl $0xc000000d,%eax\n\t" /* STATUS_INVALID_PARAMETER */
"movq %rsp,%rcx\n\t" "movq %rsp,%rcx\n\t"
/* $rcx is now pointing to "frame" again */
__ASM_CFI(".cfi_restore_state\n\t")
"jmp " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t" "jmp " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t"
".globl " __ASM_NAME("__wine_syscall_dispatcher_return") "\n" ".globl " __ASM_NAME("__wine_syscall_dispatcher_return") "\n"
__ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t" __ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t"
...@@ -2873,6 +2872,17 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, ...@@ -2873,6 +2872,17 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher,
#endif #endif
/* switch to kernel stack */ /* switch to kernel stack */
"movq %rcx,%rsp\n" "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 */ "movq %r8,%rdi\n\t" /* args */
"callq *(%r10,%rdx,8)\n\t" "callq *(%r10,%rdx,8)\n\t"
"movq %rsp,%rcx\n" "movq %rsp,%rcx\n"
...@@ -2895,14 +2905,20 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, ...@@ -2895,14 +2905,20 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher,
"1:\n\t" "1:\n\t"
#endif #endif
"movq 0x60(%rcx),%r14\n\t" "movq 0x60(%rcx),%r14\n\t"
__ASM_CFI(".cfi_same_value r14\n\t")
"movq 0x28(%rcx),%rdi\n\t" "movq 0x28(%rcx),%rdi\n\t"
__ASM_CFI(".cfi_same_value rdi\n\t")
"movq 0x20(%rcx),%rsi\n\t" "movq 0x20(%rcx),%rsi\n\t"
/* switch to user stack */ /* switch to user stack */
__ASM_CFI(".cfi_same_value rsi\n\t")
"movq 0x88(%rcx),%rsp\n\t" "movq 0x88(%rcx),%rsp\n\t"
__ASM_CFI(".cfi_def_cfa rsp, 0\n\t") __ASM_CFI(".cfi_def_cfa %rsp, 0\n\t")
__ASM_CFI_REG_IS_AT2(rip, rcx, 0x70, 0x00)
__ASM_CFI(".cfi_undefined %rbp\n\t")
__ASM_CFI(".cfi_undefined %rbx\n\t")
__ASM_CFI(".cfi_undefined %r12\n\t")
__ASM_CFI(".cfi_undefined %r13\n\t")
__ASM_CFI(".cfi_same_value %r14\n\t")
__ASM_CFI(".cfi_undefined %r15\n\t")
__ASM_CFI(".cfi_same_value %rdi\n\t")
__ASM_CFI(".cfi_same_value %rsi\n\t")
"pushq 0x70(%rcx)\n\t" /* frame->rip */ "pushq 0x70(%rcx)\n\t" /* frame->rip */
__ASM_CFI(".cfi_adjust_cfa_offset 8\n\t") __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
"ret" ) "ret" )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment