=?UTF-8?Q?R=C3=A9mi=20Bernon=20?=: ntdll: Implement zero_bits parameter in virtual alloc functions.

Alexandre Julliard julliard at winehq.org
Tue Aug 13 14:54:34 CDT 2019


Module: wine
Branch: master
Commit: 8a765533d6e19b0b8d51bf1ef7f316d79f9bb968
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=8a765533d6e19b0b8d51bf1ef7f316d79f9bb968

Author: Rémi Bernon <rbernon at 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 at codeweavers.com>
Signed-off-by: Huw Davies <huw at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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;




More information about the wine-cvs mailing list