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 */
size_t size; /* Size in bytes */
HANDLE mapping; /* Handle to the file mapping */
BYTE flags; /* Allocation flags (VFLAG_*) */
BYTE protect; /* Protection for all pages at allocation time */
unsigned int protect; /* Protection for all pages at allocation time */
BYTE prot[1]; /* Protection byte for each page */
} 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 */
static const BYTE VIRTUAL_Win32Flags[16] =
@ -196,9 +192,9 @@ static void VIRTUAL_DumpView( FILE_VIEW *view )
BYTE prot = view->prot[0];
TRACE( "View: %p - %p", addr, addr + view->size - 1 );
if (view->flags & VFLAG_SYSTEM)
if (view->protect & VPROT_SYSTEM)
TRACE( " (system)\n" );
else if (view->flags & VFLAG_VALLOC)
else if (view->protect & VPROT_VALLOC)
TRACE( " (valloc)\n" );
else if (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 */
{
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 );
if (view->mapping) NtClose( view->mapping );
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.
*/
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 list *ptr;
@ -432,10 +428,9 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
view->base = base;
view->size = size;
view->flags = 0;
view->mapping = 0;
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 */
@ -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",
prev->base, (char *)prev->base + prev->size,
base, (char *)base + view->size );
assert( prev->flags & VFLAG_SYSTEM );
assert( prev->protect & VPROT_SYSTEM );
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",
next->base, (char *)next->base + next->size,
base, (char *)base + view->size );
assert( next->flags & VFLAG_SYSTEM );
assert( next->protect & VPROT_SYSTEM );
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.
*/
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;
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.
*/
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;
int prot = VIRTUAL_GetUnixProt( vprot );
@ -1268,17 +1263,15 @@ NTSTATUS virtual_alloc_thread_stack( void *base, SIZE_T size )
size = ROUND_SIZE( base, size );
base = ROUND_ADDR( base, page_mask );
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;
view->flags |= VFLAG_VALLOC | VFLAG_SYSTEM;
}
else
{
size = (size + 0xffff) & ~0xffff; /* round to 64K boundary */
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;
view->flags |= VFLAG_VALLOC;
#ifdef VALGRIND_STACK_REGISTER
/* 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 );
@ -1448,7 +1441,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
SIZE_T *size_ptr, ULONG type, ULONG protect )
{
void *base;
BYTE vprot;
unsigned int vprot;
SIZE_T size = *size_ptr;
SIZE_T mask = get_mask( zero_bits );
NTSTATUS status = STATUS_SUCCESS;
@ -1523,7 +1516,7 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
return STATUS_NOT_SUPPORTED;
}
}
vprot = VIRTUAL_GetProt( protect );
vprot = VIRTUAL_GetProt( protect ) | VPROT_VALLOC;
if (type & MEM_COMMIT) vprot |= VPROT_COMMITTED;
/* Reserve the memory */
@ -1533,21 +1526,13 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG zero_
if (type & MEM_SYSTEM)
{
if (type & MEM_IMAGE) vprot |= VPROT_IMAGE;
status = create_view( &view, base, size, vprot | VPROT_COMMITTED );
if (status == STATUS_SUCCESS)
{
view->flags |= VFLAG_VALLOC | VFLAG_SYSTEM;
base = view->base;
}
status = create_view( &view, base, size, vprot | VPROT_COMMITTED | VPROT_SYSTEM );
if (status == STATUS_SUCCESS) base = view->base;
}
else if ((type & MEM_RESERVE) || !base)
{
status = map_view( &view, base, size, mask, type & MEM_TOP_DOWN, vprot );
if (status == STATUS_SUCCESS)
{
view->flags |= VFLAG_VALLOC;
base = view->base;
}
if (status == STATUS_SUCCESS) base = view->base;
}
else /* commit the pages */
{
@ -1616,7 +1601,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
if (!(view = VIRTUAL_FindView( base )) ||
(base + size > (char *)view->base + view->size) ||
!(view->flags & VFLAG_VALLOC))
!(view->protect & VPROT_VALLOC))
{
status = STATUS_INVALID_PARAMETER;
}
@ -1626,7 +1611,7 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
*addr_ptr = view->base;
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 */
view->flags |= VFLAG_SYSTEM;
view->protect |= VPROT_SYSTEM;
delete_view( view );
}
else if (type == MEM_RELEASE)
@ -1869,7 +1854,7 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
info->AllocationBase = alloc_base;
info->AllocationProtect = VIRTUAL_GetWin32Prot( view->protect );
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;
for (size = base - alloc_base; size < view->size; size += page_size)
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 )
{
NTSTATUS ret;
BYTE vprot;
unsigned int vprot;
DWORD len = (attr && attr->ObjectName) ? attr->ObjectName->Length : 0;
struct security_descriptor *sd = NULL;
struct object_attributes objattr;
@ -2053,7 +2038,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
SIZE_T size = 0;
SIZE_T mask = get_mask( zero_bits );
int unix_handle = -1, needs_close;
int prot;
unsigned int prot;
void *base;
struct file_view *view;
DWORD header_size;

View File

@ -1671,7 +1671,7 @@ struct create_mapping_request
unsigned int access;
unsigned int attributes;
file_pos_t size;
int protect;
unsigned int protect;
obj_handle_t file_handle;
/* VARARG(objattr,object_attributes); */
};
@ -1688,7 +1688,10 @@ struct create_mapping_reply
#define VPROT_GUARD 0x10
#define VPROT_NOCACHE 0x20
#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;
};
#define SERVER_PROTOCOL_VERSION 343
#define SERVER_PROTOCOL_VERSION 344
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -1316,13 +1316,13 @@ enum char_info_mode
unsigned int access; /* wanted access rights */
unsigned int attributes; /* object attributes */
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 */
VARARG(objattr,object_attributes); /* object attributes */
@REPLY
obj_handle_t handle; /* handle to the mapping */
@END
/* protection flags */
/* per-page protection flags */
#define VPROT_READ 0x01
#define VPROT_WRITE 0x02
#define VPROT_EXEC 0x04
@ -1330,7 +1330,10 @@ enum char_info_mode
#define VPROT_GUARD 0x10
#define VPROT_NOCACHE 0x20
#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 */

View File

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