diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index c8a8ca27d0..79150ba370 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -450,6 +450,31 @@ void WriteReplaceInstruction(u32 address, u64 hash, int size) { } } +void RestoreReplacedInstruction(u32 address) { + const u32 curInstr = Memory::Read_U32(address); + if (MIPS_IS_REPLACEMENT(curInstr)) { + Memory::Write_U32(replacedInstructions[address], address); + } + INFO_LOG(HLE, "Restored replaced func at %08x", address); + replacedInstructions.erase(address); +} + +void RestoreReplacedInstructions(u32 startAddr, u32 endAddr) { + const auto start = replacedInstructions.lower_bound(startAddr); + const auto end = replacedInstructions.upper_bound(endAddr); + int restored = 0; + for (auto it = start; it != end; ++it) { + const u32 addr = it->first; + const u32 curInstr = Memory::Read_U32(addr); + if (MIPS_IS_REPLACEMENT(curInstr)) { + Memory::Write_U32(it->second, addr); + ++restored; + } + } + INFO_LOG(HLE, "Restored %d replaced funcs between %08x-%08x", restored, startAddr, endAddr); + replacedInstructions.erase(start, end); +} + bool GetReplacedOpAt(u32 address, u32 *op) { u32 instr = Memory::Read_Opcode_JIT(address).encoding; if (MIPS_IS_REPLACEMENT(instr)) { diff --git a/Core/HLE/ReplaceTables.h b/Core/HLE/ReplaceTables.h index 423dd8f0cd..23c38f5e57 100644 --- a/Core/HLE/ReplaceTables.h +++ b/Core/HLE/ReplaceTables.h @@ -58,4 +58,6 @@ int GetReplacementFuncIndex(u64 hash, int funcSize); const ReplacementTableEntry *GetReplacementFunc(int index); void WriteReplaceInstruction(u32 address, u64 hash, int size); +void RestoreReplacedInstruction(u32 address); +void RestoreReplacedInstructions(u32 startAddr, u32 endAddr); bool GetReplacedOpAt(u32 address, u32 *op); diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 92b800e6f0..6331d5a924 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -959,10 +959,11 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro SectionID textSection = reader.GetSectionByName(".text"); if (textSection != -1) { - u32 textStart = reader.GetSectionAddr(textSection); + module->textStart = reader.GetSectionAddr(textSection); u32 textSize = reader.GetSectionSize(textSection); + module->textEnd = module->textStart + textSize; - module->nm.text_addr = textStart; + module->nm.text_addr = module->textStart; // TODO: This value appears to be wrong. In one example, the PSP has a value > 0x1000 bigger. module->nm.text_size = textSize; // TODO: It seems like the data size excludes the text size, which kinda makes sense? @@ -970,11 +971,11 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro #if !defined(MOBILE_DEVICE) bool gotSymbols = reader.LoadSymbols(); - MIPSAnalyst::ScanForFunctions(textStart, textStart + textSize, !gotSymbols); + MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols); #else if (g_Config.bFuncHashMap) { bool gotSymbols = reader.LoadSymbols(); - MIPSAnalyst::ScanForFunctions(textStart, textStart + textSize, !gotSymbols); + MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols); } #endif } @@ -1127,15 +1128,15 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro } if (textSection == -1) { - u32 textStart = reader.GetVaddr(); - u32 textEnd = firstImportStubAddr - 4; + module->textStart = reader.GetVaddr(); + module->textEnd = firstImportStubAddr - 4; #if !defined(MOBILE_DEVICE) bool gotSymbols = reader.LoadSymbols(); - MIPSAnalyst::ScanForFunctions(textStart, textEnd, !gotSymbols); + MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols); #else if (g_Config.bFuncHashMap) { bool gotSymbols = reader.LoadSymbols(); - MIPSAnalyst::ScanForFunctions(textStart, textEnd, !gotSymbols); + MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols); } #endif } diff --git a/Core/MIPS/MIPSAnalyst.cpp b/Core/MIPS/MIPSAnalyst.cpp index 9fc5a4c292..fc65f70c94 100644 --- a/Core/MIPS/MIPSAnalyst.cpp +++ b/Core/MIPS/MIPSAnalyst.cpp @@ -559,6 +559,8 @@ skip: } } + RestoreReplacedInstructions(startAddr, endAddr); + // TODO: Also wipe them from hash->function map }