Jacek Caban : ntdll: Use syscall frame in x86 set_full_cpu_context implementation.

Alexandre Julliard julliard at winehq.org
Thu Feb 25 16:45:38 CST 2021


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Thu Feb 25 18:54:24 2021 +0100

ntdll: Use syscall frame in x86 set_full_cpu_context implementation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/unix/signal_i386.c | 123 +++++++++++++++++++++++-------------------
 1 file changed, 68 insertions(+), 55 deletions(-)

diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index be3f1060e4a..73b16b645bb 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -820,16 +820,6 @@ static inline void restore_xstate( const CONTEXT *context )
 }
 
 
-/***********************************************************************
- *           signal_restore_full_cpu_context
- *
- * Restore full context from syscall frame
- */
-void signal_restore_full_cpu_context(void)
-{
-}
-
-
 /***********************************************************************
  *           fpux_to_fpu
  *
@@ -991,36 +981,36 @@ static inline void restore_context( const struct xcontext *xcontext, ucontext_t
  *
  * Set the new CPU context.
  */
-extern void set_full_cpu_context( const CONTEXT *context );
+extern void set_full_cpu_context(void);
 __ASM_GLOBAL_FUNC( set_full_cpu_context,
-                   "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 */
-                   "movw 0x94(%ecx),%es\n\t"  /* SegEs */
-                   "movl 0x9c(%ecx),%edi\n\t" /* Edi */
-                   "movl 0xa0(%ecx),%esi\n\t" /* Esi */
-                   "movl 0xa4(%ecx),%ebx\n\t" /* Ebx */
-                   "movl 0xb4(%ecx),%ebp\n\t" /* Ebp */
+                   "movl %fs:0x1f8,%ecx\n\t"
+                   "movl $0,%fs:0x1f8\n\t"    /* x86_thread_data()->syscall_frame = NULL */
+                   "movw 0x16(%ecx),%gs\n\t"  /* SegGs */
+                   "movw 0x14(%ecx),%fs\n\t"  /* SegFs */
+                   "movw 0x12(%ecx),%es\n\t"  /* SegEs */
+                   "movl 0x1c(%ecx),%ebx\n\t" /* Ebx */
+                   "movl 0x28(%ecx),%edi\n\t" /* Edi */
+                   "movl 0x2c(%ecx),%esi\n\t" /* Esi */
+                   "movl 0x30(%ecx),%ebp\n\t" /* Ebp */
                    "movw %ss,%ax\n\t"
-                   "cmpw 0xc8(%ecx),%ax\n\t"  /* SegSs */
+                   "cmpw 0x0e(%ecx),%ax\n\t"  /* SegSs */
                    "jne 1f\n\t"
                    /* As soon as we have switched stacks the context structure could
                     * be invalid (when signal handlers are executed for example). Copy
                     * values on the target stack before changing ESP. */
-                   "movl 0xc4(%ecx),%eax\n\t" /* Esp */
+                   "movl 0x08(%ecx),%eax\n\t" /* Esp */
                    "leal -4*4(%eax),%eax\n\t"
-                   "movl 0xc0(%ecx),%edx\n\t" /* EFlags */
+                   "movl (%ecx),%edx\n\t"     /* EFlags */
                    "movl %edx,3*4(%eax)\n\t"
-                   "movl 0xbc(%ecx),%edx\n\t" /* SegCs */
+                   "movl 0x0c(%ecx),%edx\n\t" /* SegCs */
                    "movl %edx,2*4(%eax)\n\t"
-                   "movl 0xb8(%ecx),%edx\n\t" /* Eip */
+                   "movl 0x04(%ecx),%edx\n\t" /* Eip */
                    "movl %edx,1*4(%eax)\n\t"
-                   "movl 0xb0(%ecx),%edx\n\t" /* Eax */
+                   "movl 0x18(%ecx),%edx\n\t" /* Eax */
                    "movl %edx,0*4(%eax)\n\t"
-                   "pushl 0x98(%ecx)\n\t"     /* SegDs */
-                   "movl 0xa8(%ecx),%edx\n\t" /* Edx */
-                   "movl 0xac(%ecx),%ecx\n\t" /* Ecx */
+                   "pushl 0x10(%ecx)\n\t"     /* SegDs */
+                   "movl 0x24(%ecx),%edx\n\t" /* Edx */
+                   "movl 0x20(%ecx),%ecx\n\t" /* Ecx */
                    "popl %ds\n\t"
                    "movl %eax,%esp\n\t"
                    "popl %eax\n\t"
@@ -1030,19 +1020,30 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context,
                     * is 16 or 32 bit, and 'movl' will throw an exception when we try to
                     * access memory above the limit. */
                    "1:\n\t"
-                   "movl 0xa8(%ecx),%edx\n\t" /* Edx */
-                   "movl 0xb0(%ecx),%eax\n\t" /* Eax */
-                   "movw 0xc8(%ecx),%ss\n\t"  /* SegSs */
-                   "movl 0xc4(%ecx),%esp\n\t" /* Esp */
-                   "pushl 0xc0(%ecx)\n\t"     /* EFlags */
-                   "pushl 0xbc(%ecx)\n\t"     /* SegCs */
-                   "pushl 0xb8(%ecx)\n\t"     /* Eip */
-                   "pushl 0x98(%ecx)\n\t"     /* SegDs */
-                   "movl 0xac(%ecx),%ecx\n\t" /* Ecx */
+                   "movl 0x24(%ecx),%edx\n\t" /* Edx */
+                   "movl 0x18(%ecx),%eax\n\t" /* Eax */
+                   "movw 0x0e(%ecx),%ss\n\t"  /* SegSs */
+                   "movl 0x08(%ecx),%esp\n\t" /* Esp */
+                   "pushl 0x00(%ecx)\n\t"     /* EFlags */
+                   "pushl 0x0c(%ecx)\n\t"     /* SegCs */
+                   "pushl 0x04(%ecx)\n\t"     /* Eip */
+                   "pushl 0x10(%ecx)\n\t"     /* SegDs */
+                   "movl 0x20(%ecx),%ecx\n\t" /* Ecx */
                    "popl %ds\n\t"
                    "iret" )
 
 
+/***********************************************************************
+ *           signal_restore_full_cpu_context
+ *
+ * Restore full context from syscall frame
+ */
+void signal_restore_full_cpu_context(void)
+{
+    set_full_cpu_context();
+}
+
+
 /***********************************************************************
  *           get_server_context_flags
  *
@@ -1215,6 +1216,7 @@ NTSTATUS context_from_server( CONTEXT *to, const context_t *from )
 NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
 {
     NTSTATUS ret = STATUS_SUCCESS;
+    struct syscall_frame *frame = x86_thread_data()->syscall_frame;
     DWORD flags = context->ContextFlags & ~CONTEXT_i386;
     BOOL self = (handle == GetCurrentThread());
 
@@ -1244,28 +1246,39 @@ NTSTATUS WINAPI NtSetContextThread( HANDLE handle, const CONTEXT *context )
         }
     }
 
+    if (flags & CONTEXT_INTEGER)
+    {
+        frame->eax = context->Eax;
+        frame->ebx = context->Ebx;
+        frame->ecx = context->Ecx;
+        frame->edx = context->Edx;
+        frame->esi = context->Esi;
+        frame->edi = context->Edi;
+    }
+    if (flags & CONTEXT_CONTROL)
+    {
+        frame->esp    = context->Esp;
+        frame->ebp    = context->Ebp;
+        frame->eip    = context->Eip;
+        frame->eflags = context->EFlags;
+        frame->cs     = context->SegCs;
+        frame->ss     = context->SegSs;
+    }
+    if (flags & CONTEXT_SEGMENTS)
+    {
+        frame->ds = context->SegDs;
+        frame->es = context->SegEs;
+        frame->fs = context->SegFs;
+        frame->gs = context->SegGs;
+    }
     if (flags & CONTEXT_EXTENDED_REGISTERS) restore_fpux( context );
     else if (flags & CONTEXT_FLOATING_POINT) restore_fpu( context );
 
     restore_xstate( context );
 
-    if (flags & CONTEXT_FULL)
-    {
-        if (!(flags & CONTEXT_CONTROL))
-            FIXME( "setting partial context (%x) not supported\n", flags );
-        else if (flags & CONTEXT_SEGMENTS)
-            set_full_cpu_context( context );
-        else
-        {
-            CONTEXT newcontext = *context;
-            newcontext.SegDs = get_ds();
-            newcontext.SegEs = get_ds();
-            newcontext.SegFs = get_fs();
-            newcontext.SegGs = get_gs();
-            set_full_cpu_context( &newcontext );
-        }
-    }
-    return ret;
+    if (!(flags & CONTEXT_INTEGER)) frame->eax = STATUS_SUCCESS;
+    signal_restore_full_cpu_context();
+    return STATUS_SUCCESS;
 }
 
 




More information about the wine-cvs mailing list