Commit 432d5041 authored by Alexandre Julliard's avatar Alexandre Julliard

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

parent 5a68254c
...@@ -610,7 +610,7 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext ) ...@@ -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[0] = (get_error_code(context) & 0x800) != 0;
rec->ExceptionInformation[1] = (ULONG_PTR)info->si_addr; rec->ExceptionInformation[1] = (ULONG_PTR)info->si_addr;
if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1], if (!(rec->ExceptionCode = virtual_handle_fault( (void *)rec->ExceptionInformation[1],
rec->ExceptionInformation[0], FALSE ))) rec->ExceptionInformation[0], NULL )))
return; return;
break; break;
case TRAP_ARM_ALIGNFLT: /* Alignment check exception */ case TRAP_ARM_ALIGNFLT: /* Alignment check exception */
......
...@@ -643,7 +643,7 @@ static void segv_handler( int signal, siginfo_t *info, void *ucontext ) ...@@ -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[0] = (get_fault_esr( context ) & 0x40) != 0;
stack->rec.ExceptionInformation[1] = (ULONG_PTR)info->si_addr; stack->rec.ExceptionInformation[1] = (ULONG_PTR)info->si_addr;
if (!(stack->rec.ExceptionCode = virtual_handle_fault( (void *)stack->rec.ExceptionInformation[1], if (!(stack->rec.ExceptionCode = virtual_handle_fault( (void *)stack->rec.ExceptionInformation[1],
stack->rec.ExceptionInformation[0], FALSE ))) stack->rec.ExceptionInformation[0], NULL )))
return; return;
break; break;
case SIGBUS: /* Alignment check exception */ case SIGBUS: /* Alignment check exception */
......
...@@ -1668,7 +1668,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -1668,7 +1668,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
if (TRAP_sig(context) == TRAP_x86_PAGEFLT && if (TRAP_sig(context) == TRAP_x86_PAGEFLT &&
(char *)stack_ptr >= (char *)get_signal_stack() && (char *)stack_ptr >= (char *)get_signal_stack() &&
(char *)stack_ptr < (char *)get_signal_stack() + signal_stack_size && (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; return;
} }
...@@ -1728,7 +1728,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -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[0] = (ERROR_sig(context) >> 1) & 0x09;
stack->rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr; stack->rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
stack->rec.ExceptionCode = virtual_handle_fault( (void *)stack->rec.ExceptionInformation[1], 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) return;
if (stack->rec.ExceptionCode == EXCEPTION_ACCESS_VIOLATION && if (stack->rec.ExceptionCode == EXCEPTION_ACCESS_VIOLATION &&
stack->rec.ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT) stack->rec.ExceptionInformation[0] == EXCEPTION_EXECUTE_FAULT)
......
...@@ -2126,7 +2126,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -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 */ /* check for exceptions on the signal stack caused by write watches */
if (TRAP_sig(ucontext) == TRAP_x86_PAGEFLT && is_inside_signal_stack( stack ) && 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; return;
} }
...@@ -2179,7 +2179,7 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext ) ...@@ -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[0] = (ERROR_sig(ucontext) >> 1) & 0x09;
stack->rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr; stack->rec.ExceptionInformation[1] = (ULONG_PTR)siginfo->si_addr;
if (!(stack->rec.ExceptionCode = virtual_handle_fault((void *)stack->rec.ExceptionInformation[1], if (!(stack->rec.ExceptionCode = virtual_handle_fault((void *)stack->rec.ExceptionInformation[1],
stack->rec.ExceptionInformation[0], FALSE ))) stack->rec.ExceptionInformation[0], NULL )))
return; return;
break; break;
case TRAP_x86_ALIGNFLT: /* Alignment check exception */ case TRAP_x86_ALIGNFLT: /* Alignment check exception */
......
...@@ -196,7 +196,7 @@ extern NTSTATUS virtual_alloc_teb( TEB **ret_teb ) DECLSPEC_HIDDEN; ...@@ -196,7 +196,7 @@ extern NTSTATUS virtual_alloc_teb( TEB **ret_teb ) DECLSPEC_HIDDEN;
extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN; extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_clear_tls_index( ULONG index ) DECLSPEC_HIDDEN; extern NTSTATUS virtual_clear_tls_index( ULONG index ) DECLSPEC_HIDDEN;
extern void virtual_map_user_shared_data(void) 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 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_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; extern ssize_t virtual_locked_pread( int fd, void *addr, size_t size, off_t offset ) DECLSPEC_HIDDEN;
......
...@@ -203,6 +203,13 @@ static struct range_entry *free_ranges; ...@@ -203,6 +203,13 @@ static struct range_entry *free_ranges;
static struct range_entry *free_ranges_end; 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 ) static void reserve_area( void *addr, void *end )
{ {
#ifdef __APPLE__ #ifdef __APPLE__
...@@ -2840,16 +2847,15 @@ void virtual_map_user_shared_data(void) ...@@ -2840,16 +2847,15 @@ void virtual_map_user_shared_data(void)
/*********************************************************************** /***********************************************************************
* virtual_handle_fault * 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; NTSTATUS ret = STATUS_ACCESS_VIOLATION;
void *page = ROUND_ADDR( addr, page_mask ); char *page = ROUND_ADDR( addr, page_mask );
sigset_t sigset;
BYTE vprot; 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 ); 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 ); set_page_vprot_bits( page, page_size, 0, VPROT_GUARD );
mprotect_range( page, page_size, 0, 0 ); mprotect_range( page, page_size, 0, 0 );
...@@ -2869,7 +2875,7 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack ) ...@@ -2869,7 +2875,7 @@ NTSTATUS virtual_handle_fault( LPCVOID addr, DWORD err, BOOL on_signal_stack )
ret = STATUS_SUCCESS; ret = STATUS_SUCCESS;
} }
} }
server_leave_uninterrupted_section( &virtual_mutex, &sigset ); pthread_mutex_unlock( &virtual_mutex );
return ret; return ret;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment