From f289f08e49b45f8220bdf5f9624d3b8d7428f4ea Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 5 May 2024 18:48:52 +0200 Subject: [PATCH 1/2] eggExpHeap matching --- config/SOUE01/symbols.txt | 30 ++++---- configure.py | 2 +- include/egg/core/eggExpHeap.h | 7 +- include/egg/core/eggHeap.h | 20 ++--- include/rvl/MEM/mem_expHeap.h | 7 +- src/egg/core/eggExpHeap.cpp | 140 ++++++++++++++++++++++++++++++++++ 6 files changed, 177 insertions(+), 29 deletions(-) create mode 100644 src/egg/core/eggExpHeap.cpp diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 97c2c8d9..ac6ef721 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -22567,16 +22567,16 @@ fn_803CC940 = .text:0x803CC940; // type:function size:0x22C fn_803CCB70 = .text:0x803CCB70; // type:function size:0xDC fn_803CCC50 = .text:0x803CCC50; // type:function size:0xC8 fn_803CCD20 = .text:0x803CCD20; // type:function size:0x168 -fn_803CCE90 = .text:0x803CCE90; // type:function size:0xB0 -fn_803CCF40 = .text:0x803CCF40; // type:function size:0x30 -fn_803CCF70 = .text:0x803CCF70; // type:function size:0xB0 -fn_803CD020 = .text:0x803CD020; // type:function size:0x1FC -fn_803CD220 = .text:0x803CD220; // type:function size:0xC4 -fn_803CD2F0 = .text:0x803CD2F0; // type:function size:0x7C -fn_803CD370 = .text:0x803CD370; // type:function size:0xD8 -fn_803CD450 = .text:0x803CD450; // type:function size:0x58 +MEMCreateExpHeapEx = .text:0x803CCE90; // type:function size:0xB0 +MEMDestroyExpHeap = .text:0x803CCF40; // type:function size:0x30 +MEMAllocFromExpHeapEx = .text:0x803CCF70; // type:function size:0xB0 +MEMResizeForMBlockExpHeap = .text:0x803CD020; // type:function size:0x1FC +MEMFreeToExpHeap = .text:0x803CD220; // type:function size:0xC4 +MEMGetAllocatableSizeForExpHeap = .text:0x803CD2F0; // type:function size:0x7C +MEMGetAllocatableSizeForExpHeapEx = .text:0x803CD370; // type:function size:0xD8 +MEMSetGroupIdForExpHeap = .text:0x803CD450; // type:function size:0x58 fn_803CD4B0 = .text:0x803CD4B0; // type:function size:0x8 -fn_803CD4C0 = .text:0x803CD4C0; // type:function size:0xD8 +MEMAdjustExpHeap = .text:0x803CD4C0; // type:function size:0xD8 fn_803CD5A0 = .text:0x803CD5A0; // type:function size:0x84 fn_803CD630 = .text:0x803CD630; // type:function size:0x30 fn_803CD660 = .text:0x803CD660; // type:function size:0x120 @@ -26215,11 +26215,11 @@ __dt__Q23EGG7ExpHeapFv = .text:0x80495AF0; // type:function size:0x74 create__Q23EGG7ExpHeapFPvUlUs = .text:0x80495B70; // type:function size:0xB8 create__Q23EGG7ExpHeapFUlPQ23EGG4HeapUs = .text:0x80495C30; // type:function size:0xCC destroy__Q23EGG7ExpHeapFv = .text:0x80495D00; // type:function size:0x88 -alloc__Q23EGG7ExpHeapFUll = .text:0x80495D90; // type:function size:0xB8 +alloc__Q23EGG7ExpHeapFUii = .text:0x80495D90; // type:function size:0xB8 free__Q23EGG7ExpHeapFPv = .text:0x80495E50; // type:function size:0x68 -resizeForMBlock__Q23EGG7ExpHeapFPvUl = .text:0x80495EC0; // type:function size:0x8 +resizeForMBlock__Q23EGG7ExpHeapFPvUi = .text:0x80495EC0; // type:function size:0x8 getTotalFreeSize__Q23EGG7ExpHeapFv = .text:0x80495ED0; // type:function size:0x8 -getAllocatableSize__Q23EGG7ExpHeapFl = .text:0x80495EE0; // type:function size:0x8 +getAllocatableSize__Q23EGG7ExpHeapFi = .text:0x80495EE0; // type:function size:0x8 setGroupID__Q23EGG7ExpHeapFUs = .text:0x80495EF0; // type:function size:0x8 adjust__Q23EGG7ExpHeapFv = .text:0x80495F00; // type:function size:0x78 getSizeForMBlock__Q23EGG7ExpHeapFPCv = .text:0x80495F80; // type:function size:0x4 @@ -37097,9 +37097,9 @@ lbl_8056E8B8 = .data:0x8056E8B8; // type:object size:0x18 __vt__Q23EGG9Allocator = .data:0x8056E8D0; // type:object size:0x14 lbl_8056E8E8 = .data:0x8056E8E8; // type:object size:0x68 __vt__Q23EGG4Heap = .data:0x8056E950; // type:object size:0x30 -lbl_8056E980 = .data:0x8056E980; // type:object size:0x10 -lbl_8056E990 = .data:0x8056E990; // type:object size:0x10 -lbl_8056E9A0 = .data:0x8056E9A0; // type:object size:0x30 +lbl_8056E980 = .data:0x8056E980; // type:object size:0xF data:string +lbl_8056E990 = .data:0x8056E990; // type:object size:0xB data:string +__vt__Q23EGG7ExpHeap = .data:0x8056E9A0; // type:object size:0x30 lbl_8056E9D0 = .data:0x8056E9D0; // type:object size:0x30 lbl_8056EA00 = .data:0x8056EA00; // type:object size:0x30 lbl_8056EA30 = .data:0x8056EA30; // type:object size:0x10 diff --git a/configure.py b/configure.py index 6c05b404..234f5627 100644 --- a/configure.py +++ b/configure.py @@ -355,7 +355,7 @@ config.libs = [ Object(NonMatching, "egg/core/eggStream.cpp"), Object(Matching, "egg/core/eggAllocator.cpp"), Object(NonMatching, "egg/core/eggHeap.cpp"), - Object(NonMatching, "egg/core/eggExpHeap.cpp"), + Object(Matching, "egg/core/eggExpHeap.cpp"), Object(NonMatching, "egg/core/eggFrmHeap.cpp"), Object(NonMatching, "egg/core/eggAssertHeap.cpp"), Object(NonMatching, "egg/core/eggDisposer.cpp"), diff --git a/include/egg/core/eggExpHeap.h b/include/egg/core/eggExpHeap.h index 2cfc534d..69b35128 100644 --- a/include/egg/core/eggExpHeap.h +++ b/include/egg/core/eggExpHeap.h @@ -24,7 +24,12 @@ public: /* 80495b70 */ static ExpHeap *create(void *block, size_t size, u16 attr); /* 80495c30 */ static ExpHeap *create(size_t size, Heap *heap, u16 attr); /* 80495d00 */ void setGroupID(u16 groupId); - /* 80495f80 */ u32 getSizeForMBlock(const void *block); + /* 80495f80 */ static u32 getSizeForMBlock(const void *block); + + // Placement new for ::create + inline void *operator new(size_t size, void *ptr) { + return ptr; + } }; } // namespace EGG diff --git a/include/egg/core/eggHeap.h b/include/egg/core/eggHeap.h index 969fc229..8d9ce935 100644 --- a/include/egg/core/eggHeap.h +++ b/include/egg/core/eggHeap.h @@ -18,12 +18,12 @@ class Allocator; struct HeapAllocArg { void *userArg; // 00 - u32 size; // 04 - int align; // 08 - Heap *heap; // 0C heap to allocate in - int another; // 10 + u32 size; // 04 + int align; // 08 + void *ptr; // 0C the allocated ptr + Heap *heap; // 10 heap to allocate in - inline HeapAllocArg() : userArg(0), size(0), align(0), heap(nullptr) {} + inline HeapAllocArg() : userArg(0), size(0), align(0), heap(nullptr), ptr(nullptr) {} }; typedef void (*HeapAllocCallback)(HeapAllocArg *arg); @@ -37,8 +37,8 @@ typedef void (*ErrorCallback)(HeapErrorArg *); struct HeapFreeArg { void *userArg; - int arg1; - int arg2; + void *ptr; + Heap *heap; }; typedef void (*HeapFreeCallback)(HeapFreeArg *); @@ -57,14 +57,14 @@ public: // vtable at 0x0 | 8056e950 /* vt 0x08 | 804954c0 */ virtual ~Heap(); /* vt 0x0C | 00000000 */ virtual eHeapKind getHeapKind() const = 0; - /* vt 0x10 | 80495a40 */ virtual void initAllocator(Allocator *allocator, s32 align) = 0; + /* vt 0x10 | 80495a40 */ virtual void initAllocator(Allocator *allocator, s32 align); /* vt 0x14 | 00000000 */ virtual void *alloc(u32 size, s32 align) = 0; /* vt 0x18 | 00000000 */ virtual void free(void *block) = 0; /* vt 0x1C | 00000000 */ virtual void destroy() = 0; /* vt 0x20 | 00000000 */ virtual u32 resizeForMBlock(void *block, u32 size) = 0; /* vt 0x24 | 00000000 */ virtual u32 getTotalFreeSize() = 0; - /* vt 0x24 | 00000000 */ virtual u32 getAllocatableSize(s32 align) = 0; - /* vt 0x28 | 00000000 */ virtual u32 adjust() = 0; + /* vt 0x28 | 00000000 */ virtual u32 getAllocatableSize(s32 align) = 0; + /* vt 0x2C | 00000000 */ virtual u32 adjust() = 0; public: void setName(const char *name) { diff --git a/include/rvl/MEM/mem_expHeap.h b/include/rvl/MEM/mem_expHeap.h index 2a8cbe88..db3ebdc1 100644 --- a/include/rvl/MEM/mem_expHeap.h +++ b/include/rvl/MEM/mem_expHeap.h @@ -53,7 +53,9 @@ struct MEMiHeapHead *MEMDestroyExpHeap(struct MEMiHeapHead *heap); void *MEMAllocFromExpHeapEx(struct MEMiHeapHead *heap, u32 size, s32 align); u32 MEMResizeForMBlockExpHeap(struct MEMiHeapHead *heap, void *memBlock, u32 size); void MEMFreeToExpHeap(struct MEMiHeapHead *heap, void *memBlock); +u32 MEMGetAllocatableSizeForExpHeap(struct MEMiHeapHead *heap); u32 MEMGetAllocatableSizeForExpHeapEx(struct MEMiHeapHead *heap, s32 align); +void MEMSetGroupIdForExpHeap(MEMiHeapHead *mHeapHandle, u16 groupId); u32 MEMAdjustExpHeap(struct MEMiHeapHead *heap); static inline struct MEMiHeapHead *MEMCreateExpHeap(void *start, u32 size) { @@ -63,10 +65,11 @@ static inline struct MEMiHeapHead *MEMCreateExpHeap(void *start, u32 size) { static inline void *MEMAllocFromExpHeap(struct MEMiHeapHead *heap, u32 size) { return MEMAllocFromExpHeapEx(heap, size, 4); } - +// This doesn't appear to be inline in SS yet +/* static inline u32 MEMGetAllocatableSizeForExpHeap(struct MEMiHeapHead *heap) { return MEMGetAllocatableSizeForExpHeapEx(heap, 4); -} +}*/ #ifdef __cplusplus } diff --git a/src/egg/core/eggExpHeap.cpp b/src/egg/core/eggExpHeap.cpp new file mode 100644 index 00000000..97e9c9a9 --- /dev/null +++ b/src/egg/core/eggExpHeap.cpp @@ -0,0 +1,140 @@ +#include + +namespace EGG { + +/* 80495ab0 */ ExpHeap::ExpHeap(MEMiHeapHead *heapHandle): Heap(heapHandle) {} + +/* 80495af0 */ ExpHeap::~ExpHeap() { + dispose(); + MEMDestroyExpHeap(mHeapHandle); +} + +/* 80495b70 */ ExpHeap* ExpHeap::create(void *heapStart, size_t size, u16 attr) { + ExpHeap *heap = nullptr; + void *startAddr = heapStart; + void *heapEnd = ROUND_DOWN_PTR((u8*)heapStart + size, 0x04); + heapStart = ROUND_UP_PTR(heapStart, 0x04); + + + if (heapStart > heapEnd || ((u8*)heapEnd - (u8*)heapStart) < 0x38u) { + return nullptr; + } + + MEMiHeapHead *head = MEMCreateExpHeapEx(((ExpHeap*)heapStart) + 1, ((u8*)heapEnd - (u8*)heapStart) - 0x34, attr); + if (head != nullptr) { + heap = new(heapStart) ExpHeap(head); + heap->mParentBlock = startAddr; + if (sCreateCallback != nullptr) { + (sCreateCallback)(heap); + } + } + + return heap; +} + +/* 80495c30 */ ExpHeap* ExpHeap::create(size_t size, Heap *heap, u16 attr) { + ExpHeap *newHeap = nullptr; + if (heap == nullptr) { + heap = sCurrentHeap; + } + + if (size == -1) { + size = heap->getAllocatableSize(0x04); + } + + void *block = heap->alloc(size, 0x04); + if (block != nullptr) { + newHeap = ExpHeap::create(block, size, attr); + if (newHeap == nullptr) { + heap->free(block); + } + } + + return newHeap; +} + +/* 80495d00 */ void ExpHeap::destroy() { + if (sDestroyCallback != nullptr) { + sDestroyCallback(this); + } + + Heap *parentHeap = findParentHeap(); + this->~ExpHeap(); + if (parentHeap != nullptr) { + parentHeap->free(this); + } +} + +/* 80495d90 */ void *ExpHeap::alloc(u32 size, s32 align) { + if (mFlag.onBit(0)) { + #line 182 + OSError("DAME DAME\n"); + } + + void *ptr = MEMAllocFromExpHeapEx(mHeapHandle, size, align); + if (sAllocCallback != nullptr) { + HeapAllocArg arg; + arg.userArg = sAllocCallbackArg; + arg.ptr = ptr; + arg.size = size; + arg.align = align; + arg.heap = this; + (sAllocCallback)(&arg); + } + + return ptr; +} + +/* 80495e50 */ void ExpHeap::free(void *ptr) { + if (sFreeCallback != nullptr) { + HeapFreeArg arg; + arg.userArg = sFreeCallbackArg; + arg.ptr = ptr; + arg.heap = this; + (sFreeCallback)(&arg); + } + MEMFreeToExpHeap(mHeapHandle, ptr); +} + +/* 80495ec0 */ u32 ExpHeap::resizeForMBlock(void *block, u32 size) { + return MEMResizeForMBlockExpHeap(mHeapHandle, block, size); +} + +/* 80495ed0 */ u32 ExpHeap::getTotalFreeSize() { + return MEMGetAllocatableSizeForExpHeap(mHeapHandle); +} + +/* 80495ee0 */ u32 ExpHeap::getAllocatableSize(s32 align) { + return MEMGetAllocatableSizeForExpHeapEx(mHeapHandle, align); +} + +/* 80495d00 */ void ExpHeap::setGroupID(u16 groupId) { + MEMSetGroupIdForExpHeap(mHeapHandle, groupId); +} + +/* 80495f00 */ u32 ExpHeap::adjust() { + u32 adjustedSize = MEMAdjustExpHeap(mHeapHandle); + u32 totalSize = adjustedSize + 0x34; + if (totalSize > 0x34) { + Heap *parent = findParentHeap(); + if (parent != nullptr) { + parent->resizeForMBlock(mParentBlock, totalSize); + return totalSize; + } + } + return 0; +} + +// TODO marked as "idk" in Ghidra +extern "C" u32 fn_803CD4B0(const void *block); + +/* 80495f80 */ u32 ExpHeap::getSizeForMBlock(const void *block) { + return fn_803CD4B0(block); +} + +/* 80495f90 */ Heap::eHeapKind ExpHeap::getHeapKind() const { + return HEAP_KIND_EXPANDED; +} + + +} // namespace EGG From 944a5315c6735ac88e437755e7137a6d1d154135 Mon Sep 17 00:00:00 2001 From: elijah-thomas774 Date: Sun, 5 May 2024 13:07:51 -0400 Subject: [PATCH 2/2] added MEMGetSizeForMBlockExpHeap symbol --- config/SOUE01/symbols.txt | 2 +- include/rvl/MEM/mem_expHeap.h | 1 + src/egg/core/eggExpHeap.cpp | 27 +++++++++++---------------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index ac6ef721..f3114665 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -22575,7 +22575,7 @@ MEMFreeToExpHeap = .text:0x803CD220; // type:function size:0xC4 MEMGetAllocatableSizeForExpHeap = .text:0x803CD2F0; // type:function size:0x7C MEMGetAllocatableSizeForExpHeapEx = .text:0x803CD370; // type:function size:0xD8 MEMSetGroupIdForExpHeap = .text:0x803CD450; // type:function size:0x58 -fn_803CD4B0 = .text:0x803CD4B0; // type:function size:0x8 +MEMGetSizeForMBlockExpHeap = .text:0x803CD4B0; // type:function size:0x8 MEMAdjustExpHeap = .text:0x803CD4C0; // type:function size:0xD8 fn_803CD5A0 = .text:0x803CD5A0; // type:function size:0x84 fn_803CD630 = .text:0x803CD630; // type:function size:0x30 diff --git a/include/rvl/MEM/mem_expHeap.h b/include/rvl/MEM/mem_expHeap.h index db3ebdc1..bdf9e79a 100644 --- a/include/rvl/MEM/mem_expHeap.h +++ b/include/rvl/MEM/mem_expHeap.h @@ -57,6 +57,7 @@ u32 MEMGetAllocatableSizeForExpHeap(struct MEMiHeapHead *heap); u32 MEMGetAllocatableSizeForExpHeapEx(struct MEMiHeapHead *heap, s32 align); void MEMSetGroupIdForExpHeap(MEMiHeapHead *mHeapHandle, u16 groupId); u32 MEMAdjustExpHeap(struct MEMiHeapHead *heap); +u32 MEMGetSizeForMBlockExpHeap(const void *block); static inline struct MEMiHeapHead *MEMCreateExpHeap(void *start, u32 size) { return MEMCreateExpHeapEx(start, size, 0); diff --git a/src/egg/core/eggExpHeap.cpp b/src/egg/core/eggExpHeap.cpp index 97e9c9a9..4c7c72c4 100644 --- a/src/egg/core/eggExpHeap.cpp +++ b/src/egg/core/eggExpHeap.cpp @@ -2,27 +2,26 @@ namespace EGG { -/* 80495ab0 */ ExpHeap::ExpHeap(MEMiHeapHead *heapHandle): Heap(heapHandle) {} +/* 80495ab0 */ ExpHeap::ExpHeap(MEMiHeapHead *heapHandle) : Heap(heapHandle) {} /* 80495af0 */ ExpHeap::~ExpHeap() { dispose(); MEMDestroyExpHeap(mHeapHandle); } -/* 80495b70 */ ExpHeap* ExpHeap::create(void *heapStart, size_t size, u16 attr) { +/* 80495b70 */ ExpHeap *ExpHeap::create(void *heapStart, size_t size, u16 attr) { ExpHeap *heap = nullptr; void *startAddr = heapStart; - void *heapEnd = ROUND_DOWN_PTR((u8*)heapStart + size, 0x04); + void *heapEnd = ROUND_DOWN_PTR((u8 *)heapStart + size, 0x04); heapStart = ROUND_UP_PTR(heapStart, 0x04); - - if (heapStart > heapEnd || ((u8*)heapEnd - (u8*)heapStart) < 0x38u) { + if (heapStart > heapEnd || ((u8 *)heapEnd - (u8 *)heapStart) < 0x38u) { return nullptr; } - MEMiHeapHead *head = MEMCreateExpHeapEx(((ExpHeap*)heapStart) + 1, ((u8*)heapEnd - (u8*)heapStart) - 0x34, attr); + MEMiHeapHead *head = MEMCreateExpHeapEx(((ExpHeap *)heapStart) + 1, ((u8 *)heapEnd - (u8 *)heapStart) - 0x34, attr); if (head != nullptr) { - heap = new(heapStart) ExpHeap(head); + heap = new (heapStart) ExpHeap(head); heap->mParentBlock = startAddr; if (sCreateCallback != nullptr) { (sCreateCallback)(heap); @@ -32,12 +31,12 @@ namespace EGG { return heap; } -/* 80495c30 */ ExpHeap* ExpHeap::create(size_t size, Heap *heap, u16 attr) { +/* 80495c30 */ ExpHeap *ExpHeap::create(size_t size, Heap *heap, u16 attr) { ExpHeap *newHeap = nullptr; if (heap == nullptr) { heap = sCurrentHeap; } - + if (size == -1) { size = heap->getAllocatableSize(0x04); } @@ -67,7 +66,7 @@ namespace EGG { /* 80495d90 */ void *ExpHeap::alloc(u32 size, s32 align) { if (mFlag.onBit(0)) { - #line 182 +#line 182 OSError("DAME DAME\n"); } @@ -119,22 +118,18 @@ namespace EGG { Heap *parent = findParentHeap(); if (parent != nullptr) { parent->resizeForMBlock(mParentBlock, totalSize); - return totalSize; + return totalSize; } } return 0; } -// TODO marked as "idk" in Ghidra -extern "C" u32 fn_803CD4B0(const void *block); - /* 80495f80 */ u32 ExpHeap::getSizeForMBlock(const void *block) { - return fn_803CD4B0(block); + return MEMGetSizeForMBlockExpHeap(block); } /* 80495f90 */ Heap::eHeapKind ExpHeap::getHeapKind() const { return HEAP_KIND_EXPANDED; } - } // namespace EGG