Alexandre Julliard : ntdll: Only restore the modified parts of the syscall frame on x86-64.
Alexandre Julliard
julliard at winehq.org
Mon Jun 7 16:30:35 CDT 2021
Module: wine
Branch: master
Commit: 32f1bfd0f0ff5a109042c6ac9a53cf773acdae27
URL: https://source.winehq.org/git/wine.git/?a=commit;h=32f1bfd0f0ff5a109042c6ac9a53cf773acdae27
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Jun 7 13:17:15 2021 +0200
ntdll: Only restore the modified parts of the syscall frame on x86-64.
Based on a patch by Jacek Caban.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/unix/signal_x86_64.c | 92 +++++++++++++----------------------------
tools/winebuild/import.c | 23 ++++++++++-
2 files changed, 50 insertions(+), 65 deletions(-)
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 086bfdfe066..524c9348ec2 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -281,31 +281,31 @@ C_ASSERT( sizeof(struct syscall_xsave) == 0x340 );
struct syscall_frame
{
- 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 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 */
+ DWORD restore_flags; /* 0094 */
+ ULONG64 rbp; /* 0098 */
};
C_ASSERT( sizeof( struct syscall_frame ) == 0xa0);
@@ -1558,34 +1558,6 @@ static void restore_context( const struct xcontext *xcontext, ucontext_t *sigcon
}
-/***********************************************************************
- * set_full_cpu_context
- *
- * Set the new CPU context.
- */
-extern void set_full_cpu_context(void) DECLSPEC_HIDDEN;
-__ASM_GLOBAL_FUNC( set_full_cpu_context,
- "movq %gs:0x30,%rdx\n\t"
- "movq 0x328(%rdx),%rsp\n\t" /* amd64_thread_data()->syscall_frame */
- "movq $0,0x328(%rdx)\n\t"
- "movq 0x00(%rsp),%rax\n\t"
- "movq 0x08(%rsp),%rbx\n\t"
- "movq 0x10(%rsp),%rcx\n\t"
- "movq 0x18(%rsp),%rdx\n\t"
- "movq 0x20(%rsp),%rsi\n\t"
- "movq 0x28(%rsp),%rdi\n\t"
- "movq 0x30(%rsp),%r8\n\t"
- "movq 0x38(%rsp),%r9\n\t"
- "movq 0x40(%rsp),%r10\n\t"
- "movq 0x48(%rsp),%r11\n\t"
- "movq 0x50(%rsp),%r12\n\t"
- "movq 0x58(%rsp),%r13\n\t"
- "movq 0x60(%rsp),%r14\n\t"
- "movq 0x68(%rsp),%r15\n\t"
- "movq 0x98(%rsp),%rbp\n\t"
- "leaq 0x70(%rsp),%rsp\n\t"
- "iretq" )
-
/***********************************************************************
* signal_restore_full_cpu_context
*
@@ -1593,17 +1565,7 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context,
*/
void signal_restore_full_cpu_context(void)
{
- struct syscall_xsave *xsave = get_syscall_xsave( amd64_thread_data()->syscall_frame );
-
- if (cpu_info.ProcessorFeatureBits & CPU_FEATURE_XSAVE)
- {
- __asm__ volatile( "xrstor64 %0" : : "m"(xsave->xsave), "a" (7), "d" (0) );
- }
- else
- {
- __asm__ volatile( "fxrstor64 %0" : : "m"(xsave->xsave) );
- }
- set_full_cpu_context();
+ amd64_thread_data()->syscall_frame->restore_flags |= CONTEXT_INTEGER;
}
@@ -1708,6 +1670,8 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
}
else xsave->xstate.Mask &= ~XSTATE_MASK_GSSE;
}
+
+ frame->restore_flags |= flags & ~CONTEXT_INTEGER;
return STATUS_SUCCESS;
}
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index 3acf720e1c6..3bd139a2b31 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -1614,6 +1614,7 @@ static void output_syscall_dispatcher(void)
output( "\tmovw %%fs,-0x1a(%%rbp)\n" );
output( "\tmovw %%ss,-0x8(%%rbp)\n" );
output( "\tmovw %%gs,-0x6(%%rbp)\n" );
+ output( "\tmovl $0,-0x4(%%rbp)\n" );
output( "\tmovq %%rsp,%%r12\n" );
output( "\tmovq %%rax,%%r13\n" );
output( "\tmovl %s(%%rip),%%r14d\n", asm_name("__wine_syscall_flags") );
@@ -1667,6 +1668,9 @@ static void output_syscall_dispatcher(void)
output( "\tcallq *(%%r10,%%r13,8)\n" );
output( "2:\tmovq %%gs:0x30,%%rcx\n" );
output( "\tmovq $0,0x328(%%rcx)\n" );
+ output( "\tmovl -4(%%rbp),%%ecx\n" ); /* frame->restore_flags */
+ output( "\ttestl $0x48,%%ecx\n" ); /* CONTEXT_FLOATING_POINT | CONTEXT_XSTATE */
+ output( "\tjz 4f\n" );
output( "\ttestl $3,%%r14d\n" ); /* SYSCALL_HAVE_XSAVE | SYSCALL_HAVE_XSAVEC */
output( "\tjz 3f\n" );
output( "\tmovq %%rax,%%r11\n" );
@@ -1687,7 +1691,24 @@ static void output_syscall_dispatcher(void)
output_cfi( ".cfi_same_value %%rsi" );
output( "\tmovq -0x90(%%rbp),%%rbx\n" );
output_cfi( ".cfi_same_value %%rbx" );
- output( "\tleaq -0x28(%%rbp),%%rsp\n" );
+ output( "\ttestl $0x3,%%ecx\n" ); /* CONTEXT_CONTROL | CONTEXT_INTEGER */
+ output( "\tjnz 1f\n" );
+ output( "\tmovq -0x28(%%rbp),%%rcx\n" ); /* frame->rip */
+ output( "\tleaq -0x10(%%rbp),%%rsp\n" ); /* frame->rsp */
+ output( "\tmovq (%%rbp),%%rbp\n" );
+ output_cfi( ".cfi_same_value %%rbp" );
+ output( "\tpopq %%rsp\n" );
+ output( "\tjmpq *%%rcx\n" );
+ output( "1:\ttestl $0x2,%%ecx\n" ); /* CONTEXT_INTEGER */
+ output( "\tjz 1f\n" );
+ output( "\tmovq -0x98(%%rbp),%%rax\n" );
+ output( "\tmovq -0x88(%%rbp),%%rcx\n" );
+ output( "\tmovq -0x80(%%rbp),%%rdx\n" );
+ output( "\tmovq -0x68(%%rbp),%%r8\n" );
+ output( "\tmovq -0x60(%%rbp),%%r9\n" );
+ output( "\tmovq -0x58(%%rbp),%%r10\n" );
+ output( "\tmovq -0x50(%%rbp),%%r11\n" );
+ output( "1:\tleaq -0x28(%%rbp),%%rsp\n" );
output_cfi( ".cfi_def_cfa_register %%rsp" );
output_cfi( ".cfi_adjust_cfa_offset 40" );
output( "\tmovq (%%rbp),%%rbp\n" );
More information about the wine-cvs
mailing list