From 95d03449b37b468277536c442542b1adc86c4d7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 9 Sep 2026 14:23:35 -0600 Subject: [PATCH] sceMp4: don't reload the modules, read the effective flags, check four bytes Three from a read-through of the sceMp4 firmware-module path: Clearing the module UIDs when the game says it's done with the MP4 module didn't unload anything - it only meant the next load brought in a second copy of libmp4.prx and mp4msv.prx, some 220KB at the top of user memory each time. Keep them for the boot instead; __UtilityInit clears them per game, which is the point at which they really are gone. The flag test read g_Config directly, so it ignored the very fallback CheckDisableHLEAvailability computes when the dump is missing - it would go and try to load modules that aren't there while import resolution had correctly stayed on HLE. It also ignored a boundary restored from a savestate. sceKernelGetModuleGPByAddress checked one byte of the pointer it writes four to. Co-Authored-By: Claude Opus 5 (1M context) --- Core/HLE/sceKernelModule.cpp | 4 +++- Core/HLE/sceUtility.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 66ad4b05fc..9ecd7474d3 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -2773,7 +2773,9 @@ struct GetModuleIdByAddressArg // needs the callee's gp in place. libmp4.prx uses it on the three callbacks it is given. // Named after what it does; the official name isn't known. static u32 sceKernelGetModuleGPByAddress(u32 addr, u32 gpPtr) { - if (!Memory::IsValidAddress(gpPtr)) { + // Four bytes get written, so check for four - IsValidAddress would pass on the last three + // bytes of a region. + if (!Memory::IsValidRange(gpPtr, 4)) { return hleLogError(Log::sceModule, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "bad gp pointer"); } diff --git a/Core/HLE/sceUtility.cpp b/Core/HLE/sceUtility.cpp index 1f1f90f14c..2eb935507d 100644 --- a/Core/HLE/sceUtility.cpp +++ b/Core/HLE/sceUtility.cpp @@ -92,7 +92,10 @@ static void NotifyLoadStatusAvcodec(int state, u32 loadAddr, u32 totalSize) { static SceUID g_mp4RealModules[2] = { 0, 0 }; static void NotifyLoadStatusMp4(int state, u32 loadAddr, u32 totalSize) { - if (!((DisableHLEFlags)g_Config.iDisableHLE & DisableHLEFlags::sceMp4)) { + // The effective flags, not the raw setting: those also account for a firmware dump that isn't + // there or is too old to have sceMp4 (which is the whole point of CheckDisableHLEAvailability), + // for the compat flags. + if (!(GetEffectiveDisableHLEFlags() & DisableHLEFlags::sceMp4)) { return; } @@ -122,9 +125,6 @@ static void NotifyLoadStatusMp4(int state, u32 loadAddr, u32 totalSize) { g_mp4RealModules[i] = id; INFO_LOG(Log::sceUtility, "Loaded the real %s", paths[i]); } - } else if (state == -1) { - g_mp4RealModules[0] = 0; - g_mp4RealModules[1] = 0; } }