From 4ca954ad0b2b098372e952f4208aff99a934841c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Bernon?= Date: Mon, 13 Jun 2022 17:47:48 +0200 Subject: [PATCH] ntdll: Remove heap pointer from SUBHEAP structure. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: RĂ©mi Bernon --- dlls/ntdll/heap.c | 69 +++++++++++++++++++++-------------------------- 1 file changed, 31 insertions(+), 38 deletions(-) diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index acaf3e53bc5..40c317417ce 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -165,7 +165,7 @@ typedef struct DECLSPEC_ALIGN(ALIGNMENT) tagSUBHEAP SIZE_T block_size; SIZE_T data_size; struct list entry; - struct heap *heap; + void *user_value; struct block block; } SUBHEAP; @@ -623,10 +623,9 @@ static SUBHEAP *find_subheap( const struct heap *heap, const struct block *block } -static inline BOOL subheap_commit( SUBHEAP *subheap, const struct block *block, SIZE_T block_size ) +static inline BOOL subheap_commit( const struct heap *heap, SUBHEAP *subheap, const struct block *block, SIZE_T block_size ) { const char *end = (char *)subheap_base( subheap ) + subheap_size( subheap ), *commit_end; - struct heap *heap = subheap->heap; ULONG flags = heap->flags; SIZE_T size; void *addr; @@ -651,10 +650,9 @@ static inline BOOL subheap_commit( SUBHEAP *subheap, const struct block *block, return TRUE; } -static inline BOOL subheap_decommit( SUBHEAP *subheap, const void *commit_end ) +static inline BOOL subheap_decommit( const struct heap *heap, SUBHEAP *subheap, const void *commit_end ) { char *base = subheap_base( subheap ); - struct heap *heap = subheap->heap; SIZE_T size; void *addr; @@ -676,11 +674,10 @@ static inline BOOL subheap_decommit( SUBHEAP *subheap, const void *commit_end ) } -static void create_free_block( SUBHEAP *subheap, struct block *block, SIZE_T block_size ) +static void create_free_block( struct heap *heap, SUBHEAP *subheap, struct block *block, SIZE_T block_size ) { const char *end = (char *)block + block_size, *commit_end = subheap_commit_end( subheap ); struct entry *entry = (struct entry *)block, *list; - struct heap *heap = subheap->heap; DWORD flags = heap->flags; struct block *next; @@ -717,9 +714,8 @@ static void create_free_block( SUBHEAP *subheap, struct block *block, SIZE_T blo } -static void free_used_block( SUBHEAP *subheap, struct block *block ) +static void free_used_block( struct heap *heap, SUBHEAP *subheap, struct block *block ) { - struct heap *heap = subheap->heap; struct entry *entry; SIZE_T block_size; @@ -744,7 +740,7 @@ static void free_used_block( SUBHEAP *subheap, struct block *block ) } else entry = (struct entry *)block; - create_free_block( subheap, block, block_size ); + create_free_block( heap, subheap, block, block_size ); if (next_block( subheap, block )) return; /* not the last block */ if (block == first_block( subheap ) && subheap != &heap->subheap) @@ -760,19 +756,19 @@ static void free_used_block( SUBHEAP *subheap, struct block *block ) else if (!heap->shared) { /* keep room for a full commited block as hysteresis */ - subheap_decommit( subheap, (char *)(entry + 1) + (COMMIT_MASK + 1) ); + subheap_decommit( heap, subheap, (char *)(entry + 1) + (COMMIT_MASK + 1) ); } } -static inline void shrink_used_block( SUBHEAP *subheap, struct block *block, UINT flags, +static inline void shrink_used_block( struct heap *heap, SUBHEAP *subheap, struct block *block, UINT flags, SIZE_T old_block_size, SIZE_T block_size, SIZE_T size ) { if (old_block_size >= block_size + HEAP_MIN_BLOCK_SIZE) { block_set_size( block, flags, block_size ); block->tail_size = block_size - sizeof(*block) - size; - create_free_block( subheap, next_block( subheap, block ), old_block_size - block_size ); + create_free_block( heap, subheap, next_block( subheap, block ), old_block_size - block_size ); } else { @@ -896,9 +892,10 @@ static BOOL validate_large_arena( const struct heap *heap, const ARENA_LARGE *ar /*********************************************************************** * HEAP_CreateSubHeap */ -static SUBHEAP *HEAP_CreateSubHeap( struct heap *heap, LPVOID address, DWORD flags, +static SUBHEAP *HEAP_CreateSubHeap( struct heap **heap_ptr, LPVOID address, DWORD flags, SIZE_T commitSize, SIZE_T totalSize ) { + struct heap *heap = *heap_ptr; struct entry *pEntry; SIZE_T block_size; SUBHEAP *subheap; @@ -932,7 +929,6 @@ static SUBHEAP *HEAP_CreateSubHeap( struct heap *heap, LPVOID address, DWORD fla /* If this is a secondary subheap, insert it into list */ subheap = address; - subheap->heap = heap; subheap_set_bounds( subheap, (char *)address + commitSize, (char *)address + totalSize ); list_add_head( &heap->subheap_list, &subheap->entry ); } @@ -952,7 +948,6 @@ static SUBHEAP *HEAP_CreateSubHeap( struct heap *heap, LPVOID address, DWORD fla list_init( &heap->large_list ); subheap = &heap->subheap; - subheap->heap = heap; subheap_set_bounds( subheap, (char *)address + commitSize, (char *)address + totalSize ); list_add_head( &heap->subheap_list, &subheap->entry ); @@ -1000,8 +995,9 @@ static SUBHEAP *HEAP_CreateSubHeap( struct heap *heap, LPVOID address, DWORD fla block_size = subheap_size( subheap ) - subheap_overhead( subheap ); block_size &= ~(ALIGNMENT - 1); - create_free_block( subheap, first_block( subheap ), block_size ); + create_free_block( heap, subheap, first_block( subheap ), block_size ); + *heap_ptr = heap; return subheap; } @@ -1023,7 +1019,7 @@ static struct block *find_free_block( struct heap *heap, SIZE_T block_size, SUBH if (block_get_size( block ) >= block_size) { *subheap = find_subheap( heap, block, FALSE ); - if (!subheap_commit( *subheap, block, block_size )) return NULL; + if (!subheap_commit( heap, *subheap, block, block_size )) return NULL; list_remove( &entry->entry ); return block; } @@ -1041,7 +1037,7 @@ static struct block *find_free_block( struct heap *heap, SIZE_T block_size, SUBH total_size = sizeof(SUBHEAP) + block_size + sizeof(struct entry); if (total_size < block_size) return NULL; /* overflow */ - if ((*subheap = HEAP_CreateSubHeap( heap, NULL, heap->flags, total_size, + if ((*subheap = HEAP_CreateSubHeap( &heap, NULL, heap->flags, total_size, max( heap->grow_size, total_size ) ))) { if (heap->grow_size < 128 * 1024 * 1024) heap->grow_size *= 2; @@ -1050,7 +1046,7 @@ static struct block *find_free_block( struct heap *heap, SIZE_T block_size, SUBH { if (heap->grow_size <= total_size || heap->grow_size <= 4 * 1024 * 1024) return NULL; heap->grow_size /= 2; - *subheap = HEAP_CreateSubHeap( heap, NULL, heap->flags, total_size, + *subheap = HEAP_CreateSubHeap( &heap, NULL, heap->flags, total_size, max( heap->grow_size, total_size ) ); } @@ -1072,11 +1068,10 @@ static BOOL is_valid_free_block( const struct heap *heap, const struct block *bl return FALSE; } -static BOOL validate_free_block( const SUBHEAP *subheap, const struct block *block ) +static BOOL validate_free_block( const struct heap *heap, const SUBHEAP *subheap, const struct block *block ) { const char *err = NULL, *base = subheap_base( subheap ), *commit_end = subheap_commit_end( subheap ); const struct entry *entry = (struct entry *)block; - struct heap *heap = subheap->heap; const struct block *prev, *next; DWORD flags = heap->flags; @@ -1126,10 +1121,9 @@ static BOOL validate_free_block( const SUBHEAP *subheap, const struct block *blo } -static BOOL validate_used_block( const SUBHEAP *subheap, const struct block *block ) +static BOOL validate_used_block( const struct heap *heap, const SUBHEAP *subheap, const struct block *block ) { const char *err = NULL, *base = subheap_base( subheap ), *commit_end = subheap_commit_end( subheap ); - const struct heap *heap = subheap->heap; DWORD flags = heap->flags; const struct block *next; int i; @@ -1198,7 +1192,7 @@ static BOOL heap_validate_ptr( const struct heap *heap, const void *ptr, SUBHEAP return validate_large_arena( heap, large_arena ); } - return validate_used_block( *subheap, arena ); + return validate_used_block( heap, *subheap, arena ); } static BOOL heap_validate( const struct heap *heap ) @@ -1220,11 +1214,11 @@ static BOOL heap_validate( const struct heap *heap ) { if (block_get_flags( block ) & BLOCK_FLAG_FREE) { - if (!validate_free_block( subheap, block )) return FALSE; + if (!validate_free_block( heap, subheap, block )) return FALSE; } else { - if (!validate_used_block( subheap, block )) return FALSE; + if (!validate_used_block( heap, subheap, block )) return FALSE; } } } @@ -1372,7 +1366,7 @@ static void heap_set_debug_flags( HANDLE handle ) HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T commitSize, PVOID unknown, PRTL_HEAP_DEFINITION definition ) { - struct heap *heap; + struct heap *heap = NULL; SUBHEAP *subheap; /* Allocate the heap block */ @@ -1382,8 +1376,7 @@ HANDLE WINAPI RtlCreateHeap( ULONG flags, PVOID addr, SIZE_T totalSize, SIZE_T c if (!process_heap || !totalSize || (flags & HEAP_SHARED)) flags |= HEAP_GROWABLE; if (!totalSize) totalSize = HEAP_DEF_SIZE; - if (!(subheap = HEAP_CreateSubHeap( NULL, addr, flags, commitSize, totalSize ))) return 0; - heap = subheap->heap; + if (!(subheap = HEAP_CreateSubHeap( &heap, addr, flags, commitSize, totalSize ))) return 0; heap_set_debug_flags( heap ); @@ -1441,7 +1434,7 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE handle ) heap->pending_free = NULL; for (tmp = pending; *tmp && tmp != pending + MAX_FREE_PENDING; ++tmp) if ((subheap = find_subheap( heap, *tmp, FALSE ))) - free_used_block( subheap, *tmp ); + free_used_block( heap, subheap, *tmp ); RtlFreeHeap( handle, 0, pending ); } @@ -1478,7 +1471,7 @@ HANDLE WINAPI RtlDestroyHeap( HANDLE handle ) return 0; } -static SIZE_T heap_get_block_size( struct heap *heap, ULONG flags, SIZE_T size ) +static SIZE_T heap_get_block_size( const struct heap *heap, ULONG flags, SIZE_T size ) { static const ULONG padd_flags = HEAP_VALIDATE | HEAP_VALIDATE_ALL | HEAP_VALIDATE_PARAMS | HEAP_ADD_USER_INFO; static const ULONG check_flags = HEAP_TAIL_CHECKING_ENABLED | HEAP_FREE_CHECKING_ENABLED | HEAP_CHECKING_ENABLED; @@ -1517,7 +1510,7 @@ static NTSTATUS heap_allocate( struct heap *heap, ULONG flags, SIZE_T size, void old_block_size = block_get_size( block ); block_set_type( block, ARENA_INUSE_MAGIC ); - shrink_used_block( subheap, block, 0, old_block_size, block_size, size ); + shrink_used_block( heap, subheap, block, 0, old_block_size, block_size, size ); initialize_block( block + 1, size, flags ); mark_block_tail( block, flags ); @@ -1558,7 +1551,7 @@ static NTSTATUS heap_free( struct heap *heap, void *ptr ) if (!(block = unsafe_block_from_ptr( heap, ptr, &subheap ))) return STATUS_INVALID_PARAMETER; if (!subheap) free_large_block( heap, ptr ); - else free_used_block( subheap, block ); + else free_used_block( heap, subheap, block ); return STATUS_SUCCESS; } @@ -1621,7 +1614,7 @@ static NTSTATUS heap_reallocate( struct heap *heap, ULONG flags, void *ptr, SIZE struct entry *entry = (struct entry *)next; list_remove( &entry->entry ); old_block_size += block_get_size( next ); - if (!subheap_commit( subheap, block, block_size )) return STATUS_NO_MEMORY; + if (!subheap_commit( heap, subheap, block, block_size )) return STATUS_NO_MEMORY; } else { @@ -1631,13 +1624,13 @@ static NTSTATUS heap_reallocate( struct heap *heap, ULONG flags, void *ptr, SIZE memcpy( *ret, block + 1, old_size ); if (flags & HEAP_ZERO_MEMORY) memset( (char *)*ret + old_size, 0, size - old_size ); valgrind_notify_free( ptr ); - free_used_block( subheap, block ); + free_used_block( heap, subheap, block ); return STATUS_SUCCESS; } } valgrind_notify_resize( block + 1, old_size, size ); - shrink_used_block( subheap, block, block_get_flags( block ), old_block_size, block_size, size ); + shrink_used_block( heap, subheap, block, block_get_flags( block ), old_block_size, block_size, size ); if (size > old_size) initialize_block( (char *)(block + 1) + old_size, size - old_size, flags ); mark_block_tail( block, flags ); @@ -1739,7 +1732,7 @@ BOOLEAN WINAPI RtlUnlockHeap( HANDLE handle ) } -static NTSTATUS heap_size( struct heap *heap, const void *ptr, SIZE_T *size ) +static NTSTATUS heap_size( const struct heap *heap, const void *ptr, SIZE_T *size ) { const struct block *block; SUBHEAP *subheap;