Commit ff04d8a4 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Move the syscall dispatcher implementation to the platform-specific files.

parent 847db3c1
......@@ -1031,4 +1031,77 @@ __ASM_GLOBAL_FUNC( signal_exit_thread,
"movne sp, r3\n\t"
"blx r1" )
/***********************************************************************
* __wine_syscall_dispatcher
*/
__ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"mrc p15, 0, r1, c13, c0, 2\n\t" /* NtCurrentTeb() */
"ldr r1, [r1, #0x1d8]\n\t" /* arm_thread_data()->syscall_frame */
"add r0, r1, #0x10\n\t"
"stm r0, {r4-r12,lr}\n\t"
"str sp, [r1, #0x38]\n\t"
"str r3, [r1, #0x3c]\n\t"
"mrs r0, CPSR\n\t"
"bfi r0, lr, #5, #1\n\t" /* set thumb bit */
"str r0, [r1, #0x40]\n\t"
"mov r0, #0\n\t"
"str r0, [r1, #0x44]\n\t" /* frame->restore_flags */
#ifndef __SOFTFP__
"vmrs r0, fpscr\n\t"
"str r0, [r1, #0x48]\n\t"
"add r0, r1, #0x60\n\t"
"vstm r0, {d0-d15}\n\t"
#endif
"mov r6, sp\n\t"
"mov sp, r1\n\t"
"mov r8, r1\n\t"
"ldr r5, [r1, #0x50]\n\t" /* frame->syscall_table */
"ubfx r4, ip, #12, #2\n\t" /* syscall table number */
"bfc ip, #12, #20\n\t" /* syscall number */
"add r4, r5, r4, lsl #4\n\t"
"ldr r5, [r4, #8]\n\t" /* table->ServiceLimit */
"cmp ip, r5\n\t"
"bcs 5f\n\t"
"ldr r5, [r4, #12]\n\t" /* table->ArgumentTable */
"ldrb r5, [r5, ip]\n\t"
"cmp r5, #16\n\t"
"it le\n\t"
"movle r5, #16\n\t"
"sub r0, sp, r5\n\t"
"and r0, #~7\n\t"
"mov sp, r0\n"
"2:\tsubs r5, r5, #4\n\t"
"ldr r0, [r6, r5]\n\t"
"str r0, [sp, r5]\n\t"
"bgt 2b\n\t"
"pop {r0-r3}\n\t" /* first 4 args are in registers */
"ldr r5, [r4]\n\t" /* table->ServiceTable */
"ldr ip, [r5, ip, lsl #2]\n\t"
"blx ip\n"
"4:\tldr ip, [r8, #0x44]\n\t" /* frame->restore_flags */
#ifndef __SOFTFP__
"tst ip, #4\n\t" /* CONTEXT_FLOATING_POINT */
"beq 3f\n\t"
"ldr r4, [r8, #0x48]\n\t"
"vmsr fpscr, r4\n\t"
"add r4, r8, #0x60\n\t"
"vldm r4, {d0-d15}\n"
"3:\n\t"
#endif
"tst ip, #2\n\t" /* CONTEXT_INTEGER */
"it ne\n\t"
"ldmne r8, {r0-r3}\n\t"
"ldr lr, [r8, #0x3c]\n\t"
"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"
"b 4b\n"
__ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t"
"mov r8, r0\n\t"
"mov r0, r1\n\t"
"b 4b" )
#endif /* __arm__ */
......@@ -1224,6 +1224,133 @@ __ASM_GLOBAL_FUNC( signal_exit_thread,
"1:\tldp x29, x30, [sp], #16\n\t"
"br x1" )
/***********************************************************************
* __wine_syscall_dispatcher
*/
__ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
/* FIXME: use x18 directly instead */
"stp x0, x1, [sp, #-96]!\n\t"
"stp x2, x3, [sp, #16]\n\t"
"stp x4, x5, [sp, #32]\n\t"
"stp x6, x7, [sp, #48]\n\t"
"stp x8, x9, [sp, #64]\n\t"
"str x30, [sp, #80]\n\t"
"bl " __ASM_NAME("NtCurrentTeb") "\n\t"
"mov x18, x0\n\t"
"ldp x2, x3, [sp, #16]\n\t"
"ldp x4, x5, [sp, #32]\n\t"
"ldp x6, x7, [sp, #48]\n\t"
"ldp x8, x9, [sp, #64]\n\t"
"ldr x30, [sp, #80]\n\t"
"ldp x0, x1, [sp], #96\n\t"
"ldr x10, [x18, #0x2f8]\n\t" /* arm64_thread_data()->syscall_frame */
"stp x18, x19, [x10, #0x90]\n\t"
"stp x20, x21, [x10, #0xa0]\n\t"
"stp x22, x23, [x10, #0xb0]\n\t"
"stp x24, x25, [x10, #0xc0]\n\t"
"stp x26, x27, [x10, #0xd0]\n\t"
"stp x28, x29, [x10, #0xe0]\n\t"
"mov x19, sp\n\t"
"stp x9, x19, [x10, #0xf0]\n\t"
"mrs x9, NZCV\n\t"
"stp x30, x9, [x10, #0x100]\n\t"
"mrs x9, FPCR\n\t"
"str w9, [x10, #0x128]\n\t"
"mrs x9, FPSR\n\t"
"str w9, [x10, #0x12c]\n\t"
"stp q0, q1, [x10, #0x130]\n\t"
"stp q2, q3, [x10, #0x150]\n\t"
"stp q4, q5, [x10, #0x170]\n\t"
"stp q6, q7, [x10, #0x190]\n\t"
"stp q8, q9, [x10, #0x1b0]\n\t"
"stp q10, q11, [x10, #0x1d0]\n\t"
"stp q12, q13, [x10, #0x1f0]\n\t"
"stp q14, q15, [x10, #0x210]\n\t"
"stp q16, q17, [x10, #0x230]\n\t"
"stp q18, q19, [x10, #0x250]\n\t"
"stp q20, q21, [x10, #0x270]\n\t"
"stp q22, q23, [x10, #0x290]\n\t"
"stp q24, q25, [x10, #0x2b0]\n\t"
"stp q26, q27, [x10, #0x2d0]\n\t"
"stp q28, q29, [x10, #0x2f0]\n\t"
"stp q30, q31, [x10, #0x310]\n\t"
"mov sp, x10\n\t"
"and x20, x8, #0xfff\n\t" /* syscall number */
"ubfx x21, x8, #12, #2\n\t" /* syscall table number */
"ldr x16, [x10, #0x118]\n\t" /* frame->syscall_table */
"add x21, x16, x21, lsl #5\n\t"
"ldr x16, [x21, #16]\n\t" /* table->ServiceLimit */
"cmp x20, x16\n\t"
"bcs 4f\n\t"
"mov x22, sp\n\t"
"ldr x16, [x21, #24]\n\t" /* table->ArgumentTable */
"ldrb w9, [x16, x20]\n\t"
"subs x9, x9, #64\n\t"
"bls 2f\n\t"
"sub sp, sp, x9\n\t"
"tbz x9, #3, 1f\n\t"
"sub sp, sp, #8\n"
"1:\tsub x9, x9, #8\n\t"
"ldr x10, [x19, x9]\n\t"
"str x10, [sp, x9]\n\t"
"cbnz x9, 1b\n"
"2:\tldr x16, [x21]\n\t" /* table->ServiceTable */
"ldr x16, [x16, x20, lsl 3]\n\t"
"blr x16\n\t"
"mov sp, x22\n"
"3:\tldp x18, x19, [sp, #0x90]\n\t"
"ldp x20, x21, [sp, #0xa0]\n\t"
"ldp x22, x23, [sp, #0xb0]\n\t"
"ldp x24, x25, [sp, #0xc0]\n\t"
"ldp x26, x27, [sp, #0xd0]\n\t"
"ldp x28, x29, [sp, #0xe0]\n\t"
"ldr w16, [sp, #0x10c]\n\t" /* frame->restore_flags */
"tbz x16, #2, 1f\n\t" /* CONTEXT_FLOATING_POINT */
"ldp q0, q1, [sp, #0x130]\n\t"
"ldp q2, q3, [sp, #0x150]\n\t"
"ldp q4, q5, [sp, #0x170]\n\t"
"ldp q6, q7, [sp, #0x190]\n\t"
"ldp q8, q9, [sp, #0x1b0]\n\t"
"ldp q10, q11, [sp, #0x1d0]\n\t"
"ldp q12, q13, [sp, #0x1f0]\n\t"
"ldp q14, q15, [sp, #0x210]\n\t"
"ldp q16, q17, [sp, #0x230]\n\t"
"ldp q18, q19, [sp, #0x250]\n\t"
"ldp q20, q21, [sp, #0x270]\n\t"
"ldp q22, q23, [sp, #0x290]\n\t"
"ldp q24, q25, [sp, #0x2b0]\n\t"
"ldp q26, q27, [sp, #0x2d0]\n\t"
"ldp q28, q29, [sp, #0x2f0]\n\t"
"ldp q30, q31, [sp, #0x310]\n\t"
"ldr w9, [sp, #0x128]\n\t"
"msr FPCR, x9\n\t"
"ldr w9, [sp, #0x12c]\n\t"
"msr FPSR, x9\n"
"1:\ttbz x16, #1, 1f\n\t" /* CONTEXT_INTEGER */
"ldp x0, x1, [sp, #0x00]\n\t"
"ldp x2, x3, [sp, #0x10]\n\t"
"ldp x4, x5, [sp, #0x20]\n\t"
"ldp x6, x7, [sp, #0x30]\n\t"
"ldp x8, x9, [sp, #0x40]\n\t"
"ldp x10, x11, [sp, #0x50]\n\t"
"ldp x12, x13, [sp, #0x60]\n\t"
"ldp x14, x15, [sp, #0x70]\n"
"1:\tldp x16, x17, [sp, #0x100]\n\t"
"msr NZCV, x17\n\t"
"ldp x30, x17, [sp, #0xf0]\n\t"
"mov sp, x17\n\t"
"ret x16\n"
"4:\tmov x0, #0xc0000000\n\t" /* STATUS_INVALID_PARAMETER */
"movk x0, #0x000d\n\t"
"b 3b\n"
__ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t"
"mov sp, x0\n\t"
"mov x0, x1\n\t"
"b 3b" )
/**********************************************************************
* NtCurrentTeb (NTDLL.@)
*/
......
......@@ -1770,7 +1770,7 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, void *stack_ptr,
*/
static BOOL handle_syscall_trap( ucontext_t *sigcontext )
{
extern void __wine_syscall_dispatcher_prolog_end(void);
extern void __wine_syscall_dispatcher_prolog_end(void) DECLSPEC_HIDDEN;
struct syscall_frame *frame = x86_thread_data()->syscall_frame;
/* disallow single-stepping through a syscall */
......@@ -2487,6 +2487,135 @@ __ASM_GLOBAL_FUNC( signal_exit_thread,
"pushl %eax\n\t"
"call *%ecx" )
/***********************************************************************
* __wine_syscall_dispatcher
*/
__ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"movl %fs:0x1f8,%ecx\n\t" /* x86_thread_data()->syscall_frame */
"movw $0,0x02(%ecx)\n\t" /* frame->restore_flags */
"popl 0x08(%ecx)\n\t" /* frame->eip */
"pushfl\n\t"
"popl 0x04(%ecx)\n" /* frame->eflags */
__ASM_NAME("__wine_syscall_dispatcher_prolog_end") ":\n\t"
"movl %esp,0x0c(%ecx)\n\t" /* frame->esp */
"movw %cs,0x10(%ecx)\n\t"
"movw %ss,0x12(%ecx)\n\t"
"movw %ds,0x14(%ecx)\n\t"
"movw %es,0x16(%ecx)\n\t"
"movw %fs,0x18(%ecx)\n\t"
"movw %gs,0x1a(%ecx)\n\t"
"movl %eax,0x1c(%ecx)\n\t"
"movl %ebx,0x20(%ecx)\n\t"
"movl %edi,0x2c(%ecx)\n\t"
"movl %esi,0x30(%ecx)\n\t"
"movl %ebp,0x34(%ecx)\n\t"
"leal 0x34(%ecx),%ebp\n\t"
"leal 4(%esp),%esi\n\t" /* first argument */
"movl %eax,%ebx\n\t"
"shrl $8,%ebx\n\t"
"andl $0x30,%ebx\n\t" /* syscall table number */
"addl 0x38(%ecx),%ebx\n\t" /* frame->syscall_table */
"testl $3,(%ecx)\n\t" /* frame->syscall_flags & (SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC) */
"jz 2f\n\t"
"movl $7,%eax\n\t"
"xorl %edx,%edx\n\t"
"movl %edx,0x240(%ecx)\n\t"
"movl %edx,0x244(%ecx)\n\t"
"movl %edx,0x248(%ecx)\n\t"
"movl %edx,0x24c(%ecx)\n\t"
"movl %edx,0x250(%ecx)\n\t"
"movl %edx,0x254(%ecx)\n\t"
"testl $2,(%ecx)\n\t" /* frame->syscall_flags & SYSCALL_HAVE_XSAVEC */
"jz 1f\n\t"
"movl %edx,0x258(%ecx)\n\t"
"movl %edx,0x25c(%ecx)\n\t"
"movl %edx,0x260(%ecx)\n\t"
"movl %edx,0x264(%ecx)\n\t"
"movl %edx,0x268(%ecx)\n\t"
"movl %edx,0x26c(%ecx)\n\t"
"movl %edx,0x270(%ecx)\n\t"
"movl %edx,0x274(%ecx)\n\t"
"movl %edx,0x278(%ecx)\n\t"
"movl %edx,0x27c(%ecx)\n\t"
"xsavec 0x40(%ecx)\n\t"
"jmp 4f\n"
"1:\txsave 0x40(%ecx)\n\t"
"jmp 4f\n"
"2:\ttestl $4,(%ecx)\n\t" /* frame->syscall_flags & SYSCALL_HAVE_FXSAVE */
"jz 3f\n\t"
"fxsave 0x40(%ecx)\n\t"
"jmp 4f\n"
"3:\tfnsave 0x40(%ecx)\n\t"
"fwait\n"
"4:\tmovl %ecx,%esp\n\t"
"movl 0x1c(%esp),%edx\n\t" /* frame->eax */
"andl $0xfff,%edx\n\t" /* syscall number */
"cmpl 8(%ebx),%edx\n\t" /* table->ServiceLimit */
"jae 6f\n\t"
"movl 12(%ebx),%eax\n\t" /* table->ArgumentTable */
"movzbl (%eax,%edx,1),%ecx\n\t"
"movl (%ebx),%eax\n\t" /* table->ServiceTable */
"subl %ecx,%esp\n\t"
"shrl $2,%ecx\n\t"
"andl $~15,%esp\n\t"
"movl %esp,%edi\n\t"
"cld\n\t"
"rep; movsl\n\t"
"call *(%eax,%edx,4)\n\t"
"leal -0x34(%ebp),%esp\n"
"5:\tmovl 0(%esp),%ecx\n\t" /* frame->syscall_flags + (frame->restore_flags << 16) */
"testl $0x68 << 16,%ecx\n\t" /* CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS | CONTEXT_XSAVE */
"jz 3f\n\t"
"testl $3,%ecx\n\t" /* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */
"jz 1f\n\t"
"movl %eax,%esi\n\t"
"movl $7,%eax\n\t"
"xorl %edx,%edx\n\t"
"xrstor 0x40(%esp)\n\t"
"movl %esi,%eax\n\t"
"jmp 3f\n"
"1:\ttestl $4,%ecx\n\t" /* SYSCALL_HAVE_FXSAVE */
"jz 2f\n\t"
"fxrstor 0x40(%esp)\n\t"
"jmp 3f\n"
"2:\tfrstor 0x40(%esp)\n\t"
"fwait\n"
"3:\tmovl 0x2c(%esp),%edi\n\t"
"movl 0x30(%esp),%esi\n\t"
"movl 0x34(%esp),%ebp\n\t"
"testl $0x7 << 16,%ecx\n\t" /* CONTEXT_CONTROL | CONTEXT_SEGMENTS | CONTEXT_INTEGER */
"jnz 1f\n\t"
"movl 0x20(%esp),%ebx\n\t"
"movl 0x08(%esp),%ecx\n\t" /* frame->eip */
"movl 0x0c(%esp),%esp\n\t" /* frame->esp */
"jmpl *%ecx\n"
"1:\ttestl $0x2 << 16,%ecx\n\t" /* CONTEXT_INTEGER */
"jz 1f\n\t"
"movl 0x1c(%esp),%eax\n\t"
"movl 0x24(%esp),%ecx\n\t"
"movl 0x28(%esp),%edx\n"
"1:\tmovl 0x0c(%esp),%ebx\n\t" /* frame->esp */
"movw 0x12(%esp),%ss\n\t"
"xchgl %ebx,%esp\n\t"
"pushl 0x04(%ebx)\n\t" /* frame->eflags */
"pushl 0x10(%ebx)\n\t" /* frame->cs */
"pushl 0x08(%ebx)\n\t" /* frame->eip */
"pushl 0x14(%ebx)\n\t" /* frame->ds */
"movw 0x16(%ebx),%es\n\t"
"movw 0x18(%ebx),%fs\n\t"
"movw 0x1a(%ebx),%gs\n\t"
"movl 0x20(%ebx),%ebx\n\t"
"popl %ds\n\t"
"iret\n"
"6:\tmovl $0xc000000d,%eax\n\t" /* STATUS_INVALID_PARAMETER */
"jmp 5b\n"
__ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t"
"movl 8(%esp),%eax\n\t"
"movl 4(%esp),%esp\n\t"
"jmp 5b" )
/**********************************************************************
* NtCurrentTeb (NTDLL.@)
*/
......
......@@ -3106,4 +3106,146 @@ __ASM_GLOBAL_FUNC( signal_exit_thread,
__ASM_CFI(".cfi_rel_offset %r15,8\n\t")
"call *%rsi" )
/***********************************************************************
* __wine_syscall_dispatcher
*/
__ASM_GLOBAL_FUNC( __wine_syscall_dispatcher,
"movq %gs:0x30,%rcx\n\t"
"movq 0x328(%rcx),%rcx\n\t" /* amd64_thread_data()->syscall_frame */
"popq 0x70(%rcx)\n\t" /* frame->rip */
"pushfq\n\t"
"popq 0x80(%rcx)\n\t"
"movl $0,0x94(%rcx)\n\t" /* frame->restore_flags */
__ASM_NAME("__wine_syscall_dispatcher_prolog_end") ":\n\t"
"movq %rax,0x00(%rcx)\n\t"
"movq %rbx,0x08(%rcx)\n\t"
"movq %rdx,0x18(%rcx)\n\t"
"movq %rsi,0x20(%rcx)\n\t"
"movq %rdi,0x28(%rcx)\n\t"
"movq %r12,0x50(%rcx)\n\t"
"movq %r13,0x58(%rcx)\n\t"
"movq %r14,0x60(%rcx)\n\t"
"movq %r15,0x68(%rcx)\n\t"
"movw %cs,0x78(%rcx)\n\t"
"movw %ds,0x7a(%rcx)\n\t"
"movw %es,0x7c(%rcx)\n\t"
"movw %fs,0x7e(%rcx)\n\t"
"movq %rsp,0x88(%rcx)\n\t"
"movw %ss,0x90(%rcx)\n\t"
"movw %gs,0x92(%rcx)\n\t"
"movq %rbp,0x98(%rcx)\n\t"
/* Legends of Runeterra hooks the first system call return instruction, and
* 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 */
"testl $3,%r14d\n\t" /* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */
"jz 2f\n\t"
"movl $7,%eax\n\t"
"xorl %edx,%edx\n\t"
"movq %rdx,0x2c0(%rcx)\n\t"
"movq %rdx,0x2c8(%rcx)\n\t"
"movq %rdx,0x2d0(%rcx)\n\t"
"testl $2,%r14d\n\t" /* SYSCALL_HAVE_XSAVEC */
"jz 1f\n\t"
"movq %rdx,0x2d8(%rcx)\n\t"
"movq %rdx,0x2e0(%rcx)\n\t"
"movq %rdx,0x2e8(%rcx)\n\t"
"movq %rdx,0x2f0(%rcx)\n\t"
"movq %rdx,0x2f8(%rcx)\n\t"
"xsavec64 0xc0(%rcx)\n\t"
"jmp 3f\n"
"1:\txsave64 0xc0(%rcx)\n\t"
"jmp 3f\n"
"2:\tfxsave64 0xc0(%rcx)\n"
"3:\tleaq 0x98(%rcx),%rbp\n\t"
#ifdef __linux__
"testl $12,%r14d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB | SYSCALL_HAVE_WRFSGSBASE */
"jz 2f\n\t"
"movq %gs:0x330,%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
"leaq 0x28(%rsp),%rsi\n\t" /* first argument */
"movq %rcx,%rsp\n\t"
"movq 0x00(%rcx),%rax\n\t"
"movq 0x18(%rcx),%rdx\n\t"
"movl %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 */
"leaq (%rcx,%rbx,2),%rbx\n\t"
"andl $0xfff,%eax\n\t" /* syscall number */
"cmpq 16(%rbx),%rax\n\t" /* table->ServiceLimit */
"jae 5f\n\t"
"movq 24(%rbx),%rcx\n\t" /* table->ArgumentTable */
"movzbl (%rcx,%rax),%ecx\n\t"
"subq $0x20,%rcx\n\t"
"jbe 1f\n\t"
"subq %rcx,%rsp\n\t"
"shrq $3,%rcx\n\t"
"andq $~15,%rsp\n\t"
"movq %rsp,%rdi\n\t"
"cld\n\t"
"rep; movsq\n"
"1:\tmovq %r10,%rcx\n\t"
"subq $0x20,%rsp\n\t"
"movq (%rbx),%r10\n\t" /* table->ServiceTable */
"callq *(%r10,%rax,8)\n\t"
"leaq -0x98(%rbp),%rcx\n"
"2:\tmovl 0x94(%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 0x7e(%rcx),%fs\n"
"1:\n\t"
#endif
"testl $0x48,%edx\n\t" /* CONTEXT_FLOATING_POINT | CONTEXT_XSTATE */
"jz 4f\n\t"
"testl $3,%r14d\n\t" /* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */
"jz 3f\n\t"
"movq %rax,%r11\n\t"
"movl $7,%eax\n\t"
"xorl %edx,%edx\n\t"
"xrstor64 0xc0(%rcx)\n\t"
"movq %r11,%rax\n\t"
"movl 0x94(%rcx),%edx\n\t"
"jmp 4f\n"
"3:\tfxrstor64 0xc0(%rcx)\n"
"4:\tmovq 0x98(%rcx),%rbp\n\t"
"movq 0x68(%rcx),%r15\n\t"
"movq 0x60(%rcx),%r14\n\t"
"movq 0x58(%rcx),%r13\n\t"
"movq 0x50(%rcx),%r12\n\t"
"movq 0x28(%rcx),%rdi\n\t"
"movq 0x20(%rcx),%rsi\n\t"
"movq 0x08(%rcx),%rbx\n\t"
"testl $0x3,%edx\n\t" /* CONTEXT_CONTROL | CONTEXT_INTEGER */
"jnz 1f\n\t"
"movq 0x88(%rcx),%rsp\n\t"
"jmpq *0x70(%rcx)\n" /* frame->rip */
"1:\tleaq 0x70(%rcx),%rsp\n\t"
"testl $0x2,%edx\n\t" /* CONTEXT_INTEGER */
"jz 1f\n\t"
"movq 0x00(%rcx),%rax\n\t"
"movq 0x18(%rcx),%rdx\n\t"
"movq 0x30(%rcx),%r8\n\t"
"movq 0x38(%rcx),%r9\n\t"
"movq 0x40(%rcx),%r10\n\t"
"movq 0x48(%rcx),%r11\n\t"
"movq 0x10(%rcx),%rcx\n"
"1:\tiretq\n"
"5:\tmovl $0xc000000d,%edx\n\t" /* STATUS_INVALID_PARAMETER */
"movq %rsp,%rcx\n"
__ASM_NAME("__wine_syscall_dispatcher_return") ":\n\t"
"movl 0xb0(%rcx),%r14d\n\t" /* frame->syscall_flags */
"movq %rdx,%rax\n\t"
"jmp 2b" )
#endif /* __x86_64__ */
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