From 3863b243fe5ef4e223a809e93a85e858952dd754 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 27 Aug 2020 11:58:26 +0200 Subject: [PATCH] ntdll: Clear the thread stack by hand instead of remapping zero pages. Signed-off-by: Alexandre Julliard --- dlls/ntdll/signal_arm.c | 3 --- dlls/ntdll/signal_arm64.c | 3 --- dlls/ntdll/signal_i386.c | 17 +++++++++++------ dlls/ntdll/signal_x86_64.c | 20 ++++++++++++++------ dlls/ntdll/virtual.c | 15 --------------- 5 files changed, 25 insertions(+), 33 deletions(-) diff --git a/dlls/ntdll/signal_arm.c b/dlls/ntdll/signal_arm.c index 1041dadf867..0e80a35b0c0 100644 --- a/dlls/ntdll/signal_arm.c +++ b/dlls/ntdll/signal_arm.c @@ -268,10 +268,7 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, */ __ASM_GLOBAL_FUNC( signal_start_thread, "mov sp, r0\n\t" /* context */ - "and r0, #~0xff0\n\t" /* round down to page size */ - "bl " __ASM_NAME("virtual_clear_thread_stack") "\n\t" "mov r1, #1\n\t" - "mov r0, sp\n\t" "b " __ASM_NAME("NtContinue") ) /********************************************************************** diff --git a/dlls/ntdll/signal_arm64.c b/dlls/ntdll/signal_arm64.c index 8d21c39f6ce..40789d318c6 100644 --- a/dlls/ntdll/signal_arm64.c +++ b/dlls/ntdll/signal_arm64.c @@ -1222,9 +1222,6 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, */ __ASM_GLOBAL_FUNC( signal_start_thread, "mov sp, x0\n\t" /* context */ - "and x0, x0, #~0xfff\n\t" /* round down to page size */ - "bl " __ASM_NAME("virtual_clear_thread_stack") "\n\t" - "mov x0, sp\n\t" "mov x1, #1\n\t" "b " __ASM_NAME("NtContinue") ) diff --git a/dlls/ntdll/signal_i386.c b/dlls/ntdll/signal_i386.c index 8f7896df0da..ddc2bf6adbd 100644 --- a/dlls/ntdll/signal_i386.c +++ b/dlls/ntdll/signal_i386.c @@ -475,13 +475,18 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, */ __ASM_GLOBAL_FUNC( signal_start_thread, "movl 4(%esp),%esi\n\t" /* context */ - "leal -12(%esi),%eax\n\t" - "movl %eax,%esp\n\t" - /* clear the stack */ - "andl $~0xfff,%eax\n\t" /* round down to page size */ - "movl %eax,(%esp)\n\t" - "call " __ASM_NAME("virtual_clear_thread_stack") "\n\t" + "leal -12(%esi),%ecx\n\t" + /* clear the thread stack */ + "andl $~0xfff,%ecx\n\t" /* round down to page size */ + "movl %fs:8,%edi\n\t" /* NtCurrentTeb()->Tib.StackLimit */ + "addl $0x1000,%edi\n\t" + "movl %edi,%esp\n\t" + "subl %edi,%ecx\n\t" + "xorl %eax,%eax\n\t" + "shrl $2,%ecx\n\t" + "rep; stosl\n\t" /* switch to the initial context */ + "leal -12(%esi),%esp\n\t" "movl $1,4(%esp)\n\t" "movl %esi,(%esp)\n\t" "call " __ASM_STDCALL("NtContinue", 8) ) diff --git a/dlls/ntdll/signal_x86_64.c b/dlls/ntdll/signal_x86_64.c index 87acff3dcd4..ba91cc13dfe 100644 --- a/dlls/ntdll/signal_x86_64.c +++ b/dlls/ntdll/signal_x86_64.c @@ -1486,13 +1486,21 @@ USHORT WINAPI RtlCaptureStackBackTrace( ULONG skip, ULONG count, PVOID *buffer, * signal_start_thread */ __ASM_GLOBAL_FUNC( signal_start_thread, - "movq %rcx,%rbx\n\t" /* context */ - "leaq -32(%rcx),%rcx\n\t" - "movq %rcx,%rsp\n\t" - "andq $~0xfff,%rcx\n\t" /* round down to page size */ - "call " __ASM_NAME("virtual_clear_thread_stack") "\n\t" - "movl $1,%edx\n\t" + "movq %rcx,%rbx\n\t" /* context */ + /* clear the thread stack */ + "andq $~0xfff,%rcx\n\t" /* round down to page size */ + "movq %gs:0x30,%rax\n\t" + "movq 0x10(%rax),%rdi\n\t" /* NtCurrentTeb()->Tib.StackLimit */ + "addq $0x2000,%rdi\n\t" + "movq %rdi,%rsp\n\t" + "subq %rdi,%rcx\n\t" + "xorl %eax,%eax\n\t" + "shrq $3,%rcx\n\t" + "rep; stosq\n\t" + /* switch to the initial context */ + "leaq -32(%rbx),%rsp\n\t" "movq %rbx,%rcx\n\t" + "movl $1,%edx\n\t" "call " __ASM_NAME("NtContinue") ) diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index acaa6f75657..e0435181e95 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -105,18 +105,3 @@ void WINAPI RtlFreeUserStack( void *stack ) NtFreeVirtualMemory( NtCurrentProcess(), &stack, &size, MEM_RELEASE ); } - - -/*********************************************************************** - * virtual_clear_thread_stack - * - * Clear the stack contents before calling the main entry point, some broken apps need that. - */ -void CDECL virtual_clear_thread_stack( void *stack_end ) -{ - void *stack = NtCurrentTeb()->Tib.StackLimit; - SIZE_T size = (char *)stack_end - (char *)stack; - - NtFreeVirtualMemory( GetCurrentProcess(), &stack, &size, MEM_DECOMMIT ); - NtAllocateVirtualMemory( GetCurrentProcess(), &stack, 0, &size, MEM_COMMIT, PAGE_READWRITE ); -}