From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52213 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54346 --- dlls/ntdll/unix/signal_arm.c | 7 +++++++ dlls/ntdll/unix/signal_arm64.c | 6 ++++++ dlls/ntdll/unix/signal_i386.c | 7 +++++++ dlls/ntdll/unix/signal_x86_64.c | 6 ++++++ 4 files changed, 26 insertions(+)
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c index 28cb2222809..ea062f0520c 100644 --- a/dlls/ntdll/unix/signal_arm.c +++ b/dlls/ntdll/unix/signal_arm.c @@ -1173,6 +1173,7 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, "str sp, [r4, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */ "ldr r6, [r5, #0x50]\n\t" /* prev_frame->syscall_table */ "str r6, [sp, #0x50]\n\t" /* frame->syscall_table */ + /* switch to user stack */ "mov sp, r1\n\t" "bx ip" )
@@ -1618,6 +1619,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "cbnz r6, 1f\n\t" "sub r6, sp, #0x160\n\t" /* sizeof(struct syscall_frame) */ "str r6, [r3, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */ + /* switch to kernel stack */ "1:\tmov sp, r6\n\t" "bl " __ASM_NAME("call_init_thunk") )
@@ -1660,6 +1662,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "vstm r0, {d0-d15}\n\t" #endif "mov r6, sp\n\t" + /* switch to kernel stack */ "mov sp, r1\n\t" "mov r8, r1\n\t" "ldr r5, [r1, #0x50]\n\t" /* frame->syscall_table */ @@ -1700,9 +1703,11 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "it ne\n\t" "ldmne r8, {r0-r3}\n\t" "ldr lr, [r8, #0x3c]\n\t" + /* switch to user stack */ "ldr sp, [r8, #0x38]\n\t" "add r8, r8, #0x10\n\t" "ldm r8, {r4-r12,pc}\n" + "5:\tmovw r0, #0x000d\n\t" /* STATUS_INVALID_PARAMETER */ "movt r0, #0xc000\n\t" "add sp, sp, #0x10\n\t" @@ -1737,12 +1742,14 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "vstm r4, {d0-d15}\n\t" #endif "ldr ip, [r0, r2, lsl #2]\n\t" + /* switch to kernel stack */ "mov sp, r1\n\t" "mov r0, r3\n\t" /* args */ "blx ip\n" "mov r8, sp\n\t" "ldr r1, [r8, #0x44]\n\t" /* frame->restore_flags */ "cbnz r1, 1f\n\t" + /* switch to user stack */ "ldr sp, [r8, #0x38]\n\t" "add r8, r8, #0x10\n\t" "ldm r8, {r4-r12,pc}\n\t" diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c index 4897b8e1824..db5e86a3f5f 100644 --- a/dlls/ntdll/unix/signal_arm64.c +++ b/dlls/ntdll/unix/signal_arm64.c @@ -1133,6 +1133,7 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, "sub x3, sp, #0x330\n\t" /* sizeof(struct syscall_frame) */ "str x3, [x18, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */ "ldr x8, [x7, #0x118]\n\t" /* prev_frame->syscall_table */ + /* switch to user stack */ "mov sp, x1\n\t" /* stack */ "stp x7, x8, [x3, #0x110]\n\t" /* frame->prev_frame, frame->syscall_table */ "br x5" ) @@ -1682,6 +1683,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "cbnz x8, 1f\n\t" "sub x8, sp, #0x330\n\t" /* sizeof(struct syscall_frame) */ "str x8, [x3, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */ + /* switch to kernel stack */ "1:\tmov sp, x8\n\t" "bl " __ASM_NAME("call_init_thunk") )
@@ -1733,6 +1735,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "stp q26, q27, [x10, #0x2d0]\n\t" "stp q28, q29, [x10, #0x2f0]\n\t" "stp q30, q31, [x10, #0x310]\n\t" + /* switch to kernel stack */ "mov sp, x10\n\t" "and x20, x8, #0xfff\n\t" /* syscall number */ "ubfx x21, x8, #12, #2\n\t" /* syscall table number */ @@ -1804,6 +1807,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "1:\tldp x16, x17, [sp, #0x100]\n\t" "msr NZCV, x17\n\t" "ldp x30, x17, [sp, #0xf0]\n\t" + /* switch to user stack */ "mov sp, x17\n\t" "ret x16\n" "4:\tmov x0, #0xc0000000\n\t" /* STATUS_INVALID_PARAMETER */ @@ -1835,6 +1839,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "stp x30, x9, [x10, #0xf0]\n\t" "mrs x9, NZCV\n\t" "stp x30, x9, [x10, #0x100]\n\t" + /* switch to kernel stack */ "mov sp, x10\n\t" "ldr x16, [x0, x1, lsl 3]\n\t" "mov x0, x2\n\t" /* args */ @@ -1843,6 +1848,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "cbnz w16, " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t" "ldr x18, [sp, #0x90]\n\t" "ldp x16, x17, [sp, #0xf8]\n\t" + /* switch to user stack */ "mov sp, x16\n\t" "ret x17" )
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index 293b8689c06..9485ffe6a85 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -1602,6 +1602,7 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, "movl %esp,0x1f8(%edx)\n\t" /* x86_thread_data()->syscall_frame */ "movl 0x1c(%ebp),%ecx\n\t" /* func */ "movl 0x0c(%ebp),%edx\n\t" /* args */ + /* switch to user stack */ "leal -4(%edx),%esp\n\t" "pushl 0x10(%ebp)\n\t" /* len */ "pushl %edx\n\t" /* args */ @@ -2491,6 +2492,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "leal -0x380(%esp),%eax\n\t" /* sizeof(struct syscall_frame) */ "andl $~63,%eax\n\t" "movl %eax,0x1f8(%ecx)\n" /* x86_thread_data()->syscall_frame */ + /* switch to kernel stack */ "1:\tmovl %eax,%esp\n\t" "pushl %ecx\n\t" /* teb */ "pushl 16(%ebp)\n\t" /* suspend */ @@ -2604,6 +2606,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "jmp 4f\n" "3:\tfnsave 0x40(%ecx)\n\t" "fwait\n" + /* switch to kernel stack */ "4:\tmovl %ecx,%esp\n\t" "movl 0x1c(%esp),%edx\n\t" /* frame->eax */ "andl $0xfff,%edx\n\t" /* syscall number */ @@ -2660,6 +2663,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, __ASM_CFI(".cfi_same_value %ebx\n\t") "movl 0x08(%esp),%ecx\n\t" /* frame->eip */ __ASM_CFI(".cfi_register %eip, %ecx\n\t") + /* switch to user stack */ "movl 0x0c(%esp),%esp\n\t" /* frame->esp */ __ASM_CFI(".cfi_same_value %esp\n\t") "pushl %ecx\n\t" @@ -2674,6 +2678,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "1:\tmovl 0x0c(%esp),%ebx\n\t" /* frame->esp */ __ASM_CFI(".cfi_register %esp, %ebx\n\t") "movw 0x12(%esp),%ss\n\t" + /* switch to user stack */ "xchgl %ebx,%esp\n\t" __ASM_CFI(".cfi_def_cfa %esp, 0\n\t") __ASM_CFI(".cfi_same_value %esp\n\t") @@ -2749,6 +2754,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "movl %edx,-16(%ecx)\n\t" "movl (%esp),%eax\n\t" /* handle */ "movl 8(%esp),%edx\n\t" /* code */ + /* switch to kernel stack */ "leal -16(%ecx),%esp\n\t" "call *(%eax,%edx,4)\n\t" "leal 16(%esp),%esp\n\t" @@ -2763,6 +2769,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "jnz " __ASM_LOCAL_LABEL("__wine_syscall_dispatcher_return") "\n\t" "movl 0x08(%esp),%ecx\n\t" /* frame->eip */ __ASM_CFI(".cfi_register %eip, %ecx\n\t") + /* switch to user stack */ "movl 0x0c(%esp),%esp\n\t" /* frame->esp */ __ASM_CFI(".cfi_same_value %esp\n\t") "pushl %ecx\n\t" diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index eac5d961a07..525fbd03a57 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -1593,6 +1593,7 @@ __ASM_GLOBAL_FUNC( call_user_mode_callback, "movq %rdi,%rcx\n\t" /* id */ "movq %rdx,%r8\n\t" /* len */ "movq %rsi,%rdx\n\t" /* args */ + /* switch to user stack */ "leaq -0x20(%rsi),%rsp\n\t" "push $0\n\t" "jmpq *%r9" ) @@ -2544,6 +2545,7 @@ __ASM_GLOBAL_FUNC( signal_start_thread, "leaq -0x400(%rsp),%rax\n\t" /* sizeof(struct syscall_frame) */ "andq $~63,%rax\n\t" "movq %rax,0x328(%rcx)\n" /* amd64_thread_data()->syscall_frame */ + /* switch to kernel stack */ "1:\tmovq %rax,%rsp\n\t" "call " __ASM_NAME("call_init_thunk"))
@@ -2668,6 +2670,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "movq 0x28(%rsp),%r12\n\t" /* 5th argument */ "movq 0x30(%rsp),%r13\n\t" /* 6th argument */ "leaq 0x38(%rsp),%rsi\n\t" /* 7th argument */ + /* switch to kernel stack */ "movq %rcx,%rsp\n\t" "movq 0x00(%rcx),%rax\n\t" "movq 0x18(%rcx),%r11\n\t" /* 2nd argument */ @@ -2753,6 +2756,7 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "movq 0x80(%rcx),%r11\n\t" /* frame->eflags */ "pushq %r11\n\t" "popfq\n\t" + /* switch to user stack */ "movq 0x88(%rcx),%rsp\n\t" __ASM_CFI(".cfi_def_cfa rsp, 0\n\t") __ASM_CFI(".cfi_same_value rsp\n\t") @@ -2870,6 +2874,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "mov %r9,%rcx\n\t" "2:\n\t" #endif + /* switch to kernel stack */ "movq %rcx,%rsp\n" "movq %r8,%rdi\n\t" /* args */ "callq *(%r10,%rdx,8)\n\t" @@ -2897,6 +2902,7 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "movq 0x28(%rcx),%rdi\n\t" __ASM_CFI(".cfi_same_value rdi\n\t") "movq 0x20(%rcx),%rsi\n\t" + /* switch to user stack */ __ASM_CFI(".cfi_same_value rsi\n\t") "movq 0x88(%rcx),%rsp\n\t" __ASM_CFI(".cfi_def_cfa rsp, 0\n\t")