diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 5b0e59f195..f411ce1b69 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -587,6 +587,19 @@ void __KernelModuleDoState(PointerWrap &p) { } } } + // A module that was only loaded in the state was never scanned, so nothing in it could be + // replaced or hooked (or show up as functions in the debugger.) + for (SceUID moduleId : loadedModules) { + PSPModule *module = kernelObjects.Get(moduleId, error); + if (!module || module->isFake || module->textEnd <= module->textStart) { + continue; + } + // textEnd is inclusive. + if (Memory::IsValid4AlignedRange(module->textStart, module->textEnd + 4 - module->textStart) && + !MIPSAnalyst::HasFunctionsInRange(module->textStart, module->textEnd + 4)) { + MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, true); + } + } // The functions were found in memory from before the load, where other code may have been // (an overlay module, say.) Hash them from what's there now, so a hook only goes where it matches. MIPSAnalyst::RehashFunctions(); diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index bb6abd4cf2..19d98fd4e3 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -1295,6 +1295,16 @@ namespace MIPSAnalyst { return false; } + bool HasFunctionsInRange(u32 startAddr, u32 endAddr) { + std::lock_guard guard(functions_lock); + for (const AnalyzedFunction &f : functions) { + if (f.start >= startAddr && f.start < endAddr) { + return true; + } + } + return false; + } + void RehashFunctions() { std::lock_guard guard(functions_lock); HashFunctions(); diff --git a/Core/MIPS/MIPSAnalyst.h b/Core/MIPS/MIPSAnalyst.h index 1c1a679a78..fda9908b56 100644 --- a/Core/MIPS/MIPSAnalyst.h +++ b/Core/MIPS/MIPSAnalyst.h @@ -109,6 +109,8 @@ namespace MIPSAnalyst { void ForgetFunctions(u32 startAddr, u32 endAddr); bool GetAnalyzedFunctionAt(u32 addr, AnalyzedFunction *out); + // endAddr is exclusive. + bool HasFunctionsInRange(u32 startAddr, u32 endAddr); void LoadBuiltinHashMap(); void LoadHashMap(const Path &filename);