ntdll: Add a magic parameter to NtFreeVirtualMemory() for releasing address space.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
c44218ba50
commit
669d1cce03
|
@ -3775,6 +3775,17 @@ static void init_wow64( CONTEXT *context )
|
||||||
#endif
|
#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.@)
|
* LdrInitializeThunk (NTDLL.@)
|
||||||
*
|
*
|
||||||
|
@ -3901,7 +3912,7 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
|
||||||
NtTerminateProcess( GetCurrentProcess(), status );
|
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.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.Flags & LDR_WINE_INTERNAL) unix_funcs->init_builtin_dll( wm->ldr.DllBase );
|
||||||
if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie );
|
if (wm->ldr.ActivationContext) RtlDeactivateActivationContext( 0, cookie );
|
||||||
|
|
|
@ -1895,7 +1895,6 @@ static struct unix_funcs unix_funcs =
|
||||||
ntdll_sin,
|
ntdll_sin,
|
||||||
ntdll_sqrt,
|
ntdll_sqrt,
|
||||||
ntdll_tan,
|
ntdll_tan,
|
||||||
virtual_release_address_space,
|
|
||||||
load_so_dll,
|
load_so_dll,
|
||||||
init_builtin_dll,
|
init_builtin_dll,
|
||||||
init_unix_lib,
|
init_unix_lib,
|
||||||
|
|
|
@ -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,
|
extern NTSTATUS CDECL fast_wait_cv( RTL_CONDITION_VARIABLE *variable, const void *value,
|
||||||
const LARGE_INTEGER *timeout ) DECLSPEC_HIDDEN;
|
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,
|
extern NTSTATUS CDECL unwind_builtin_dll( ULONG type, struct _DISPATCHER_CONTEXT *dispatch,
|
||||||
CONTEXT *context ) DECLSPEC_HIDDEN;
|
CONTEXT *context ) DECLSPEC_HIDDEN;
|
||||||
|
|
||||||
|
|
|
@ -580,6 +580,20 @@ static void mmap_init( const struct preload_info *preload_info )
|
||||||
#endif
|
#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
|
* add_builtin_module
|
||||||
*/
|
*/
|
||||||
|
@ -2703,17 +2717,8 @@ void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info, BOOL wow64 )
|
||||||
info->LowestUserAddress = (void *)0x10000;
|
info->LowestUserAddress = (void *)0x10000;
|
||||||
info->ActiveProcessorsAffinityMask = get_system_affinity_mask();
|
info->ActiveProcessorsAffinityMask = get_system_affinity_mask();
|
||||||
info->NumberOfProcessors = peb->NumberOfProcessors;
|
info->NumberOfProcessors = peb->NumberOfProcessors;
|
||||||
#ifdef _WIN64
|
if (wow64) info->HighestUserAddress = (char *)get_wow_user_space_limit() - 1;
|
||||||
if (wow64)
|
else info->HighestUserAddress = (char *)user_space_limit - 1;
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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.
|
* 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;
|
struct free_range range;
|
||||||
sigset_t sigset;
|
|
||||||
|
|
||||||
if (is_win64) return;
|
|
||||||
|
|
||||||
server_enter_uninterrupted_section( &virtual_mutex, &sigset );
|
|
||||||
|
|
||||||
range.base = (char *)0x82000000;
|
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)
|
if (range.limit > range.base)
|
||||||
{
|
{
|
||||||
while (mmap_enum_reserved_areas( free_reserved_memory, &range, 1 )) /* nothing */;
|
while (mmap_enum_reserved_areas( free_reserved_memory, &range, 1 )) /* nothing */;
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
/* On macOS, we still want to free some of low memory, for OpenGL resources */
|
/* On macOS, we still want to free some of low memory, for OpenGL resources */
|
||||||
range.base = (char *)0x40000000;
|
range.base = (char *)0x40000000;
|
||||||
#else
|
#else
|
||||||
range.base = NULL;
|
return;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else range.base = (char *)0x20000000;
|
||||||
range.base = (char *)0x20000000;
|
|
||||||
|
|
||||||
if (range.base)
|
range.limit = (char *)0x7f000000;
|
||||||
{
|
while (mmap_enum_reserved_areas( free_reserved_memory, &range, 0 )) /* nothing */;
|
||||||
range.limit = (char *)0x7f000000;
|
|
||||||
while (mmap_enum_reserved_areas( free_reserved_memory, &range, 0 )) /* nothing */;
|
|
||||||
}
|
|
||||||
|
|
||||||
server_leave_uninterrupted_section( &virtual_mutex, &sigset );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3884,12 +3880,16 @@ NTSTATUS WINAPI NtFreeVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T *si
|
||||||
size = ROUND_SIZE( addr, size );
|
size = ROUND_SIZE( addr, size );
|
||||||
base = ROUND_ADDR( addr, page_mask );
|
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 );
|
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;
|
status = STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
struct _DISPATCHER_CONTEXT;
|
struct _DISPATCHER_CONTEXT;
|
||||||
|
|
||||||
/* increment this when you change the function table */
|
/* increment this when you change the function table */
|
||||||
#define NTDLL_UNIXLIB_VERSION 123
|
#define NTDLL_UNIXLIB_VERSION 124
|
||||||
|
|
||||||
struct unix_funcs
|
struct unix_funcs
|
||||||
{
|
{
|
||||||
|
@ -69,9 +69,6 @@ struct unix_funcs
|
||||||
double (CDECL *sqrt)( double d );
|
double (CDECL *sqrt)( double d );
|
||||||
double (CDECL *tan)( double d );
|
double (CDECL *tan)( double d );
|
||||||
|
|
||||||
/* virtual memory functions */
|
|
||||||
void (CDECL *virtual_release_address_space)(void);
|
|
||||||
|
|
||||||
/* loader functions */
|
/* loader functions */
|
||||||
NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module );
|
NTSTATUS (CDECL *load_so_dll)( UNICODE_STRING *nt_name, void **module );
|
||||||
void (CDECL *init_builtin_dll)( void *module );
|
void (CDECL *init_builtin_dll)( void *module );
|
||||||
|
|
Loading…
Reference in New Issue