Alexandre Julliard : ntdll: Pass the stack address to the virtual_handle_fault() function.

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


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

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

ntdll: Pass the stack address to the virtual_handle_fault() function.

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

---

 dlls/ntdll/unix/signal_arm.c    |  2 +-
 dlls/ntdll/unix/signal_arm64.c  |  2 +-
 dlls/ntdll/unix/signal_i386.c   |  4 ++--
 dlls/ntdll/unix/signal_x86_64.c |  4 ++--
 dlls/ntdll/unix/unix_private.h  |  2 +-
 dlls/ntdll/unix/virtual.c       | 18 ++++++++++++------
 6 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index 4ec311de44..b74dbd32de 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -610,7 +610,7 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
         rec->ExceptionInformation[0] = (get_error_code(context) & 0x800) != 0;
         rec->ExceptionInformation[1] = (ULONG_PTR)info->si_addr;
         if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1],
-                                                         rec->ExceptionInformation[0], FALSE )))
+                                                         rec->ExceptionInformation[0], NULL )))
             return;
         break;
     case TRAP_ARM_ALIGNFLT:  /* Alignment check exception */
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
index 6c86ec265e..b402ecb93d 100644
--- a/dlls/ntdll/unix/signal_arm64.c
+++ b/dlls/ntdll/unix/signal_arm64.c
@@ -643,7 +643,7 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext )
         stack->rec.ExceptionInformation[0] = (get_fault_esr( context ) & 0x40) != 0;
         stack->rec.ExceptionInformation[1] = (ULONG_PTR)info->si_addr;
         if (!(stack->rec.ExceptionCode = virtual_handle_fault( (void *)stack->rec.ExceptionInformation[1],
-                                                         stack->rec.ExceptionInformation[0], FALSE )))
+                                                         stack->rec.ExceptionInformation[0], NULL )))
             return;
         break;
     case SIGBUS:  /* Alignment check exception */
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index be041f3fb2..3bdf7c38e9 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -1668,7 +1668,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
     if (TRAP_sig(context) == TRAP_x86_PAGEFLT &&
         (char *)stack_ptr >= (char *)get_signal_stack() &&
         (char *)stack_ptr < (char *)get_signal_stack() + signal_stack_size &&
-        !virtual_handle_fault( siginfo->si_addr, (ERROR_sig(context) >> 1) & 0x09, TRUE ))
+        !virtual_handle_fault( siginfo->si_addr, (ERROR_sig(context) >> 1) & 0x09, stack_ptr ))
     {
         return;
     }
@@ -1728,7 +1728,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
         stack->rec.ExceptionInformation[0] = (ERROR_sig(context) >> 1) & 0x09;
         stack->rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
         stack->rec.ExceptionCode = virtual_handle_fault( (void *)stack->rec.ExceptionInformation[1],
-                                                         stack->rec.ExceptionInformation[0], FALSE );
+                                                         stack->rec.ExceptionInformation[0], NULL );
         if (!stack->rec.ExceptionCode) return;
         if (stack->rec.ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
             stack->rec.ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT)
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index f4d64ed4e5..9b56044c70 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -2126,7 +2126,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
 
     /* check for exceptions on the signal stack caused by write watches */
     if (TRAP_sig(ucontext) == TRAP_x86_PAGEFLT && is_inside_signal_stack( stack ) &&
-        !virtual_handle_fault( siginfo->si_addr, (ERROR_sig(ucontext) >> 1) & 0x09, TRUE ))
+        !virtual_handle_fault( siginfo->si_addr, (ERROR_sig(ucontext) >> 1) & 0x09, stack ))
     {
         return;
     }
@@ -2179,7 +2179,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
         stack->rec.ExceptionInformation[0] = (ERROR_sig(ucontext) >> 1) & 0x09;
         stack->rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
         if (!(stack->rec.ExceptionCode = virtual_handle_fault((void *)stack->rec.ExceptionInformation[1],
-                                                              stack->rec.ExceptionInformation[0], FALSE )))
+                                                              stack->rec.ExceptionInformation[0], NULL )))
             return;
         break;
     case TRAP_x86_ALIGNFLT:  /* Alignment check exception */
diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h
index 1e8f82a8a7..79b5d1e118 100644
--- a/dlls/ntdll/unix/unix_private.h
+++ b/dlls/ntdll/unix/unix_private.h
@@ -196,7 +196,7 @@ extern NTSTATUS virtual_alloc_teb( TEB **ret_teb ) DECLSPEC_HIDDEN;
 extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN;
 extern NTSTATUS virtual_clear_tls_index( ULONG index ) DECLSPEC_HIDDEN;
 extern void virtual_map_user_shared_data(void) DECLSPEC_HIDDEN;
-extern NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) DECLSPEC_HIDDEN;
+extern NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack ) DECLSPEC_HIDDEN;
 extern unsigned int virtual_locked_server_call( void *req_ptr ) DECLSPEC_HIDDEN;
 extern ssize_t virtual_locked_read( int fd, void *addr, size_t size ) DECLSPEC_HIDDEN;
 extern ssize_t virtual_locked_pread( int fd, void *addr, size_t size, off_t offset ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 9ba1053a0d..a155fc46f8 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -203,6 +203,13 @@ static struct range_entry *free_ranges;
 static struct range_entry *free_ranges_end;
 
 
+static inline BOOL is_inside_signal_stack( void *ptr )
+{
+    return ((char *)ptr >= (char *)get_signal_stack() &&
+            (char *)ptr < (char *)get_signal_stack() + signal_stack_size);
+}
+
+
 static void reserve_area( void *addr, void *end )
 {
 #ifdef __APPLE__
@@ -2840,16 +2847,15 @@ void virtual_map_user_shared_data(void)
 /***********************************************************************
  *           virtual_handle_fault
  */
-NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack )
+NTSTATUS virtual_handle_fault( void *addr, DWORD err, void *stack )
 {
     NTSTATUS ret = STATUS_ACCESS_VIOLATION;
-    void *page = ROUND_ADDR( addr, page_mask );
-    sigset_t sigset;
+    char *page = ROUND_ADDR( addr, page_mask );
     BYTE vprot;
 
-    server_enter_uninterrupted_section( &virtual_mutex, &sigset );
+    pthread_mutex_lock( &virtual_mutex );  /* no need for signal masking inside signal handler */
     vprot = get_page_vprot( page );
-    if (!on_signal_stack && (vprot & VPROT_GUARD))
+    if (!is_inside_signal_stack( stack ) && (vprot & VPROT_GUARD))
     {
         set_page_vprot_bits( page, page_size, 0, VPROT_GUARD );
         mprotect_range( page, page_size, 0, 0 );
@@ -2869,7 +2875,7 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack )
                 ret = STATUS_SUCCESS;
         }
     }
-    server_leave_uninterrupted_section( &virtual_mutex, &sigset );
+    pthread_mutex_unlock( &virtual_mutex );
     return ret;
 }
 




More information about the wine-cvs mailing list