mirror of https://github.com/PCSX2/pcsx2.git
DebugTools: Add noreturn heuristic
This commit is contained in:
parent
b07b56fce6
commit
4919f9b18c
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ namespace MIPSAnalyst
|
|||
u32 size;
|
||||
bool isStraightLeaf;
|
||||
bool hasHash;
|
||||
bool suspectedNoReturn;
|
||||
bool usesVFPU;
|
||||
char name[64];
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue