Load injected firmware modules at the top of user memory, not the bottom

The flash0 PRXes we swap in for our HLE took the lowest free block, which sits
right where a game's own EBOOT wants to go. That pushes the game up, shifting
every address in it - invalidating cheats and RetroAchievements - and for a game
whose EBOOT has to load at a fixed low address it fails outright: Tekken 6 wants
0x08804018 and got "block taken", so it didn't boot at all.

Give KernelLoadModule a fromTop flag and use it for the modules we inject. The
game keeps its normal load address and the firmware sits out of the way at the
top.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GgACRqkQNpfJQ4fjwyoEup
This commit is contained in:
Henrik Rydgård
2026-09-08 11:43:49 -06:00
co-authored by Claude Opus 5
parent 1fc823681f
commit c0c715ac2e
3 changed files with 8 additions and 4 deletions
+2 -2
View File
@@ -1921,14 +1921,14 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
return module;
}
SceUID KernelLoadModule(const std::string &filename, std::string *error_string) {
SceUID KernelLoadModule(const std::string &filename, std::string *error_string, bool fromTop) {
std::vector<uint8_t> buffer;
if (pspFileSystem.ReadEntireFile(filename, buffer) < 0)
return SCE_KERNEL_ERROR_NOFILE;
u32 error = SCE_KERNEL_ERROR_ILLEGAL_OBJECT;
u32 magic;
PSPModule *module = __KernelLoadELFFromPtr(&buffer[0], buffer.size(), 0, false, error_string, &magic, filename, error);
PSPModule *module = __KernelLoadELFFromPtr(&buffer[0], buffer.size(), 0, fromTop, error_string, &magic, filename, error);
if (module == nullptr)
return error;