Commit fd9792bd authored by Alexandre Julliard's avatar Alexandre Julliard

Added support for the IMAGE_FILE_LARGE_ADDRESS_AWARE flag.

parent 77b7f957
...@@ -1935,6 +1935,8 @@ void WINAPI LdrInitializeThunk( HANDLE main_file, ULONG unknown2, ULONG unknown3 ...@@ -1935,6 +1935,8 @@ void WINAPI LdrInitializeThunk( HANDLE main_file, ULONG unknown2, ULONG unknown3
if ((status = process_attach( wm, (LPVOID)1 )) != STATUS_SUCCESS) goto error; if ((status = process_attach( wm, (LPVOID)1 )) != STATUS_SUCCESS) goto error;
RtlLeaveCriticalSection( &loader_section ); RtlLeaveCriticalSection( &loader_section );
if (nt->FileHeader.Characteristics & IMAGE_FILE_LARGE_ADDRESS_AWARE) VIRTUAL_UseLargeAddressSpace();
return; return;
error: error:
......
...@@ -91,6 +91,7 @@ typedef BOOL (*HANDLERPROC)(LPVOID, LPCVOID); ...@@ -91,6 +91,7 @@ typedef BOOL (*HANDLERPROC)(LPVOID, LPCVOID);
extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, HANDLERPROC proc, LPVOID arg); extern BOOL VIRTUAL_SetFaultHandler(LPCVOID addr, HANDLERPROC proc, LPVOID arg);
extern DWORD VIRTUAL_HandleFault(LPCVOID addr); extern DWORD VIRTUAL_HandleFault(LPCVOID addr);
extern BOOL VIRTUAL_HasMapping( LPCVOID addr ); extern BOOL VIRTUAL_HasMapping( LPCVOID addr );
extern void VIRTUAL_UseLargeAddressSpace(void);
/* code pages */ /* code pages */
extern int ntdll_umbstowcs(DWORD flags, const char* src, int srclen, WCHAR* dst, int dstlen); extern int ntdll_umbstowcs(DWORD flags, const char* src, int srclen, WCHAR* dst, int dstlen);
......
...@@ -137,6 +137,8 @@ static UINT page_size; ...@@ -137,6 +137,8 @@ static UINT page_size;
#define VIRTUAL_DEBUG_DUMP_VIEW(view) \ #define VIRTUAL_DEBUG_DUMP_VIEW(view) \
if (!TRACE_ON(virtual)); else VIRTUAL_DumpView(view) if (!TRACE_ON(virtual)); else VIRTUAL_DumpView(view)
static void *user_space_limit = USER_SPACE_LIMIT;
/*********************************************************************** /***********************************************************************
* VIRTUAL_GetProtStr * VIRTUAL_GetProtStr
...@@ -258,13 +260,13 @@ static void add_reserved_area( void *addr, size_t size ) ...@@ -258,13 +260,13 @@ static void add_reserved_area( void *addr, size_t size )
{ {
TRACE( "adding %p-%p\n", addr, (char *)addr + size ); TRACE( "adding %p-%p\n", addr, (char *)addr + size );
if (addr < USER_SPACE_LIMIT) if (addr < user_space_limit)
{ {
/* unmap the part of the area that is below the limit */ /* unmap the part of the area that is below the limit */
assert( (char *)addr + size > (char *)USER_SPACE_LIMIT ); assert( (char *)addr + size > (char *)user_space_limit );
munmap( addr, (char *)USER_SPACE_LIMIT - (char *)addr ); munmap( addr, (char *)user_space_limit - (char *)addr );
size -= (char *)USER_SPACE_LIMIT - (char *)addr; size -= (char *)user_space_limit - (char *)addr;
addr = USER_SPACE_LIMIT; addr = user_space_limit;
} }
/* blow away existing mappings */ /* blow away existing mappings */
wine_anon_mmap( addr, size, PROT_NONE, MAP_NORESERVE | MAP_FIXED ); wine_anon_mmap( addr, size, PROT_NONE, MAP_NORESERVE | MAP_FIXED );
...@@ -273,6 +275,47 @@ static void add_reserved_area( void *addr, size_t size ) ...@@ -273,6 +275,47 @@ static void add_reserved_area( void *addr, size_t size )
/*********************************************************************** /***********************************************************************
* remove_reserved_area
*
* Remove a reserved area from the list maintained by libwine.
* The csVirtual section must be held by caller.
*/
static void remove_reserved_area( void *addr, size_t size )
{
struct list *ptr;
LIST_FOR_EACH( ptr, &views_list )
{
struct file_view *view = LIST_ENTRY( ptr, struct file_view, entry );
if ((char *)view->base >= (char *)addr + size) break;
if ((char *)view->base + view->size <= (char *)addr) continue;
/* now we have an overlapping view */
if (view->base > addr)
{
wine_mmap_remove_reserved_area( addr, (char *)view->base - (char *)addr, TRUE );
size -= (char *)view->base - (char *)addr;
addr = view->base;
}
if ((char *)view->base + view->size >= (char *)addr + size)
{
/* view covers all the remaining area */
wine_mmap_remove_reserved_area( addr, size, FALSE );
size = 0;
break;
}
else /* view covers only part of the area */
{
wine_mmap_remove_reserved_area( addr, (char *)view->base + view->size - (char *)addr, FALSE );
size -= (char *)view->base + view->size - (char *)addr;
addr = (char *)view->base + view->size;
}
}
/* remove remaining space */
if (size) wine_mmap_remove_reserved_area( addr, size, TRUE );
}
/***********************************************************************
* is_beyond_limit * is_beyond_limit
* *
* Check if an address range goes beyond a given limit. * Check if an address range goes beyond a given limit.
...@@ -536,7 +579,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, ...@@ -536,7 +579,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
if (ptr != base) if (ptr != base)
{ {
/* We couldn't get the address we wanted */ /* We couldn't get the address we wanted */
if (is_beyond_limit( ptr, size, USER_SPACE_LIMIT )) add_reserved_area( ptr, size ); if (is_beyond_limit( ptr, size, user_space_limit )) add_reserved_area( ptr, size );
else munmap( ptr, size ); else munmap( ptr, size );
return STATUS_CONFLICTING_ADDRESSES; return STATUS_CONFLICTING_ADDRESSES;
} }
...@@ -563,7 +606,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size, ...@@ -563,7 +606,7 @@ static NTSTATUS map_view( struct file_view **view_ret, void *base, size_t size,
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
/* if we got something beyond the user limit, unmap it and retry */ /* if we got something beyond the user limit, unmap it and retry */
if (is_beyond_limit( ptr, view_size, USER_SPACE_LIMIT )) add_reserved_area( ptr, view_size ); if (is_beyond_limit( ptr, view_size, user_space_limit )) add_reserved_area( ptr, view_size );
else break; else break;
} }
...@@ -1098,6 +1141,21 @@ BOOL VIRTUAL_HasMapping( LPCVOID addr ) ...@@ -1098,6 +1141,21 @@ BOOL VIRTUAL_HasMapping( LPCVOID addr )
/*********************************************************************** /***********************************************************************
* VIRTUAL_UseLargeAddressSpace
*
* Increase the address space size for apps that support it.
*/
void VIRTUAL_UseLargeAddressSpace(void)
{
if (user_space_limit >= ADDRESS_SPACE_LIMIT) return;
RtlEnterCriticalSection( &csVirtual );
remove_reserved_area( user_space_limit, (char *)ADDRESS_SPACE_LIMIT - (char *)user_space_limit );
user_space_limit = ADDRESS_SPACE_LIMIT;
RtlLeaveCriticalSection( &csVirtual );
}
/***********************************************************************
* NtAllocateVirtualMemory (NTDLL.@) * NtAllocateVirtualMemory (NTDLL.@)
* ZwAllocateVirtualMemory (NTDLL.@) * ZwAllocateVirtualMemory (NTDLL.@)
*/ */
...@@ -1379,14 +1437,14 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr, ...@@ -1379,14 +1437,14 @@ NTSTATUS WINAPI NtQueryVirtualMemory( HANDLE process, LPCVOID addr,
{ {
/* make the address space end at the user limit, except if /* make the address space end at the user limit, except if
* the last view was mapped beyond that */ * the last view was mapped beyond that */
if (alloc_base < (char *)USER_SPACE_LIMIT) if (alloc_base < (char *)user_space_limit)
{ {
if (USER_SPACE_LIMIT && base >= (char *)USER_SPACE_LIMIT) if (user_space_limit && base >= (char *)user_space_limit)
{ {
RtlLeaveCriticalSection( &csVirtual ); RtlLeaveCriticalSection( &csVirtual );
return STATUS_WORKING_SET_LIMIT_RANGE; return STATUS_WORKING_SET_LIMIT_RANGE;
} }
size = (char *)USER_SPACE_LIMIT - alloc_base; size = (char *)user_space_limit - alloc_base;
} }
else size = (char *)ADDRESS_SPACE_LIMIT - alloc_base; else size = (char *)ADDRESS_SPACE_LIMIT - alloc_base;
view = NULL; view = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment