ntdll: Store the per-view flags in the high word of the page protection bits.

This commit is contained in:
Alexandre Julliard 2008-11-04 13:05:32 +01:00
parent cf164785af
commit 0b0b6c351a
4 changed files with 35 additions and 44 deletions

View File

@ -75,14 +75,10 @@ typedef struct file_view
void *base; /* Base address */ void *base; /* Base address */
size_t size; /* Size in bytes */ size_t size; /* Size in bytes */
HANDLE mapping; /* Handle to the file mapping */ HANDLE mapping; /* Handle to the file mapping */
BYTE flags; /* Allocation flags (VFLAG_*) */ unsigned int protect; /* Protection for all pages at allocation time */
BYTE protect; /* Protection for all pages at allocation time */
BYTE prot[1]; /* Protection byte for each page */ BYTE prot[1]; /* Protection byte for each page */
} FILE_VIEW; } FILE_VIEW;
/* Per-view flags */
#define VFLAG_SYSTEM 0x01 /* system view (underlying mmap not under our control) */
#define VFLAG_VALLOC 0x02 /* allocated by VirtualAlloc */
/* Conversion from VPROT_* to Win32 flags */ /* Conversion from VPROT_* to Win32 flags */
static const BYTE VIRTUAL_Win32Flags[16] = static const BYTE VIRTUAL_Win32Flags[16] =
@ -196,9 +192,9 @@ static void VIRTUAL_DumpView( FILE_VIEW *view )
BYTE prot = view->prot[0]; BYTE prot = view->prot[0];
TRACE( "View: %p - %p", addr, addr + view->size - 1 ); TRACE( "View: %p - %p", addr, addr + view->size - 1 );
if (view->flags & VFLAG_SYSTEM) if (view->protect & VPROT_SYSTEM)
TRACE( " (system)\n" ); TRACE( " (system)\n" );
else if (view->flags & VFLAG_VALLOC) else if (view->protect & VPROT_VALLOC)
TRACE( " (valloc)\n" ); TRACE( " (valloc)\n" );
else if (view->mapping) else if (view->mapping)
TRACE( " %p\n", view->mapping ); TRACE( " %p\n", view->mapping );
@ -401,7 +397,7 @@ static inline void unmap_area( void *addr, size_t size )
*/ */
static void delete_view( struct file_view *view ) /* [in] View */ static void delete_view( struct file_view *view ) /* [in] View */
{ {
if (!(view->flags & VFLAG_SYSTEM)) unmap_area( view->base, view->size ); if (!(view->protect & VPROT_SYSTEM)) unmap_area( view->base, view->size );
list_remove( &view->entry ); list_remove( &view->entry );
if (view->mapping) NtClose( view->mapping ); if (view->mapping) NtClose( view->mapping );
RtlFreeHeap( virtual_heap, 0, view ); RtlFreeHeap( virtual_heap, 0, view );
@ -413,7 +409,7 @@ static void delete_view( struct file_view *view ) /* [in] View */
* *
* Create a view. The csVirtual section must be held by caller. * Create a view. The csVirtual section must be held by caller.
*/ */
static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t size, BYTE vprot ) static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t size, unsigned int vprot )
{ {
struct file_view *view; struct file_view *view;
struct list *ptr; struct list *ptr;
@ -432,10 +428,9 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
view->base = base; view->base = base;
view->size = size; view->size = size;
view->flags = 0;
view->mapping = 0; view->mapping = 0;
view->protect = vprot; view->protect = vprot;
memset( view->prot, vprot & ~VPROT_IMAGE, size >> page_shift ); memset( view->prot, vprot, size >> page_shift );
/* Insert it in the linked list */ /* Insert it in the linked list */
@ -458,7 +453,7 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
TRACE( "overlapping prev view %p-%p for %p-%p\n", TRACE( "overlapping prev view %p-%p for %p-%p\n",
prev->base, (char *)prev->base + prev->size, prev->base, (char *)prev->base + prev->size,
base, (char *)base + view->size ); base, (char *)base + view->size );
assert( prev->flags & VFLAG_SYSTEM ); assert( prev->protect & VPROT_SYSTEM );
delete_view( prev ); delete_view( prev );
} }
} }
@ -470,7 +465,7 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
TRACE( "overlapping next view %p-%p for %p-%p\n", TRACE( "overlapping next view %p-%p for %p-%p\n",
next->base, (char *)next->base + next->size, next->base, (char *)next->base + next->size,
base, (char *)base + view->size ); base, (char *)base + view->size );
assert( next->flags & VFLAG_SYSTEM ); assert( next->protect & VPROT_SYSTEM );
delete_view( next ); delete_view( next );
} }
} }
@ -684,7 +679,7 @@ static int alloc_reserved_area_callback( void *start, size_t size, void *arg )
* The csVirtual section must be held by caller. * The csVirtual section must be held by caller.
*/ */
static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, size_t mask, static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, size_t mask,
int top_down, BYTE vprot ) int top_down, unsigned int vprot )
{ {
void *ptr; void *ptr;
NTSTATUS status; NTSTATUS status;
@ -825,7 +820,7 @@ static void *unaligned_mmap( void *addr, size_t length, unsigned int prot,
* The csVirtual section must be held by caller. * The csVirtual section must be held by caller.
*/ */
static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start, size_t size, static NTSTATUS map_file_into_view( struct file_view *view, int fd, size_t start, size_t size,
off_t offset, BYTE vprot, BOOL removable ) off_t offset, unsigned int vprot, BOOL removable )
{ {
void *ptr; void *ptr;
int prot = VIRTUAL_GetUnixProt( vprot ); int prot = VIRTUAL_GetUnixProt( vprot );
@ -1268,17 +1263,15 @@ NTSTATUS virtual_alloc_thread_stack( void *base, SIZE_T size )
size = ROUND_SIZE( base, size ); size = ROUND_SIZE( base, size );
base = ROUND_ADDR( base, page_mask ); base = ROUND_ADDR( base, page_mask );
if ((status = create_view( &view, base, size, if ((status = create_view( &view, base, size,
VPROT_READ | VPROT_WRITE | VPROT_COMMITTED )) != STATUS_SUCCESS) VPROT_READ | VPROT_WRITE | VPROT_COMMITTED | VPROT_VALLOC | VPROT_SYSTEM )) != STATUS_SUCCESS)
goto done; goto done;
view->flags |= VFLAG_VALLOC | VFLAG_SYSTEM;
} }
else else
{ {
size = (size + 0xffff) & ~0xffff; /* round to 64K boundary */ size = (size + 0xffff) & ~0xffff; /* round to 64K boundary */
if ((status = map_view( &view, NULL, size, 0xffff, 0, if ((status = map_view( &view, NULL, size, 0xffff, 0,
VPROT_READ | VPROT_WRITE | VPROT_COMMITTED )) != STATUS_SUCCESS) VPROT_READ | VPROT_WRITE | VPROT_COMMITTED | VPROT_VALLOC )) != STATUS_SUCCESS)
goto done; goto done;
view->flags |= VFLAG_VALLOC;
#ifdef VALGRIND_STACK_REGISTER #ifdef VALGRIND_STACK_REGISTER
/* no need to de-register the stack as it's the one of the main thread */ /* no need to de-register the stack as it's the one of the main thread */
VALGRIND_STACK_REGISTER( view->base, (char *)view->base + view->size ); VALGRIND_STACK_REGISTER( view->base, (char *)view->base + view->size );
@ -1448,7 +1441,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
SIZE_T *size_ptr, ULONG type, ULONG protect ) SIZE_T *size_ptr, ULONG type, ULONG protect )
{ {
void *base; void *base;
BYTE vprot; unsigned int vprot;
SIZE_T size = *size_ptr; SIZE_T size = *size_ptr;
SIZE_T mask = get_mask( zero_bits ); SIZE_T mask = get_mask( zero_bits );
NTSTATUS status = STATUS_SUCCESS; NTSTATUS status = STATUS_SUCCESS;
@ -1523,7 +1516,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
} }
vprot = VIRTUAL_GetProt( protect ); vprot = VIRTUAL_GetProt( protect ) | VPROT_VALLOC;
if (type & MEM_COMMIT) vprot |= VPROT_COMMITTED; if (type & MEM_COMMIT) vprot |= VPROT_COMMITTED;
/* Reserve the memory */ /* Reserve the memory */
@ -1533,21 +1526,13 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
if (type & MEM_SYSTEM) if (type & MEM_SYSTEM)
{ {
if (type & MEM_IMAGE) vprot |= VPROT_IMAGE; if (type & MEM_IMAGE) vprot |= VPROT_IMAGE;
status = create_view( &view, base, size, vprot | VPROT_COMMITTED ); status = create_view( &view, base, size, vprot | VPROT_COMMITTED | VPROT_SYSTEM );
if (status == STATUS_SUCCESS) if (status == STATUS_SUCCESS) base = view->base;
{
view->flags |= VFLAG_VALLOC | VFLAG_SYSTEM;
base = view->base;
}
} }
else if ((type & MEM_RESERVE) || !base) else if ((type & MEM_RESERVE) || !base)
{ {
status = map_view( &view, base, size, mask, type & MEM_TOP_DOWN, vprot ); status = map_view( &view, base, size, mask, type & MEM_TOP_DOWN, vprot );
if (status == STATUS_SUCCESS) if (status == STATUS_SUCCESS) base = view->base;
{
view->flags |= VFLAG_VALLOC;
base = view->base;
}
} }
else /* commit the pages */ else /* commit the pages */
{ {
@ -1616,7 +1601,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
if (!(view = VIRTUAL_FindView( base )) || if (!(view = VIRTUAL_FindView( base )) ||
(base + size > (char *)view->base + view->size) || (base + size > (char *)view->base + view->size) ||
!(view->flags & VFLAG_VALLOC)) !(view->protect & VPROT_VALLOC))
{ {
status = STATUS_INVALID_PARAMETER; status = STATUS_INVALID_PARAMETER;
} }
@ -1626,7 +1611,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
*addr_ptr = view->base; *addr_ptr = view->base;
if (!wine_mmap_is_in_reserved_area( view->base, view->size )) *size_ptr = view->size; if (!wine_mmap_is_in_reserved_area( view->base, view->size )) *size_ptr = view->size;
else *size_ptr = 0; /* make sure we don't munmap anything from a reserved area */ else *size_ptr = 0; /* make sure we don't munmap anything from a reserved area */
view->flags |= VFLAG_SYSTEM; view->protect |= VPROT_SYSTEM;
delete_view( view ); delete_view( view );
} }
else if (type == MEM_RELEASE) else if (type == MEM_RELEASE)
@ -1869,7 +1854,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
info->AllocationBase = alloc_base; info->AllocationBase = alloc_base;
info->AllocationProtect = VIRTUAL_GetWin32Prot( view->protect ); info->AllocationProtect = VIRTUAL_GetWin32Prot( view->protect );
if (view->protect & VPROT_IMAGE) info->Type = MEM_IMAGE; if (view->protect & VPROT_IMAGE) info->Type = MEM_IMAGE;
else if (view->flags & VFLAG_VALLOC) info->Type = MEM_PRIVATE; else if (view->protect & VPROT_VALLOC) info->Type = MEM_PRIVATE;
else info->Type = MEM_MAPPED; else info->Type = MEM_MAPPED;
for (size = base - alloc_base; size < view->size; size += page_size) for (size = base - alloc_base; size < view->size; size += page_size)
if (view->prot[size >> page_shift] != vprot) break; if (view->prot[size >> page_shift] != vprot) break;
@ -1966,7 +1951,7 @@ NTSTATUS WINAPI NtCreateSection( HANDLE *handle, ACCESS_MASK access, const OBJEC
ULONG sec_flags, HANDLE file ) ULONG sec_flags, HANDLE file )
{ {
NTSTATUS ret; NTSTATUS ret;
BYTE vprot; unsigned int vprot;
DWORD len = (attr && attr->ObjectName) ? attr->ObjectName->Length : 0; DWORD len = (attr && attr->ObjectName) ? attr->ObjectName->Length : 0;
struct security_descriptor *sd = NULL; struct security_descriptor *sd = NULL;
struct object_attributes objattr; struct object_attributes objattr;
@ -2053,7 +2038,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
SIZE_T size = 0; SIZE_T size = 0;
SIZE_T mask = get_mask( zero_bits ); SIZE_T mask = get_mask( zero_bits );
int unix_handle = -1, needs_close; int unix_handle = -1, needs_close;
int prot; unsigned int prot;
void *base; void *base;
struct file_view *view; struct file_view *view;
DWORD header_size; DWORD header_size;

View File

@ -1671,7 +1671,7 @@ struct create_mapping_request
unsigned int access; unsigned int access;
unsigned int attributes; unsigned int attributes;
file_pos_t size; file_pos_t size;
int protect; unsigned int protect;
obj_handle_t file_handle; obj_handle_t file_handle;
/* VARARG(objattr,object_attributes); */ /* VARARG(objattr,object_attributes); */
}; };
@ -1688,7 +1688,10 @@ struct create_mapping_reply
#define VPROT_GUARD 0x10 #define VPROT_GUARD 0x10
#define VPROT_NOCACHE 0x20 #define VPROT_NOCACHE 0x20
#define VPROT_COMMITTED 0x40 #define VPROT_COMMITTED 0x40
#define VPROT_IMAGE 0x80
#define VPROT_IMAGE 0x0100
#define VPROT_SYSTEM 0x0200
#define VPROT_VALLOC 0x0400
@ -5031,6 +5034,6 @@ union generic_reply
struct set_window_layered_info_reply set_window_layered_info_reply; struct set_window_layered_info_reply set_window_layered_info_reply;
}; };
#define SERVER_PROTOCOL_VERSION 343 #define SERVER_PROTOCOL_VERSION 344
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -1316,13 +1316,13 @@ enum char_info_mode
unsigned int access; /* wanted access rights */ unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */ unsigned int attributes; /* object attributes */
file_pos_t size; /* mapping size */ file_pos_t size; /* mapping size */
int protect; /* protection flags (see below) */ unsigned int protect; /* protection flags (see below) */
obj_handle_t file_handle; /* file handle */ obj_handle_t file_handle; /* file handle */
VARARG(objattr,object_attributes); /* object attributes */ VARARG(objattr,object_attributes); /* object attributes */
@REPLY @REPLY
obj_handle_t handle; /* handle to the mapping */ obj_handle_t handle; /* handle to the mapping */
@END @END
/* protection flags */ /* per-page protection flags */
#define VPROT_READ 0x01 #define VPROT_READ 0x01
#define VPROT_WRITE 0x02 #define VPROT_WRITE 0x02
#define VPROT_EXEC 0x04 #define VPROT_EXEC 0x04
@ -1330,7 +1330,10 @@ enum char_info_mode
#define VPROT_GUARD 0x10 #define VPROT_GUARD 0x10
#define VPROT_NOCACHE 0x20 #define VPROT_NOCACHE 0x20
#define VPROT_COMMITTED 0x40 #define VPROT_COMMITTED 0x40
#define VPROT_IMAGE 0x80 /* per-mapping protection flags */
#define VPROT_IMAGE 0x0100 /* mapping for an exe image */
#define VPROT_SYSTEM 0x0200 /* system view (underlying mmap not under our control) */
#define VPROT_VALLOC 0x0400 /* allocated by VirtualAlloc */
/* Open a mapping */ /* Open a mapping */

View File

@ -1742,7 +1742,7 @@ static void dump_create_mapping_request( const struct create_mapping_request *re
fprintf( stderr, " size=" ); fprintf( stderr, " size=" );
dump_file_pos( &req->size ); dump_file_pos( &req->size );
fprintf( stderr, "," ); fprintf( stderr, "," );
fprintf( stderr, " protect=%d,", req->protect ); fprintf( stderr, " protect=%08x,", req->protect );
fprintf( stderr, " file_handle=%p,", req->file_handle ); fprintf( stderr, " file_handle=%p,", req->file_handle );
fprintf( stderr, " objattr=" ); fprintf( stderr, " objattr=" );
dump_varargs_object_attributes( cur_size ); dump_varargs_object_attributes( cur_size );