mirror of
https://github.com/wiiu-env/WUMSLoader.git
synced 2026-04-26 01:47:24 -05:00
Wipe stack before booting into the application
This commit is contained in:
parent
6170bcb5e2
commit
fa409d38b7
|
|
@ -11,6 +11,7 @@
|
||||||
#include "utils/utils.h"
|
#include "utils/utils.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include <coreinit/debug.h>
|
#include <coreinit/debug.h>
|
||||||
|
#include <coreinit/interrupts.h>
|
||||||
#include <coreinit/kernel.h>
|
#include <coreinit/kernel.h>
|
||||||
#include <coreinit/memexpheap.h>
|
#include <coreinit/memexpheap.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
@ -23,6 +24,25 @@ void CallInitHooksForModule(const std::shared_ptr<ModuleData> &curModule);
|
||||||
bool CheckModulesByDependencies(const std::vector<std::shared_ptr<ModuleData>> &loadedModules);
|
bool CheckModulesByDependencies(const std::vector<std::shared_ptr<ModuleData>> &loadedModules);
|
||||||
std::vector<std::shared_ptr<ModuleData>> OrderModulesByDependencies(const std::vector<std::shared_ptr<ModuleData>> &loadedModules);
|
std::vector<std::shared_ptr<ModuleData>> OrderModulesByDependencies(const std::vector<std::shared_ptr<ModuleData>> &loadedModules);
|
||||||
|
|
||||||
|
void wipeStack(void *stackEnd) {
|
||||||
|
volatile char current_stack_marker = 0;
|
||||||
|
volatile char *wipePtr = static_cast<volatile char *>(stackEnd) + 16;
|
||||||
|
const char *safeLimit = reinterpret_cast<char *>(reinterpret_cast<uintptr_t>(¤t_stack_marker) - 256);
|
||||||
|
|
||||||
|
if (wipePtr >= safeLimit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto state = OSDisableInterrupts();
|
||||||
|
while (const_cast<char *>(wipePtr) < safeLimit) {
|
||||||
|
*wipePtr = 0;
|
||||||
|
wipePtr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
OSRestoreInterrupts(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// We need to wrap it to make sure the main function is called AFTER our code.
|
// We need to wrap it to make sure the main function is called AFTER our code.
|
||||||
// The compiler tries to optimize this otherwise and calling the main function earlier
|
// The compiler tries to optimize this otherwise and calling the main function earlier
|
||||||
extern "C" int _start(int argc, char **argv) {
|
extern "C" int _start(int argc, char **argv) {
|
||||||
|
|
@ -44,6 +64,11 @@ extern "C" int _start(int argc, char **argv) {
|
||||||
doStart(argc, argv);
|
doStart(argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some games like TNT Racers (00050000-10142800) have parts of the games state on the stack with uninitialized fields.
|
||||||
|
// Usually the stack is completely empty when booting into a game, but our modules/plugins run on the same thread, leaving "garbage"" on the (unused) stack.
|
||||||
|
// To make sure the stack is as clean as possible, we want to clear it
|
||||||
|
wipeStack(OSGetCurrentThread()->stackEnd);
|
||||||
|
|
||||||
KernelInfo0 kernelInfo0;
|
KernelInfo0 kernelInfo0;
|
||||||
__KernelGetInfo0(&kernelInfo0, 0);
|
__KernelGetInfo0(&kernelInfo0, 0);
|
||||||
asm(
|
asm(
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ IMPORT(OSFastCond_Signal);
|
||||||
IMPORT(OSFastMutex_Unlock);
|
IMPORT(OSFastMutex_Unlock);
|
||||||
IMPORT(OSInitSpinLock);
|
IMPORT(OSInitSpinLock);
|
||||||
IMPORT(OSGetAlarmUserData);
|
IMPORT(OSGetAlarmUserData);
|
||||||
|
IMPORT(OSRestoreInterrupts);
|
||||||
|
IMPORT(OSDisableInterrupts);
|
||||||
|
|
||||||
IMPORT(FSTimeToCalendarTime);
|
IMPORT(FSTimeToCalendarTime);
|
||||||
IMPORT(FSInit);
|
IMPORT(FSInit);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user