mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-09-20 11:27:48 +02:00
Clamp the module function scan to the text range it already validated
The no-code-sections path validates textStart..textEnd, then derives its actual scan boundaries from modinfo->libent/libstub without checking those land inside it. flash0:/kd/sysmem.prx and loadcore.prx from a real firmware dump put them tens of megabytes past the end of the text, so the scan walked off into unmapped memory - a debug assert in Read_Instruction, and a pointless 134MB scan in release builds. For a well-formed module every boundary is already inside the range, so this is a no-op there. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
Henrik Rydgård
co-authored by
Claude Opus 5
parent
4d795f5130
commit
fb976d4f61
@@ -1695,16 +1695,29 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
|
||||
u32 scanEnd = module->textEnd;
|
||||
|
||||
if (Memory::IsValid4AlignedRange(scanStart, scanEnd - scanStart)) {
|
||||
// libent/libstub come from the module's own header, and nothing has checked that
|
||||
// they land inside the range validated just above. flash0:/kd/sysmem.prx and
|
||||
// loadcore.prx from a real firmware dump put them tens of megabytes past the end
|
||||
// of the text. So let's clamp.
|
||||
const u32 textStart = scanStart;
|
||||
auto clampToText = [textStart, scanEnd](u32 addr) {
|
||||
return std::min(std::max(addr, textStart), scanEnd);
|
||||
};
|
||||
auto scanRange = [&insertSymbols](u32 from, u32 to) {
|
||||
if (from < to) {
|
||||
insertSymbols = MIPSAnalyst::ScanForFunctions(from, to, insertSymbols);
|
||||
}
|
||||
};
|
||||
// Skip the exports and imports sections, they're not code.
|
||||
if (scanEnd >= std::min(modinfo->libent, modinfo->libstub)) {
|
||||
insertSymbols = MIPSAnalyst::ScanForFunctions(scanStart, std::min(modinfo->libent, modinfo->libstub), insertSymbols);
|
||||
scanStart = std::min(modinfo->libentend, modinfo->libstubend);
|
||||
scanRange(scanStart, clampToText(std::min(modinfo->libent, modinfo->libstub)));
|
||||
scanStart = clampToText(std::min(modinfo->libentend, modinfo->libstubend));
|
||||
}
|
||||
if (scanEnd >= std::max(modinfo->libent, modinfo->libstub)) {
|
||||
insertSymbols = MIPSAnalyst::ScanForFunctions(scanStart, std::max(modinfo->libent, modinfo->libstub), insertSymbols);
|
||||
scanStart = std::max(modinfo->libentend, modinfo->libstubend);
|
||||
scanRange(scanStart, clampToText(std::max(modinfo->libent, modinfo->libstub)));
|
||||
scanStart = clampToText(std::max(modinfo->libentend, modinfo->libstubend));
|
||||
}
|
||||
insertSymbols = MIPSAnalyst::ScanForFunctions(scanStart, scanEnd, insertSymbols);
|
||||
scanRange(scanStart, scanEnd);
|
||||
} else {
|
||||
ERROR_LOG(Log::Loader, "Bad text scan range %08x-%08x", scanStart, scanEnd);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user