From: Rémi Bernon rbernon@codeweavers.com
--- dlls/ntdll/unix/signal_i386.c | 15 ++++++++++++++- dlls/ntdll/unix/signal_x86_64.c | 26 ++++++++++++++++++++++++-- tools/winebuild/import.c | 4 ++++ 3 files changed, 42 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c index efb7cc497ef..60a4696ef48 100644 --- a/dlls/ntdll/unix/signal_i386.c +++ b/dlls/ntdll/unix/signal_i386.c @@ -2582,6 +2582,8 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "shrl $8,%ebx\n\t" "andl $0x30,%ebx\n\t" /* syscall table number */ "addl 0x38(%ecx),%ebx\n\t" /* frame->syscall_table */ + "cmpl $0xfa57ca11,0x1c(%ecx)\n\t" + "je 5f\n\t" "testl $3,(%ecx)\n\t" /* frame->syscall_flags & (SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC) */ "jz 2f\n\t" "movl $7,%eax\n\t" @@ -2613,7 +2615,18 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "fxsave 0x40(%ecx)\n\t" "jmp 4f\n" "3:\tfnsave 0x40(%ecx)\n\t" - "fwait\n" + "fwait\n\t" + "jmp 4f\n" + "5:\tmovl %ecx,%esp\n\t" + "subl $4,%esp\n\t" + "andl $~15,%esp\n\t" + "movl 0xc(%esi),%eax\n\t" + "movl %eax,(%esp)\n\t" + "movl 0x8(%esi),%eax\n\t" + "movl (%esi),%edx\n\t" + "call *(%edx,%eax,4)\n\t" + "leal -0x34(%ebp),%esp\n" + "jmp 5f\n" "4:\tmovl %ecx,%esp\n\t" "movl 0x1c(%esp),%edx\n\t" /* frame->eax */ "andl $0xfff,%edx\n\t" /* syscall number */ diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 263bb64c8cc..7150779e24b 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2665,6 +2665,8 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, * depends on us returning to it. Adjust the return address accordingly. */ "subq $0xb,0x70(%rcx)\n\t" "movl 0xb0(%rcx),%r14d\n\t" /* frame->syscall_flags */ + "cmpl $0xfa57ca11,%eax\n\t" + "je 4f\n\t" "testl $3,%r14d\n\t" /* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */ "jz 2f\n\t" "movl $7,%eax\n\t" @@ -2683,7 +2685,20 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "jmp 3f\n" "1:\txsave64 0xc0(%rcx)\n\t" "jmp 3f\n" - "2:\tfxsave64 0xc0(%rcx)\n" + "2:\tfxsave64 0xc0(%rcx)\n\t" + "jmp 3f\n" + "4:\tstmxcsr 0xd8(%rcx)\n\t" + "fnstcw 0xc0(%rcx)\n\t" + "movdqa %xmm6,0x1c0(%rcx)\n\t" + "movdqa %xmm7,0x1d0(%rcx)\n\t" + "movdqa %xmm8,0x1e0(%rcx)\n\t" + "movdqa %xmm9,0x1f0(%rcx)\n\t" + "movdqa %xmm10,0x200(%rcx)\n\t" + "movdqa %xmm11,0x210(%rcx)\n\t" + "movdqa %xmm12,0x220(%rcx)\n\t" + "movdqa %xmm13,0x230(%rcx)\n\t" + "movdqa %xmm14,0x240(%rcx)\n\t" + "movdqa %xmm15,0x250(%rcx)\n" /* remember state when $rcx is pointing to "frame" */ __ASM_CFI(".cfi_remember_state\n\t") "3:\tleaq 0x98(%rcx),%rbp\n\t" @@ -2716,7 +2731,14 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "movq %rcx,%rsp\n\t" "movq 0x00(%rcx),%rax\n\t" "movq 0x18(%rcx),%rdx\n\t" - "movl %eax,%ebx\n\t" + "cmpl $0xfa57ca11,%eax\n\t" + "jne 1f\n\t" + "movq %r8,%rdi\n\t" + "subq $0x20,%rsp\n\t" + "callq *(%r10,%rdx,8)\n\t" + "leaq -0x98(%rbp),%rcx\n\t" + "jmp 2f\n" + "1:\tmovl %eax,%ebx\n\t" "shrl $8,%ebx\n\t" "andl $0x30,%ebx\n\t" /* syscall table number */ "movq 0xa8(%rcx),%rcx\n\t" /* frame->syscall_table */ diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index c934e456cfe..436df547f49 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -1403,6 +1403,8 @@ void output_syscalls( DLLSPEC *spec ) switch (target.cpu) { case CPU_i386: + if (!strcmp(name, "__wine_unix_call@16")) id = 0xfa57ca11; + if (UsePIC) { output( "\tcall %s\n", asm_name("__wine_spec_get_pc_thunk_eax") ); @@ -1419,6 +1421,8 @@ void output_syscalls( DLLSPEC *spec ) output( "\tret $%u\n", odp->type == TYPE_STDCALL ? get_args_size( odp ) : 0 ); break; case CPU_x86_64: + if (!strcmp(name, "__wine_unix_call")) id = 0xfa57ca11; + /* Chromium depends on syscall thunks having the same form as on * Windows. For 64-bit systems the only viable form we can emulate is * having an int $0x2e fallback. Since actually using an interrupt is