Module: wine Branch: master Commit: 800fc4164f9d4ef4af23c2249b5c8ee92f48c673 URL: https://gitlab.winehq.org/wine/wine/-/commit/800fc4164f9d4ef4af23c2249b5c8ee...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Jun 8 13:19:51 2023 +0200
ntdll: Reimplement fill_basic_memory_info() without using a callback.
And merge reported free areas.
---
dlls/ntdll/unix/virtual.c | 93 +++++++++++++++++------------------------------ 1 file changed, 33 insertions(+), 60 deletions(-)
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 3597935fd00..6c64163b323 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -4589,50 +4589,6 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T }
-/* retrieve state for a free memory area; callback for mmap_enum_reserved_areas */ -static int get_free_mem_state_callback( void *start, SIZE_T size, void *arg ) -{ - MEMORY_BASIC_INFORMATION *info = arg; - void *end = (char *)start + size; - - if ((char *)info->BaseAddress + info->RegionSize <= (char *)start) return 0; - - if (info->BaseAddress >= end) - { - if (info->AllocationBase < end) info->AllocationBase = end; - return 0; - } - - if (info->BaseAddress >= start || start <= address_space_start) - { - /* it's a real free area */ - info->State = MEM_FREE; - info->Protect = PAGE_NOACCESS; - info->AllocationBase = 0; - info->AllocationProtect = 0; - info->Type = 0; - if ((char *)info->BaseAddress + info->RegionSize > (char *)end) - info->RegionSize = (char *)end - (char *)info->BaseAddress; - } - else /* outside of the reserved area, pretend it's allocated */ - { - info->RegionSize = (char *)start - (char *)info->BaseAddress; -#ifdef __i386__ - info->State = MEM_RESERVE; - info->Protect = PAGE_NOACCESS; - info->AllocationProtect = PAGE_NOACCESS; - info->Type = MEM_PRIVATE; -#else - info->State = MEM_FREE; - info->Protect = PAGE_NOACCESS; - info->AllocationBase = 0; - info->AllocationProtect = 0; - info->Type = 0; -#endif - } - return 1; -} - static unsigned int fill_basic_memory_info( const void *addr, MEMORY_BASIC_INFORMATION *info ) { char *base, *alloc_base = 0, *alloc_end = working_set_limit; @@ -4671,38 +4627,55 @@ static unsigned int fill_basic_memory_info( const void *addr, MEMORY_BASIC_INFOR
/* Fill the info structure */
- info->AllocationBase = alloc_base; - info->BaseAddress = base; - info->RegionSize = alloc_end - base; + info->BaseAddress = base; + info->RegionSize = alloc_end - base;
if (!ptr) { - if (!mmap_enum_reserved_areas( get_free_mem_state_callback, info, 0 )) - { - /* not in a reserved area at all, pretend it's allocated */ + info->State = MEM_FREE; + info->Protect = PAGE_NOACCESS; + info->AllocationBase = 0; + info->AllocationProtect = 0; + info->Type = 0; + #ifdef __i386__ - if (base >= (char *)address_space_start) + /* on i386, pretend that space outside of a reserved area is allocated, + * so that the app doesn't believe it's fully available */ + { + struct reserved_area *area; + + LIST_FOR_EACH_ENTRY( area, &reserved_areas, struct reserved_area, entry ) { + char *area_start = area->base; + char *area_end = (char *)area_start + area->size; + + if (area_end <= base) + { + if (alloc_base < area_end) alloc_base = area_end; + continue; + } + if (area_start <= base || area_start <= (char *)address_space_start) + { + if (area_end < alloc_end) info->RegionSize = area_end - base; + break; + } + /* pretend it's allocated */ + if (area_start < alloc_end) info->RegionSize = area_start - base; info->State = MEM_RESERVE; info->Protect = PAGE_NOACCESS; + info->AllocationBase = alloc_base; info->AllocationProtect = PAGE_NOACCESS; info->Type = MEM_PRIVATE; - } - else -#endif - { - info->State = MEM_FREE; - info->Protect = PAGE_NOACCESS; - info->AllocationBase = 0; - info->AllocationProtect = 0; - info->Type = 0; + break; } } +#endif } else { BYTE vprot;
+ info->AllocationBase = alloc_base; info->RegionSize = get_committed_size( view, base, &vprot, ~VPROT_WRITEWATCH ); info->State = (vprot & VPROT_COMMITTED) ? MEM_COMMIT : MEM_RESERVE; info->Protect = (vprot & VPROT_COMMITTED) ? get_win32_prot( vprot, view->protect ) : 0;