1+ #include " CThread.h"
2+ #include " globals.h"
3+ #include " logger.h"
4+
5+
16#include < coreinit/cache.h>
7+ #include < coreinit/core.h>
8+ #include < coreinit/memexpheap.h>
29#include < coreinit/memorymap.h>
310#include < kernel/kernel.h>
411
@@ -25,4 +32,92 @@ bool ReadFromPhysicalAddress(uint32_t srcPhys, uint32_t *out) {
2532 DCFlushRange ((void *) ¤tInstruction, 4 );
2633 *out = currentInstruction;
2734 return true ;
28- }
35+ }
36+
37+ bool CheckMemExpHeapBlock (MEMExpHeap *heap, MEMExpHeapBlockList *block, uint32_t tag, const char *listName, uint32_t &totalSizeOut) {
38+ MEMExpHeapBlock *prevBlock = nullptr ;
39+ for (auto *cur = block->head ; cur != nullptr ; cur = cur->next ) {
40+ if (cur->prev != prevBlock) {
41+ DEBUG_FUNCTION_LINE_ERR (" [Exp Heap Check] \" %s\" prev is invalid. expected %p actual %p" , listName, prevBlock, cur->prev );
42+
43+ return false ;
44+ }
45+ if (cur < heap->header .dataStart || cur > heap->header .dataEnd || ((uint32_t ) cur + sizeof (MEMExpHeapBlock) + cur->blockSize ) > (uint32_t ) heap->header .dataEnd ) {
46+ DEBUG_FUNCTION_LINE_ERR (" [Exp Heap Check] Block is not inside heap. block: %p size %d; heap start %p heap end %p" , cur, sizeof (MEMExpHeapBlock) + cur->blockSize , heap->header .dataStart , heap->header .dataEnd );
47+
48+ return false ;
49+ }
50+ if (cur->tag != tag) {
51+ DEBUG_FUNCTION_LINE_ERR (" [%p][%d][Exp Heap Check] Invalid block tag expected %04X, actual %04X" , &cur->tag , OSGetCoreId (), tag, cur->tag );
52+
53+ return false ;
54+ }
55+
56+ totalSizeOut = totalSizeOut + cur->blockSize + (cur->attribs >> 8 & 0x7fffff ) + sizeof (MEMExpHeapBlock);
57+ prevBlock = cur;
58+ }
59+ if (prevBlock != block->tail ) {
60+ DEBUG_FUNCTION_LINE_ERR (" [Exp Heap Check] \" %s\" tail is unexpected! expected %p, actual %p" , listName, heap->usedList .tail , prevBlock);
61+
62+ return false ;
63+ }
64+ return true ;
65+ }
66+
67+ bool CheckMemExpHeapCore (MEMExpHeap *heap) {
68+ uint32_t totalSize = 0 ;
69+ #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
70+ if (!CheckMemExpHeapBlock (heap, &heap->usedList , 0x5544 , " used" , totalSize)) {
71+ return false ;
72+ }
73+
74+ #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
75+ if (!CheckMemExpHeapBlock (heap, &heap->freeList , 0x4652 , " free" , totalSize)) {
76+ return false ;
77+ }
78+
79+ if (totalSize != (uint32_t ) heap->header .dataEnd - (uint32_t ) heap->header .dataStart ) {
80+ DEBUG_FUNCTION_LINE_ERR (" [Exp Heap Check] heap size is unexpected! expected %08X, actual %08X" , (uint32_t ) heap->header .dataEnd - (uint32_t ) heap->header .dataStart , totalSize);
81+ return false ;
82+ }
83+ return true ;
84+ }
85+
86+
87+ bool CheckMemExpHeap (MEMExpHeap *heap) {
88+
89+ OSMemoryBarrier ();
90+ if (heap->header .tag != MEM_EXPANDED_HEAP_TAG ) {
91+ DEBUG_FUNCTION_LINE_ERR (" [Exp Heap Check] Invalid heap handle. - %08X" , heap->header .tag );
92+ return false ;
93+ }
94+
95+ if (heap->header .flags & MEM_HEAP_FLAG_USE_LOCK ) {
96+ #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
97+ OSUninterruptibleSpinLock_Acquire (&(heap->header ).lock );
98+ }
99+
100+ auto result = CheckMemExpHeapCore (heap);
101+
102+ if (heap->header .flags & MEM_HEAP_FLAG_USE_LOCK ) {
103+ #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
104+ OSUninterruptibleSpinLock_Release (&(heap->header ).lock );
105+ }
106+
107+ return result;
108+ }
109+
110+
111+ static void CheckMemExpHeapJumpDataCallback (CThread *, void *) {
112+ if (gJumpHeapHandle != nullptr ) {
113+ if (!CheckMemExpHeap (reinterpret_cast <MEMExpHeap *>(gJumpHeapHandle ))) {
114+ OSFatal (" FunctionPatcherModule: Corrupted heap" );
115+ } else {
116+ DEBUG_FUNCTION_LINE_VERBOSE (" JumpData heap has no curruption. Checked on core %d" , OSGetCoreId ());
117+ }
118+ }
119+ }
120+
121+ void CheckMemExpHeapJumpData () {
122+ CThread::runOnAllCores (CheckMemExpHeapJumpDataCallback, nullptr , 0 , 16 , 0x1000 );
123+ }
0 commit comments