You've already forked pico-loader
mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-01-09 16:28:35 -08:00
101 lines
2.1 KiB
C++
101 lines
2.1 KiB
C++
#include "common.h"
|
|
#include "PatchHeap.h"
|
|
|
|
PatchHeap::PatchHeap()
|
|
: _freeBlocks(nullptr)
|
|
{
|
|
_unusedBlockPool = &_blocks[0];
|
|
for (u32 i = 0; i < _blocks.size() - 1; i++)
|
|
_blocks[i].next = &_blocks[i + 1];
|
|
_blocks[_blocks.size() - 1].next = nullptr;
|
|
}
|
|
|
|
void PatchHeap::AddFreeSpace(void* block, u32 size)
|
|
{
|
|
PatchHeapBlock* cur = _freeBlocks;
|
|
|
|
bool added = false;
|
|
while (cur)
|
|
{
|
|
if ((u8*)cur->block + cur->size == block)
|
|
{
|
|
cur->size += size;
|
|
added = true;
|
|
break;
|
|
}
|
|
else if ((u8*)block + size == cur->block)
|
|
{
|
|
cur->block = block;
|
|
cur->size += size;
|
|
added = true;
|
|
break;
|
|
}
|
|
|
|
cur = cur->next;
|
|
}
|
|
|
|
if (added)
|
|
return;
|
|
|
|
PatchHeapBlock* heapBlock = _unusedBlockPool;
|
|
_unusedBlockPool = _unusedBlockPool->next;
|
|
|
|
heapBlock->block = block;
|
|
heapBlock->size = size;
|
|
heapBlock->next = _freeBlocks;
|
|
_freeBlocks = heapBlock;
|
|
}
|
|
|
|
void* PatchHeap::Alloc(u32 size)
|
|
{
|
|
PatchHeapBlock* prev = nullptr;
|
|
PatchHeapBlock* cur = _freeBlocks;
|
|
|
|
PatchHeapBlock* bestBlock = nullptr;
|
|
PatchHeapBlock* bestBlockPrev = nullptr;
|
|
|
|
while (cur)
|
|
{
|
|
if (cur->size >= size && (!bestBlock || cur->size < bestBlock->size))
|
|
{
|
|
bestBlock = cur;
|
|
bestBlockPrev = prev;
|
|
if (bestBlock->size == size)
|
|
break;
|
|
}
|
|
|
|
prev = cur;
|
|
cur = cur->next;
|
|
}
|
|
|
|
if (!bestBlock)
|
|
{
|
|
LOG_FATAL("No space found to put patch of size 0x%x\n", size);
|
|
while (1);
|
|
return nullptr;
|
|
}
|
|
|
|
void* result = bestBlock->block;
|
|
|
|
if (bestBlock->size == size)
|
|
{
|
|
if (bestBlockPrev)
|
|
bestBlockPrev->next = bestBlock->next;
|
|
|
|
if (_freeBlocks == bestBlock)
|
|
_freeBlocks = bestBlock->next;
|
|
|
|
bestBlock->next = _unusedBlockPool;
|
|
_unusedBlockPool = bestBlock;
|
|
}
|
|
else
|
|
{
|
|
bestBlock->block = (u8*)bestBlock->block + size;
|
|
bestBlock->size -= size;
|
|
}
|
|
|
|
LOG_DEBUG("Allocated 0x%p, size = 0x%X\n", result, size);
|
|
|
|
return result;
|
|
}
|