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 isConditionalMet = line.info.conditionMet;
|
||||||
const bool isCurrentPC = m_cpu->getPC() == address;
|
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 auto demangler = demangler::CDemangler::createGcc();
|
||||||
const bool showOpcode = m_showInstructionOpcode && m_cpu->isAlive();
|
const bool showOpcode = m_showInstructionOpcode && m_cpu->isAlive();
|
||||||
|
|
||||||
QString lineString;
|
QString lineString;
|
||||||
if (showOpcode)
|
if (showOpcode)
|
||||||
{
|
{
|
||||||
lineString = QString(" %1 %2 %3 %4 %5 %6");
|
lineString = QString(" %1 %2 %3 %4 %5 %6 %7");
|
||||||
}
|
}
|
||||||
else
|
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
|
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);
|
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)
|
if (showOpcode)
|
||||||
|
|
|
@ -190,6 +190,7 @@ namespace MIPSAnalyst
|
||||||
bool looking = false;
|
bool looking = false;
|
||||||
bool end = false;
|
bool end = false;
|
||||||
bool isStraightLeaf = true;
|
bool isStraightLeaf = true;
|
||||||
|
bool suspectedNoReturn = false;
|
||||||
|
|
||||||
functions.clear();
|
functions.clear();
|
||||||
|
|
||||||
|
@ -219,6 +220,16 @@ namespace MIPSAnalyst
|
||||||
if (target > furthestBranch) {
|
if (target > furthestBranch) {
|
||||||
furthestBranch = target;
|
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) {
|
} else if ((op & 0xFC000000) == 0x08000000) {
|
||||||
u32 sureTarget = GetJumpTarget(addr);
|
u32 sureTarget = GetJumpTarget(addr);
|
||||||
// Check for a tail call. Might not even have a jr ra.
|
// Check for a tail call. Might not even have a jr ra.
|
||||||
|
@ -286,11 +297,13 @@ namespace MIPSAnalyst
|
||||||
|
|
||||||
currentFunction.end = addr + 4;
|
currentFunction.end = addr + 4;
|
||||||
currentFunction.isStraightLeaf = isStraightLeaf;
|
currentFunction.isStraightLeaf = isStraightLeaf;
|
||||||
|
currentFunction.suspectedNoReturn = suspectedNoReturn;
|
||||||
functions.push_back(currentFunction);
|
functions.push_back(currentFunction);
|
||||||
furthestBranch = 0;
|
furthestBranch = 0;
|
||||||
addr += 4;
|
addr += 4;
|
||||||
looking = false;
|
looking = false;
|
||||||
end = false;
|
end = false;
|
||||||
|
suspectedNoReturn = false;
|
||||||
isStraightLeaf = true;
|
isStraightLeaf = true;
|
||||||
|
|
||||||
currentFunction.start = addr+4;
|
currentFunction.start = addr+4;
|
||||||
|
@ -304,7 +317,7 @@ namespace MIPSAnalyst
|
||||||
iter->size = iter->end - iter->start + 4;
|
iter->size = iter->end - iter->start + 4;
|
||||||
if (insertSymbols) {
|
if (insertSymbols) {
|
||||||
char temp[256];
|
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;
|
u32 size;
|
||||||
bool isStraightLeaf;
|
bool isStraightLeaf;
|
||||||
bool hasHash;
|
bool hasHash;
|
||||||
|
bool suspectedNoReturn;
|
||||||
bool usesVFPU;
|
bool usesVFPU;
|
||||||
char name[64];
|
char name[64];
|
||||||
};
|
};
|
||||||
|
|
|
@ -241,7 +241,7 @@ std::vector<SymbolEntry> SymbolMap::GetAllSymbols(SymbolType symmask) const
|
||||||
return result;
|
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);
|
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.size = size;
|
||||||
func.index = (int)functions.size();
|
func.index = (int)functions.size();
|
||||||
func.name = name;
|
func.name = name;
|
||||||
|
func.noReturn = noReturn;
|
||||||
functions[address] = func;
|
functions[address] = func;
|
||||||
|
|
||||||
functions.insert(std::make_pair(address, func));
|
functions.insert(std::make_pair(address, func));
|
||||||
|
@ -321,6 +322,16 @@ int SymbolMap::GetFunctionNum(u32 address) const
|
||||||
return it->second.index;
|
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()
|
void SymbolMap::AssignFunctionIndices()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
std::lock_guard<std::recursive_mutex> guard(m_lock);
|
||||||
|
|
|
@ -72,9 +72,10 @@ public:
|
||||||
std::string GetDescription(unsigned int address) const;
|
std::string GetDescription(unsigned int address) const;
|
||||||
std::vector<SymbolEntry> GetAllSymbols(SymbolType symmask) 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;
|
u32 GetFunctionStart(u32 address) const;
|
||||||
int GetFunctionNum(u32 address) const;
|
int GetFunctionNum(u32 address) const;
|
||||||
|
bool GetFunctionNoReturn(u32 address) const;
|
||||||
u32 GetFunctionSize(u32 startAddress) const;
|
u32 GetFunctionSize(u32 startAddress) const;
|
||||||
bool SetFunctionSize(u32 startAddress, u32 newSize);
|
bool SetFunctionSize(u32 startAddress, u32 newSize);
|
||||||
bool RemoveFunction(u32 startAddress);
|
bool RemoveFunction(u32 startAddress);
|
||||||
|
@ -113,6 +114,7 @@ private:
|
||||||
u32 size;
|
u32 size;
|
||||||
int index;
|
int index;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
bool noReturn;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LabelEntry
|
struct LabelEntry
|
||||||
|
|
Loading…
Reference in New Issue