ntdll: Remove support for custom virtual memory alignments.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
feature/deterministic
Alexandre Julliard 2020-04-30 10:07:36 +02:00
parent dee934c0ff
commit 2af035f53f
3 changed files with 41 additions and 57 deletions

View File

@ -192,8 +192,8 @@ extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
UINT disposition ) DECLSPEC_HIDDEN;
/* virtual memory */
extern NTSTATUS virtual_alloc_aligned( PVOID *ret, unsigned short zero_bits_64, SIZE_T *size_ptr,
ULONG type, ULONG protect, ULONG alignment ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_alloc( PVOID *ret, unsigned short zero_bits_64, SIZE_T *size_ptr,
ULONG type, ULONG protect ) DECLSPEC_HIDDEN;
extern NTSTATUS virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsigned short zero_bits_64, SIZE_T commit_size,
const LARGE_INTEGER *offset_ptr, SIZE_T *size_ptr, ULONG alloc_type,
ULONG protect, pe_image_info_t *image_info ) DECLSPEC_HIDDEN;

View File

@ -505,11 +505,9 @@ static void invoke_system_apc( const apc_call_t *call, apc_result_t *result )
size = call->virtual_alloc.size;
if ((ULONG_PTR)addr == call->virtual_alloc.addr && size == call->virtual_alloc.size)
{
result->virtual_alloc.status = virtual_alloc_aligned( &addr,
call->virtual_alloc.zero_bits_64, &size,
call->virtual_alloc.op_type,
call->virtual_alloc.prot,
0 );
result->virtual_alloc.status = virtual_alloc( &addr, call->virtual_alloc.zero_bits_64, &size,
call->virtual_alloc.op_type,
call->virtual_alloc.prot );
result->virtual_alloc.addr = wine_server_client_ptr( addr );
result->virtual_alloc.size = size;
}

View File

@ -159,6 +159,7 @@ static void *working_set_limit;
static void *address_space_start = (void *)0x10000;
#endif /* __i386__ */
static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
static const UINT_PTR granularity_mask = 0xffff;
SIZE_T signal_stack_size = 0;
SIZE_T signal_stack_mask = 0;
@ -430,18 +431,6 @@ static struct file_view *VIRTUAL_FindView( const void *addr, size_t size )
}
/***********************************************************************
* get_mask
*/
static inline UINT_PTR get_mask( ULONG alignment )
{
if (!alignment) return 0xffff; /* allocations are aligned to 64K by default */
if (alignment < page_shift) alignment = page_shift;
if (alignment > 21) return 0;
return (1 << alignment) - 1;
}
/***********************************************************************
* zero_bits_win_to_64
*
@ -582,16 +571,15 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
* Find a free area between views inside the specified range and map it.
* The csVirtual section must be held by caller.
*/
static void *map_free_area( void *base, void *end, size_t size, size_t mask, int top_down,
int unix_prot )
static void *map_free_area( void *base, void *end, size_t size, int top_down, int unix_prot )
{
struct wine_rb_entry *first = find_view_inside_range( &base, &end, top_down );
ptrdiff_t step = top_down ? -(mask + 1) : (mask + 1);
ptrdiff_t step = top_down ? -(granularity_mask + 1) : (granularity_mask + 1);
void *start;
if (top_down)
{
start = ROUND_ADDR( (char *)end - size, mask );
start = ROUND_ADDR( (char *)end - size, granularity_mask );
if (start >= end || start < base) return NULL;
while (first)
@ -599,7 +587,7 @@ static void *map_free_area( void *base, void *end, size_t size, size_t mask, int
struct file_view *view = WINE_RB_ENTRY_VALUE( first, struct file_view, entry );
if ((start = try_map_free_area( (char *)view->base + view->size, (char *)start + size, step,
start, size, unix_prot ))) break;
start = ROUND_ADDR( (char *)view->base - size, mask );
start = ROUND_ADDR( (char *)view->base - size, granularity_mask );
/* stop if remaining space is not large enough */
if (!start || start >= end || start < base) return NULL;
first = wine_rb_prev( first );
@ -607,7 +595,7 @@ static void *map_free_area( void *base, void *end, size_t size, size_t mask, int
}
else
{
start = ROUND_ADDR( (char *)base + mask, mask );
start = ROUND_ADDR( (char *)base + granularity_mask, granularity_mask );
if (!start || start >= end || (char *)end - (char *)start < size) return NULL;
while (first)
@ -615,7 +603,7 @@ static void *map_free_area( void *base, void *end, size_t size, size_t mask, int
struct file_view *view = WINE_RB_ENTRY_VALUE( first, struct file_view, entry );
if ((start = try_map_free_area( start, view->base, step,
start, size, unix_prot ))) break;
start = ROUND_ADDR( (char *)view->base + view->size + mask, mask );
start = ROUND_ADDR( (char *)view->base + view->size + granularity_mask, granularity_mask );
/* stop if remaining space is not large enough */
if (!start || start >= end || (char *)end - (char *)start < size) return NULL;
first = wine_rb_next( first );
@ -636,14 +624,14 @@ static void *map_free_area( void *base, void *end, size_t size, size_t mask, int
* The csVirtual section must be held by caller.
* The range must be inside the preloader reserved range.
*/
static void *find_reserved_free_area( void *base, void *end, size_t size, size_t mask, int top_down )
static void *find_reserved_free_area( void *base, void *end, size_t size, int top_down )
{
struct wine_rb_entry *first = find_view_inside_range( &base, &end, top_down );
void *start;
if (top_down)
{
start = ROUND_ADDR( (char *)end - size, mask );
start = ROUND_ADDR( (char *)end - size, granularity_mask );
if (start >= end || start < base) return NULL;
while (first)
@ -651,7 +639,7 @@ static void *find_reserved_free_area( void *base, void *end, size_t size, size_t
struct file_view *view = WINE_RB_ENTRY_VALUE( first, struct file_view, entry );
if ((char *)view->base + view->size <= (char *)start) break;
start = ROUND_ADDR( (char *)view->base - size, mask );
start = ROUND_ADDR( (char *)view->base - size, granularity_mask );
/* stop if remaining space is not large enough */
if (!start || start >= end || start < base) return NULL;
first = wine_rb_prev( first );
@ -659,7 +647,7 @@ static void *find_reserved_free_area( void *base, void *end, size_t size, size_t
}
else
{
start = ROUND_ADDR( (char *)base + mask, mask );
start = ROUND_ADDR( (char *)base + granularity_mask, granularity_mask );
if (!start || start >= end || (char *)end - (char *)start < size) return NULL;
while (first)
@ -667,7 +655,7 @@ static void *find_reserved_free_area( void *base, void *end, size_t size, size_t
struct file_view *view = WINE_RB_ENTRY_VALUE( first, struct file_view, entry );
if ((char *)view->base >= (char *)start + size) break;
start = ROUND_ADDR( (char *)view->base + view->size + mask, mask );
start = ROUND_ADDR( (char *)view->base + view->size + granularity_mask, granularity_mask );
/* stop if remaining space is not large enough */
if (!start || start >= end || (char *)end - (char *)start < size) return NULL;
first = wine_rb_next( first );
@ -1115,11 +1103,11 @@ static void reset_write_watches( void *base, SIZE_T size )
*
* Release the extra memory while keeping the range starting on the granularity boundary.
*/
static inline void *unmap_extra_space( void *ptr, size_t total_size, size_t wanted_size, size_t mask )
static inline void *unmap_extra_space( void *ptr, size_t total_size, size_t wanted_size )
{
if ((ULONG_PTR)ptr & mask)
if ((ULONG_PTR)ptr & granularity_mask)
{
size_t extra = mask + 1 - ((ULONG_PTR)ptr & mask);
size_t extra = granularity_mask + 1 - ((ULONG_PTR)ptr & granularity_mask);
munmap( ptr, extra );
ptr = (char *)ptr + extra;
total_size -= extra;
@ -1133,7 +1121,6 @@ static inline void *unmap_extra_space( void *ptr, size_t total_size, size_t want
struct alloc_area
{
size_t size;
size_t mask;
int top_down;
void *limit;
void *result;
@ -1166,13 +1153,13 @@ static int alloc_reserved_area_callback( void *start, size_t size, void *arg )
{
/* range is split in two by the preloader reservation, try first part */
if ((alloc->result = find_reserved_free_area( start, preload_reserve_start, alloc->size,
alloc->mask, alloc->top_down )))
alloc->top_down )))
return 1;
/* then fall through to try second part */
start = preload_reserve_end;
}
}
if ((alloc->result = find_reserved_free_area( start, end, alloc->size, alloc->mask, alloc->top_down )))
if ((alloc->result = find_reserved_free_area( start, end, alloc->size, alloc->top_down )))
return 1;
return 0;
@ -1241,12 +1228,11 @@ static NTSTATUS map_fixed_area( void *base, size_t size, unsigned int vprot )
* Create a view and mmap the corresponding memory area.
* The csVirtual section must be held by caller.
*/
static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, size_t alignment,
static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
int top_down, unsigned int vprot, unsigned short zero_bits_64 )
{
void *ptr;
NTSTATUS status;
size_t mask = get_mask( alignment );
if (base)
{
@ -1258,11 +1244,10 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
}
else
{
size_t view_size = size + mask + 1;
size_t view_size = size + granularity_mask + 1;
struct alloc_area alloc;
alloc.size = size;
alloc.mask = mask;
alloc.top_down = top_down;
alloc.limit = (void*)(get_zero_bits_64_mask( zero_bits_64 ) & (UINT_PTR)user_space_limit);
@ -1277,7 +1262,8 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
if (zero_bits_64)
{
if (!(ptr = map_free_area( address_space_start, alloc.limit, size, mask, top_down, VIRTUAL_GetUnixProt(vprot) )))
if (!(ptr = map_free_area( address_space_start, alloc.limit, size,
top_down, VIRTUAL_GetUnixProt(vprot) )))
return STATUS_NO_MEMORY;
TRACE( "got mem with map_free_area %p-%p\n", ptr, (char *)ptr + size );
goto done;
@ -1295,7 +1281,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
if (is_beyond_limit( ptr, view_size, user_space_limit )) add_reserved_area( ptr, view_size );
else break;
}
ptr = unmap_extra_space( ptr, view_size, size, mask );
ptr = unmap_extra_space( ptr, view_size, size );
}
done:
status = create_view( view_ret, ptr, size, vprot );
@ -1453,7 +1439,7 @@ static NTSTATUS allocate_dos_memory( struct file_view **view, unsigned int vprot
if (addr != low_64k)
{
if (addr != (void *)-1) munmap( addr, dosmem_size - 0x10000 );
return map_view( view, NULL, dosmem_size, 0, FALSE, vprot, 0 );
return map_view( view, NULL, dosmem_size, FALSE, vprot, 0 );
}
}
@ -1556,11 +1542,11 @@ static NTSTATUS map_image( HANDLE hmapping, ACCESS_MASK access, int fd, int top_
server_enter_uninterrupted_section( &csVirtual, &sigset );
if (base >= (char *)address_space_start) /* make sure the DOS area remains free */
status = map_view( &view, base, total_size, 0, top_down, SEC_IMAGE | SEC_FILE |
status = map_view( &view, base, total_size, top_down, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY, zero_bits_64 );
if (status != STATUS_SUCCESS)
status = map_view( &view, NULL, total_size, 0, top_down, SEC_IMAGE | SEC_FILE |
status = map_view( &view, NULL, total_size, top_down, SEC_IMAGE | SEC_FILE |
VPROT_COMMITTED | VPROT_READ | VPROT_EXEC | VPROT_WRITECOPY, zero_bits_64 );
if (status != STATUS_SUCCESS) goto error;
@ -1883,7 +1869,7 @@ NTSTATUS virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsigned short zer
get_vprot_flags( protect, &vprot, sec_flags & SEC_IMAGE );
vprot |= sec_flags;
if (!(sec_flags & SEC_RESERVE)) vprot |= VPROT_COMMITTED;
res = map_view( &view, *addr_ptr, size, 0, alloc_type & MEM_TOP_DOWN, vprot, zero_bits_64 );
res = map_view( &view, *addr_ptr, size, alloc_type & MEM_TOP_DOWN, vprot, zero_bits_64 );
if (res)
{
server_leave_uninterrupted_section( &csVirtual, &sigset );
@ -2038,7 +2024,7 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info )
}
#endif
info->MmNumberOfPhysicalPages = info->MmHighestPhysicalPage - info->MmLowestPhysicalPage;
info->AllocationGranularity = get_mask(0) + 1;
info->AllocationGranularity = granularity_mask + 1;
info->LowestUserAddress = (void *)0x10000;
info->HighestUserAddress = (char *)user_space_limit - 1;
info->ActiveProcessorsAffinityMask = get_system_affinity_mask();
@ -2230,7 +2216,7 @@ NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size, SI
server_enter_uninterrupted_section( &csVirtual, &sigset );
if ((status = map_view( &view, NULL, size + extra_size, 0, FALSE,
if ((status = map_view( &view, NULL, size + extra_size, FALSE,
VPROT_READ | VPROT_WRITE | VPROT_COMMITTED, 0 )) != STATUS_SUCCESS)
goto done;
@ -2829,17 +2815,17 @@ NTSTATUS WINAPI NtAllocateVirtualMemory( HANDLE process, PVOID *ret, ULONG_PTR z
return result.virtual_alloc.status;
}
return virtual_alloc_aligned( ret, zero_bits_64, size_ptr, type, protect, 0 );
return virtual_alloc( ret, zero_bits_64, size_ptr, type, protect );
}
/***********************************************************************
* virtual_alloc_aligned (NTDLL.@)
* virtual_alloc (NTDLL.@)
*
* Same as NtAllocateVirtualMemory but with an alignment parameter
* Same as NtAllocateVirtualMemory for the current process.
*/
NTSTATUS virtual_alloc_aligned( PVOID *ret, unsigned short zero_bits_64, SIZE_T *size_ptr,
ULONG type, ULONG protect, ULONG alignment )
NTSTATUS virtual_alloc( PVOID *ret, unsigned short zero_bits_64, SIZE_T *size_ptr,
ULONG type, ULONG protect )
{
void *base;
unsigned int vprot;
@ -2856,7 +2842,7 @@ NTSTATUS virtual_alloc_aligned( PVOID *ret, unsigned short zero_bits_64, SIZE_T
if (*ret)
{
if (type & MEM_RESERVE) /* Round down to 64k boundary */
base = ROUND_ADDR( *ret, get_mask( alignment ) );
base = ROUND_ADDR( *ret, granularity_mask );
else
base = ROUND_ADDR( *ret, page_mask );
size = (((UINT_PTR)*ret + size + page_mask) & ~page_mask) - (UINT_PTR)base;
@ -2900,7 +2886,7 @@ NTSTATUS virtual_alloc_aligned( PVOID *ret, unsigned short zero_bits_64, SIZE_T
if (vprot & VPROT_WRITECOPY) status = STATUS_INVALID_PAGE_PROTECTION;
else if (is_dos_memory) status = allocate_dos_memory( &view, vprot );
else status = map_view( &view, base, size, alignment, type & MEM_TOP_DOWN, vprot, zero_bits_64 );
else status = map_view( &view, base, size, type & MEM_TOP_DOWN, vprot, zero_bits_64 );
if (status == STATUS_SUCCESS) base = view->base;
}
@ -3498,7 +3484,7 @@ NTSTATUS WINAPI NtMapViewOfSection( HANDLE handle, HANDLE process, PVOID *addr_p
SECTION_INHERIT inherit, ULONG alloc_type, ULONG protect )
{
NTSTATUS res;
SIZE_T mask = get_mask( 0 );
SIZE_T mask = granularity_mask;
pe_image_info_t image_info;
LARGE_INTEGER offset;
unsigned short zero_bits_64 = zero_bits_win_to_64( zero_bits );