Commit 1049acc2 authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Handle stack faults without fetching the view pointer.

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