made all define configs configurable in runtime per heap

This commit is contained in:
2026-06-10 01:09:36 +02:00
parent 9dd2ebaa5a
commit e17def2790
3 changed files with 119 additions and 103 deletions

View File

@@ -1,4 +1,4 @@
/* Version 1.6 */
/* Version 1.7 */
#ifndef __MINIMAL_HEAP_H__
#define __MINIMAL_HEAP_H__
@@ -11,23 +11,7 @@
#define MIHP_IMPLEMENTATION 0
#endif
#define MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_NONE 0
#define MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_MAGIC_NUMBER 1
#define MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_CHECKSUM 2
/* Defines to be configured by the library user */
#ifndef MIHP_HEAP_STRUCTURE_VALIDATION_TYPE
#define MIHP_HEAP_STRUCTURE_VALIDATION_TYPE MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_CHECKSUM
#endif
#ifndef MIHP_MIN_TRAVERSELS_BEFORE_EXPANSION
#define MIHP_MIN_TRAVERSELS_BEFORE_EXPANSION 10000
#endif
#ifndef MIHP_MIN_EXPANSION_TRAVERSEL_RATIO_INT_PERCENT
#define MIHP_MIN_EXPANSION_TRAVERSEL_RATIO_INT_PERCENT 40
#endif
#ifndef MIHP_ASSERT
#define MIHP_ASSERT(Condition) while(1) { if (Condition) break; *(volatile char*)(0x0) = 0; }
#endif
@@ -40,27 +24,42 @@
typedef void*(MIHP_PlatformReqeustMemoryFn)(const struct _MIHP_Heap* heap, size_t minRequestedSize, size_t* outActualSize);
typedef bool (MIHP_PlatformFreeMemoryFn)(const struct _MIHP_Heap* heap, void* ptr, size_t actualSize);
#define MIHP_HEAP_CORRUPTION_TYPE_MEMORY_AREA_CHECKSUM_MISMATCH 0
#define MIHP_HEAP_CORRUPTION_TYPE_SEGMENT_CHECKSUM_MISMATCH 1
#define MIHP_HEAP_CORRUPTION_TYPE_DOUBLE_FREE 2
typedef enum _MIHP_HEAP_CORRUPTION_ERROR
{
MIHP_HCE_MemoryAreaChecksumMismatch = 0,
MIHP_HCE_SegmentChecksumMismatch = 1,
MIHP_HCE_DoubleFree = 2,
};
typedef void (MIHP_OnHeapCorruptionDetectedFn)(const struct _MIHP_Heap* heap, struct _MIHP_HeapCorruptionInfo corruptionInfo);
typedef void(MIHIP_LockHeapFn)(const struct _MIHP_Heap* heap, void* heapLock);
typedef void(MIHIP_UnlockHeapFn)(const struct _MIHP_Heap* heap, void* heapLock);
typedef enum _MIHP_HeapValidationMode
{
MIHP_HVM_None = 0,
MIHP_HVM_MagicNumber = 1,
MIHP_HVM_Checksum = 2
} MIHP_HeapValidationMode;
typedef struct _MIHP_HeapConfig
{
MIHP_PlatformReqeustMemoryFn* PlatformRequestMemoryFn; // Alignment must at least be alignment of size_t, outActualSize must at least be minRequestedSize
MIHP_PlatformFreeMemoryFn* PlatformFreeMemoryFn; // Can return false if the memory cannot be freed
MIHP_OnHeapCorruptionDetectedFn* OnHeapCorruptionDetectedFn; // Can be NULL
size_t MinimalMemoryAreaSize; // Must be a multiple of AllocationAlignment
size_t MaximalMemoryAreaSize; // Must be a multiple of AllocationAlignment
size_t MinMemoryAreaSize; // Must be a multiple of AllocationAlignment
size_t MaxMemoryAreaSize; // Must be a multiple of AllocationAlignment
size_t MinTotalTraversalsBeforeHeapExpansion; // Minimal amounts of traversals during allocation before considering expanding the heap
char MinHeapTraversalPercentToExpand; // Minimal integer percent of the heap traversed before expanding the heap
size_t AllocationAlignment; // Must be power of two and at least sizeof(size_t)
char AllocationInitialValue; // Initial value the returned blocks are to be filled with
MIHP_HeapValidationMode HeapValidationMode;
void* HeapLock; // Does not need to be reentred safe, can be NULL to disable locking
MIHIP_LockHeapFn* LockHeapFn; // Can be NULL if HeapLock is NULL
MIHIP_LockHeapFn* UnlockHeapFn; // Can be NULL if HeapLock is NULL
@@ -124,6 +123,8 @@ typedef struct _MIHP_Heap
} MIHP_Heap;
/* API Interface */
MIHP_HeapConfig MIHP_MakeDefaultConfigPreset();
bool MIHP_InitializeHeap(MIHP_Heap* heap, MIHP_HeapConfig config);
bool MIHP_IsHeapInitialized(const MIHP_Heap* heap);
bool MIHP_UninitializeHeap(MIHP_Heap* heap, bool force);
@@ -158,8 +159,8 @@ MIHP_HeapSegmentHeader* MIHP_GetSegmentHeaderPtr(MIHP_Heap* heap, void* payloadP
size_t MIHP_GetHeapAlignedSize(const MIHP_Heap* heap, size_t size);
uint32_t MIHP_HashMemoryRegion(const void* data, size_t size);
uint32_t MIHP_GenerateHeapMemoryAreaChecksum(const MIHP_HeapMemoryAreaHeader* area);
uint32_t MIHP_GenerateHeapSegmentChecksum(const MIHP_HeapSegmentHeader* segment);
uint32_t MIHP_GenerateHeapMemoryAreaChecksum(const MIHP_Heap* heap, const MIHP_HeapMemoryAreaHeader* area);
uint32_t MIHP_GenerateHeapSegmentChecksum(const MIHP_Heap* heap, const MIHP_HeapSegmentHeader* segment);
void MIHP_ValidateHeapMemoryAreaHeader(const MIHP_Heap* heap, const MIHP_HeapMemoryAreaHeader* area);
void MIHP_ValidateHeapSegmentHeader(const MIHP_Heap* heap, const MIHP_HeapSegmentHeader* segment);

View File

@@ -3,6 +3,24 @@
#define MIHP_IS_PO2(Val) (Val != 0 && (Val & (Val - 1)) == 0)
MIHP_HeapConfig MIHP_MakeDefaultConfigPreset()
{
MIHP_HeapConfig cfg = { 0 };
cfg.MinMemoryAreaSize = 4096 * 32;
cfg.MaxMemoryAreaSize = 4096 * 4096 * 8;
cfg.MinTotalTraversalsBeforeHeapExpansion = 10'000;
cfg.MinHeapTraversalPercentToExpand = 80;
cfg.AllocationAlignment = 16;
cfg.AllocationInitialValue = 0xbe;
cfg.HeapValidationMode = MIHP_HVM_MagicNumber;
return cfg;
}
bool MIHP_InitializeHeap(MIHP_Heap* heap, MIHP_HeapConfig config)
{
if (heap == NULL)
@@ -17,16 +35,22 @@ bool MIHP_InitializeHeap(MIHP_Heap* heap, MIHP_HeapConfig config)
if (config.PlatformFreeMemoryFn == NULL)
return false;
if (config.MinTotalTraversalsBeforeHeapExpansion < 10)
return false;
if (config.MinHeapTraversalPercentToExpand > 100)
return false;
if (config.AllocationAlignment < sizeof(size_t))
return false;
if (!MIHP_IS_PO2(config.AllocationAlignment))
return false;
if (config.MinimalMemoryAreaSize % config.AllocationAlignment != 0)
if (config.MinMemoryAreaSize % config.AllocationAlignment != 0)
return false;
if (config.MaximalMemoryAreaSize % config.AllocationAlignment != 0)
if (config.MaxMemoryAreaSize % config.AllocationAlignment != 0)
return false;
if (config.HeapLock != NULL)
@@ -41,10 +65,10 @@ bool MIHP_InitializeHeap(MIHP_Heap* heap, MIHP_HeapConfig config)
MIHP_MEMSET(heap, sizeof(MIHP_Heap), 0);
heap->Config = config;
heap->FirstArea = MIHP_CreateHeapMemoryArea(heap, config.MinimalMemoryAreaSize);
heap->FirstArea = MIHP_CreateHeapMemoryArea(heap, config.MinMemoryAreaSize);
heap->LastSuccessfulAllocationArea = heap->FirstArea;
heap->FirstArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap->FirstArea);
heap->FirstArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, heap->FirstArea);
return heap;
}
@@ -89,7 +113,7 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
if (size == 0)
return NULL;
if (size > heap->Config.MaximalMemoryAreaSize)
if (size > heap->Config.MaxMemoryAreaSize)
return NULL;
MIHP_LockHeap(heap);
@@ -108,14 +132,14 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
if (currentArea->NumOccupiedSegments == currentArea->NumSegments)
continue;
size_t numTraversalsPerArea = MIHP_MAX(100, MIHP_MIN_TRAVERSELS_BEFORE_EXPANSION * currentArea->NumSegments) / heap->Stats.NumTotalSegments;
size_t numTraversalsPerArea = MIHP_MAX(100, heap->Config.MinTotalTraversalsBeforeHeapExpansion * currentArea->NumSegments) / heap->Stats.NumTotalSegments;
size_t numTraversedAreaSegments = 0;
MIHP_HeapSegmentHeader* nextSegment = currentArea->FirstSegment;
while (nextSegment)
{
if (numTraversedAreaSegments > numTraversalsPerArea)
if (numTraversedAreaSegments * 100 > currentArea->NumSegments * MIHP_MIN_EXPANSION_TRAVERSEL_RATIO_INT_PERCENT)
if (numTraversedAreaSegments * 100 > currentArea->NumSegments * heap->Config.MinHeapTraversalPercentToExpand)
break;
numTraversedAreaSegments++;
@@ -138,10 +162,10 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
continue;
targetSegment->OccupiedSize = size;
targetSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(targetSegment);
targetSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, targetSegment);
currentArea->NumOccupiedSegments++;
currentArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(currentArea);
currentArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, currentArea);
heap->Stats.NumTotalOccupiedSegments++;
heap->LastSuccessfulAllocationArea = currentArea;
@@ -160,7 +184,7 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
size_t newAreaSize = heap->Stats.TotalSize;
while (newAreaSize < size)
newAreaSize = MIHP_MIN(heap->Config.MaximalMemoryAreaSize, newAreaSize * 2);
newAreaSize = MIHP_MIN(heap->Config.MaxMemoryAreaSize, newAreaSize * 2);
MIHP_HeapMemoryAreaHeader* newArea = MIHP_CreateHeapMemoryArea(heap, newAreaSize);
if (newArea == NULL)
@@ -171,11 +195,11 @@ void* MIHP_Allocate(MIHP_Heap* heap, size_t size)
newArea->NextArea = heap->FirstArea;
heap->FirstArea->PreviousArea = newArea;
heap->FirstArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap->FirstArea);
heap->FirstArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, heap->FirstArea);
heap->FirstArea = newArea;
heap->LastSuccessfulAllocationArea = newArea;
newArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(newArea);
newArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, newArea);
MIHP_UnlockHeap(heap);
return MIHP_Allocate(heap, size);
@@ -211,7 +235,7 @@ void* MIHP_Reallocate(MIHP_Heap* heap, void* ptr, size_t newSize)
{
MIHP_MEMSET((char*)ptr + segment->OccupiedSize, newSize - segment->OccupiedSize, heap->Config.AllocationInitialValue);
segment->OccupiedSize = newSize;
segment->Checksum = MIHP_GenerateHeapSegmentChecksum(segment);
segment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, segment);
MIHP_UnlockHeap(heap);
return ptr;
@@ -238,7 +262,7 @@ void* MIHP_Reallocate(MIHP_Heap* heap, void* ptr, size_t newSize)
else if (newSize < segment->OccupiedSize)
{
segment->OccupiedSize = newSize;
segment->Checksum = MIHP_GenerateHeapSegmentChecksum(segment);
segment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, segment);
size_t alignedNewSize = MIHP_GetHeapAlignedSize(heap, newSize);
if (segment->SegmentSize > 2 * segmentHeaderSize + alignedNewSize + MIHP_GetMinimalPayloadSize(heap))
@@ -281,7 +305,7 @@ bool MIHP_Free(MIHP_Heap* heap, void* ptr)
if (segment->OccupiedSize == 0)
{
MIHP_HeapCorruptionInfo corruptionInfo = {0};
corruptionInfo.Type = MIHP_HEAP_CORRUPTION_TYPE_DOUBLE_FREE;
corruptionInfo.Type = MIHP_HCE_DoubleFree;
corruptionInfo.Ptr = ptr;
if (heap->Config.OnHeapCorruptionDetectedFn != NULL)
@@ -290,10 +314,10 @@ bool MIHP_Free(MIHP_Heap* heap, void* ptr)
}
segment->OccupiedSize = 0;
segment->Checksum = MIHP_GenerateHeapSegmentChecksum(segment);
segment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, segment);
area->NumOccupiedSegments--;
area->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(area);
area->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, area);
heap->Stats.NumTotalOccupiedSegments--;
@@ -308,14 +332,14 @@ bool MIHP_Free(MIHP_Heap* heap, void* ptr)
{
MIHP_ValidateHeapMemoryAreaHeader(heap, prevArea);
prevArea->NextArea = nextArea;
prevArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(prevArea);
prevArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, prevArea);
}
if (nextArea)
{
MIHP_ValidateHeapMemoryAreaHeader(heap, nextArea);
nextArea->PreviousArea = prevArea;
nextArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(nextArea);
nextArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, nextArea);
}
if (heap->FirstArea == area)
@@ -367,10 +391,13 @@ bool MIHP_MergeHeaps(MIHP_Heap* sourceHeap, MIHP_Heap* heapToAbsorb)
if (sourceHeap->Config.AllocationAlignment != heapToAbsorb->Config.AllocationAlignment)
return false;
if (sourceHeap->Config.MinimalMemoryAreaSize > heapToAbsorb->Config.MinimalMemoryAreaSize)
if (sourceHeap->Config.MinMemoryAreaSize > heapToAbsorb->Config.MinMemoryAreaSize)
return false;
if (sourceHeap->Config.MaximalMemoryAreaSize < heapToAbsorb->Config.MaximalMemoryAreaSize)
if (sourceHeap->Config.MaxMemoryAreaSize < heapToAbsorb->Config.MaxMemoryAreaSize)
return false;
if (sourceHeap->Config.HeapValidationMode != heapToAbsorb->Config.HeapValidationMode)
return false;
MIHP_LockHeap(sourceHeap);
@@ -399,8 +426,8 @@ bool MIHP_MergeHeaps(MIHP_Heap* sourceHeap, MIHP_Heap* heapToAbsorb)
MIHP_UnlockHeap(heapToAbsorb);
MIHP_MEMSET(heapToAbsorb, sizeof(MIHP_Heap), 0);
sourceEndArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(sourceEndArea);
sourceEndArea->NextArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(sourceEndArea->NextArea);
sourceEndArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(sourceHeap, sourceEndArea);
sourceEndArea->NextArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(sourceHeap, sourceEndArea->NextArea);
MIHP_UnlockHeap(sourceHeap);
return true;
}
@@ -484,9 +511,9 @@ MIHP_HeapMemoryAreaHeader* MIHP_CreateHeapMemoryArea(MIHP_Heap* heap, size_t req
{
MIHP_ASSERT(heap);
size_t effectiveSize = ((requestedSize + heap->Config.MinimalMemoryAreaSize - 1) / heap->Config.MinimalMemoryAreaSize) * heap->Config.MinimalMemoryAreaSize;
effectiveSize = MIHP_MAX(effectiveSize, heap->Config.MinimalMemoryAreaSize);
effectiveSize = MIHP_MIN(effectiveSize, heap->Config.MaximalMemoryAreaSize);
size_t effectiveSize = ((requestedSize + heap->Config.MinMemoryAreaSize - 1) / heap->Config.MinMemoryAreaSize) * heap->Config.MinMemoryAreaSize;
effectiveSize = MIHP_MAX(effectiveSize, heap->Config.MinMemoryAreaSize);
effectiveSize = MIHP_MIN(effectiveSize, heap->Config.MaxMemoryAreaSize);
size_t actualSize = 0;
MIHP_HeapMemoryAreaHeader* area = (MIHP_HeapMemoryAreaHeader*)heap->Config.PlatformRequestMemoryFn(heap, effectiveSize, &actualSize);
@@ -502,7 +529,7 @@ MIHP_HeapMemoryAreaHeader* MIHP_CreateHeapMemoryArea(MIHP_Heap* heap, size_t req
size_t headerSize = MIHP_GetHeapAlignedSize(heap, sizeof(MIHP_HeapMemoryAreaHeader));
area->FirstSegment = MIHP_InitializeHeapSegment(heap, area, (char*)area + headerSize, area->AreaSize - headerSize);
area->FirstSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(area->FirstSegment);
area->FirstSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, area->FirstSegment);
heap->Stats.NumMemoryAreas++;
heap->Stats.TotalSize += area->AreaSize;
@@ -544,7 +571,7 @@ MIHP_HeapSegmentHeader* MIHP_InitializeHeapSegment(MIHP_Heap* heap, MIHP_HeapMem
segment->Checksum = ~0;
area->NumSegments++;
area->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(area);
area->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, area);
heap->Stats.NumTotalSegments++;
@@ -559,7 +586,7 @@ bool MIHP_UninitializeHeapSegment(MIHP_Heap* heap, MIHP_HeapSegmentHeader* segme
return false;
segment->OwningMemoryArea->NumSegments--;
segment->OwningMemoryArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(segment->OwningMemoryArea);
segment->OwningMemoryArea->Checksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, segment->OwningMemoryArea);
heap->Stats.NumTotalSegments--;
MIHP_MEMSET(segment, sizeof(MIHP_HeapSegmentHeader), 0);
@@ -592,13 +619,13 @@ bool MIHP_SplitHeapSegment(MIHP_Heap* heap, MIHP_HeapSegmentHeader* sourceSegmen
{
MIHP_ValidateHeapSegmentHeader(heap, sourceSegment->NextSegment);
sourceSegment->NextSegment->PreviousSegment = newSegment;
sourceSegment->NextSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(sourceSegment->NextSegment);
sourceSegment->NextSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, sourceSegment->NextSegment);
}
sourceSegment->NextSegment = newSegment;
newSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(newSegment);
sourceSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(sourceSegment);
newSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, newSegment);
sourceSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, sourceSegment);
*outNewSegment = newSegment;
return true;
@@ -619,13 +646,13 @@ bool MIHP_MergeHeapSegments(MIHP_Heap* heap, MIHP_HeapSegmentHeader* sourceSegme
{
MIHP_ValidateHeapSegmentHeader(heap, sourceSegment->NextSegment);
sourceSegment->NextSegment->PreviousSegment = sourceSegment;
sourceSegment->NextSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(sourceSegment->NextSegment);
sourceSegment->NextSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, sourceSegment->NextSegment);
}
sourceSegment->SegmentSize += segmentToAbsorb->SegmentSize;
MIHP_UninitializeHeapSegment(heap, segmentToAbsorb);
sourceSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(sourceSegment);
sourceSegment->Checksum = MIHP_GenerateHeapSegmentChecksum(heap, sourceSegment);
return true;
}
@@ -664,43 +691,34 @@ uint32_t MIHP_HashMemoryRegion(const void* data, size_t size)
return hash;
}
uint32_t MIHP_GenerateHeapMemoryAreaChecksum(const MIHP_HeapMemoryAreaHeader* area)
uint32_t MIHP_GenerateHeapMemoryAreaChecksum(const MIHP_Heap* heap, const MIHP_HeapMemoryAreaHeader* area)
{
if (heap->Config.HeapValidationMode == MIHP_HVM_None)
return 0;
#if MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_NONE
return 0;
#elif MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_MAGIC_NUMBER
return 0xAADEADAA;
#elif MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_CHECKSUM
if (heap->Config.HeapValidationMode == MIHP_HVM_MagicNumber)
return 0xAADEADAA;
MIHP_ASSERT(area);
// Do not include the checksum itself into the new checksum
size_t size = offsetof(MIHP_HeapMemoryAreaHeader, Checksum);
return MIHP_HashMemoryRegion(area, size);
#else
#error "Invalid heap structure validation type"
#endif
}
uint32_t MIHP_GenerateHeapSegmentChecksum(const MIHP_HeapSegmentHeader* segment)
uint32_t MIHP_GenerateHeapSegmentChecksum(const MIHP_Heap* heap, const MIHP_HeapSegmentHeader* segment)
{
#if MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_NONE
return 0;
#elif MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_MAGIC_NUMBER
return 0x55DEAD55;
#elif MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_CHECKSUM
if (heap->Config.HeapValidationMode == MIHP_HVM_None)
return 0;
if (heap->Config.HeapValidationMode == MIHP_HVM_MagicNumber)
return 0x55DEAD55;
MIHP_ASSERT(segment);
// Do not include the checksum itself into the new checksum
size_t size = offsetof(MIHP_HeapSegmentHeader, Checksum);
return MIHP_HashMemoryRegion(segment, size);
#else
#error "Invalid heap structure validation type"
#endif
}
void MIHP_ValidateHeapMemoryAreaHeader(const MIHP_Heap* heap, const MIHP_HeapMemoryAreaHeader* area)
@@ -710,20 +728,20 @@ void MIHP_ValidateHeapMemoryAreaHeader(const MIHP_Heap* heap, const MIHP_HeapMem
uint32_t newChecksum;
#if MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_NONE
return;
#elif MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_MAGIC_NUMBER
newChecksum = 0xAADEADAA;
#elif MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_CHECKSUM
newChecksum = MIHP_GenerateHeapMemoryAreaChecksum(area);
#else
#error "Invalid heap structure validation type"
#endif
if (heap->Config.HeapValidationMode == MIHP_HVM_None)
return;
if (heap->Config.HeapValidationMode == MIHP_HVM_MagicNumber)
newChecksum = 0xAADEADAA;
else if (heap->Config.HeapValidationMode == MIHP_HVM_Checksum)
newChecksum = MIHP_GenerateHeapMemoryAreaChecksum(heap, area);
else
MIHP_ASSERT(false);
if (area->Checksum != newChecksum)
{
MIHP_HeapCorruptionInfo corruptionInfo;
corruptionInfo.Type = MIHP_HEAP_CORRUPTION_TYPE_MEMORY_AREA_CHECKSUM_MISMATCH;
corruptionInfo.Type = MIHP_HCE_MemoryAreaChecksumMismatch;
corruptionInfo.Ptr = area;
corruptionInfo.ExpectedValue = area->Checksum;
corruptionInfo.ActualValue = newChecksum;
@@ -739,20 +757,20 @@ void MIHP_ValidateHeapSegmentHeader(const MIHP_Heap* heap, const MIHP_HeapSegmen
uint32_t newChecksum;
#if MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_NONE
return;
#elif MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_MAGIC_NUMBER
newChecksum = 0x55DEAD55;
#elif MIHP_HEAP_STRUCTURE_VALIDATION_TYPE == MIHP_HEAP_STRUCTURE_VALIDATION_TYPE_CHECKSUM
newChecksum = MIHP_GenerateHeapSegmentChecksum(segment);
#else
#error "Invalid heap structure validation type"
#endif
if (heap->Config.HeapValidationMode == MIHP_HVM_None)
return;
if (heap->Config.HeapValidationMode == MIHP_HVM_MagicNumber)
newChecksum = 0x55DEAD55;
else if (heap->Config.HeapValidationMode == MIHP_HVM_Checksum)
newChecksum = MIHP_GenerateHeapSegmentChecksum(heap, segment);
else
MIHP_ASSERT(false);
if (segment->Checksum != newChecksum)
{
MIHP_HeapCorruptionInfo corruptionInfo;
corruptionInfo.Type = MIHP_HEAP_CORRUPTION_TYPE_SEGMENT_CHECKSUM_MISMATCH;
corruptionInfo.Type = MIHP_HCE_SegmentChecksumMismatch;
corruptionInfo.Ptr = segment;
corruptionInfo.ExpectedValue = segment->Checksum;
corruptionInfo.ActualValue = newChecksum;

View File

@@ -32,16 +32,13 @@ void* myptrs[NUM_ALLOCATIONS] = { 0 };
int main()
{
MIHP_HeapConfig config = {0};
MIHP_HeapConfig config = MIHP_MakeDefaultConfigPreset();
config.PlatformRequestMemoryFn = RequestMemory;
config.PlatformFreeMemoryFn = FreeMemory;
config.OnHeapCorruptionDetectedFn = OnHeapCorruptionDetectedCallback;
config.AllocationInitialValue = 0xbe;
config.AllocationAlignment = 16;
config.MinimalMemoryAreaSize = 4096 * 32;
config.MaximalMemoryAreaSize = 4096ull * 4096ull * 4096ull;
config.HeapValidationMode = MIHP_HVM_None;
MIHP_Heap myHeap = { 0 };
MIHP_InitializeHeap(&myHeap, config);