From 2af035f53f2ebdcc56974aa938c1de83ada5b8ec Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 30 Apr 2020 10:07:36 +0200 Subject: [PATCH] ntdll: Remove support for custom virtual memory alignments. Signed-off-by: Alexandre Julliard --- dlls/ntdll/ntdll_misc.h | 4 +- dlls/ntdll/server.c | 8 ++-- dlls/ntdll/virtual.c | 86 +++++++++++++++++------------------------ 3 files changed, 41 insertions(+), 57 deletions(-) diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index a22b77b4819..76e8ec284e8 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -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; diff --git a/dlls/ntdll/server.c b/dlls/ntdll/server.c index edb91cf91a6..3832a80f1e2 100644 --- a/dlls/ntdll/server.c +++ b/dlls/ntdll/server.c @@ -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; } diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index 5900616e0ca..7700385eb7b 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -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 );