PPU Analyser: minor fixups for end pointer

Add more sanity checks for sections.
Remove some redundancy.
This commit is contained in:
Nekotekina 2021-02-02 19:54:43 +03:00
parent b7ff2ecffb
commit 9463238490
2 changed files with 14 additions and 28 deletions

View File

@ -529,15 +529,13 @@ namespace ppu_patterns
};
}
void ppu_module::analyse(u32 lib_toc, u32 entry, u32 end)
void ppu_module::analyse(u32 lib_toc, u32 entry, const u32 sec_end)
{
// Assume first segment is executable
const u32 start = segs[0].addr;
if (!end)
{
end = segs[0].addr + segs[0].size;
}
// End of executable segment (may change)
u32 end = sec_end ? sec_end : segs[0].addr + segs[0].size;
// Known TOCs (usually only 1)
std::unordered_set<u32> TOCs;
@ -1529,6 +1527,12 @@ void ppu_module::analyse(u32 lib_toc, u32 entry, u32 end)
ppu_log.notice("Function analysis: %zu functions (%zu enqueued)", fmap.size(), func_queue.size());
// Decompose functions to basic blocks
if (!entry && !sec_end)
{
// Regenerate end from blocks
end = 0;
}
for (auto&& [_, func] : as_rvalue(std::move(fmap)))
{
if (func.attr & ppu_attr::no_size && entry)
@ -1570,10 +1574,10 @@ void ppu_module::analyse(u32 lib_toc, u32 entry, u32 end)
block.toc = func.toc;
ppu_log.trace("Block __0x%x added (func=0x%x, size=0x%x, toc=0x%x)", block.addr, _, block.size, block.toc);
if (!entry)
if (!entry && !sec_end)
{
// Workaround for SPRX: update end to the last found function
end = block.addr + block.size;
end = std::max<u32>(end, block.addr + block.size);
}
}
}

View File

@ -868,7 +868,6 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
if (prog.p_flags & 0x1)
{
ppu_register_range(addr, mem_size);
end = std::max<u32>(end, addr + mem_size);
}
_seg.addr = addr;
@ -885,11 +884,6 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
}
}
if (!elf.shdrs.empty())
{
end = 0;
}
for (const auto& s : elf.shdrs)
{
ppu_loader.notice("** Section: sh_type=0x%x, addr=0x%llx, size=0x%llx, flags=0x%x", s.sh_type, s.sh_addr, s.sh_size, s.sh_flags);
@ -915,7 +909,7 @@ std::shared_ptr<lv2_prx> ppu_load_prx(const ppu_prx_object& elf, const std::stri
_sec.filesz = 0;
prx->secs.emplace_back(_sec);
if (_sec.flags & 0x4)
if (_sec.flags & 0x4 && i == 0)
{
end = std::max<u32>(end, _sec.addr + _sec.size);
}
@ -1271,7 +1265,6 @@ bool ppu_load_exec(const ppu_exec_object& elf)
if (prog.p_flags & 0x1)
{
ppu_register_range(addr, size);
end = std::max<u32>(end, addr + size);
}
// Store only LOAD segments (TODO)
@ -1279,11 +1272,6 @@ bool ppu_load_exec(const ppu_exec_object& elf)
}
}
if (!elf.shdrs.empty())
{
end = 0;
}
// Load section list, used by the analyser
for (const auto& s : elf.shdrs)
{
@ -1303,7 +1291,7 @@ bool ppu_load_exec(const ppu_exec_object& elf)
{
_main->secs.emplace_back(_sec);
if (_sec.flags & 0x4)
if (_sec.flags & 0x4 && addr >= _main->segs[0].addr && addr + size <= _main->segs[0].addr + _main->segs[0].size)
{
end = std::max<u32>(end, addr + size);
}
@ -1828,7 +1816,6 @@ std::pair<std::shared_ptr<lv2_overlay>, CellError> ppu_load_overlay(const ppu_ex
if (prog.p_flags & 0x1)
{
ppu_register_range(addr, size);
end = std::max<u32>(end, addr + size);
}
// Store only LOAD segments (TODO)
@ -1836,11 +1823,6 @@ std::pair<std::shared_ptr<lv2_overlay>, CellError> ppu_load_overlay(const ppu_ex
}
}
if (elf.shdrs.size())
{
end = 0;
}
// Load section list, used by the analyser
for (const auto& s : elf.shdrs)
{
@ -1860,7 +1842,7 @@ std::pair<std::shared_ptr<lv2_overlay>, CellError> ppu_load_overlay(const ppu_ex
{
ovlm->secs.emplace_back(_sec);
if (_sec.flags & 0x4)
if (_sec.flags & 0x4 && addr >= ovlm->segs[0].addr && addr + size <= ovlm->segs[0].addr + ovlm->segs[0].size)
{
end = std::max<u32>(end, addr + size);
}