ntdll: Determine the available address space dynamically on ARM64.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56130
This commit is contained in:
parent
def5e1a61d
commit
0900d919e2
1 changed files with 44 additions and 13 deletions
|
@ -162,23 +162,18 @@ static void *address_space_start = (void *)0x110000; /* keep DOS area clear */
|
|||
#else
|
||||
static void *address_space_start = (void *)0x10000;
|
||||
#endif
|
||||
|
||||
#ifdef __aarch64__
|
||||
static void *address_space_limit = (void *)0xffffffff0000; /* top of the total available address space */
|
||||
#elif defined(_WIN64)
|
||||
static void *address_space_limit = (void *)0x7fffffff0000;
|
||||
#else
|
||||
static void *address_space_limit = (void *)0xc0000000;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN64
|
||||
static void *address_space_limit = (void *)0x7fffffff0000; /* top of the total available address space */
|
||||
static void *user_space_limit = (void *)0x7fffffff0000; /* top of the user address space */
|
||||
static void *working_set_limit = (void *)0x7fffffff0000; /* top of the current working set */
|
||||
#else
|
||||
static void *address_space_limit = (void *)0xc0000000;
|
||||
static void *user_space_limit = (void *)0x7fff0000;
|
||||
static void *working_set_limit = (void *)0x7fff0000;
|
||||
#endif
|
||||
|
||||
static void *host_addr_space_limit; /* top of the host virtual address space */
|
||||
|
||||
static struct file_view *arm64ec_view;
|
||||
|
||||
ULONG_PTR user_space_wow_limit = 0;
|
||||
|
@ -2009,6 +2004,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
|||
if (is_beyond_limit( base, size, address_space_limit )) return STATUS_WORKING_SET_LIMIT_RANGE;
|
||||
if (limit_low && base < (void *)limit_low) return STATUS_CONFLICTING_ADDRESSES;
|
||||
if (limit_high && is_beyond_limit( base, size, (void *)limit_high )) return STATUS_CONFLICTING_ADDRESSES;
|
||||
if (is_beyond_limit( base, size, host_addr_space_limit )) return STATUS_CONFLICTING_ADDRESSES;
|
||||
if ((status = map_fixed_area( base, size, vprot ))) return status;
|
||||
if (is_beyond_limit( base, size, working_set_limit )) working_set_limit = address_space_limit;
|
||||
ptr = base;
|
||||
|
@ -2016,7 +2012,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
|||
else
|
||||
{
|
||||
void *start = address_space_start;
|
||||
void *end = user_space_limit;
|
||||
void *end = min( user_space_limit, host_addr_space_limit );
|
||||
size_t view_size, unmap_size;
|
||||
|
||||
if (!align_mask) align_mask = granularity_mask;
|
||||
|
@ -2031,7 +2027,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
|
|||
goto done;
|
||||
}
|
||||
|
||||
if (start > address_space_start || end < address_space_limit || top_down)
|
||||
if (start > address_space_start || end < host_addr_space_limit || top_down)
|
||||
{
|
||||
if (!(ptr = map_free_area( start, end, size, top_down, get_unix_prot(vprot), align_mask )))
|
||||
return STATUS_NO_MEMORY;
|
||||
|
@ -2442,6 +2438,33 @@ static NTSTATUS map_pe_header( void *ptr, size_t size, int fd, BOOL *removable )
|
|||
|
||||
#ifdef __aarch64__
|
||||
|
||||
/***********************************************************************
|
||||
* get_host_addr_space_limit
|
||||
*/
|
||||
static void *get_host_addr_space_limit(void)
|
||||
{
|
||||
unsigned int flags = MAP_PRIVATE | MAP_ANON;
|
||||
UINT_PTR addr = (UINT_PTR)1 << 63;
|
||||
|
||||
#ifdef MAP_FIXED_NOREPLACE
|
||||
flags |= MAP_FIXED_NOREPLACE;
|
||||
#endif
|
||||
|
||||
while (addr >> 32)
|
||||
{
|
||||
void *ret = mmap( (void *)addr, page_size, PROT_NONE, flags, -1, 0 );
|
||||
if (ret != MAP_FAILED)
|
||||
{
|
||||
munmap( ret, page_size );
|
||||
if (ret >= (void *)addr) break;
|
||||
}
|
||||
else if (errno == EEXIST) break;
|
||||
addr >>= 1;
|
||||
}
|
||||
return (void *)((addr << 1) - (granularity_mask + 1));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* alloc_arm64ec_map
|
||||
*/
|
||||
|
@ -3223,7 +3246,8 @@ static void *alloc_virtual_heap( SIZE_T size )
|
|||
void *base = area->base;
|
||||
void *end = (char *)base + area->size;
|
||||
|
||||
if (is_beyond_limit( base, area->size, address_space_limit )) address_space_limit = end;
|
||||
if (is_beyond_limit( base, area->size, address_space_limit ))
|
||||
address_space_limit = host_addr_space_limit = end;
|
||||
if (is_win64 && base < (void *)0x80000000) break;
|
||||
if (preload_reserve_end >= end)
|
||||
{
|
||||
|
@ -3261,6 +3285,13 @@ void virtual_init(void)
|
|||
pthread_mutex_init( &virtual_mutex, &attr );
|
||||
pthread_mutexattr_destroy( &attr );
|
||||
|
||||
#ifdef __aarch64__
|
||||
host_addr_space_limit = get_host_addr_space_limit();
|
||||
TRACE( "host addr space limit: %p\n", host_addr_space_limit );
|
||||
#else
|
||||
host_addr_space_limit = address_space_limit;
|
||||
#endif
|
||||
|
||||
if (preload_info && *preload_info)
|
||||
for (i = 0; (*preload_info)[i].size; i++)
|
||||
mmap_add_reserved_area( (*preload_info)[i].addr, (*preload_info)[i].size );
|
||||
|
@ -3282,7 +3313,7 @@ void virtual_init(void)
|
|||
|
||||
/* try to find space in a reserved area for the views and pages protection table */
|
||||
#ifdef _WIN64
|
||||
pages_vprot_size = ((size_t)address_space_limit >> page_shift >> pages_vprot_shift) + 1;
|
||||
pages_vprot_size = ((size_t)host_addr_space_limit >> page_shift >> pages_vprot_shift) + 1;
|
||||
size = 2 * view_block_size + pages_vprot_size * sizeof(*pages_vprot);
|
||||
#else
|
||||
size = 2 * view_block_size + (1U << (32 - page_shift));
|
||||
|
|
Loading…
Add table
Reference in a new issue