Module: wine Branch: master Commit: 669d1cce03a42ea978faf9a4608552b2d11ef5ac URL: https://source.winehq.org/git/wine.git/?a=commit;h=669d1cce03a42ea978faf9a46...
Author: Alexandre Julliard julliard@winehq.org Date: Tue Aug 3 12:02:51 2021 +0200
ntdll: Add a magic parameter to NtFreeVirtualMemory() for releasing address space.
Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/loader.c | 13 ++++++++- dlls/ntdll/unix/loader.c | 1 - dlls/ntdll/unix/unix_private.h | 2 -- dlls/ntdll/unix/virtual.c | 66 +++++++++++++++++++++--------------------- dlls/ntdll/unixlib.h | 5 +--- 5 files changed, 46 insertions(+), 41 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 2b840a864a6..1139a228c2c 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -3775,6 +3775,17 @@ static void init_wow64( CONTEXT *context ) #endif
+/* release some address space once dlls are loaded*/ +static void release_address_space(void) +{ +#ifndef _WIN64 + void *addr = (void *)1; + SIZE_T size = 0; + + NtFreeVirtualMemory( GetCurrentProcess(), &addr, &size, MEM_RELEASE ); +#endif +} + /****************************************************************** * LdrInitializeThunk (NTDLL.@) * @@ -3901,7 +3912,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR NtTerminateProcess( GetCurrentProcess(), status ); } } - unix_funcs->virtual_release_address_space(); + release_address_space(); if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.DllBase, DLL_PROCESS_ATTACH ); if (wm->ldr.Flags & LDR_WINE_INTERNAL) unix_funcs->init_builtin_dll( wm->ldr.DllBase ); if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie ); diff --git a/dlls/ntdll/unix/loader.c b/dlls/ntdll/unix/loader.c index 0e580cd7556..bf5f8048124 100644 --- a/dlls/ntdll/unix/loader.c +++ b/dlls/ntdll/unix/loader.c @@ -1895,7 +1895,6 @@ static struct unix_funcs unix_funcs = ntdll_sin, ntdll_sqrt, ntdll_tan, - virtual_release_address_space, load_so_dll, init_builtin_dll, init_unix_lib, diff --git a/dlls/ntdll/unix/unix_private.h b/dlls/ntdll/unix/unix_private.h index 3bb763a5eda..d65807b8057 100644 --- a/dlls/ntdll/unix/unix_private.h +++ b/dlls/ntdll/unix/unix_private.h @@ -109,8 +109,6 @@ extern LONGLONG CDECL fast_RtlGetSystemTimePrecise(void) DECLSPEC_HIDDEN; extern NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value, const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
-extern void CDECL virtual_release_address_space(void) DECLSPEC_HIDDEN; - extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch, CONTEXT *context ) DECLSPEC_HIDDEN;
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index fbdbf79d9d5..cd677cd2c69 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -580,6 +580,20 @@ static void mmap_init( const struct preload_info *preload_info ) #endif }
+ +/*********************************************************************** + * get_wow_user_space_limit + */ +static void *get_wow_user_space_limit(void) +{ +#ifdef _WIN64 + if (main_image_info.ImageCharacteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) return (void *)0xc0000000; + return (void *)0x7fff0000; +#endif + return user_space_limit; +} + + /*********************************************************************** * add_builtin_module */ @@ -2703,17 +2717,8 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info, BOOL wow64 ) info->LowestUserAddress = (void *)0x10000; info->ActiveProcessorsAffinityMask = get_system_affinity_mask(); info->NumberOfProcessors = peb->NumberOfProcessors; -#ifdef _WIN64 - if (wow64) - { - if (main_image_info.ImageCharacteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) - info->HighestUserAddress = (char *)0xc0000000 - 1; - else - info->HighestUserAddress = (char *)0x7fff0000 - 1; - return; - } -#endif - info->HighestUserAddress = (char *)user_space_limit - 1; + if (wow64) info->HighestUserAddress = (char *)get_wow_user_space_limit() - 1; + else info->HighestUserAddress = (char *)user_space_limit - 1; }
@@ -3639,38 +3644,29 @@ static int CDECL free_reserved_memory( void *base, SIZE_T size, void *arg ) * * Release some address space once we have loaded and initialized the app. */ -void CDECL virtual_release_address_space(void) +static void virtual_release_address_space(void) { struct free_range range; - sigset_t sigset; - - if (is_win64) return; - - server_enter_uninterrupted_section( &virtual_mutex, &sigset );
range.base = (char *)0x82000000; - range.limit = user_space_limit; + range.limit = get_wow_user_space_limit(); + + if (range.limit > (char *)0xfffff000) return; /* 64-bit limit, nothing to do */
if (range.limit > range.base) { while (mmap_enum_reserved_areas( free_reserved_memory, &range, 1 )) /* nothing */; #ifdef __APPLE__ /* On macOS, we still want to free some of low memory, for OpenGL resources */ - range.base = (char *)0x40000000; + range.base = (char *)0x40000000; #else - range.base = NULL; + return; #endif } - else - range.base = (char *)0x20000000; + else range.base = (char *)0x20000000;
- if (range.base) - { - range.limit = (char *)0x7f000000; - while (mmap_enum_reserved_areas( free_reserved_memory, &range, 0 )) /* nothing */; - } - - server_leave_uninterrupted_section( &virtual_mutex, &sigset ); + range.limit = (char *)0x7f000000; + while (mmap_enum_reserved_areas( free_reserved_memory, &range, 0 )) /* nothing */; }
@@ -3884,12 +3880,16 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si size = ROUND_SIZE( addr, size ); base = ROUND_ADDR( addr, page_mask );
- /* avoid freeing the DOS area when a broken app passes a NULL pointer */ - if (!base) return STATUS_INVALID_PARAMETER; - server_enter_uninterrupted_section( &virtual_mutex, &sigset );
- if (!(view = find_view( base, size )) || !is_view_valloc( view )) + /* avoid freeing the DOS area when a broken app passes a NULL pointer */ + if (!base) + { + /* address 1 is magic to mean release reserved space */ + if (addr == (void *)1 && !*size_ptr && type == MEM_RELEASE) virtual_release_address_space(); + else status = STATUS_INVALID_PARAMETER; + } + else if (!(view = find_view( base, size )) || !is_view_valloc( view )) { status = STATUS_INVALID_PARAMETER; } diff --git a/dlls/ntdll/unixlib.h b/dlls/ntdll/unixlib.h index ba37297a324..8747ec5039f 100644 --- a/dlls/ntdll/unixlib.h +++ b/dlls/ntdll/unixlib.h @@ -26,7 +26,7 @@ struct _DISPATCHER_CONTEXT;
/* increment this when you change the function table */ -#define NTDLL_UNIXLIB_VERSION 123 +#define NTDLL_UNIXLIB_VERSION 124
struct unix_funcs { @@ -69,9 +69,6 @@ struct unix_funcs double (CDECL *sqrt)( double d ); double (CDECL *tan)( double d );
- /* virtual memory functions */ - void (CDECL *virtual_release_address_space)(void); - /* loader functions */ NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module ); void (CDECL *init_builtin_dll)( void *module );