Alexandre Julliard : ntdll: Add a helper function to grow the stack on guard page faults.

Alexandre Julliard julliard at winehq.org
Wed Jul 15 16:44:45 CDT 2020


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Wed Jul 15 10:28:57 2020 +0200

ntdll: Add a helper function to grow the stack on guard page faults.

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

---

 dlls/ntdll/unix/virtual.c | 46 ++++++++++++++++++++++++++++------------------
 1 file changed, 28 insertions(+), 18 deletions(-)

diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index a155fc46f8..122f372978 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -2844,6 +2844,33 @@ void virtual_map_user_shared_data(void)
 }
 
 
+/***********************************************************************
+ *           grow_thread_stack
+ */
+static NTSTATUS grow_thread_stack( char *page )
+{
+    NTSTATUS ret = 0;
+    size_t guaranteed = max( NtCurrentTeb()->GuaranteedStackBytes, page_size * (is_win64 ? 2 : 1) );
+
+    set_page_vprot_bits( page, page_size, 0, VPROT_GUARD );
+    mprotect_range( page, page_size, 0, 0 );
+    if (page >= (char *)NtCurrentTeb()->DeallocationStack + page_size + guaranteed)
+    {
+        set_page_vprot_bits( page - page_size, page_size, VPROT_COMMITTED | VPROT_GUARD, 0 );
+        mprotect_range( page - page_size, page_size, 0, 0 );
+    }
+    else  /* inside guaranteed space -> overflow exception */
+    {
+        page = (char *)NtCurrentTeb()->DeallocationStack + page_size;
+        set_page_vprot_bits( page, guaranteed, VPROT_COMMITTED, VPROT_GUARD );
+        mprotect_range( page, guaranteed, 0, 0 );
+        ret = STATUS_STACK_OVERFLOW;
+    }
+    NtCurrentTeb()->Tib.StackLimit = page;
+    return ret;
+}
+
+
 /***********************************************************************
  *           virtual_handle_fault
  */
@@ -3045,24 +3072,7 @@ int virtual_handle_stack_fault( void *addr )
     pthread_mutex_lock( &virtual_mutex );  /* no need for signal masking inside signal handler */
     if (get_page_vprot( addr ) & VPROT_GUARD)
     {
-        size_t guaranteed = max( NtCurrentTeb()->GuaranteedStackBytes, page_size * (is_win64 ? 2 : 1) );
-        char *page = ROUND_ADDR( addr, page_mask );
-        set_page_vprot_bits( page, page_size, 0, VPROT_GUARD );
-        mprotect_range( page, page_size, 0, 0 );
-        if (page >= (char *)NtCurrentTeb()->DeallocationStack + page_size + guaranteed)
-        {
-            set_page_vprot_bits( page - page_size, page_size, VPROT_COMMITTED | VPROT_GUARD, 0 );
-            mprotect_range( page - page_size, page_size, 0, 0 );
-            ret = 1;
-        }
-        else  /* inside guaranteed space -> overflow exception */
-        {
-            page = (char *)NtCurrentTeb()->DeallocationStack + page_size;
-            set_page_vprot_bits( page, guaranteed, VPROT_COMMITTED, VPROT_GUARD );
-            mprotect_range( page, guaranteed, 0, 0 );
-            ret = -1;
-        }
-        NtCurrentTeb()->Tib.StackLimit = page;
+        ret = grow_thread_stack( ROUND_ADDR( addr, page_mask )) ? -1 : 1;
     }
     pthread_mutex_unlock( &virtual_mutex );
     return ret;




More information about the wine-cvs mailing list