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