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>
This commit is contained in:
Rémi Bernon 2019-08-01 10:07:45 +02:00 committed by Alexandre Julliard
parent 6672fc9d85
commit 8a765533d6
2 changed files with 17 additions and 13 deletions

View File

@ -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);

View File

@ -442,6 +442,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
*/
@ -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;