Updated ntdll-ForceBottomUpAlloc patchset.

This commit is contained in:
Paul Gofman 2020-06-02 21:10:34 +03:00
parent 6387991cc0
commit 676f261e5e
11 changed files with 531 additions and 517 deletions

View File

@ -1,4 +1,4 @@
From b42d3dd8af6e0910bb204d64ac885d2cdc09e4df Mon Sep 17 00:00:00 2001
From 7dd611828bb181c29d20544c7dcae8f52215ae70 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Thu, 9 Jan 2020 15:05:09 +0300
Subject: [PATCH] ntdll: Stop search on mmap() error in try_map_free_area().
@ -10,10 +10,10 @@ makes the search take incredible time until it fails.
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 8b515fcbce..1d6239f765 100644
index c6f3c1685e0..37f83efa8fc 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -570,8 +570,14 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
@@ -767,8 +767,14 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
return start;
TRACE( "Found free area is already mapped, start %p.\n", start );
@ -31,5 +31,5 @@ index 8b515fcbce..1d6239f765 100644
if ((step > 0 && (char *)end - (char *)start < step) ||
(step < 0 && (char *)start - (char *)base < -step) ||
--
2.24.1
2.26.2

View File

@ -1,4 +1,4 @@
From 61e5e74a97121f630fc7f5c5144fd0172d547b60 Mon Sep 17 00:00:00 2001
From dae806ca4aa1d25e65539f33b784791a9b357a77 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Thu, 16 Jan 2020 16:09:24 +0300
Subject: [PATCH] ntdll: Use MAP_FIXED_NOREPLACE flag in try_map_free_area() if
@ -11,10 +11,10 @@ already mapped.
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 1d6239f765..486693f312 100644
index 37f83efa8fc..4ee30af6548 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -562,22 +562,28 @@ static struct wine_rb_entry *find_view_inside_range( void **base_ptr, void **end
@@ -759,22 +759,28 @@ static struct wine_rb_entry *find_view_inside_range( void **base_ptr, void **end
static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
void *start, size_t size, int unix_prot )
{
@ -47,5 +47,5 @@ index 1d6239f765..486693f312 100644
if ((step > 0 && (char *)end - (char *)start < step) ||
(step < 0 && (char *)start - (char *)base < -step) ||
--
2.24.1
2.26.2

View File

@ -1,4 +1,4 @@
From 53e3f063ddc0ac0dfee0e53deffc58f818479cdd Mon Sep 17 00:00:00 2001
From 15fdb467ef17b05df48abe7f5f23e718ce876d57 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Mon, 25 Nov 2019 12:19:20 +0300
Subject: [PATCH] ntdll: Force bottom up allocation order for 64 bit arch
@ -11,10 +11,10 @@ Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46568
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 170e310f34d..e90fabf614a 100644
index 4ee30af6548..ba9ecd5a5b1 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -1256,13 +1256,19 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
@@ -1492,13 +1492,19 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
}
else
{
@ -35,7 +35,7 @@ index 170e310f34d..e90fabf614a 100644
if (unix_funcs->mmap_enum_reserved_areas( alloc_reserved_area_callback, &alloc, top_down ))
{
ptr = alloc.result;
@@ -1272,7 +1278,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
@@ -1508,7 +1514,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
goto done;
}
@ -44,7 +44,7 @@ index 170e310f34d..e90fabf614a 100644
{
if (!(ptr = map_free_area( address_space_start, alloc.limit, size,
top_down, VIRTUAL_GetUnixProt(vprot) )))
@@ -1281,6 +1287,8 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
@@ -1517,6 +1523,8 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
goto done;
}

View File

@ -1,4 +1,4 @@
From 0c2da5027e397cd2a3677cad6e505482e7c8b063 Mon Sep 17 00:00:00 2001
From a95074355fd65c1396ac0fbd9fbc1c2c151b434b Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Tue, 14 Jan 2020 21:39:23 +0300
Subject: [PATCH] ntdll: Increase step after failed map attempt in
@ -9,10 +9,10 @@ Subject: [PATCH] ntdll: Increase step after failed map attempt in
1 file changed, 1 insertion(+)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 81d844ab17..a262401f58 100644
index ba9ecd5a5b1..86062cd4546 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -590,6 +590,7 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
@@ -787,6 +787,7 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
step == 0)
break;
start = (char *)start + step;
@ -21,5 +21,5 @@ index 81d844ab17..a262401f58 100644
return NULL;
--
2.24.1
2.26.2

View File

@ -1,260 +0,0 @@
From 20012afe9a7e47f06550c9802e62d66ac9f9abba Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Tue, 14 Jan 2020 21:28:57 +0300
Subject: [PATCH] libs/wine: Add functions for managing free area list.
---
include/wine/library.h | 6 ++++
libs/wine/mmap.c | 75 ++++++++++++++++++++++++++++++++----------
libs/wine/wine.map | 4 +++
3 files changed, 68 insertions(+), 17 deletions(-)
diff --git a/include/wine/library.h b/include/wine/library.h
index 60d6b525c75..70b6a0b3055 100644
--- a/include/wine/library.h
+++ b/include/wine/library.h
@@ -79,6 +79,12 @@ extern int wine_mmap_is_in_reserved_area( void *addr, size_t size );
extern int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, void *arg),
void *arg, int top_down );
+extern void wine_mmap_add_free_area( void *addr, size_t size );
+extern void wine_mmap_remove_free_area( void *addr, size_t size, int unmap );
+extern int wine_mmap_is_in_free_area( void *addr, size_t size );
+extern int wine_mmap_enum_free_areas( int (*enum_func)(void *base, size_t size, void *arg),
+ void *arg, int top_down );
+
#ifdef __cplusplus
}
#endif
diff --git a/libs/wine/mmap.c b/libs/wine/mmap.c
index f2b5adc1d29..baa466c7766 100644
--- a/libs/wine/mmap.c
+++ b/libs/wine/mmap.c
@@ -52,7 +52,9 @@ struct reserved_area
size_t size;
};
-static struct list reserved_areas = LIST_INIT(reserved_areas);
+static struct list reserved_areas_list = LIST_INIT(reserved_areas_list);
+static struct list free_areas_list = LIST_INIT(free_areas_list);
+
#ifndef __APPLE__
static const unsigned int granularity_mask = 0xffff; /* reserved areas have 64k granularity */
#endif
@@ -427,7 +429,7 @@ void mmap_init(void)
reserve_malloc_space( 8 * 1024 * 1024 );
- if (!list_head( &reserved_areas ))
+ if (!list_head( &reserved_areas_list ))
{
/* if we don't have a preloader, try to reserve some space below 2Gb */
reserve_area( (void *)0x00110000, (void *)0x40000000 );
@@ -435,7 +437,7 @@ void mmap_init(void)
/* check for a reserved area starting at the user space limit */
/* to avoid wasting time trying to allocate it again */
- LIST_FOR_EACH( ptr, &reserved_areas )
+ LIST_FOR_EACH( ptr, &reserved_areas_list )
{
area = LIST_ENTRY( ptr, struct reserved_area, entry );
if ((char *)area->base > user_space_limit) break;
@@ -466,7 +468,7 @@ void mmap_init(void)
/* reserve the DOS area if not already done */
- ptr = list_head( &reserved_areas );
+ ptr = list_head( &reserved_areas_list );
if (ptr)
{
area = LIST_ENTRY( ptr, struct reserved_area, entry );
@@ -476,7 +478,7 @@ void mmap_init(void)
#elif defined(__x86_64__) || defined(__aarch64__)
- if (!list_head( &reserved_areas ))
+ if (!list_head( &reserved_areas_list ))
{
/* if we don't have a preloader, try to reserve the space now */
reserve_area( (void *)0x000000010000, (void *)0x000068000000 );
@@ -497,14 +499,14 @@ void mmap_init(void)
* Note: the reserved areas functions are not reentrant, caller is
* responsible for proper locking.
*/
-void wine_mmap_add_reserved_area( void *addr, size_t size )
+static void wine_mmap_add_area( struct list *areas, void *addr, size_t size )
{
struct reserved_area *area;
struct list *ptr;
if (!((char *)addr + size)) size--; /* avoid wrap-around */
- LIST_FOR_EACH( ptr, &reserved_areas )
+ LIST_FOR_EACH( ptr, areas )
{
area = LIST_ENTRY( ptr, struct reserved_area, entry );
if (area->base > addr)
@@ -524,7 +526,7 @@ void wine_mmap_add_reserved_area( void *addr, size_t size )
area->size += size;
/* try to merge with the next one too */
- if ((ptr = list_next( &reserved_areas, ptr )))
+ if ((ptr = list_next( areas, ptr )))
{
struct reserved_area *next = LIST_ENTRY( ptr, struct reserved_area, entry );
if ((char *)addr + size == (char *)next->base)
@@ -546,6 +548,15 @@ void wine_mmap_add_reserved_area( void *addr, size_t size )
}
}
+void wine_mmap_add_reserved_area( void *addr, size_t size )
+{
+ wine_mmap_add_area(&reserved_areas_list, addr, size);
+}
+
+void wine_mmap_add_free_area( void *addr, size_t size )
+{
+ wine_mmap_add_area(&free_areas_list, addr, size);
+}
/***********************************************************************
* wine_mmap_remove_reserved_area
@@ -556,14 +567,14 @@ void wine_mmap_add_reserved_area( void *addr, size_t size )
* Note: the reserved areas functions are not reentrant, caller is
* responsible for proper locking.
*/
-void wine_mmap_remove_reserved_area( void *addr, size_t size, int unmap )
+static void wine_mmap_remove_area( struct list *areas, void *addr, size_t size, int unmap )
{
struct reserved_area *area;
struct list *ptr;
if (!((char *)addr + size)) size--; /* avoid wrap-around */
- ptr = list_head( &reserved_areas );
+ ptr = list_head( areas );
/* find the first area covering address */
while (ptr)
{
@@ -584,7 +595,7 @@ void wine_mmap_remove_reserved_area( void *addr, size_t size, int unmap )
else
{
/* range contains the whole area -> remove area completely */
- ptr = list_next( &reserved_areas, ptr );
+ ptr = list_next( areas, ptr );
if (unmap) munmap( area->base, area->size );
list_remove( &area->entry );
free( area );
@@ -616,10 +627,19 @@ void wine_mmap_remove_reserved_area( void *addr, size_t size, int unmap )
}
}
}
- ptr = list_next( &reserved_areas, ptr );
+ ptr = list_next( areas, ptr );
}
}
+void wine_mmap_remove_reserved_area( void *addr, size_t size, int unmap )
+{
+ wine_mmap_remove_area(&reserved_areas_list, addr, size, unmap);
+}
+
+void wine_mmap_remove_free_area( void *addr, size_t size, int unmap )
+{
+ wine_mmap_remove_area(&free_areas_list, addr, size, unmap);
+}
/***********************************************************************
* wine_mmap_is_in_reserved_area
@@ -631,12 +651,12 @@ void wine_mmap_remove_reserved_area( void *addr, size_t size, int unmap )
* Note: the reserved areas functions are not reentrant, caller is
* responsible for proper locking.
*/
-int wine_mmap_is_in_reserved_area( void *addr, size_t size )
+static int wine_mmap_is_in_area( struct list *areas, void *addr, size_t size )
{
struct reserved_area *area;
struct list *ptr;
- LIST_FOR_EACH( ptr, &reserved_areas )
+ LIST_FOR_EACH( ptr, areas )
{
area = LIST_ENTRY( ptr, struct reserved_area, entry );
if (area->base > addr) break;
@@ -648,6 +668,15 @@ int wine_mmap_is_in_reserved_area( void *addr, size_t size )
return 0;
}
+int wine_mmap_is_in_reserved_area( void *addr, size_t size )
+{
+ return wine_mmap_is_in_area( &reserved_areas_list, addr, size );
+}
+
+int wine_mmap_is_in_free_area( void *addr, size_t size )
+{
+ return wine_mmap_is_in_area( &free_areas_list, addr, size );
+}
/***********************************************************************
* wine_mmap_enum_reserved_areas
@@ -658,7 +687,7 @@ int wine_mmap_is_in_reserved_area( void *addr, size_t size )
* Note: the reserved areas functions are not reentrant, caller is
* responsible for proper locking.
*/
-int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, void *arg), void *arg,
+int wine_mmap_enum_areas( struct list *areas, int (*enum_func)(void *base, size_t size, void *arg), void *arg,
int top_down )
{
int ret = 0;
@@ -666,7 +695,7 @@ int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, voi
if (top_down)
{
- for (ptr = reserved_areas.prev; ptr != &reserved_areas; ptr = ptr->prev)
+ for (ptr = areas->prev; ptr != areas; ptr = ptr->prev)
{
struct reserved_area *area = LIST_ENTRY( ptr, struct reserved_area, entry );
if ((ret = enum_func( area->base, area->size, arg ))) break;
@@ -674,7 +703,7 @@ int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, voi
}
else
{
- for (ptr = reserved_areas.next; ptr != &reserved_areas; ptr = ptr->next)
+ for (ptr = areas->next; ptr != areas; ptr = ptr->next)
{
struct reserved_area *area = LIST_ENTRY( ptr, struct reserved_area, entry );
if ((ret = enum_func( area->base, area->size, arg ))) break;
@@ -682,3 +711,15 @@ int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, voi
}
return ret;
}
+
+int wine_mmap_enum_reserved_areas( int (*enum_func)(void *base, size_t size, void *arg), void *arg,
+ int top_down )
+{
+ return wine_mmap_enum_areas(&reserved_areas_list, enum_func, arg, top_down);
+}
+
+int wine_mmap_enum_free_areas( int (*enum_func)(void *base, size_t size, void *arg), void *arg,
+ int top_down )
+{
+ return wine_mmap_enum_areas(&free_areas_list, enum_func, arg, top_down);
+}
diff --git a/libs/wine/wine.map b/libs/wine/wine.map
index 9c4c86dde4d..32bf99bd6e6 100644
--- a/libs/wine/wine.map
+++ b/libs/wine/wine.map
@@ -31,6 +31,10 @@ WINE_1.0
wine_mmap_enum_reserved_areas;
wine_mmap_is_in_reserved_area;
wine_mmap_remove_reserved_area;
+ wine_mmap_add_free_area;
+ wine_mmap_enum_free_areas;
+ wine_mmap_is_in_free_area;
+ wine_mmap_remove_free_area;
wine_wctype_table;
/* the following functions are obsolete and only exported for backwards compatibility */
--
2.25.1

View File

@ -0,0 +1,447 @@
From d757532f375dee8d7b717e546ef14406ebbc3653 Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Tue, 14 Jan 2020 21:42:21 +0300
Subject: [PATCH] ntdll: Use free area list for virtual memory allocation.
---
dlls/ntdll/virtual.c | 319 +++++++++++++++++++++++++++----------------
1 file changed, 204 insertions(+), 115 deletions(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 86062cd4546..81592a84715 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -190,7 +190,11 @@ static BYTE *pages_vprot;
#endif
static struct file_view *view_block_start, *view_block_end, *next_free_view;
+#ifdef _WIN64
+static const size_t view_block_size = 0x200000;
+#else
static const size_t view_block_size = 0x100000;
+#endif
static void *preload_reserve_start;
static void *preload_reserve_end;
static BOOL use_locks;
@@ -235,13 +239,13 @@ static struct range_entry *free_ranges_lower_bound( void *addr )
*
* Updates the free_ranges after a new view has been created.
*/
-static void free_ranges_insert_view( struct file_view *view )
+static void free_ranges_remove_range( void *view_base, void *view_end, void *view_base_unaligned )
{
- void *view_base = ROUND_ADDR( view->base, granularity_mask );
- void *view_end = ROUND_ADDR( (char *)view->base + view->size + granularity_mask, granularity_mask );
struct range_entry *range = free_ranges_lower_bound( view_base );
struct range_entry *next = range + 1;
+ TRACE("view %p-%p (%p).\n", view_base, view_end, view_base_unaligned);
+
/* free_ranges initial value is such that the view is either inside range or before another one. */
assert( range != free_ranges_end );
assert( range->end > view_base || next != free_ranges_end );
@@ -252,7 +256,7 @@ static void free_ranges_insert_view( struct file_view *view )
(range->end == view_base && next->base >= view_end))
{
/* on Win64, assert that it's correctly aligned so we're not going to be in trouble later */
- assert( (!is_win64 && !is_wow64) || view->base == view_base );
+ assert( (!is_win64 && !is_wow64) || view_base_unaligned == view_base );
WARN( "range %p - %p is already mapped\n", view_base, view_end );
return;
}
@@ -292,6 +296,12 @@ static void free_ranges_insert_view( struct file_view *view )
}
}
+static void free_ranges_insert_view( struct file_view *view )
+{
+ free_ranges_remove_range(ROUND_ADDR(view->base, granularity_mask),
+ ROUND_ADDR((char *)view->base + view->size + granularity_mask, granularity_mask),
+ view->base);
+}
/***********************************************************************
* free_ranges_remove_view
@@ -322,6 +332,7 @@ static void free_ranges_remove_view( struct file_view *view )
return;
}
#endif
+ TRACE("view %p-%p.\n", view_base, view_end);
/* free_ranges initial value is such that the view is either inside range or before another one. */
assert( range != free_ranges_end );
@@ -712,44 +723,6 @@ static struct file_view *find_view_range( const void *addr, size_t size )
}
-/***********************************************************************
- * find_view_inside_range
- *
- * Find first (resp. last, if top_down) view inside a range.
- * The csVirtual section must be held by caller.
- */
-static struct wine_rb_entry *find_view_inside_range( void **base_ptr, void **end_ptr, int top_down )
-{
- struct wine_rb_entry *first = NULL, *ptr = views_tree.root;
- void *base = *base_ptr, *end = *end_ptr;
-
- /* find the first (resp. last) view inside the range */
- while (ptr)
- {
- struct file_view *view = WINE_RB_ENTRY_VALUE( ptr, struct file_view, entry );
- if ((char *)view->base + view->size >= (char *)end)
- {
- end = min( end, view->base );
- ptr = ptr->left;
- }
- else if (view->base <= base)
- {
- base = max( (char *)base, (char *)view->base + view->size );
- ptr = ptr->right;
- }
- else
- {
- first = ptr;
- ptr = top_down ? ptr->right : ptr->left;
- }
- }
-
- *base_ptr = base;
- *end_ptr = end;
- return first;
-}
-
-
/***********************************************************************
* try_map_free_area
*
@@ -793,65 +766,11 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
return NULL;
}
-
-/***********************************************************************
- * map_free_area
- *
- * 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, int top_down, int unix_prot )
-{
- struct wine_rb_entry *first = find_view_inside_range( &base, &end, top_down );
- ptrdiff_t step = top_down ? -(granularity_mask + 1) : (granularity_mask + 1);
- void *start;
-
- if (top_down)
- {
- start = ROUND_ADDR( (char *)end - size, granularity_mask );
- if (start >= end || start < base) return NULL;
-
- while (first)
- {
- 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, granularity_mask );
- /* stop if remaining space is not large enough */
- if (!start || start >= end || start < base) return NULL;
- first = wine_rb_prev( first );
- }
- }
- else
- {
- start = ROUND_ADDR( (char *)base + granularity_mask, granularity_mask );
- if (!start || start >= end || (char *)end - (char *)start < size) return NULL;
-
- while (first)
- {
- 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 + 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 );
- }
- }
-
- if (!first)
- return try_map_free_area( base, end, step, start, size, unix_prot );
-
- return start;
-}
-
-
/***********************************************************************
* find_reserved_free_area
*
* Find a free area between views inside the specified range.
* 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, int top_down )
{
@@ -1065,8 +984,7 @@ static void delete_view( struct file_view *view ) /* [in] View */
{
if (!(view->protect & VPROT_SYSTEM)) unmap_area( view->base, view->size );
set_page_vprot( view->base, view->size, 0 );
- if (unix_funcs->mmap_is_in_reserved_area( view->base, view->size ))
- free_ranges_remove_view( view );
+ free_ranges_remove_view( view );
wine_rb_remove( &views_tree, &view->entry );
*(struct file_view **)view = next_free_view;
next_free_view = view;
@@ -1114,8 +1032,7 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
set_page_vprot( base, size, vprot );
wine_rb_put( &views_tree, view->base, &view->entry );
- if (unix_funcs->mmap_is_in_reserved_area( view->base, view->size ))
- free_ranges_insert_view( view );
+ free_ranges_insert_view( view );
*view_ret = view;
@@ -1373,6 +1290,7 @@ struct alloc_area
int top_down;
void *limit;
void *result;
+ int unix_prot;
};
/***********************************************************************
@@ -1414,6 +1332,179 @@ static int CDECL alloc_reserved_area_callback( void *start, SIZE_T size, void *a
return 0;
}
+struct area_alloc_reserved
+{
+ char *map_area_start, *map_area_end, *result;
+ size_t size;
+ ptrdiff_t step;
+ int unix_prot;
+ BOOL top_down;
+};
+
+static int CDECL alloc_area_in_reserved_or_between_callback( void *start, SIZE_T size, void *arg )
+{
+ struct area_alloc_reserved *area = arg;
+ char *end = (char *)start + size;
+ char *intersect_start, *intersect_end;
+ char *alloc_start;
+
+ if (area->top_down)
+ {
+ if (area->map_area_start >= end)
+ return 1;
+
+ if (area->map_area_end <= (char *)start)
+ return 0;
+
+ intersect_start = max((char *)start, area->map_area_start);
+ intersect_end = min((char *)end, area->map_area_end);
+
+ assert(ROUND_ADDR(intersect_start, granularity_mask) == intersect_start);
+ assert(ROUND_ADDR(intersect_end + granularity_mask - 1, granularity_mask) == intersect_end);
+
+ alloc_start = ROUND_ADDR( (char *)area->map_area_end - size, granularity_mask );
+
+ if (alloc_start >= intersect_end)
+ {
+ if ((area->result = try_map_free_area( area->map_area_start, alloc_start + size, area->step,
+ alloc_start, area->size, area->unix_prot )))
+ return 1;
+ }
+
+ alloc_start = ROUND_ADDR( intersect_end - area->size, granularity_mask );
+ if (alloc_start >= intersect_start)
+ {
+ if ((area->result = wine_anon_mmap( alloc_start, area->size, area->unix_prot, MAP_FIXED )) != alloc_start)
+ ERR("Could not map in reserved area, alloc_start %p, size %p.\n",
+ alloc_start, (void *)area->size);
+ return 1;
+ }
+
+ area->map_area_end = intersect_start;
+ if (area->map_area_end - area->map_area_start < area->size)
+ return 1;
+ }
+ else
+ {
+ if (area->map_area_end <= (char *)start)
+ {
+ return 1;
+ }
+
+ if (area->map_area_start >= (char *)end)
+ return 0;
+
+ intersect_start = max((char *)start, area->map_area_start);
+ intersect_end = min((char *)end, area->map_area_end);
+
+ assert(ROUND_ADDR(intersect_start, granularity_mask) == intersect_start);
+ assert(ROUND_ADDR(intersect_end + granularity_mask - 1, granularity_mask) == intersect_end);
+
+ if (intersect_start - area->map_area_start >= area->size)
+ {
+ if ((area->result = try_map_free_area( area->map_area_start, intersect_start, area->step,
+ area->map_area_start, area->size, area->unix_prot )))
+ return 1;
+ }
+
+ if (intersect_end - intersect_start >= area->size)
+ {
+ if ((area->result = wine_anon_mmap( intersect_start, area->size, area->unix_prot, MAP_FIXED ))
+ != intersect_start)
+ ERR("Could not map in reserved area.\n");
+ return 1;
+ }
+ area->map_area_start = intersect_end;
+ if (area->map_area_end - area->map_area_start < area->size)
+ return 1;
+ }
+
+ return 0;
+}
+
+static void *alloc_free_area(void *limit, size_t size, BOOL top_down, int unix_prot)
+{
+ struct range_entry *range, *ranges_start, *ranges_end;
+ struct area_alloc_reserved area;
+ char *start, *base, *end;
+ int ranges_inc;
+
+ TRACE("limit %p, size %p, top_down %#x.\n", limit, (void *)size, top_down);
+
+ if (top_down)
+ {
+ ranges_start = free_ranges_end - 1;
+ ranges_end = free_ranges - 1;
+ ranges_inc = -1;
+ }
+ else
+ {
+ ranges_start = free_ranges;
+ ranges_end = free_ranges_end;
+ ranges_inc = 1;
+ }
+
+ memset(&area, 0, sizeof(area));
+ area.step = top_down ? -(granularity_mask + 1) : (granularity_mask + 1);
+ area.size = size;
+ area.top_down = top_down;
+ area.unix_prot = unix_prot;
+
+ for (range = ranges_start; range != ranges_end; range += ranges_inc)
+ {
+ base = range->base;
+ end = range->end;
+
+ TRACE("range %p-%p.\n", base, end);
+
+ if (base < (char *)address_space_start) base = (char *)address_space_start;
+ if (end > (char *)limit + granularity_mask + 1) end = (char *)limit + granularity_mask + 1;
+ if (base >= end) continue;
+
+ area.map_area_start = base;
+ area.map_area_end = end;
+
+ if (top_down)
+ {
+ start = ROUND_ADDR( (char *)end - size, granularity_mask );
+ if (start >= end || start < base)
+ continue;
+ }
+ else
+ {
+ start = ROUND_ADDR( (char *)base + granularity_mask, granularity_mask );
+ if (!start || start >= end || (char *)end - (char *)start < size)
+ continue;
+ }
+ unix_funcs->mmap_enum_reserved_areas( alloc_area_in_reserved_or_between_callback, &area, top_down );
+ if (area.result)
+ return area.result;
+
+ if (top_down)
+ {
+ start = ROUND_ADDR( area.map_area_end - size, granularity_mask );
+ if (start >= area.map_area_end || start < area.map_area_start)
+ continue;
+
+ if ((area.result = try_map_free_area( area.map_area_start, start + size, area.step,
+ start, size, unix_prot )))
+ return area.result;
+ }
+ else
+ {
+ start = ROUND_ADDR( area.map_area_start + granularity_mask, granularity_mask );
+ if (!start || start >= area.map_area_end
+ || area.map_area_end - start < size)
+ continue;
+
+ if ((area.result = try_map_free_area( start, area.map_area_end, area.step,
+ start, size, unix_prot )))
+ return area.result;
+ }
+ }
+ return NULL;
+}
+
/***********************************************************************
* map_fixed_area
*
@@ -1499,11 +1590,15 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
alloc.size = size;
alloc.top_down = top_down;
alloc.limit = (void*)(get_zero_bits_64_mask( zero_bits_64 ) & (UINT_PTR)user_space_limit);
+ alloc.unix_prot = VIRTUAL_GetUnixProt(vprot);
- if (is_win64 && !top_down)
+ if (is_win64 || zero_bits_64)
{
- /* Ditch 0x7ffffe000000 - 0x7fffffff0000 reserved area. */
- alloc.limit = min(alloc.limit, (void *)0x7ffffe000000);
+ if (!(ptr = alloc_free_area( alloc.limit, alloc.size, top_down, alloc.unix_prot)))
+ return STATUS_NO_MEMORY;
+
+ TRACE( "got mem in free area %p-%p\n", ptr, (char *)ptr + size );
+ goto done;
}
if (unix_funcs->mmap_enum_reserved_areas( alloc_reserved_area_callback, &alloc, top_down ))
@@ -1514,16 +1609,6 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
return STATUS_INVALID_PARAMETER;
goto done;
}
-
- if (is_win64 || zero_bits_64)
- {
- 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;
- }
-
view_size = size + granularity_mask + 1;
for (;;)
@@ -2256,10 +2341,14 @@ void virtual_init(void)
pages_vprot = (void *)((char *)alloc_views.base + 2 * view_block_size);
wine_rb_init( &views_tree, compare_view );
- free_ranges[0].base = (void *)0;
- free_ranges[0].end = (void *)~0;
+ free_ranges[0].base = address_space_start;
+ free_ranges[0].end = address_space_limit;
free_ranges_end = free_ranges + 1;
+ free_ranges_remove_range(ROUND_ADDR(preload_reserve_start, granularity_mask),
+ ROUND_ADDR((char *)preload_reserve_end + granularity_mask,
+ granularity_mask), preload_reserve_start);
+
/* make the DOS area accessible (except the low 64K) to hide bugs in broken apps like Excel 2003 */
size = (char *)address_space_start - (char *)0x10000;
if (size && unix_funcs->mmap_is_in_reserved_area( (void*)0x10000, size ) == 1)
--
2.26.2

View File

@ -1,18 +1,18 @@
From edf5fb86ff4d075fb48fd562fc0be2140c8e66bb Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Wed, 15 Jan 2020 17:05:09 +0300
From 0c26b2508ad1fc3c5bfb8eb775fb21febfeb4c0e Mon Sep 17 00:00:00 2001
From: Paul Gofman <pgofman@codeweavers.com>
Date: Tue, 2 Jun 2020 21:06:33 +0300
Subject: [PATCH] ntdll: Permanently exclude natively mapped areas from free
areas list.
---
dlls/ntdll/virtual.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
dlls/ntdll/virtual.c | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 18524fc12de..63a10435890 100644
index 81592a84715..6c6efea0285 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -111,6 +111,9 @@ static const BYTE VIRTUAL_Win32Flags[16] =
@@ -112,6 +112,9 @@ static const BYTE VIRTUAL_Win32Flags[16] =
static struct wine_rb_tree views_tree;
@ -22,7 +22,7 @@ index 18524fc12de..63a10435890 100644
static RTL_CRITICAL_SECTION csVirtual;
static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
{
@@ -566,6 +569,13 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
@@ -755,6 +758,13 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
if (ptr != (void *)-1)
munmap( ptr, size );
@ -36,37 +36,31 @@ index 18524fc12de..63a10435890 100644
if ((step > 0 && (char *)end - (char *)start < step) ||
(step < 0 && (char *)start - (char *)base < -step) ||
step == 0)
@@ -1136,6 +1146,8 @@ static int alloc_free_area_callback( void *base, size_t area_size, void *arg )
ptrdiff_t step = alloc->top_down ? -(granularity_mask + 1) : (granularity_mask + 1);
void *start;
@@ -1594,9 +1604,24 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
+ TRACE("base %p, area_size %p, size %p.\n", base, (void *)area_size, (void *)size);
+
if (base < address_space_start) base = address_space_start;
if (is_beyond_limit( base, size, alloc->limit )) end = alloc->limit;
if (base >= end) return 0;
@@ -1265,11 +1277,21 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
goto done;
}
+
if (is_win64 || zero_bits_64)
{
+ last_already_mapped = NULL;
+
if (!wine_mmap_enum_free_areas( alloc_free_area_callback, &alloc, top_down ))
if (!(ptr = alloc_free_area( alloc.limit, alloc.size, top_down, alloc.unix_prot)))
return STATUS_NO_MEMORY;
+ if (last_already_mapped)
+ {
+ void *last_mapped_start, *last_mapped_end;
+
+ TRACE("Permanently excluding %p - %p from free list.\n",
+ last_already_mapped, (char *)last_already_mapped + last_already_mapped_size - 1);
+ wine_mmap_remove_free_area(last_already_mapped, last_already_mapped_size, 0);
+ last_mapped_start = ROUND_ADDR(last_already_mapped, granularity_mask);
+ last_mapped_end = ROUND_ADDR((char *)last_already_mapped + last_already_mapped_size + granularity_mask,
+ granularity_mask);
+ if (ptr > last_mapped_end || (char *)ptr + size < (char *)last_mapped_start)
+ free_ranges_remove_range(last_mapped_start, last_mapped_end, last_already_mapped);
+ }
+
ptr = alloc.result;
TRACE( "got mem in free area %p-%p\n", ptr, (char *)ptr + size );
goto done;
}
--
2.26.2

View File

@ -1,198 +0,0 @@
From e659b08734ee7f9265736dadfe7b9a763e7ee2c6 Mon Sep 17 00:00:00 2001
From: Paul Gofman <gofmanp@gmail.com>
Date: Tue, 14 Jan 2020 21:42:21 +0300
Subject: [PATCH] ntdll: Use free area list for virtual memory allocation.
---
dlls/ntdll/virtual.c | 111 +++++++++++++++++++++----------------------
1 file changed, 55 insertions(+), 56 deletions(-)
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 167b9a7fedc..b66b7874ab7 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -577,59 +577,6 @@ static void* try_map_free_area( void *base, void *end, ptrdiff_t step,
return NULL;
}
-
-/***********************************************************************
- * map_free_area
- *
- * 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, int top_down, int unix_prot )
-{
- struct wine_rb_entry *first = find_view_inside_range( &base, &end, top_down );
- ptrdiff_t step = top_down ? -(granularity_mask + 1) : (granularity_mask + 1);
- void *start;
-
- if (top_down)
- {
- start = ROUND_ADDR( (char *)end - size, granularity_mask );
- if (start >= end || start < base) return NULL;
-
- while (first)
- {
- 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, granularity_mask );
- /* stop if remaining space is not large enough */
- if (!start || start >= end || start < base) return NULL;
- first = wine_rb_prev( first );
- }
- }
- else
- {
- start = ROUND_ADDR( (char *)base + granularity_mask, granularity_mask );
- if (!start || start >= end || (char *)end - (char *)start < size) return NULL;
-
- while (first)
- {
- 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 + 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 );
- }
- }
-
- if (!first)
- return try_map_free_area( base, end, step, start, size, unix_prot );
-
- return start;
-}
-
-
/***********************************************************************
* find_reserved_free_area
*
@@ -844,6 +791,7 @@ static struct file_view *alloc_view(void)
*/
static void delete_view( struct file_view *view ) /* [in] View */
{
+ wine_mmap_add_free_area(view->base, view->size);
if (!(view->protect & VPROT_SYSTEM)) unmap_area( view->base, view->size );
set_page_vprot( view->base, view->size, 0 );
wine_rb_remove( &views_tree, &view->entry );
@@ -901,6 +849,7 @@ static NTSTATUS create_view( struct file_view **view_ret, void *base, size_t siz
TRACE( "forcing exec permission on %p-%p\n", base, (char *)base + size - 1 );
mprotect( base, size, unix_prot | PROT_EXEC );
}
+ wine_mmap_remove_free_area(view->base, view->size, 0);
return STATUS_SUCCESS;
}
@@ -1137,6 +1086,7 @@ struct alloc_area
int top_down;
void *limit;
void *result;
+ int unix_prot;
};
/***********************************************************************
@@ -1178,6 +1128,41 @@ static int CDECL alloc_reserved_area_callback( void *start, SIZE_T size, void *a
return 0;
}
+static int alloc_free_area_callback( void *base, size_t area_size, void *arg )
+{
+ struct alloc_area *alloc = arg;
+ void *end = (char *)base + area_size;
+ size_t size = alloc->size;
+ ptrdiff_t step = alloc->top_down ? -(granularity_mask + 1) : (granularity_mask + 1);
+ void *start;
+
+ if (base < address_space_start) base = address_space_start;
+ if (is_beyond_limit( base, size, alloc->limit )) end = alloc->limit;
+ if (base >= end) return 0;
+
+ if (alloc->top_down)
+ {
+ start = ROUND_ADDR( (char *)end - size, granularity_mask );
+ if (start >= end || start < base)
+ return 0;
+
+ if ((alloc->result = try_map_free_area( base, (char *)start + size, step,
+ start, size, alloc->unix_prot )))
+ return 1;
+ }
+ else
+ {
+ start = ROUND_ADDR( (char *)base + granularity_mask, granularity_mask );
+ if (!start || start >= end || (char *)end - (char *)start < size)
+ return 0;
+
+ if ((alloc->result = try_map_free_area( start, end, step,
+ start, size, alloc->unix_prot )))
+ return 1;
+ }
+ return 0;
+}
+
/***********************************************************************
* map_fixed_area
*
@@ -1263,6 +1248,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
alloc.size = size;
alloc.top_down = top_down;
alloc.limit = (void*)(get_zero_bits_64_mask( zero_bits_64 ) & (UINT_PTR)user_space_limit);
+ alloc.unix_prot = VIRTUAL_GetUnixProt(vprot);
if (is_win64 && !top_down)
{
@@ -1281,10 +1267,11 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
if (is_win64 || zero_bits_64)
{
- if (!(ptr = map_free_area( address_space_start, alloc.limit, size,
- top_down, VIRTUAL_GetUnixProt(vprot) )))
+ if (!wine_mmap_enum_free_areas( alloc_free_area_callback, &alloc, top_down ))
return STATUS_NO_MEMORY;
- TRACE( "got mem with map_free_area %p-%p\n", ptr, (char *)ptr + size );
+
+ ptr = alloc.result;
+ TRACE( "got mem in free area %p-%p\n", ptr, (char *)ptr + size );
goto done;
}
@@ -1956,6 +1943,12 @@ static int CDECL alloc_virtual_heap( void *base, SIZE_T size, void *arg )
return (alloc->base != (void *)-1);
}
+static int remove_reserved_area_from_free( void *base, size_t size, void *arg )
+{
+ wine_mmap_remove_free_area(base, size, 0);
+ return 0;
+}
+
/***********************************************************************
* virtual_init
*/
@@ -2021,6 +2014,9 @@ void virtual_init(void)
size = (char *)address_space_start - (char *)0x10000;
if (size && unix_funcs->mmap_is_in_reserved_area( (void*)0x10000, size ) == 1)
wine_anon_mmap( (void *)0x10000, size, PROT_READ | PROT_WRITE, MAP_FIXED );
+
+ wine_mmap_add_free_area(address_space_start, (char *)user_space_limit - (char *)address_space_start);
+ wine_mmap_enum_reserved_areas( remove_reserved_area_from_free, NULL, 0);
}
@@ -2792,6 +2788,9 @@ void virtual_set_large_address_space(void)
/* no large address space on win9x */
if (NtCurrentTeb()->Peb->OSPlatformId != VER_PLATFORM_WIN32_NT) return;
+ if (address_space_limit > user_space_limit)
+ wine_mmap_add_free_area(user_space_limit, (char *)address_space_limit - (char *)user_space_limit);
+
user_space_limit = working_set_limit = address_space_limit;
}
--
2.26.2

View File

@ -1,3 +1,3 @@
Fixes: [48175] AION (64 bit) - crashes in crysystem.dll.CryFree() due to high memory pointers allocated
Fixes: [46568] 64-bit msxml6.dll from Microsoft Core XML Services 6.0 redist package fails to load (Wine doesn't respect 44-bit user-mode VA limitation from Windows < 8.1)
Disabled: true

View File

@ -1,4 +1,4 @@
From 70785e15d5f0344c186714e859595b667dc34a07 Mon Sep 17 00:00:00 2001
From bc7e6ddf9534dd8afced865788a3d6ce8d068a47 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 28 May 2017 11:17:26 +0200
Subject: [PATCH] ntdll: Resolve drive symlinks before returning section name.
@ -11,10 +11,10 @@ Subject: [PATCH] ntdll: Resolve drive symlinks before returning section name.
4 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 453568d641e..12da4316e88 100644
index 7a9de26ccb0..1062e35e009 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -2798,7 +2798,7 @@ static NTSTATUS nt_to_unix_file_name_internal( const UNICODE_STRING *nameW, ANSI
@@ -2806,7 +2806,7 @@ static NTSTATUS nt_to_unix_file_name_internal( const UNICODE_STRING *nameW, ANSI
}
/* read the contents of an NT symlink object */
@ -24,10 +24,10 @@ index 453568d641e..12da4316e88 100644
OBJECT_ATTRIBUTES attr;
UNICODE_STRING targetW;
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 427cdaad441..f92adb0c0dc 100644
index b6507599a92..b7822c54ad0 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -177,6 +177,7 @@ extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
@@ -182,6 +182,7 @@ extern NTSTATUS nt_to_unix_file_name_attr( const OBJECT_ATTRIBUTES *attr, ANSI_S
UINT disposition ) DECLSPEC_HIDDEN;
/* virtual memory */
@ -36,19 +36,19 @@ index 427cdaad441..f92adb0c0dc 100644
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/virtual.c b/dlls/ntdll/virtual.c
index fb9a1a57729..89ed3bb3f0b 100644
index cc1d6e5d6f2..3d53b92cb8e 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -188,6 +188,8 @@ static BYTE **pages_vprot;
@@ -192,6 +192,8 @@ static BYTE **pages_vprot;
static BYTE *pages_vprot;
#endif
+#define MAX_DIR_ENTRY_LEN 255 /* max length of a directory entry in chars */
+
static struct file_view *view_block_start, *view_block_end, *next_free_view;
static const size_t view_block_size = 0x100000;
static void *preload_reserve_start;
@@ -3471,12 +3473,15 @@ static NTSTATUS get_section_name( HANDLE process, LPCVOID addr,
#ifdef _WIN64
static const size_t view_block_size = 0x200000;
@@ -3713,12 +3715,15 @@ static NTSTATUS get_section_name( HANDLE process, LPCVOID addr,
MEMORY_SECTION_NAME *info,
SIZE_T len, SIZE_T *res_len )
{
@ -65,7 +65,7 @@ index fb9a1a57729..89ed3bb3f0b 100644
if (!addr || !info || !res_len) return STATUS_INVALID_PARAMETER;
@@ -3535,14 +3540,34 @@ static NTSTATUS get_section_name( HANDLE process, LPCVOID addr,
@@ -3777,14 +3782,34 @@ static NTSTATUS get_section_name( HANDLE process, LPCVOID addr,
}
found:
@ -106,10 +106,10 @@ index fb9a1a57729..89ed3bb3f0b 100644
else
status = (len < sizeof(MEMORY_SECTION_NAME)) ? STATUS_INFO_LENGTH_MISMATCH : STATUS_BUFFER_OVERFLOW;
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
index f6a7b69eca0..a8263a2f44b 100644
index 99e87db9543..3984805d2b9 100644
--- a/dlls/psapi/tests/psapi_main.c
+++ b/dlls/psapi/tests/psapi_main.c
@@ -476,7 +476,6 @@ static void test_GetMappedFileName(void)
@@ -488,7 +488,6 @@ static void test_GetMappedFileName(void)
ret = GetMappedFileNameA(GetCurrentProcess(), base, map_name, sizeof(map_name));
ok(ret, "GetMappedFileName error %d\n", GetLastError());
ok(ret > strlen(device_name), "map_name should be longer than device_name\n");
@ -117,7 +117,7 @@ index f6a7b69eca0..a8263a2f44b 100644
ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name);
SetLastError(0xdeadbeef);
@@ -489,7 +488,6 @@ todo_wine {
@@ -501,7 +500,6 @@ todo_wine {
{
ok(memcmp(map_nameW, nt_map_name, lstrlenW(map_nameW)) == 0, "map name does not start with a device name: %s\n", map_name);
WideCharToMultiByte(CP_ACP, 0, map_nameW, -1, map_name, MAX_PATH, NULL, NULL);
@ -125,7 +125,7 @@ index f6a7b69eca0..a8263a2f44b 100644
ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name);
}
@@ -502,7 +500,6 @@ todo_wine
@@ -514,7 +512,6 @@ todo_wine
{
ok(memcmp(map_nameW, nt_map_name, lstrlenW(map_nameW)) == 0, "map name does not start with a device name: %s\n", map_name);
WideCharToMultiByte(CP_ACP, 0, map_nameW, -1, map_name, MAX_PATH, NULL, NULL);
@ -133,7 +133,7 @@ index f6a7b69eca0..a8263a2f44b 100644
ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name);
}
@@ -510,7 +507,6 @@ todo_wine
@@ -522,7 +519,6 @@ todo_wine
ret = GetMappedFileNameA(GetCurrentProcess(), base + 0x2000, map_name, sizeof(map_name));
ok(ret, "GetMappedFileName error %d\n", GetLastError());
ok(ret > strlen(device_name), "map_name should be longer than device_name\n");
@ -141,7 +141,7 @@ index f6a7b69eca0..a8263a2f44b 100644
ok(memcmp(map_name, device_name, strlen(device_name)) == 0, "map name does not start with a device name: %s\n", map_name);
SetLastError(0xdeadbeef);
@@ -592,7 +588,7 @@ static void test_GetProcessImageFileName(void)
@@ -604,7 +600,7 @@ static void test_GetProcessImageFileName(void)
{
/* Windows returns 2*strlen-1 */
ok(ret >= strlen(szImgPath), "szImgPath=\"%s\" ret=%d\n", szImgPath, ret);

View File

@ -175,6 +175,7 @@ patch_enable_all ()
enable_ntdll_FileDispositionInformation="$1"
enable_ntdll_FileFsFullSizeInformation="$1"
enable_ntdll_Fix_Alignment="$1"
enable_ntdll_ForceBottomUpAlloc="$1"
enable_ntdll_HashLinks="$1"
enable_ntdll_Heap_Improvements="$1"
enable_ntdll_Hide_Wine_Exports="$1"
@ -625,6 +626,9 @@ patch_enable ()
ntdll-Fix_Alignment)
enable_ntdll_Fix_Alignment="$2"
;;
ntdll-ForceBottomUpAlloc)
enable_ntdll_ForceBottomUpAlloc="$2"
;;
ntdll-HashLinks)
enable_ntdll_HashLinks="$2"
;;
@ -3863,6 +3867,33 @@ if test "$enable_ntdll_Fix_Alignment" -eq 1; then
) >> "$patchlist"
fi
# Patchset ntdll-ForceBottomUpAlloc
# |
# | This patchset fixes the following Wine bugs:
# | * [#48175] AION (64 bit) - crashes in crysystem.dll.CryFree() due to high memory pointers allocated
# | * [#46568] 64-bit msxml6.dll from Microsoft Core XML Services 6.0 redist package fails to load (Wine doesn't respect
# | 44-bit user-mode VA limitation from Windows < 8.1)
# |
# | Modified files:
# | * dlls/ntdll/virtual.c
# |
if test "$enable_ntdll_ForceBottomUpAlloc" -eq 1; then
patch_apply ntdll-ForceBottomUpAlloc/0001-ntdll-Stop-search-on-mmap-error-in-try_map_free_area.patch
patch_apply ntdll-ForceBottomUpAlloc/0002-ntdll-Use-MAP_FIXED_NOREPLACE-flag-in-try_map_free_a.patch
patch_apply ntdll-ForceBottomUpAlloc/0003-ntdll-Force-bottom-up-allocation-order-for-64-bit-ar.patch
patch_apply ntdll-ForceBottomUpAlloc/0004-ntdll-Increase-step-after-failed-map-attempt-in-try_.patch
patch_apply ntdll-ForceBottomUpAlloc/0005-ntdll-Use-free-area-list-for-virtual-memory-allocati.patch
patch_apply ntdll-ForceBottomUpAlloc/0006-ntdll-Permanently-exclude-natively-mapped-areas-from.patch
(
printf '%s\n' '+ { "Paul Gofman", "ntdll: Stop search on mmap() error in try_map_free_area().", 1 },';
printf '%s\n' '+ { "Paul Gofman", "ntdll: Use MAP_FIXED_NOREPLACE flag in try_map_free_area() if available.", 1 },';
printf '%s\n' '+ { "Paul Gofman", "ntdll: Force bottom up allocation order for 64 bit arch unless top down is requested.", 1 },';
printf '%s\n' '+ { "Paul Gofman", "ntdll: Increase step after failed map attempt in try_map_free_area().", 1 },';
printf '%s\n' '+ { "Paul Gofman", "ntdll: Use free area list for virtual memory allocation.", 1 },';
printf '%s\n' '+ { "Paul Gofman", "ntdll: Permanently exclude natively mapped areas from free areas list.", 1 },';
) >> "$patchlist"
fi
# Patchset ntdll-HashLinks
# |
# | Modified files: