DebugTools: Add noreturn heuristic

This commit is contained in:
Ty Lamontagne 2024-02-23 13:39:31 -05:00 committed by refractionpcsx2
parent b07b56fce6
commit 4919f9b18c
5 changed files with 48 additions and 7 deletions

View File

@ -745,19 +745,33 @@ inline QString DisassemblyWidget::DisassemblyStringFromAddress(u32 address, QFon
const bool isConditionalMet = line.info.conditionMet;
const bool isCurrentPC = m_cpu->getPC() == address;
const std::string addressSymbol = m_cpu->GetSymbolMap().GetLabelName(address);
bool isFunctionNoReturn = false;
const std::string addressSymbol = m_cpu->GetSymbolMap().GetLabelName(address);
if(m_cpu->GetSymbolMap().GetFunctionStart(address) == address)
{
isFunctionNoReturn = m_cpu->GetSymbolMap().GetFunctionNoReturn(address);
}
const auto demangler = demangler::CDemangler::createGcc();
const bool showOpcode = m_showInstructionOpcode && m_cpu->isAlive();
QString lineString;
if (showOpcode)
{
lineString = QString(" %1 %2 %3 %4 %5 %6");
lineString = QString(" %1 %2 %3 %4 %5 %6 %7");
}
else
{
lineString = QString(" %1 %2 %3 %4 %5");
lineString = QString(" %1 %2 %3 %4 %5 %6");
}
if(isFunctionNoReturn)
{
lineString = lineString.arg("NR");
}
else
{
lineString = lineString.arg(" ");
}
if (addressSymbol.empty()) // The address wont have symbol text if it's the start of a function for example
@ -780,7 +794,7 @@ inline QString DisassemblyWidget::DisassemblyStringFromAddress(u32 address, QFon
symbolString = QString::fromStdString(addressSymbol);
}
lineString = lineString.arg(metric.elidedText(symbolString, Qt::ElideRight, (selected ? 32.0f : 7.5f) * font.pointSize()));
lineString = lineString.arg(metric.elidedText(symbolString, Qt::ElideRight, (selected ? 32 : 7) * font.pointSize()));
}
if (showOpcode)

View File

@ -190,6 +190,7 @@ namespace MIPSAnalyst
bool looking = false;
bool end = false;
bool isStraightLeaf = true;
bool suspectedNoReturn = false;
functions.clear();
@ -219,6 +220,16 @@ namespace MIPSAnalyst
if (target > furthestBranch) {
furthestBranch = target;
}
// beq $zero, $zero, xyz
if ((op >> 16) == 0x1000)
{
// If it's backwards, and there's no other branch passing it, treat as noreturn
if(target < addr && furthestBranch < addr)
{
end = suspectedNoReturn = true;
}
}
} else if ((op & 0xFC000000) == 0x08000000) {
u32 sureTarget = GetJumpTarget(addr);
// Check for a tail call. Might not even have a jr ra.
@ -286,11 +297,13 @@ namespace MIPSAnalyst
currentFunction.end = addr + 4;
currentFunction.isStraightLeaf = isStraightLeaf;
currentFunction.suspectedNoReturn = suspectedNoReturn;
functions.push_back(currentFunction);
furthestBranch = 0;
addr += 4;
looking = false;
end = false;
suspectedNoReturn = false;
isStraightLeaf = true;
currentFunction.start = addr+4;
@ -304,7 +317,7 @@ namespace MIPSAnalyst
iter->size = iter->end - iter->start + 4;
if (insertSymbols) {
char temp[256];
map.AddFunction(DefaultFunctionName(temp, iter->start), iter->start, iter->end - iter->start + 4);
map.AddFunction(DefaultFunctionName(temp, iter->start), iter->start, iter->end - iter->start + 4, iter->suspectedNoReturn);
}
}
}

View File

@ -25,6 +25,7 @@ namespace MIPSAnalyst
u32 size;
bool isStraightLeaf;
bool hasHash;
bool suspectedNoReturn;
bool usesVFPU;
char name[64];
};

View File

@ -241,7 +241,7 @@ std::vector<SymbolEntry> SymbolMap::GetAllSymbols(SymbolType symmask) const
return result;
}
void SymbolMap::AddFunction(const std::string& name, u32 address, u32 size)
void SymbolMap::AddFunction(const std::string& name, u32 address, u32 size, bool noReturn)
{
std::lock_guard<std::recursive_mutex> guard(m_lock);
@ -258,6 +258,7 @@ void SymbolMap::AddFunction(const std::string& name, u32 address, u32 size)
func.size = size;
func.index = (int)functions.size();
func.name = name;
func.noReturn = noReturn;
functions[address] = func;
functions.insert(std::make_pair(address, func));
@ -321,6 +322,16 @@ int SymbolMap::GetFunctionNum(u32 address) const
return it->second.index;
}
bool SymbolMap::GetFunctionNoReturn(u32 address) const
{
std::lock_guard<std::recursive_mutex> guard(m_lock);
auto it = functions.find(address);
if (it == functions.end())
return false;
return it->second.noReturn;
}
void SymbolMap::AssignFunctionIndices()
{
std::lock_guard<std::recursive_mutex> guard(m_lock);

View File

@ -72,9 +72,10 @@ public:
std::string GetDescription(unsigned int address) const;
std::vector<SymbolEntry> GetAllSymbols(SymbolType symmask) const;
void AddFunction(const std::string& name, u32 address, u32 size);
void AddFunction(const std::string& name, u32 address, u32 size, bool noReturn = false);
u32 GetFunctionStart(u32 address) const;
int GetFunctionNum(u32 address) const;
bool GetFunctionNoReturn(u32 address) const;
u32 GetFunctionSize(u32 startAddress) const;
bool SetFunctionSize(u32 startAddress, u32 newSize);
bool RemoveFunction(u32 startAddress);
@ -113,6 +114,7 @@ private:
u32 size;
int index;
std::string name;
bool noReturn;
};
struct LabelEntry