Module: wine Branch: master Commit: 8a765533d6e19b0b8d51bf1ef7f316d79f9bb968 URL: https://source.winehq.org/git/wine.git/?a=commit;h=8a765533d6e19b0b8d51bf1ef...
Author: Rémi Bernon rbernon@codeweavers.com Date: Thu Aug 1 10:07:45 2019 +0200
ntdll: Implement zero_bits parameter in virtual alloc functions.
Use alloc_area.limit field to limit the search in reserved areas to the desired memory range, or call find_free_area to get a pointer to a free memory region which matches the zero_bits constraint, then mmap it with MAP_FIXED flag.
Signed-off-by: Rémi Bernon rbernon@codeweavers.com Signed-off-by: Huw Davies huw@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/tests/virtual.c | 8 -------- dlls/ntdll/virtual.c | 22 +++++++++++++++++----- 2 files changed, 17 insertions(+), 13 deletions(-)
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c index 9eec912..31eb66c 100644 --- a/dlls/ntdll/tests/virtual.c +++ b/dlls/ntdll/tests/virtual.c @@ -120,7 +120,6 @@ static void test_NtAllocateVirtualMemory(void) "NtAllocateVirtualMemory returned %08x\n", status); if (status == STATUS_SUCCESS) { - todo_wine_if(is_win64) ok(((UINT_PTR)addr2 >> (32 - zero_bits)) == 0, "NtAllocateVirtualMemory returned address: %p\n", addr2);
@@ -141,7 +140,6 @@ static void test_NtAllocateVirtualMemory(void) "NtAllocateVirtualMemory with %d zero_bits returned %08x\n", (int)zero_bits, status); if (status == STATUS_SUCCESS) { - todo_wine ok(((UINT_PTR)addr2 >> (32 - zero_bits)) == 0, "NtAllocateVirtualMemory with %d zero_bits returned address %p\n", (int)zero_bits, addr2);
@@ -156,7 +154,6 @@ static void test_NtAllocateVirtualMemory(void) addr2 = NULL; status = NtAllocateVirtualMemory(NtCurrentProcess(), &addr2, 21, &size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); - todo_wine ok(status == STATUS_NO_MEMORY || status == STATUS_INVALID_PARAMETER, "NtAllocateVirtualMemory returned %08x\n", status); if (status == STATUS_SUCCESS) @@ -192,7 +189,6 @@ static void test_NtAllocateVirtualMemory(void) "NtAllocateVirtualMemory returned %08x\n", status); if (status == STATUS_SUCCESS) { - todo_wine ok(((UINT_PTR)addr2 & ~get_zero_bits_mask(zero_bits)) == 0 && ((UINT_PTR)addr2 & ~zero_bits) != 0, /* only the leading zeroes matter */ "NtAllocateVirtualMemory returned address %p\n", addr2); @@ -330,7 +326,6 @@ static void test_NtMapViewOfSection(void) "NtMapViewOfSection returned %08x\n", status); if (status == STATUS_SUCCESS) { - todo_wine_if(is_win64) ok(((UINT_PTR)ptr2 >> (32 - zero_bits)) == 0, "NtMapViewOfSection returned address: %p\n", ptr2);
@@ -348,7 +343,6 @@ static void test_NtMapViewOfSection(void) "NtMapViewOfSection with %d zero_bits returned %08x\n", (int)zero_bits, status); if (status == STATUS_SUCCESS) { - todo_wine ok(((UINT_PTR)ptr2 >> (32 - zero_bits)) == 0, "NtMapViewOfSection with %d zero_bits returned address %p\n", (int)zero_bits, ptr2);
@@ -362,7 +356,6 @@ static void test_NtMapViewOfSection(void) size = 0; offset.QuadPart = 0; status = NtMapViewOfSection(mapping, process, &ptr2, 21, 0, &offset, &size, 1, 0, PAGE_READWRITE); - todo_wine ok(status == STATUS_NO_MEMORY || status == STATUS_INVALID_PARAMETER, "NtMapViewOfSection returned %08x\n", status);
@@ -391,7 +384,6 @@ static void test_NtMapViewOfSection(void) "NtMapViewOfSection returned %08x\n", status); if (status == STATUS_SUCCESS) { - todo_wine ok(((UINT_PTR)ptr2 & ~get_zero_bits_mask(zero_bits)) == 0 && ((UINT_PTR)ptr2 & ~zero_bits) != 0, /* only the leading zeroes matter */ "NtMapViewOfSection returned address %p\n", ptr2); diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c index d651a16..f8d80b6 100644 --- a/dlls/ntdll/virtual.c +++ b/dlls/ntdll/virtual.c @@ -443,6 +443,15 @@ static inline unsigned short zero_bits_win_to_64( ULONG_PTR zero_bits )
/*********************************************************************** + * get_zero_bits_64_mask + */ +static inline UINT_PTR get_zero_bits_64_mask( USHORT zero_bits_64 ) +{ + return (UINT_PTR)((~(UINT64)0) >> zero_bits_64); +} + + +/*********************************************************************** * is_write_watch_range */ static inline BOOL is_write_watch_range( const void *addr, size_t size ) @@ -1126,13 +1135,11 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, size_t view_size = size + mask + 1; struct alloc_area alloc;
- if (zero_bits_64) - FIXME("Unimplemented zero_bits parameter value\n"); - alloc.size = size; alloc.mask = mask; alloc.top_down = top_down; - alloc.limit = user_space_limit; + alloc.limit = (void*)(get_zero_bits_64_mask( zero_bits_64 ) & (UINT_PTR)user_space_limit); + if (wine_mmap_enum_reserved_areas( alloc_reserved_area_callback, &alloc, top_down )) { ptr = alloc.result; @@ -1144,7 +1151,12 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
for (;;) { - if ((ptr = wine_anon_mmap( NULL, view_size, VIRTUAL_GetUnixProt(vprot), 0 )) == (void *)-1) + if (!zero_bits_64) + ptr = NULL; + else if (!(ptr = find_free_area( (void*)0, alloc.limit, view_size, mask, top_down ))) + return STATUS_NO_MEMORY; + + if ((ptr = wine_anon_mmap( ptr, view_size, VIRTUAL_GetUnixProt(vprot), ptr ? MAP_FIXED : 0 )) == (void *)-1) { if (errno == ENOMEM) return STATUS_NO_MEMORY; return STATUS_INVALID_PARAMETER;