mirror of
https://github.com/ran-j/PS2Recomp.git
synced 2026-09-26 08:51:05 -04:00
Feature/vu fixes (#55)
* fix: added missing header include for gcc * fix: small thread fix on syscalls fix: fix incorrect VU translations (they was using wrong register) * feat: added authoritative system for function extraction, this will prevent functions overlap when we have debug symbols
This commit is contained in:
@@ -493,6 +493,72 @@ namespace ps2recomp
|
||||
std::unordered_map<uint32_t, size_t> indexByStart;
|
||||
indexByStart.reserve(functions.capacity());
|
||||
|
||||
// Symbol table sizes are authoritative wwhen exist
|
||||
std::unordered_map<uint32_t, uint32_t> authoritativeEndByStart;
|
||||
authoritativeEndByStart.reserve(m_symbols.size());
|
||||
for (const auto &symbol : m_symbols)
|
||||
{
|
||||
if (!symbol.isFunction || symbol.isImported || symbol.size == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const uint32_t symbolEnd = symbol.address + symbol.size;
|
||||
auto inserted = authoritativeEndByStart.emplace(symbol.address, symbolEnd);
|
||||
if (!inserted.second && symbolEnd > inserted.first->second)
|
||||
{
|
||||
inserted.first->second = symbolEnd;
|
||||
}
|
||||
}
|
||||
|
||||
// Named debug/map functions with explicit bounds are authoritative too.
|
||||
for (const auto &extra : m_extraFunctions)
|
||||
{
|
||||
if (extra.start == 0 || extra.end <= extra.start || extra.name.empty() || IsAutoGeneratedName(extra.name))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto inserted = authoritativeEndByStart.emplace(extra.start, extra.end);
|
||||
if (!inserted.second && extra.end > inserted.first->second)
|
||||
{
|
||||
inserted.first->second = extra.end;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::pair<uint32_t, uint32_t>> authoritativeRanges;
|
||||
authoritativeRanges.reserve(authoritativeEndByStart.size());
|
||||
for (const auto &entry : authoritativeEndByStart)
|
||||
{
|
||||
authoritativeRanges.emplace_back(entry.first, entry.second);
|
||||
}
|
||||
std::sort(authoritativeRanges.begin(), authoritativeRanges.end(),
|
||||
[](const std::pair<uint32_t, uint32_t> &a, const std::pair<uint32_t, uint32_t> &b)
|
||||
{ return a.first < b.first; });
|
||||
|
||||
auto isInsideAuthoritativeRange = [&](uint32_t startAddress)
|
||||
{
|
||||
if (authoritativeRanges.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it = std::upper_bound(
|
||||
authoritativeRanges.begin(),
|
||||
authoritativeRanges.end(),
|
||||
startAddress,
|
||||
[](uint32_t value, const std::pair<uint32_t, uint32_t> &range)
|
||||
{ return value < range.first; });
|
||||
|
||||
if (it == authoritativeRanges.begin())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
--it;
|
||||
return startAddress > it->first && startAddress < it->second;
|
||||
};
|
||||
|
||||
auto addOrMerge = [&](const Function &newFunction)
|
||||
{
|
||||
if (newFunction.start == 0)
|
||||
@@ -500,11 +566,27 @@ namespace ps2recomp
|
||||
return;
|
||||
}
|
||||
|
||||
const bool insideAuthoritativeRange = isInsideAuthoritativeRange(newFunction.start);
|
||||
const bool hasOwnAuthoritativeRange = authoritativeEndByStart.contains(newFunction.start);
|
||||
const bool hasAutoName = newFunction.name.empty() || IsAutoGeneratedName(newFunction.name);
|
||||
|
||||
if (insideAuthoritativeRange && (!hasOwnAuthoritativeRange || hasAutoName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto it = indexByStart.find(newFunction.start);
|
||||
if (it == indexByStart.end())
|
||||
{
|
||||
indexByStart.emplace(newFunction.start, functions.size());
|
||||
functions.push_back(newFunction);
|
||||
|
||||
Function &insertedFunction = functions.back();
|
||||
auto authoritativeIt = authoritativeEndByStart.find(insertedFunction.start);
|
||||
if (authoritativeIt != authoritativeEndByStart.end())
|
||||
{
|
||||
insertedFunction.end = authoritativeIt->second;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -518,7 +600,12 @@ namespace ps2recomp
|
||||
}
|
||||
}
|
||||
|
||||
if (newFunction.end > existing.end)
|
||||
auto authoritativeIt = authoritativeEndByStart.find(existing.start);
|
||||
if (authoritativeIt != authoritativeEndByStart.end())
|
||||
{
|
||||
existing.end = authoritativeIt->second;
|
||||
}
|
||||
else if (newFunction.end > existing.end)
|
||||
{
|
||||
existing.end = newFunction.end;
|
||||
}
|
||||
@@ -557,6 +644,13 @@ namespace ps2recomp
|
||||
{
|
||||
Function &func = functions[index];
|
||||
|
||||
auto authoritativeIt = authoritativeEndByStart.find(func.start);
|
||||
if (authoritativeIt != authoritativeEndByStart.end())
|
||||
{
|
||||
func.end = authoritativeIt->second;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (func.end > func.start)
|
||||
{
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user