ntdll: Reserve space for all registers in x86_64 syscall frame.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2021-02-15 21:57:55 +01:00 committed by Alexandre Julliard
parent 877f06d123
commit 6d2f08cfcb
2 changed files with 48 additions and 31 deletions

View File

@ -275,20 +275,37 @@ C_ASSERT( sizeof(struct syscall_xsave) == 0x200 );
struct syscall_frame
{
ULONG64 r12;
ULONG64 r13;
ULONG64 r14;
ULONG64 r15;
ULONG64 rdi;
ULONG64 rsi;
ULONG64 rbx;
ULONG64 rbp;
ULONG64 rax; /* 0000 */
ULONG64 rbx; /* 0008 */
ULONG64 rcx; /* 0010 */
ULONG64 rdx; /* 0018 */
ULONG64 rsi; /* 0020 */
ULONG64 rdi; /* 0028 */
ULONG64 r8; /* 0030 */
ULONG64 r9; /* 0038 */
ULONG64 r10; /* 0040 */
ULONG64 r11; /* 0048 */
ULONG64 r12; /* 0050 */
ULONG64 r13; /* 0058 */
ULONG64 r14; /* 0060 */
ULONG64 r15; /* 0068 */
ULONG64 rip; /* 0070 */
WORD cs; /* 0078 */
WORD ds; /* 007a */
WORD es; /* 007c */
WORD fs; /* 007e */
ULONG64 eflags; /* 0080 */
ULONG64 rsp; /* 0088 */
WORD ss; /* 0090 */
WORD gs; /* 0092 */
WORD pad[2]; /* 0094 */
ULONG64 rbp; /* 0098 */
ULONG64 thunk_addr;
ULONG64 ret_addr;
};
/* Should match the offset in call_user_apc_dispatcher(). */
C_ASSERT( offsetof( struct syscall_frame, ret_addr ) == 0x48);
C_ASSERT( offsetof( struct syscall_frame, ret_addr ) == 0xa8);
struct amd64_thread_data
{
@ -2087,7 +2104,7 @@ __ASM_GLOBAL_FUNC( call_user_apc_dispatcher,
"movq 0x98(%rcx),%rdx\n\t" /* context->Rsp */
"jmp 2f\n\t"
"1:\tmovq 0x328(%rbx),%rax\n\t" /* amd64_thread_data()->syscall_frame */
"leaq 0x48(%rax),%rdx\n\t" /* &amd64_thread_data()->syscall_frame->ret_addr */
"leaq 0xa8(%rax),%rdx\n\t" /* &amd64_thread_data()->syscall_frame->ret_addr */
"2:\tsubq $0x510,%rdx\n\t" /* sizeof(struct apc_stack_layout) */
"andq $~0xf,%rdx\n\t"
"addq $8,%rsp\n\t" /* pop return address */
@ -2135,12 +2152,12 @@ __ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher,
"leaq -0x200(%rax),%r8\n\t"
"andq $~63,%r8\n\t"
"fxrstor64 (%r8)\n\t"
"movq 0x20(%rax),%rdi\n\t" /* frame->rdi */
"movq 0x28(%rax),%rsi\n\t" /* frame->rsi */
"movq 0x30(%rax),%rbx\n\t" /* frame->rbx */
"movq 0x38(%rax),%rbp\n\t" /* frame->rbp */
"movq 0x8(%rax),%rbx\n\t" /* frame->rbx */
"movq 0x20(%rax),%rsi\n\t" /* frame->rsi */
"movq 0x28(%rax),%rdi\n\t" /* frame->rdi */
"movq 0x98(%rax),%rbp\n\t" /* frame->rbp */
"movq $0,0x328(%rdx)\n\t"
"leaq 0x48(%rax),%rsp\n\t"
"leaq 0xa8(%rax),%rsp\n\t"
"jmpq *%rcx" )

View File

@ -1508,24 +1508,24 @@ 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 -0x238(%%rbp),%%rsp\n" );
output( "\tleaq -0x2a8(%%rbp),%%rsp\n" );
output( "\tandq $~63,%%rsp\n" );
output( "\tmovq %%gs:0x30,%%rcx\n" );
output( "\tmovq %%r12,-0x38(%%rbp)\n" );
output( "\tmovq %%r13,-0x30(%%rbp)\n" );
output( "\tmovq %%r14,-0x28(%%rbp)\n" );
output( "\tmovq %%r15,-0x20(%%rbp)\n" );
output( "\tmovq %%rdi,-0x18(%%rbp)\n" );
output_cfi( ".cfi_rel_offset %%rdi,-24" );
output( "\tmovq %%rsi,-0x10(%%rbp)\n" );
output_cfi( ".cfi_rel_offset %%rsi,-16" );
output( "\tmovq %%rbx,-0x08(%%rbp)\n" );
output_cfi( ".cfi_rel_offset %%rbx,-8" );
output( "\tmovq %%rbx,-0x90(%%rbp)\n" );
output_cfi( ".cfi_rel_offset %%rbx,-144" );
output( "\tmovq %%rsi,-0x78(%%rbp)\n" );
output_cfi( ".cfi_rel_offset %%rsi,-120" );
output( "\tmovq %%rdi,-0x70(%%rbp)\n" );
output_cfi( ".cfi_rel_offset %%rdi,-112" );
output( "\tmovq %%r12,-0x48(%%rbp)\n" );
output( "\tmovq %%r13,-0x40(%%rbp)\n" );
output( "\tmovq %%r14,-0x38(%%rbp)\n" );
output( "\tmovq %%r15,-0x30(%%rbp)\n" );
output( "\tfxsave64 (%%rsp)\n" );
/* 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( "\tleaq -0x38(%%rbp),%%rbx\n" );
output( "\tmovq %%gs:0x30,%%rcx\n" );
output( "\tleaq -0x98(%%rbp),%%rbx\n" );
output( "\tmovq %%rbx,0x328(%%rcx)\n" ); /* amd64_thread_data()->syscall_frame */
output( "\tcmpq $%u,%%rax\n", count );
output( "\tjae 3f\n" );
@ -1546,11 +1546,11 @@ void output_syscalls( DLLSPEC *spec )
output( "\tcallq *(%%r10,%%rax,8)\n" );
output( "2:\tmovq %%gs:0x30,%%rcx\n" );
output( "\tmovq $0,0x328(%%rcx)\n" );
output( "\tmovq -0x18(%%rbp),%%rdi\n" );
output( "\tmovq -0x70(%%rbp),%%rdi\n" );
output_cfi( ".cfi_same_value %%rdi" );
output( "\tmovq -0x10(%%rbp),%%rsi\n" );
output( "\tmovq -0x78(%%rbp),%%rsi\n" );
output_cfi( ".cfi_same_value %%rsi" );
output( "\tmovq -0x8(%%rbp),%%rbx\n" );
output( "\tmovq -0x90(%%rbp),%%rbx\n" );
output_cfi( ".cfi_same_value %%rbx" );
output_cfi( ".cfi_def_cfa_register %%rsp" );
output( "\tleave\n" );