Alexandre Julliard : ntdll: Pass the stack pointer to virtual_clear_thread_stack().

Alexandre Julliard julliard at winehq.org
Mon Dec 4 14:58:21 CST 2017


Module: wine
Branch: master
Commit: b526a48a245c866a1e3e18234a82aeca09561e4a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=b526a48a245c866a1e3e18234a82aeca09561e4a

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Mon Dec  4 13:56:32 2017 +0100

ntdll: Pass the stack pointer to virtual_clear_thread_stack().

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

---

 dlls/ntdll/ntdll_misc.h    |  2 +-
 dlls/ntdll/signal_i386.c   | 63 ++++++++++++++++++++++------------------------
 dlls/ntdll/signal_x86_64.c | 30 +++++++++-------------
 dlls/ntdll/virtual.c       |  8 +++---
 4 files changed, 47 insertions(+), 56 deletions(-)

diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 72c33fe..c9c79fb 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -168,7 +168,7 @@ extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_H
 extern NTSTATUS virtual_create_builtin_view( void *base ) DECLSPEC_HIDDEN;
 extern NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size,
                                             SIZE_T commit_size, SIZE_T extra_size ) DECLSPEC_HIDDEN;
-extern void virtual_clear_thread_stack(void) DECLSPEC_HIDDEN;
+extern void virtual_clear_thread_stack( void *stack_end ) DECLSPEC_HIDDEN;
 extern BOOL virtual_handle_stack_fault( void *addr ) DECLSPEC_HIDDEN;
 extern BOOL virtual_is_valid_code_address( const void *addr, SIZE_T size ) DECLSPEC_HIDDEN;
 extern NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c
index 8623152..351b67c 100644
--- a/dlls/ntdll/signal_i386.c
+++ b/dlls/ntdll/signal_i386.c
@@ -1312,7 +1312,7 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context,
  *
  * Set the new CPU context. Used by NtSetContextThread.
  */
-static void set_cpu_context( const CONTEXT *context )
+void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context )
 {
     DWORD flags = context->ContextFlags & ~CONTEXT_i386;
 
@@ -2867,28 +2867,37 @@ __ASM_GLOBAL_FUNC( start_thread,
                    "movl %ebp,(%eax)\n\t"
                    /* build initial context on thread stack */
                    "movl %fs:4,%eax\n\t"        /* NtCurrentTeb()->StackBase */
-                   "leal -0x2dc(%eax),%ecx\n\t" /* sizeof(context) + 16 */
-                   "movl $0x10007,(%ecx)\n\t"   /* context->ContextFlags = CONTEXT_FULL */
-                   "movw %cs,0xbc(%ecx)\n\t"    /* context->SegCs */
-                   "movw %ds,0x98(%ecx)\n\t"    /* context->SegDs */
-                   "movw %es,0x94(%ecx)\n\t"    /* context->SegEs */
-                   "movw %fs,0x90(%ecx)\n\t"    /* context->SegFs */
-                   "movw %gs,0x8c(%ecx)\n\t"    /* context->SegGs */
-                   "movw %ss,0xc8(%ecx)\n\t"    /* context->SegSs */
+                   "leal -0x2dc(%eax),%esi\n\t" /* sizeof(context) + 16 */
+                   "movl $0x10007,(%esi)\n\t"   /* context->ContextFlags = CONTEXT_FULL */
+                   "movw %cs,0xbc(%esi)\n\t"    /* context->SegCs */
+                   "movw %ds,0x98(%esi)\n\t"    /* context->SegDs */
+                   "movw %es,0x94(%esi)\n\t"    /* context->SegEs */
+                   "movw %fs,0x90(%esi)\n\t"    /* context->SegFs */
+                   "movw %gs,0x8c(%esi)\n\t"    /* context->SegGs */
+                   "movw %ss,0xc8(%esi)\n\t"    /* context->SegSs */
                    "movl 8(%ebp),%eax\n\t"
-                   "movl %eax,0xb0(%ecx)\n\t"   /* context->Eax = entry */
+                   "movl %eax,0xb0(%esi)\n\t"   /* context->Eax = entry */
                    "movl 12(%ebp),%eax\n\t"
-                   "movl %eax,0xa4(%ecx)\n\t"   /* context->Ebx = arg */
+                   "movl %eax,0xa4(%esi)\n\t"   /* context->Ebx = arg */
                    "movl 20(%ebp),%eax\n\t"
-                   "movl %eax,0xb8(%ecx)\n\t"   /* context->Eip = relay */
-                   "leal 0x2cc(%ecx),%eax\n\t"
-                   "movl %eax,0xc4(%ecx)\n\t"   /* context->Esp */
-                   /* switch to thread stack and call thread_startup() */
-                   "leal -12(%ecx),%esp\n\t"
+                   "movl %eax,0xb8(%esi)\n\t"   /* context->Eip = relay */
+                   "leal 0x2cc(%esi),%eax\n\t"
+                   "movl %eax,0xc4(%esi)\n\t"   /* context->Esp */
+                   /* switch to thread stack */
+                   "leal -12(%esi),%esp\n\t"
+                   /* attach dlls */
                    "pushl 16(%ebp)\n\t"         /* suspend */
-                   "pushl %ecx\n\t"             /* context */
+                   "pushl %esi\n\t"             /* context */
                    "xorl %ebp,%ebp\n\t"
-                   "call " __ASM_NAME("thread_startup") )
+                   "call " __ASM_NAME("attach_dlls") "\n\t"
+                   "addl $20,%esp\n\t"
+                   /* clear the stack */
+                   "leal -0xd24(%esi),%eax\n\t"  /* round down to page size */
+                   "pushl %eax\n\t"
+                   "call " __ASM_NAME("virtual_clear_thread_stack") "\n\t"
+                   /* switch to the initial context */
+                   "movl %esi,(%esp)\n\t"
+                   "call " __ASM_NAME("set_cpu_context") )
 
 extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), void *frame );
 __ASM_GLOBAL_FUNC( call_thread_exit_func,
@@ -2951,24 +2960,13 @@ void DECLSPEC_HIDDEN call_thread_func( LPTHREAD_START_ROUTINE entry, void *arg )
 
 
 /***********************************************************************
- *           thread_startup
- */
-void DECLSPEC_HIDDEN thread_startup( CONTEXT *context, BOOL suspend )
-{
-    attach_dlls( context, suspend );
-    virtual_clear_thread_stack();
-    set_cpu_context( context );
-}
-
-/***********************************************************************
  *           signal_start_thread
  *
  * Thread startup sequence:
  * signal_start_thread()
  *   -> start_thread()
- *     -> thread_startup()
- *       -> call_thread_entry()
- *         -> call_thread_func()
+ *     -> call_thread_entry()
+ *       -> call_thread_func()
  */
 void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
 {
@@ -2981,8 +2979,7 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend
  * Process startup sequence:
  * signal_start_process()
  *   -> start_thread()
- *     -> thread_startup()
- *       -> kernel32_start_process()
+ *     -> kernel32_start_process()
  */
 void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
 {
diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c
index 83521ee..c955c4c 100644
--- a/dlls/ntdll/signal_x86_64.c
+++ b/dlls/ntdll/signal_x86_64.c
@@ -1889,7 +1889,7 @@ __ASM_GLOBAL_FUNC( set_full_cpu_context,
  *
  * Set the new CPU context. Used by NtSetContextThread.
  */
-static void set_cpu_context( const CONTEXT *context )
+void DECLSPEC_HIDDEN set_cpu_context( const CONTEXT *context )
 {
     DWORD flags = context->ContextFlags & ~CONTEXT_AMD64;
 
@@ -4103,11 +4103,18 @@ __ASM_GLOBAL_FUNC( start_thread,
                    "movq %rax,0x98(%r10)\n\t"       /* context->Rsp */
                    "movq %rcx,0xf8(%r10)\n\t"       /* context->Rip = relay */
                    "fxsave 0x100(%r10)\n\t"         /* context->FtlSave */
-                   /* switch to thread stack and call thread_startup() */
+                   /* switch to thread stack */
                    "movq %r10,%rsp\n\t"
+                   /* attach dlls */
                    "movq %r10,%rdi\n\t"         /* context */
                    "movq %rdx,%rsi\n\t"         /* suspend */
-                   "call " __ASM_NAME("thread_startup") )
+                   "call " __ASM_NAME("attach_dlls") "\n\t"
+                   /* clear the stack */
+                   "leaq -0xb00(%rsp),%rdi\n\t"  /* round down to page size */
+                   "call " __ASM_NAME("virtual_clear_thread_stack") "\n\t"
+                   /* switch to the initial context */
+                   "movq %rsp,%rdi\n\t"
+                   "call " __ASM_NAME("set_cpu_context") )
 
 extern void DECLSPEC_NORETURN call_thread_exit_func( int status, void (*func)(int), void *frame );
 __ASM_GLOBAL_FUNC( call_thread_exit_func,
@@ -4123,24 +4130,12 @@ __ASM_GLOBAL_FUNC( call_thread_exit_func,
 
 
 /***********************************************************************
- *           thread_startup
- */
-void DECLSPEC_HIDDEN thread_startup( CONTEXT *context, BOOL suspend )
-{
-    attach_dlls( context, suspend );
-    virtual_clear_thread_stack();
-    set_cpu_context( context );
-}
-
-
-/***********************************************************************
  *           signal_start_thread
  *
  * Thread startup sequence:
  * signal_start_thread()
  *   -> start_thread()
- *     -> thread_startup()
- *       -> call_thread_func()
+ *     -> call_thread_func()
  */
 void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend )
 {
@@ -4155,8 +4150,7 @@ void signal_start_thread( LPTHREAD_START_ROUTINE entry, void *arg, BOOL suspend
  * Process startup sequence:
  * signal_start_process()
  *   -> start_thread()
- *     -> thread_startup()
- *       -> kernel32_start_process()
+ *     -> kernel32_start_process()
  */
 void signal_start_process( LPTHREAD_START_ROUTINE entry, BOOL suspend )
 {
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 8325b28..1156fc1 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1825,13 +1825,13 @@ done:
  *
  * Clear the stack contents before calling the main entry point, some broken apps need that.
  */
-void virtual_clear_thread_stack(void)
+void virtual_clear_thread_stack( void *stack_end )
 {
     void *stack = NtCurrentTeb()->Tib.StackLimit;
-    size_t size = (char *)NtCurrentTeb()->Tib.StackBase - (char *)NtCurrentTeb()->Tib.StackLimit;
+    size_t size = (char *)stack_end - (char *)stack;
 
-    wine_anon_mmap( stack, size - page_size, PROT_READ | PROT_WRITE, MAP_FIXED );
-    if (force_exec_prot) mprotect( stack, size - page_size, PROT_READ | PROT_WRITE | PROT_EXEC );
+    wine_anon_mmap( stack, size, PROT_READ | PROT_WRITE, MAP_FIXED );
+    if (force_exec_prot) mprotect( stack, size, PROT_READ | PROT_WRITE | PROT_EXEC );
 }
 
 




More information about the wine-cvs mailing list