Alexandre Julliard : winebuild: Store the syscall frame in the thread data on x86_64.

Alexandre Julliard julliard at winehq.org
Tue Jul 28 15:53:31 CDT 2020


Module: wine
Branch: master
Commit: 9a7c56d9e7f8e49dc98dace53b10d0753f0e27a7
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=9a7c56d9e7f8e49dc98dace53b10d0753f0e27a7

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Jul 28 13:01:24 2020 +0200

winebuild: Store the syscall frame in the thread data on x86_64.

Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/signal_x86_64.c | 34 +++++++++++++++++++++++++++-------
 tools/winebuild/import.c        | 41 +++++++++++++++++++++++++++++++++--------
 2 files changed, 60 insertions(+), 15 deletions(-)

diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 630f8e22f3..b954ef9458 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -240,19 +240,39 @@ struct stack_layout
 
 C_ASSERT( sizeof(struct stack_layout) == 0x630 ); /* Should match the size in call_user_exception_dispatcher(). */
 
+struct syscall_frame
+{
+    struct syscall_frame *prev_frame;
+    ULONG64               pad;
+    ULONG64               xmm[10 * 2];  /* xmm6-xmm15 */
+    ULONG64               mxcsr;
+    ULONG64               r12;
+    ULONG64               r13;
+    ULONG64               r14;
+    ULONG64               r15;
+    ULONG64               rdi;
+    ULONG64               rsi;
+    ULONG64               rbx;
+    ULONG64               rbp;
+    ULONG64               thunk_addr;
+    ULONG64               ret_addr;
+};
+
 struct amd64_thread_data
 {
-    DWORD_PTR dr0;           /* 02f0 debug registers */
-    DWORD_PTR dr1;
-    DWORD_PTR dr2;
-    DWORD_PTR dr3;
-    DWORD_PTR dr6;
-    DWORD_PTR dr7;
-    void     *exit_frame;    /* 0320 exit frame pointer */
+    DWORD_PTR             dr0;           /* 02f0 debug registers */
+    DWORD_PTR             dr1;           /* 02f8 */
+    DWORD_PTR             dr2;           /* 0300 */
+    DWORD_PTR             dr3;           /* 0308 */
+    DWORD_PTR             dr6;           /* 0310 */
+    DWORD_PTR             dr7;           /* 0318 */
+    void                 *exit_frame;    /* 0320 exit frame pointer */
+    struct syscall_frame *syscall_frame; /* 0328 syscall frame pointer */
 };
 
 C_ASSERT( sizeof(struct amd64_thread_data) <= sizeof(((struct ntdll_thread_data *)0)->cpu_data) );
 C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct amd64_thread_data, exit_frame ) == 0x320 );
+C_ASSERT( offsetof( TEB, GdiTebBatch ) + offsetof( struct amd64_thread_data, syscall_frame ) == 0x328 );
 
 static inline struct amd64_thread_data *amd64_thread_data(void)
 {
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index cb0b80a6f7..09cb320b5d 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -1496,10 +1496,31 @@ 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( "\tpushq %%rsi\n" );
-            output_cfi( ".cfi_rel_offset %%rsi,-8" );
-            output( "\tpushq %%rdi\n" );
-            output_cfi( ".cfi_rel_offset %%rdi,-16" );
+            output( "\tleaq -0xe8(%%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" );
+            output( "\tmovdqu %%xmm9,-0xb0(%%rbp)\n" );
+            output( "\tmovdqu %%xmm10,-0xa0(%%rbp)\n" );
+            output( "\tmovdqu %%xmm11,-0x90(%%rbp)\n" );
+            output( "\tmovdqu %%xmm12,-0x80(%%rbp)\n" );
+            output( "\tmovdqu %%xmm13,-0x70(%%rbp)\n" );
+            output( "\tmovdqu %%xmm14,-0x60(%%rbp)\n" );
+            output( "\tmovdqu %%xmm15,-0x50(%%rbp)\n" );
+            output( "\tstmxcsr -0x40(%%rbp)\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" );
             /* 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" );
@@ -1522,13 +1543,17 @@ 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:\tleaq -0x10(%%rbp),%%rsp\n" );
-            output( "\tpopq %%rdi\n" );
+            output( "3:\tpushq -0xf0(%%rbp)\n" );
+            output( "\tmovq %%gs:0x30,%%rcx\n" );
+            output( "\tpopq 0x328(%%rcx)\n" );  /* prev frame */
+            output( "\tmovq -0x18(%%rbp),%%rdi\n" );
             output_cfi( ".cfi_same_value %%rdi" );
-            output( "\tpopq %%rsi\n" );
+            output( "\tmovq -0x10(%%rbp),%%rsi\n" );
             output_cfi( ".cfi_same_value %%rsi" );
+            output( "\tmovq -0x8(%%rbp),%%rbx\n" );
+            output_cfi( ".cfi_same_value %%rbx" );
             output_cfi( ".cfi_def_cfa_register %%rsp" );
-            output( "\tpopq %%rbp\n" );
+            output( "\tleave\n" );
             output_cfi( ".cfi_adjust_cfa_offset -8" );
             output_cfi( ".cfi_same_value %%rbp" );
             output( "\tret\n" );




More information about the wine-cvs mailing list