Alexandre Julliard : ntdll: Handle stack faults without fetching the view pointer.

Alexandre Julliard julliard at winehq.org
Fri Sep 22 15:49:05 CDT 2017


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

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Fri Sep 22 12:13:50 2017 +0200

ntdll: Handle stack faults without fetching the view pointer.

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

---

 dlls/ntdll/virtual.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index ceb4216..7d6b36d 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -183,6 +183,7 @@ static BYTE get_page_vprot( const void *addr )
     size_t idx = (size_t)addr >> page_shift;
 
 #ifdef _WIN64
+    if (!pages_vprot[idx >> pages_vprot_shift]) return 0;
     return pages_vprot[idx >> pages_vprot_shift][idx & pages_vprot_mask];
 #else
     return pages_vprot[idx];
@@ -671,6 +672,7 @@ static struct file_view *alloc_view(void)
 static void delete_view( struct file_view *view ) /* [in] View */
 {
     if (!(view->protect & VPROT_SYSTEM)) unmap_area( view->base, view->size );
+    set_page_vprot( view->base, view->size, 0 );
     wine_rb_remove( &views_tree, &view->entry );
     if (view->mapping) close_handle( view->mapping );
     *(struct file_view **)view = next_free_view;
@@ -1720,9 +1722,10 @@ NTSTATUS virtual_alloc_thread_stack( TEB *teb, SIZE_T reserve_size, SIZE_T commi
 #endif
 
     /* setup no access guard page */
-    VIRTUAL_SetProt( view, view->base, page_size, VPROT_COMMITTED );
-    VIRTUAL_SetProt( view, (char *)view->base + page_size, page_size,
-                     VPROT_READ | VPROT_WRITE | VPROT_COMMITTED | VPROT_GUARD );
+    set_page_vprot( view->base, page_size, VPROT_COMMITTED );
+    set_page_vprot( (char *)view->base + page_size, page_size,
+                    VPROT_READ | VPROT_WRITE | VPROT_COMMITTED | VPROT_GUARD );
+    mprotect_range( view->base, 2 * page_size, 0, 0 );
     VIRTUAL_DEBUG_DUMP_VIEW( view );
 
     /* note: limit is lower than base since the stack grows down */
@@ -1812,25 +1815,22 @@ BOOL virtual_is_valid_code_address( const void *addr, SIZE_T size )
  */
 BOOL virtual_handle_stack_fault( void *addr )
 {
-    struct file_view *view;
     BOOL ret = FALSE;
 
     RtlEnterCriticalSection( &csVirtual );  /* no need for signal masking inside signal handler */
-    if ((view = VIRTUAL_FindView( addr, 0 )))
+    if (get_page_vprot( addr ) & VPROT_GUARD)
     {
-        void *page = ROUND_ADDR( addr, page_mask );
-        BYTE vprot = get_page_vprot( page );
-        if (vprot & VPROT_GUARD)
+        char *page = ROUND_ADDR( addr, page_mask );
+        set_page_vprot_bits( page, page_size, 0, VPROT_GUARD );
+        mprotect_range( page, page_size, 0, 0 );
+        NtCurrentTeb()->Tib.StackLimit = page;
+        if (page >= (char *)NtCurrentTeb()->DeallocationStack + 2*page_size)
         {
-            VIRTUAL_SetProt( view, page, page_size, vprot & ~VPROT_GUARD );
-            NtCurrentTeb()->Tib.StackLimit = page;
-            if ((char *)page >= (char *)NtCurrentTeb()->DeallocationStack + 2*page_size)
-            {
-                vprot = get_page_vprot( (char *)page - page_size );
-                VIRTUAL_SetProt( view, (char *)page - page_size, page_size, vprot | VPROT_COMMITTED | VPROT_GUARD );
-            }
-            ret = TRUE;
+            page -= page_size;
+            set_page_vprot_bits( page, page_size, VPROT_COMMITTED | VPROT_GUARD, 0 );
+            mprotect_range( page, page_size, 0, 0 );
         }
+        ret = TRUE;
     }
     RtlLeaveCriticalSection( &csVirtual );
     return ret;




More information about the wine-cvs mailing list