ntdll: Clear the syscall frame on return instead of popping the previous one.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2020-08-27 11:41:36 +02:00
parent 4e4b1d1406
commit 75e616d52b
5 changed files with 105 additions and 134 deletions

View file

@ -174,7 +174,7 @@ enum arm_trap_code
struct syscall_frame
{
struct syscall_frame *prev_frame;
DWORD pad;
DWORD cpsr;
DWORD r5;
DWORD r6;
@ -463,8 +463,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
ret = set_thread_context( handle, &server_context, &self );
if (self && ret == STATUS_SUCCESS)
{
struct syscall_frame *frame = arm_thread_data()->syscall_frame;
arm_thread_data()->syscall_frame = frame->prev_frame;
arm_thread_data()->syscall_frame = NULL;
set_cpu_context( context );
}
return ret;
@ -594,16 +593,16 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"ldr r9, [sp, #4]\n\t" /* dispatcher */
"bl " __ASM_NAME("NtCurrentTeb") "\n\t"
"add r10, r0, #0x1d8\n\t" /* arm_thread_data()->syscall_frame */
"ldr r12, [r10]\n\t"
"movs r0, r4\n\t"
"beq 1f\n\t"
"ldr r0, [r0, #0x38]\n\t" /* context_ptr->Sp */
"sub r0, r0, #0x1c8\n\t" /* sizeof(CONTEXT) + offsetof(frame,r4) */
"ldr r12, [r12]\n\t" /* frame->prev_frame */
"str r12, [r10]\n\t"
"mov ip, #0\n\t"
"str ip, [r10]\n\t"
"mov sp, r0\n\t"
"b 2f\n"
"1:\tsub r11, r12, #0x1a0\n\t"
"1:\tldr r0, [r10]\n\t"
"sub r11, r0, #0x1a0\n\t"
"cmp r11, sp\n\t"
"movlo sp, r11\n\t"
"mov r0, #3\n\t"
@ -615,8 +614,8 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"mov r0, #0xc0\n\t"
"str r0, [r11, #4]\n\t" /* context.R0 = STATUS_USER_APC */
"mov r0, r11\n\t"
"ldr r12, [r12]\n\t" /* frame->prev_frame */
"str r12, [r10]\n"
"mov ip, #0\n\t"
"str ip, [r10]\n\t"
"2:\tmov r1, r5\n\t" /* ctx */
"mov r2, r6\n\t" /* arg1 */
"mov r3, r7\n\t" /* arg2 */
@ -646,8 +645,8 @@ __ASM_GLOBAL_FUNC( call_user_exception_dispatcher,
"mov r1, r5\n\t"
"mov r2, r6\n\t"
"ldr r3, [r7]\n\t"
"ldr r4, [r3]\n\t" /* frame->prev_frame */
"str r4, [r7]\n\t"
"mov ip, #0\n\t"
"str ip, [r7]\n\t"
"add r3, r3, #8\n\t"
"ldm r3, {r5-r11}\n\t"
"ldr r4, [r3, #32]\n\t"
@ -708,7 +707,7 @@ static BOOL handle_syscall_fault( ucontext_t *context, EXCEPTION_RECORD *rec )
SP_sig(context) = (DWORD)&frame->r4;
PC_sig(context) = frame->thunk_addr;
CPSR_sig(context) = frame->cpsr;
arm_thread_data()->syscall_frame = frame->prev_frame;
arm_thread_data()->syscall_frame = NULL;
}
return TRUE;
}

View file

@ -136,9 +136,7 @@ struct syscall_frame
{
ULONG64 x29;
ULONG64 thunk_addr;
ULONG64 x0, x1, x2, x3, x4, x5, x6, x7, x8;
struct syscall_frame *prev_frame;
ULONG64 x19, x20, x21, x22, x23, x24, x25, x26, x27, x28;
ULONG64 x0, x1, x2, x3, x4, x5, x6, x7, x19, x20, x21, x22, x23, x24, x25, x26, x27, x28;
ULONG64 thunk_x29;
ULONG64 ret_addr;
};
@ -521,8 +519,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
if (self && ret == STATUS_SUCCESS)
{
struct syscall_frame *frame = arm64_thread_data()->syscall_frame;
arm64_thread_data()->syscall_frame = frame->prev_frame;
arm64_thread_data()->syscall_frame = NULL;
InterlockedExchangePointer( (void **)&arm64_thread_data()->context, (void *)context );
raise( SIGUSR2 );
}
@ -651,15 +648,14 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"mov x24, x5\n\t" /* dispatcher */
"bl " __ASM_NAME("NtCurrentTeb") "\n\t"
"add x25, x0, #0x2f8\n\t" /* arm64_thread_data()->syscall_frame */
"ldr x26, [x25]\n\t"
"cbz x19, 1f\n\t"
"ldr x0, [x19, #0x100]\n\t" /* context.Sp */
"sub x0, x0, #0x440\n\t" /* sizeof(CONTEXT) + offsetof(frame,thunk_x29) */
"ldr x6, [x26, #88]\n\t" /* frame->prev_frame */
"str x6, [x25]\n\t"
"sub x0, x0, #0x430\n\t" /* sizeof(CONTEXT) + offsetof(frame,thunk_x29) */
"str xzr, [x25]\n\t"
"mov sp, x0\n\t"
"b 2f\n"
"1:\tsub x19, x26, #0x390\n\t"
"1:\tldr x0, [x25]\n\t"
"sub x19, x0, #0x390\n\t"
"mov x0, sp\n\t"
"cmp x19, x0\n\t"
"csel x0, x19, x0, lo\n\t"
@ -672,8 +668,7 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"bl " __ASM_NAME("NtGetContextThread") "\n\t"
"mov w2, #0xc0\n\t" /* context.X0 = STATUS_USER_APC */
"str x2, [x19, #8]\n\t"
"ldr x6, [x26, #88]\n\t" /* frame->prev_frame */
"str x6, [x25]\n\t"
"str xzr, [x25]\n\t"
"mov x0, x19\n" /* context */
"2:\tldr lr, [x0, #0xf8]\n\t" /* context.Lr */
"mov x1, x20\n\t" /* ctx */
@ -701,18 +696,17 @@ __ASM_GLOBAL_FUNC( call_user_exception_dispatcher,
"bl " __ASM_NAME("NtCurrentTeb") "\n\t"
"add x4, x0, #0x2f8\n\t" /* arm64_thread_data()->syscall_frame */
"ldr x5, [x4]\n\t"
"ldr x6, [x5, #88]\n\t" /* frame->prev_frame */
"str x6, [x4]\n\t"
"str xzr, [x4]\n\t"
"mov x0, x19\n\t"
"mov x1, x20\n\t"
"mov x2, x21\n\t"
"ldp x19, x20, [x5, #96]\n\t" /* frame->x19,x20 */
"ldp x21, x22, [x5, #112]\n\t" /* frame->x21,x22 */
"ldp x23, x24, [x5, #128]\n\t" /* frame->x23,x24 */
"ldp x25, x26, [x5, #144]\n\t" /* frame->x25,x26 */
"ldp x27, x28, [x5, #160]\n\t" /* frame->x27,x28 */
"ldp x29, x30, [x5, #176]\n\t" /* frame->thunk_x29,ret_addr */
"add sp, x5, #192\n\t"
"ldp x19, x20, [x5, #64]\n\t" /* frame->x19,x20 */
"ldp x21, x22, [x5, #96]\n\t" /* frame->x21,x22 */
"ldp x23, x24, [x5, #112]\n\t" /* frame->x23,x24 */
"ldp x25, x26, [x5, #128]\n\t" /* frame->x25,x26 */
"ldp x27, x28, [x5, #144]\n\t" /* frame->x27,x28 */
"ldp x29, x30, [x5, #160]\n\t" /* frame->thunk_x29,ret_addr */
"add sp, x5, #176\n\t"
"br x2" )
@ -785,7 +779,7 @@ static BOOL handle_syscall_fault( ucontext_t *context, EXCEPTION_RECORD *rec )
LR_sig(context) = frame->ret_addr;
SP_sig(context) = (DWORD)&frame->thunk_x29;
PC_sig(context) = frame->thunk_addr;
arm64_thread_data()->syscall_frame = frame->prev_frame;
arm64_thread_data()->syscall_frame = NULL;
}
return TRUE;
}

View file

@ -463,7 +463,6 @@ enum i386_trap_code
struct syscall_frame
{
struct syscall_frame *prev_frame;
DWORD edi;
DWORD esi;
DWORD ebx;
@ -908,9 +907,7 @@ static inline void restore_context( const struct xcontext *xcontext, ucontext_t
*/
extern void set_full_cpu_context( const CONTEXT *context );
__ASM_GLOBAL_FUNC( set_full_cpu_context,
"movl %fs:0x1f8,%eax\n\t" /* x86_thread_data()->syscall_frame */
"movl (%eax),%eax\n\t" /* frame->prev_frame */
"movl %eax,%fs:0x1f8\n\t"
"movl $0,%fs:0x1f8\n\t" /* x86_thread_data()->syscall_frame = NULL */
"movl 4(%esp),%ecx\n\t"
"movw 0x8c(%ecx),%gs\n\t" /* SegGs */
"movw 0x90(%ecx),%fs\n\t" /* SegFs */
@ -1614,11 +1611,10 @@ static void setup_exception( ucontext_t *sigcontext, EXCEPTION_RECORD *rec )
__ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"movl 4(%esp),%esi\n\t" /* context_ptr */
"movl 24(%esp),%edi\n\t" /* dispatcher */
"movl %fs:0x1f8,%ebx\n\t" /* x86_thread_data()->syscall_frame */
"test %esi,%esi\n\t"
"jz 1f\n\t"
"movl 0xc4(%esi),%eax\n\t" /* context_ptr->Rsp */
"leal -0x2fc(%eax),%eax\n\t" /* sizeof(CONTEXT) + offsetof(frame,ret_addr) + params */
"leal -0x2f8(%eax),%eax\n\t" /* sizeof(CONTEXT) + offsetof(frame,ret_addr) + params */
"movl %esi,4(%eax)\n\t"
"movl 8(%esp),%ecx\n\t" /* ctx */
"movl %ecx,8(%eax)\n\t"
@ -1629,8 +1625,9 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"movl 20(%esp),%ecx\n\t" /* func */
"movl %ecx,20(%eax)\n\t"
"leal 4(%eax),%esp\n\t"
"jmp 2f\n\t"
"1:\tleal -0x2cc(%ebx),%esi\n\t"
"jmp 2f\n"
"1:\tmovl %fs:0x1f8,%eax\n\t" /* x86_thread_data()->syscall_frame */
"leal -0x2cc(%eax),%esi\n\t"
"movl %esp,%ecx\n\t"
"cmpl %esp,%esi\n\t"
"cmovbl %esi,%esp\n\t"
@ -1644,8 +1641,7 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"pushl $0xfffffffe\n\t"
"call " __ASM_STDCALL("NtGetContextThread",8) "\n\t"
"movl $0xc0,0xb0(%esi)\n" /* context.Eax = STATUS_USER_APC */
"2:\tmovl (%ebx),%edx\n\t" /* frame->prev_frame */
"movl %edx,%fs:0x1f8\n\t"
"2:\tmovl $0,%fs:0x1f8\n\t" /* x86_thread_data()->syscall_frame = NULL */
"pushl $0xdeaddead\n\t"
"jmp *%edi\n" )
@ -1655,14 +1651,13 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
*/
__ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher,
"movl %fs:0x1f8,%eax\n\t" /* x86_thread_data()->syscall_frame */
"pushl (%eax)\n\t" /* frame->prev_frame */
"popl %fs:0x1f8\n\t"
"movl 4(%eax),%edi\n\t" /* frame->edi */
"movl 8(%eax),%esi\n\t" /* frame->esi */
"movl 12(%eax),%ebx\n\t" /* frame->ebx */
"movl 16(%eax),%ebp\n\t" /* frame->ebp */
"movl 0(%eax),%edi\n\t" /* frame->edi */
"movl 4(%eax),%esi\n\t" /* frame->esi */
"movl 8(%eax),%ebx\n\t" /* frame->ebx */
"movl 12(%eax),%ebp\n\t" /* frame->ebp */
"movl 4(%esp),%edx\n\t" /* dispatcher */
"leal 24(%eax),%esp\n\t"
"movl $0,%fs:0x1f8\n\t"
"leal 20(%eax),%esp\n\t"
"jmp *%edx" )
@ -1676,16 +1671,15 @@ __ASM_GLOBAL_FUNC( call_user_exception_dispatcher,
"jne 1f\n\t"
"decl 0xb8(%ecx)\n" /* context->Eip */
"1:\tmovl %fs:0x1f8,%eax\n\t" /* x86_thread_data()->syscall_frame */
"pushl (%eax)\n\t" /* frame->prev_frame */
"popl %fs:0x1f8\n\t"
"movl 4(%eax),%edi\n\t" /* frame->edi */
"movl 8(%eax),%esi\n\t" /* frame->esi */
"movl 12(%eax),%ebx\n\t" /* frame->ebx */
"movl 16(%eax),%ebp\n\t" /* frame->ebp */
"movl %edx,16(%eax)\n\t"
"movl %ecx,20(%eax)\n\t"
"movl 0(%eax),%edi\n\t" /* frame->edi */
"movl 4(%eax),%esi\n\t" /* frame->esi */
"movl 8(%eax),%ebx\n\t" /* frame->ebx */
"movl 12(%eax),%ebp\n\t" /* frame->ebp */
"movl %edx,12(%eax)\n\t"
"movl %ecx,16(%eax)\n\t"
"movl 12(%esp),%edx\n\t" /* dispatcher */
"leal 16(%eax),%esp\n\t"
"movl $0,%fs:0x1f8\n\t"
"leal 12(%eax),%esp\n\t"
"jmp *%edx" )
/**********************************************************************
@ -1809,7 +1803,7 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, void *stack_ptr,
EBP_sig(sigcontext) = frame->ebp;
ESP_sig(sigcontext) = (DWORD)&frame->ret_addr;
EIP_sig(sigcontext) = frame->thunk_addr;
x86_thread_data()->syscall_frame = frame->prev_frame;
x86_thread_data()->syscall_frame = NULL;
}
return TRUE;
}

View file

@ -256,8 +256,6 @@ C_ASSERT( sizeof(struct stack_layout) == 0x5b0 ); /* Should match the size in ca
struct syscall_frame
{
struct syscall_frame *prev_frame;
ULONG64 pad;
ULONG64 xmm[10 * 2]; /* xmm6-xmm15 */
ULONG64 mxcsr;
ULONG64 r12;
@ -1506,12 +1504,14 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context,
__ASM_SEH(".seh_stackalloc 0x40\n\t")
__ASM_SEH(".seh_endprologue\n\t")
__ASM_CFI(".cfi_adjust_cfa_offset 40\n\t")
"movq %gs:0x30,%rdx\n\t"
"movw 0x38(%rdi),%ax\n\t" /* context->SegCs */
"movq %rax,8(%rsp)\n\t"
"movw 0x42(%rdi),%ax\n\t" /* context->SegSs */
"movq %rax,32(%rsp)\n\t"
"movq 0x44(%rdi),%rax\n\t" /* context->Eflags */
"movq %rax,16(%rsp)\n\t"
"movq $0,0x328(%rdx)\n\t" /* amd64_thread_data()->syscall_frame */
"movq 0x80(%rdi),%rcx\n\t" /* context->Rcx */
"movq 0x88(%rdi),%rdx\n\t" /* context->Rdx */
"movq 0x90(%rdi),%rbx\n\t" /* context->Rbx */
@ -1760,11 +1760,7 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
if (!(flags & CONTEXT_CONTROL))
FIXME( "setting partial context (%x) not supported\n", flags );
else
{
struct syscall_frame *frame = amd64_thread_data()->syscall_frame;
amd64_thread_data()->syscall_frame = frame->prev_frame;
set_full_cpu_context( context );
}
}
return ret;
}
@ -1959,7 +1955,7 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"movq %gs:0x30,%rbx\n\t"
"jrcxz 1f\n\t"
"movq 0x98(%rcx),%rax\n\t" /* context_ptr->Rsp */
"leaq -0x5d0(%rax),%rsp\n\t" /* sizeof(CONTEXT) + offsetof(frame,ret_addr) */
"leaq -0x5c0(%rax),%rsp\n\t" /* sizeof(CONTEXT) + offsetof(frame,ret_addr) */
"jmp 2f\n"
"1:\tmovq 0x328(%rbx),%rax\n\t" /* amd64_thread_data()->syscall_frame */
"leaq -0x4d0(%rax),%r10\n\t"
@ -1979,9 +1975,7 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"movq %r12,%rdx\n\t" /* ctx */
"movq %r13,%r8\n\t" /* arg1 */
"movq %r14,%r9\n" /* arg2 */
"2:\tmovq 0x328(%rbx),%rax\n\t" /* amd64_thread_data()->syscall_frame */
"movq (%rax),%rax\n\t" /* frame->prev_frame */
"movq %rax,0x328(%rbx)\n\t"
"2:\tmovq $0,0x328(%rbx)\n\t"
"movq %rsi,0x20(%rsp)\n\t" /* func */
"leaq -8(%rsp),%rsp\n\t"
"jmp *%rdi" )
@ -1993,28 +1987,27 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
__ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher,
"movq %gs:0x30,%rdx\n\t"
"movq 0x328(%rdx),%rax\n\t" /* amd64_thread_data()->syscall_frame */
"pushq (%rax)\n\t" /* frame->prev_frame */
"popq 0x328(%rdx)\n\t"
"movdqu 0x10(%rax),%xmm6\n\t" /* frame->xmm[0..19] */
"movdqu 0x20(%rax),%xmm7\n\t"
"movdqu 0x30(%rax),%xmm8\n\t"
"movdqu 0x40(%rax),%xmm9\n\t"
"movdqu 0x50(%rax),%xmm10\n\t"
"movdqu 0x60(%rax),%xmm11\n\t"
"movdqu 0x70(%rax),%xmm12\n\t"
"movdqu 0x80(%rax),%xmm13\n\t"
"movdqu 0x90(%rax),%xmm14\n\t"
"movdqu 0xa0(%rax),%xmm15\n\t"
"ldmxcsr 0xb0(%rax)\n\t" /* frame->mxcsr */
"movq 0xb8(%rax),%r12\n\t" /* frame->r12 */
"movq 0xc0(%rax),%r13\n\t" /* frame->r13 */
"movq 0xc8(%rax),%r14\n\t" /* frame->r14 */
"movq 0xd0(%rax),%r15\n\t" /* frame->r15 */
"movq 0xd8(%rax),%rdi\n\t" /* frame->rdi */
"movq 0xe0(%rax),%rsi\n\t" /* frame->rsi */
"movq 0xe8(%rax),%rbx\n\t" /* frame->rbx */
"movq 0xf0(%rax),%rbp\n\t" /* frame->rbp */
"leaq 0x100(%rax),%rsp\n\t"
"movdqu 0x0(%rax),%xmm6\n\t" /* frame->xmm[0..19] */
"movdqu 0x10(%rax),%xmm7\n\t"
"movdqu 0x20(%rax),%xmm8\n\t"
"movdqu 0x30(%rax),%xmm9\n\t"
"movdqu 0x40(%rax),%xmm10\n\t"
"movdqu 0x50(%rax),%xmm11\n\t"
"movdqu 0x60(%rax),%xmm12\n\t"
"movdqu 0x70(%rax),%xmm13\n\t"
"movdqu 0x80(%rax),%xmm14\n\t"
"movdqu 0x90(%rax),%xmm15\n\t"
"ldmxcsr 0xa0(%rax)\n\t" /* frame->mxcsr */
"movq 0xa8(%rax),%r12\n\t" /* frame->r12 */
"movq 0xb0(%rax),%r13\n\t" /* frame->r13 */
"movq 0xb8(%rax),%r14\n\t" /* frame->r14 */
"movq 0xc0(%rax),%r15\n\t" /* frame->r15 */
"movq 0xc8(%rax),%rdi\n\t" /* frame->rdi */
"movq 0xd0(%rax),%rsi\n\t" /* frame->rsi */
"movq 0xd8(%rax),%rbx\n\t" /* frame->rbx */
"movq 0xe0(%rax),%rbp\n\t" /* frame->rbp */
"movq $0,0x328(%rdx)\n\t"
"leaq 0xf0(%rax),%rsp\n\t"
"jmpq *%rcx" )
@ -2037,8 +2030,6 @@ void WINAPI do_call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *c
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*),
struct stack_layout *stack )
{
struct syscall_frame *frame = amd64_thread_data()->syscall_frame;
if ((context->ContextFlags & CONTEXT_XSTATE) == CONTEXT_XSTATE)
{
CONTEXT_EX *xctx = (CONTEXT_EX *)context + 1;
@ -2069,7 +2060,7 @@ void WINAPI do_call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *c
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if (stack->rec.ExceptionCode == EXCEPTION_BREAKPOINT) stack->context.Rip--;
amd64_thread_data()->syscall_frame = frame->prev_frame;
amd64_thread_data()->syscall_frame = NULL;
user_exception_dispatcher_trampoline( stack, dispatcher );
}
@ -2260,7 +2251,7 @@ static BOOL handle_syscall_fault( ucontext_t *sigcontext, EXCEPTION_RECORD *rec,
fpu->MxCsr =frame->mxcsr;
memcpy( fpu->XmmRegisters + 6, frame->xmm, sizeof(frame->xmm) );
}
amd64_thread_data()->syscall_frame = frame->prev_frame;
amd64_thread_data()->syscall_frame = NULL;
}
return TRUE;
}

View file

@ -1455,8 +1455,7 @@ void output_syscalls( DLLSPEC *spec )
output_cfi( ".cfi_rel_offset %%esi,-8\n" );
output( "\tpushl %%edi\n" );
output_cfi( ".cfi_rel_offset %%edi,-12\n" );
output( "\tpushl %%fs:0x1f8\n" ); /* x86_thread_data()->syscall_frame */
output( "\tmovl %%esp,%%fs:0x1f8\n" );
output( "\tmovl %%esp,%%fs:0x1f8\n" ); /* x86_thread_data()->syscall_frame */
output( "\tcmpl $%u,%%eax\n", count );
output( "\tjae 3f\n" );
if (UsePIC)
@ -1478,8 +1477,8 @@ void output_syscalls( DLLSPEC *spec )
output( "\tcall *.Lsyscall_table-1b(%%eax,%%edx,4)\n" );
else
output( "\tcall *.Lsyscall_table(,%%eax,4)\n" );
output( "\tleal -16(%%ebp),%%esp\n" );
output( "2:\tpopl %%fs:0x1f8\n" );
output( "\tleal -12(%%ebp),%%esp\n" );
output( "2:\tmovl $0,%%fs:0x1f8\n" );
output( "\tpopl %%edi\n" );
output_cfi( ".cfi_same_value %%edi\n" );
output( "\tpopl %%esi\n" );
@ -1499,10 +1498,8 @@ void output_syscalls( DLLSPEC *spec )
output_cfi( ".cfi_rel_offset %%rbp,0" );
output( "\tmovq %%rsp,%%rbp\n" );
output_cfi( ".cfi_def_cfa_register %%rbp" );
output( "\tleaq -0xe8(%%rbp),%%rsp\n" );
output( "\tleaq -0xe0(%%rbp),%%rsp\n" );
output( "\tmovq %%gs:0x30,%%rcx\n" );
output( "\tpushq 0x328(%%rcx)\n" ); /* amd64_thread_data()->syscall_frame */
output( "\tmovq %%rsp,0x328(%%rcx)\n" );
output( "\tmovdqu %%xmm6,-0xe0(%%rbp)\n" );
output( "\tmovdqu %%xmm7,-0xd0(%%rbp)\n" );
output( "\tmovdqu %%xmm8,-0xc0(%%rbp)\n" );
@ -1527,6 +1524,7 @@ void output_syscalls( DLLSPEC *spec )
/* Legends of Runeterra hooks the first system call return instruction, and
* depends on us returning to it. Adjust the return address accordingly. */
output( "\tsubq $0xb,0x8(%%rbp)\n" );
output( "\tmovq %%rsp,0x328(%%rcx)\n" ); /* amd64_thread_data()->syscall_frame */
output( "\tcmpq $%u,%%rax\n", count );
output( "\tjae 4f\n" );
output( "\tleaq .Lsyscall_args(%%rip),%%rcx\n" );
@ -1546,9 +1544,8 @@ void output_syscalls( DLLSPEC *spec )
output( "\tsubq $0x20,%%rsp\n" );
output( "\tleaq .Lsyscall_table(%%rip),%%r10\n" );
output( "\tcallq *(%%r10,%%rax,8)\n" );
output( "3:\tpushq -0xf0(%%rbp)\n" );
output( "\tmovq %%gs:0x30,%%rcx\n" );
output( "\tpopq 0x328(%%rcx)\n" ); /* prev frame */
output( "3:\tmovq %%gs:0x30,%%rcx\n" );
output( "\tmovq $0,0x328(%%rcx)\n" );
output( "\tmovq -0x18(%%rbp),%%rdi\n" );
output_cfi( ".cfi_same_value %%rdi" );
output( "\tmovq -0x10(%%rbp),%%rsi\n" );
@ -1574,11 +1571,9 @@ void output_syscalls( DLLSPEC *spec )
output( "\tbl %s\n", asm_name("NtCurrentTeb") );
output( "\tadd r7, r0, #0x1d8\n" ); /* arm_thread_data()->syscall_frame */
output( "\tpop {r0-r3}\n" );
output( "\tldr r8, [r7]\n" );
output( "\tstr r8, [sp]\n" ); /* prev frame */
output( "\tstr sp, [r7]\n" ); /* syscall frame */
output( "\tmrs ip, CPSR\n" );
output( "\tstr ip, [sp, #4]\n" );
output( "\tstr sp, [r7]\n" ); /* syscall frame */
output( "\tldr r5, 7f\n");
output( "\tadd r5, pc\n");
output( "\tldrb r5, [r5, r4]\n" ); /* syscall args */
@ -1594,7 +1589,8 @@ void output_syscalls( DLLSPEC *spec )
output( "\tadd r5, pc\n");
output( "\tldr ip, [r5, r4, lsl #2]\n"); /* syscall table */
output( "4:\tblx ip\n");
output( "\tstr r8, [r7]\n" ); /* prev frame */
output( "\tmov ip, #0\n" );
output( "\tstr ip, [r7]\n" );
output( "\tsub sp, r6, #40\n" );
output( "\tpop {r5-r11,pc}\n" );
output( "5:\tldr r0, 9f\n" );
@ -1607,53 +1603,50 @@ void output_syscalls( DLLSPEC *spec )
case CPU_ARM64:
output( "\tcmp x8, %u\n", count );
output( "\tbcs 3f\n" );
output( "\tstp x29, x30, [sp,#-176]!\n" );
output( "\tstp x29, x30, [sp,#-160]!\n" );
output( "\tmov x29, sp\n" );
output( "\tstp x27, x28, [sp, #160]\n" );
output( "\tstp x25, x26, [sp, #144]\n" );
output( "\tstp x23, x24, [sp, #128]\n" );
output( "\tstp x21, x22, [sp, #112]\n" );
output( "\tstp x19, x20, [sp, #96]\n" );
output( "\tstr x8, [sp, #80]\n" );
output( "\tstp x27, x28, [sp, #144]\n" );
output( "\tstp x25, x26, [sp, #128]\n" );
output( "\tstp x23, x24, [sp, #112]\n" );
output( "\tstp x21, x22, [sp, #96]\n" );
output( "\tstp x19, x20, [sp, #80]\n" );
output( "\tstp x6, x7, [sp, #64]\n" );
output( "\tstp x4, x5, [sp, #48]\n" );
output( "\tstp x2, x3, [sp, #32]\n" );
output( "\tstp x0, x1, [sp, #16]\n" );
output( "\tmov x20, x8\n" );
output( "\tbl %s\n", asm_name("NtCurrentTeb") );
output( "\tadd x19, x0, #0x2f8\n" ); /* arm64_thread_data()->syscall_frame */
output( "\tstr x29, [x19]\n" );
output( "\tldp x0, x1, [sp, #16]\n" );
output( "\tldp x2, x3, [sp, #32]\n" );
output( "\tldp x4, x5, [sp, #48]\n" );
output( "\tldp x6, x7, [sp, #64]\n" );
output( "\tldr x8, [sp, #80]\n" );
output( "\tldr x20, [x19]\n" ); /* prev frame */
output( "\tstr x20, [sp, #88]\n" );
output( "\tstr x29, [x19]\n" ); /* syscall frame */
output( "\tadrp x16, %s\n", arm64_page(".Lsyscall_args") );
output( "\tadd x16, x16, #%s\n", arm64_pageoff(".Lsyscall_args") );
output( "\tldrb w9, [x16, x8]\n" );
output( "\tldrb w9, [x16, x20]\n" );
output( "\tsubs x9, x9, #64\n" );
output( "\tbls 2f\n" );
output( "\tadd x11, x29, #192\n" );
output( "\tadd x11, x29, #176\n" );
output( "\tsub sp, sp, x9\n" );
output( "\ttbz x9, #3, 1f\n" );
output( "\tsub SP, SP, #8\n" );
output( "\tsub sp, sp, #8\n" );
output( "1:\tsub x9, x9, #8\n" );
output( "\tldr x10, [x11, x9]\n" );
output( "\tstr x10, [sp, x9]\n" );
output( "\tcbnz x9, 1b\n" );
output( "2:\tadrp x16, %s\n", arm64_page(".Lsyscall_table") );
output( "\tadd x16, x16, #%s\n", arm64_pageoff(".Lsyscall_table") );
output( "\tldr x16, [x16, x8, lsl 3]\n" );
output( "\tldr x16, [x16, x20, lsl 3]\n" );
output( "\tblr x16\n" );
output( "\tmov sp, x29\n" );
output( "\tstr x20, [x19]\n" ); /* prev frame */
output( "\tldp x19, x20, [sp, #96]\n" );
output( "\tldp x21, x22, [sp, #112]\n" );
output( "\tldp x23, x24, [sp, #128]\n" );
output( "\tldp x25, x26, [sp, #144]\n" );
output( "\tldp x27, x28, [sp, #160]\n" );
output( "\tldp x29, x30, [sp], #176\n" );
output( "\tstr xzr, [x19]\n" );
output( "\tldp x19, x20, [sp, #80]\n" );
output( "\tldp x21, x22, [sp, #96]\n" );
output( "\tldp x23, x24, [sp, #112]\n" );
output( "\tldp x25, x26, [sp, #128]\n" );
output( "\tldp x27, x28, [sp, #144]\n" );
output( "\tldp x29, x30, [sp], #160\n" );
output( "\tret\n" );
output( "3:\tmov x0, #0x%x\n", invalid_param & 0xffff0000 );
output( "\tmovk x0, #0x%x\n", invalid_param & 0x0000ffff );
@ -1719,7 +1712,7 @@ void output_syscalls( DLLSPEC *spec )
output( "\t.byte 0xc3\n" ); /* ret */
if (target_platform == PLATFORM_WINDOWS)
{
output( "1:\t.byte 0xff,0x14,0x25\n" ); /* 2: callq *(__wine_syscall_dispatcher) */
output( "1:\t.byte 0xff,0x14,0x25\n" ); /* 1: callq *(__wine_syscall_dispatcher) */
output( "\t.long __wine_syscall_dispatcher\n" );
}
else