[PATCH 1/6] ntdll: Use a block member in large blocks.
Rémi Bernon
wine at gitlab.winehq.org
Fri Jun 3 03:14:23 CDT 2022
From: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
dlls/kernel32/tests/heap.c | 3 ---
dlls/ntdll/heap.c | 26 +++++++++++++++++---------
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/dlls/kernel32/tests/heap.c b/dlls/kernel32/tests/heap.c
index 91f582f36de..99602bd2969 100644
--- a/dlls/kernel32/tests/heap.c
+++ b/dlls/kernel32/tests/heap.c
@@ -354,9 +354,7 @@ static void test_HeapCreate(void)
ok( !!ptrs[i], "HeapAlloc failed, error %lu\n", GetLastError() );
align |= (UINT_PTR)ptrs[i];
}
- todo_wine_if( sizeof(void *) == 8 )
ok( !(align & (8 * sizeof(void *) - 1)), "got wrong alignment\n" );
- todo_wine_if( sizeof(void *) == 8 )
ok( align & (8 * sizeof(void *)), "got wrong alignment\n" );
for (i = 0; i < ARRAY_SIZE(ptrs); ++i)
{
@@ -2228,7 +2226,6 @@ static void test_block_layout( HANDLE heap, DWORD global_flags, DWORD heap_flags
ok( !!ptr2, "HeapAlloc failed, error %lu\n", GetLastError() );
align = (UINT_PTR)ptr0 | (UINT_PTR)ptr1 | (UINT_PTR)ptr2;
- todo_wine_if( sizeof(void *) == 8 || alloc_size == 0x7efe9 )
ok( !(align & (8 * sizeof(void *) - 1)), "wrong align\n" );
expect_size = max( alloc_size, 2 * sizeof(void *) );
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c
index 0ecff6f6cba..3184ae43dab 100644
--- a/dlls/ntdll/heap.c
+++ b/dlls/ntdll/heap.c
@@ -91,6 +91,7 @@ C_ASSERT( sizeof(struct block) == 8 );
#define BLOCK_FLAG_FREE 0x00000001
#define BLOCK_FLAG_PREV_FREE 0x00000002
#define BLOCK_FLAG_FREE_LINK 0x00000003
+#define BLOCK_FLAG_LARGE 0x00000004
/* entry to link free blocks in free lists */
@@ -103,18 +104,21 @@ struct DECLSPEC_ALIGN(ALIGNMENT) entry
C_ASSERT( sizeof(struct entry) == 2 * ALIGNMENT );
-typedef struct
+typedef struct region
{
+ SIZE_T __pad[sizeof(SIZE_T) / sizeof(DWORD)];
struct list entry; /* entry in heap large blocks list */
SIZE_T data_size; /* size of user data */
SIZE_T block_size; /* total size of virtual memory block */
- DWORD pad[2]; /* padding to ensure 16-byte alignment of data */
- DWORD size; /* fields for compatibility with normal arenas */
- DWORD magic; /* these must remain at the end of the structure */
+ SIZE_T pad; /* padding to ensure 16-byte alignment of data */
+ struct block block;
} ARENA_LARGE;
+/* block must be last and aligned */
+C_ASSERT( sizeof(struct region) == offsetof(struct region, block) + sizeof(struct block) );
+C_ASSERT( sizeof(struct region) == 4 * ALIGNMENT );
+
#define ARENA_SIZE_MASK (~3)
-#define ARENA_LARGE_SIZE 0xfedcba90 /* magic value for 'size' field in large blocks */
/* Value for arena 'magic' field */
#define ARENA_INUSE_MAGIC 0x455355
@@ -800,8 +804,8 @@ static void *allocate_large_block( HEAP *heap, DWORD flags, SIZE_T size )
arena = address;
arena->data_size = size;
arena->block_size = block_size;
- arena->size = ARENA_LARGE_SIZE;
- arena->magic = ARENA_LARGE_MAGIC;
+ block_set_type( &arena->block, ARENA_LARGE_MAGIC );
+ block_set_size( &arena->block, BLOCK_FLAG_LARGE, 0 );
list_add_tail( &heap->large_list, &arena->entry );
valgrind_make_noaccess( (char *)arena + sizeof(*arena) + arena->data_size,
arena->block_size - sizeof(*arena) - arena->data_size );
@@ -875,8 +879,12 @@ static BOOL validate_large_arena( const HEAP *heap, const ARENA_LARGE *arena )
if ((ULONG_PTR)arena & COMMIT_MASK)
err = "invalid block alignment";
- else if (arena->size != ARENA_LARGE_SIZE || arena->magic != ARENA_LARGE_MAGIC)
- err = "invalid block header";
+ else if (block_get_size( &arena->block ))
+ err = "invalid block size";
+ else if (block_get_flags( &arena->block ) != BLOCK_FLAG_LARGE)
+ err = "invalid block flags";
+ else if (block_get_type( &arena->block ) != ARENA_LARGE_MAGIC)
+ err = "invalid block type";
else if (!contains( arena, arena->block_size, arena + 1, arena->data_size ))
err = "invalid block size";
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/178
More information about the wine-devel
mailing list