diff --git a/src/imports.h b/src/imports.h
index d5273d9..60ce3d9 100644
--- a/src/imports.h
+++ b/src/imports.h
@@ -57,6 +57,7 @@ IMPORT(OSCompareAndSwapAtomicEx);
IMPORT(OSCompareAndSwapAtomic);
IMPORT(OSGetThreadSpecific);
IMPORT(OSSetThreadSpecific);
+IMPORT(OSReport);
IMPORT(exit);
IMPORT(_Exit);
diff --git a/src/main.cpp b/src/main.cpp
index bbaaf45..cd37a38 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,5 +1,5 @@
/****************************************************************************
- * Copyright (C) 2018-2020 Maschell
+ * Copyright (C) 2018-2022 Maschell
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -15,6 +15,7 @@
* along with this program. If not, see .
****************************************************************************/
+#include
#include
#include
#include
@@ -43,13 +44,16 @@ std::string PayloadSelectionScreen(const std::map &pay
extern "C" void __init_wut();
extern "C" void __fini_wut();
-uint32_t memory_start = 0;
+MEMExpHeapBlock *memory_start = nullptr;
extern "C" uint32_t start_wrapper(int argc, char **argv) {
doKernelSetup();
InitFunctionPointers();
- memory_start = (uint32_t) malloc(1024);
+ // Save last entry on mem2 heap to detect leaked memory
+ MEMHeapHandle mem2_heap_handle = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2);
+ auto heap = (MEMExpHeap *) mem2_heap_handle;
+ memory_start = heap->usedList.tail;
__init_wut();
@@ -92,17 +96,21 @@ extern "C" uint32_t start_wrapper(int argc, char **argv) {
extern "C" int _start(int argc, char **argv) {
uint32_t entryPoint = start_wrapper(argc, argv);
- // Somewhere in this loader is a memory leak.
- // This is a hacky solution to free that memory.
- uint32_t head_end = (uint32_t) malloc(1024);
- MEMExpHeapBlock *curUsedBlock = (MEMExpHeapBlock *) (head_end - 0x14);
- while (curUsedBlock != 0) {
- curUsedBlock = curUsedBlock->prev;
- free(&curUsedBlock[1]);
-
- if (((uint32_t) &curUsedBlock[1]) == memory_start) {
- break;
+ MEMHeapHandle mem2_heap_handle = MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2);
+ auto heap = (MEMExpHeap *) mem2_heap_handle;
+ // free leaked memory
+ if (memory_start) {
+ int leak_count = 0;
+ while (true) {
+ MEMExpHeapBlock *memory_end = heap->usedList.tail;
+ if (memory_end == memory_start) {
+ break;
+ }
+ auto mem_ptr = &memory_end[1]; // &memory_end + sizeof(MEMExpHeapBlock);
+ free(mem_ptr);
+ leak_count++;
}
+ OSReport("Freed %d leaked memory blocks\n", leak_count);
}
int res = -1;
@@ -219,7 +227,6 @@ std::string PayloadSelectionScreen(const std::map &pay
int pos = 0;
-
OSScreenPutFontEx(SCREEN_TV, 0, pos, header.c_str());
OSScreenPutFontEx(SCREEN_DRC, 0, pos, header.c_str());
@@ -256,6 +263,9 @@ std::string PayloadSelectionScreen(const std::map &pay
OSSleepTicks(OSMillisecondsToTicks(16));
}
+
+ free(screenBuffer);
+
int i = 0;
for (auto const &[key, val] : payloads) {
if (i == selected) {
@@ -263,6 +273,5 @@ std::string PayloadSelectionScreen(const std::map &pay
}
i++;
}
- free(screenBuffer);
return "";
}
\ No newline at end of file