mirror of
https://github.com/ToyB-Chan/minimal-heap.git
synced 2026-07-13 21:51:16 +02:00
added custom metadata and heapwalk function
This commit is contained in:
@@ -91,6 +91,11 @@ typedef struct _MIHP_HeapMemoryAreaHeader
|
|||||||
uint32_t Checksum; // Checksum must be the last member !
|
uint32_t Checksum; // Checksum must be the last member !
|
||||||
} MIHP_HeapMemoryAreaHeader;
|
} MIHP_HeapMemoryAreaHeader;
|
||||||
|
|
||||||
|
typedef struct _MIHP_AllocationCustomMetadata
|
||||||
|
{
|
||||||
|
uint8_t data[16];
|
||||||
|
} MIHP_AllocationCustomMetadata;
|
||||||
|
|
||||||
// This structs size must be multiple of 8
|
// This structs size must be multiple of 8
|
||||||
typedef struct _MIHP_HeapSegmentHeader
|
typedef struct _MIHP_HeapSegmentHeader
|
||||||
{
|
{
|
||||||
@@ -101,9 +106,9 @@ typedef struct _MIHP_HeapSegmentHeader
|
|||||||
struct _MIHP_HeapSegmentHeader* PreviousSegment;
|
struct _MIHP_HeapSegmentHeader* PreviousSegment;
|
||||||
struct _MIHP_HeapMemoryAreaHeader* OwningMemoryArea;
|
struct _MIHP_HeapMemoryAreaHeader* OwningMemoryArea;
|
||||||
|
|
||||||
uint8_t _padding0[16];
|
struct _MIHP_AllocationCustomMetadata CustomMetadata;
|
||||||
|
|
||||||
uint32_t Checksum; // Checksum must be the last member !
|
uint32_t Checksum; // Checksum must be the last member !
|
||||||
|
|
||||||
} MIHP_HeapSegmentHeader;
|
} MIHP_HeapSegmentHeader;
|
||||||
|
|
||||||
@@ -134,11 +139,18 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size);
|
|||||||
void* MIHP_Reallocate(MIHP_Heap* heap, void* ptr, size_t newSize);
|
void* MIHP_Reallocate(MIHP_Heap* heap, void* ptr, size_t newSize);
|
||||||
bool MIHP_Free(MIHP_Heap* heap, void* ptr);
|
bool MIHP_Free(MIHP_Heap* heap, void* ptr);
|
||||||
|
|
||||||
|
bool MIHP_SetCustomMetadata(MIHP_Heap* heap, void* ptr, MIHP_AllocationCustomMetadata metadata);
|
||||||
|
bool MIHP_GetCustomMetadata(MIHP_Heap* heap, void* ptr, MIHP_AllocationCustomMetadata* outMetadata);
|
||||||
|
|
||||||
bool MIHP_MergeHeaps(MIHP_Heap* sourceHeap, MIHP_Heap* heapToAbsorb);
|
bool MIHP_MergeHeaps(MIHP_Heap* sourceHeap, MIHP_Heap* heapToAbsorb);
|
||||||
|
|
||||||
bool MIHP_IsPointerInHeap(MIHP_Heap* heap, void* ptr);
|
bool MIHP_IsPointerInHeap(MIHP_Heap* heap, void* ptr);
|
||||||
size_t MIHP_GetPtrAllocationSize(MIHP_Heap* heap, void* ptr);
|
size_t MIHP_GetPtrAllocationSize(MIHP_Heap* heap, void* ptr);
|
||||||
void MIHP_ValidateHeap(MIHP_Heap* heap);
|
void MIHP_ValidateHeap(MIHP_Heap* heap);
|
||||||
|
|
||||||
|
typedef void(MIHP_WalkHeapCallbackFn)(const MIHP_Heap* heap, const MIHP_HeapMemoryAreaHeader* area, const MIHP_HeapSegmentHeader* segment);
|
||||||
|
|
||||||
|
bool MIHP_WalkHeap(MIHP_Heap* heap, MIHP_WalkHeapCallbackFn* callback);
|
||||||
/* */
|
/* */
|
||||||
|
|
||||||
/* Internals */
|
/* Internals */
|
||||||
|
|||||||
@@ -82,9 +82,6 @@ bool MIHP_IsHeapInitialized(const MIHP_Heap* heap)
|
|||||||
|
|
||||||
bool MIHP_UninitializeHeap(MIHP_Heap* heap, bool force)
|
bool MIHP_UninitializeHeap(MIHP_Heap* heap, bool force)
|
||||||
{
|
{
|
||||||
if (heap == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!MIHP_IsHeapInitialized(heap))
|
if (!MIHP_IsHeapInitialized(heap))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -107,7 +104,7 @@ bool MIHP_UninitializeHeap(MIHP_Heap* heap, bool force)
|
|||||||
|
|
||||||
void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
|
void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
|
||||||
{
|
{
|
||||||
if (heap == NULL)
|
if (!MIHP_IsHeapInitialized(heap))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
@@ -228,9 +225,6 @@ void* MIHP_Reallocate(MIHP_Heap* heap, void* ptr, size_t newSize)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (heap == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
return MIHP_Allocate(heap, newSize);
|
return MIHP_Allocate(heap, newSize);
|
||||||
|
|
||||||
@@ -302,12 +296,6 @@ void* MIHP_Reallocate(MIHP_Heap* heap, void* ptr, size_t newSize)
|
|||||||
|
|
||||||
bool MIHP_Free(MIHP_Heap* heap, void* ptr)
|
bool MIHP_Free(MIHP_Heap* heap, void* ptr)
|
||||||
{
|
{
|
||||||
if (heap == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (ptr == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!MIHP_IsPointerInHeap(heap, ptr))
|
if (!MIHP_IsPointerInHeap(heap, ptr))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -385,14 +373,33 @@ bool MIHP_Free(MIHP_Heap* heap, void* ptr)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MIHP_SetCustomMetadata(MIHP_Heap* heap, void* ptr, MIHP_AllocationCustomMetadata metadata)
|
||||||
|
{
|
||||||
|
if (!MIHP_IsPointerInHeap(heap, ptr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MIHP_HeapSegmentHeader* segment = MIHP_GetSegmentHeaderPtr(heap, ptr);
|
||||||
|
MIHP_ValidateHeapSegmentHeader(heap, segment);
|
||||||
|
segment->CustomMetadata = metadata;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MIHP_GetCustomMetadata(MIHP_Heap* heap, void* ptr, MIHP_AllocationCustomMetadata* outMetadata)
|
||||||
|
{
|
||||||
|
if (outMetadata == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!MIHP_IsPointerInHeap(heap, ptr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MIHP_HeapSegmentHeader* segment = MIHP_GetSegmentHeaderPtr(heap, ptr);
|
||||||
|
MIHP_ValidateHeapSegmentHeader(heap, segment);
|
||||||
|
*outMetadata = segment->CustomMetadata;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool MIHP_MergeHeaps(MIHP_Heap* sourceHeap, MIHP_Heap* heapToAbsorb)
|
bool MIHP_MergeHeaps(MIHP_Heap* sourceHeap, MIHP_Heap* heapToAbsorb)
|
||||||
{
|
{
|
||||||
if (sourceHeap == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (heapToAbsorb == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!MIHP_IsHeapInitialized(sourceHeap))
|
if (!MIHP_IsHeapInitialized(sourceHeap))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -448,7 +455,7 @@ bool MIHP_MergeHeaps(MIHP_Heap* sourceHeap, MIHP_Heap* heapToAbsorb)
|
|||||||
|
|
||||||
bool MIHP_IsPointerInHeap(MIHP_Heap* heap, void* ptr)
|
bool MIHP_IsPointerInHeap(MIHP_Heap* heap, void* ptr)
|
||||||
{
|
{
|
||||||
if (heap == NULL)
|
if (!MIHP_IsHeapInitialized(heap))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
MIHP_LockHeap(heap);
|
MIHP_LockHeap(heap);
|
||||||
@@ -492,6 +499,11 @@ size_t MIHP_GetPtrAllocationSize(MIHP_Heap* heap, void* ptr)
|
|||||||
|
|
||||||
void MIHP_ValidateHeap(MIHP_Heap* heap)
|
void MIHP_ValidateHeap(MIHP_Heap* heap)
|
||||||
{
|
{
|
||||||
|
if (!MIHP_IsHeapInitialized(heap))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MIHP_LockHeap(heap);
|
||||||
|
|
||||||
MIHP_HeapMemoryAreaHeader* nextArea = heap->FirstArea;
|
MIHP_HeapMemoryAreaHeader* nextArea = heap->FirstArea;
|
||||||
while (nextArea)
|
while (nextArea)
|
||||||
{
|
{
|
||||||
@@ -507,6 +519,37 @@ void MIHP_ValidateHeap(MIHP_Heap* heap)
|
|||||||
nextSegment = currentSegment->NextSegment;
|
nextSegment = currentSegment->NextSegment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MIHP_UnlockHeap(heap);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MIHP_WalkHeap(MIHP_Heap* heap, MIHP_WalkHeapCallbackFn* callback)
|
||||||
|
{
|
||||||
|
if (!MIHP_IsHeapInitialized(heap))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (callback == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MIHP_HeapMemoryAreaHeader* nextArea = heap->FirstArea;
|
||||||
|
while (nextArea != NULL)
|
||||||
|
{
|
||||||
|
MIHP_HeapMemoryAreaHeader* currentArea = nextArea;
|
||||||
|
MIHP_ValidateHeapMemoryAreaHeader(heap, currentArea);
|
||||||
|
nextArea = currentArea->NextArea;
|
||||||
|
|
||||||
|
MIHP_HeapSegmentHeader* nextSegment = currentArea->FirstSegment;
|
||||||
|
while (nextSegment != NULL)
|
||||||
|
{
|
||||||
|
MIHP_HeapSegmentHeader* currentSegment = nextSegment;
|
||||||
|
MIHP_ValidateHeapSegmentHeader(heap, currentSegment);
|
||||||
|
nextSegment = currentSegment->NextSegment;
|
||||||
|
|
||||||
|
callback(heap, currentArea, currentSegment);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MIHP_LockHeap(MIHP_Heap* heap)
|
void MIHP_LockHeap(MIHP_Heap* heap)
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <intrin.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#define USE_MALLOC 0
|
#define USE_MALLOC 0
|
||||||
|
|
||||||
#define MIHP_ValidateHeap(x)
|
#define MIHP_ValidateHeap(x)
|
||||||
@@ -30,6 +33,11 @@ void OnHeapCorruptionDetectedCallback(const MIHP_Heap* heap, MIHP_HeapCorruption
|
|||||||
|
|
||||||
void* myptrs[NUM_ALLOCATIONS] = { 0 };
|
void* myptrs[NUM_ALLOCATIONS] = { 0 };
|
||||||
|
|
||||||
|
void* GetThisAddress()
|
||||||
|
{
|
||||||
|
return _ReturnAddress();
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
MIHP_HeapConfig config = MIHP_MakeDefaultConfigPreset();
|
MIHP_HeapConfig config = MIHP_MakeDefaultConfigPreset();
|
||||||
@@ -51,7 +59,23 @@ int main()
|
|||||||
myptrs[i] = malloc(size);
|
myptrs[i] = malloc(size);
|
||||||
#else
|
#else
|
||||||
myptrs[i] = MIHP_Allocate(&myHeap, size);
|
myptrs[i] = MIHP_Allocate(&myHeap, size);
|
||||||
|
|
||||||
|
MIHP_AllocationCustomMetadata metadata = { 0 };
|
||||||
|
void* ptr = GetThisAddress();
|
||||||
|
memcpy(&metadata.data, &ptr, sizeof(void*));
|
||||||
|
|
||||||
|
MIHP_SetCustomMetadata(&myHeap, myptrs[i], metadata);
|
||||||
MIHP_ValidateHeap(&myHeap);
|
MIHP_ValidateHeap(&myHeap);
|
||||||
|
|
||||||
|
MIHP_AllocationCustomMetadata outMetadata = { 0 };
|
||||||
|
MIHP_GetCustomMetadata(&myHeap, myptrs[i], &outMetadata);
|
||||||
|
void* returnPtr;
|
||||||
|
|
||||||
|
memcpy(&returnPtr, &outMetadata.data, sizeof(void*));
|
||||||
|
|
||||||
|
MIHP_ASSERT(ptr == returnPtr);
|
||||||
|
|
||||||
|
__debugbreak();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user