Merge pull request #13113 from CelestialAmber/mwld-map
Core: Store object name separately for symbols
This commit is contained in:
commit
57b1234feb
|
@ -44,6 +44,7 @@ struct Symbol
|
|||
|
||||
std::string name;
|
||||
std::string function_name; // stripped function name
|
||||
std::string object_name; // name of object/source file symbol belongs to
|
||||
std::vector<SCall> callers; // addresses of functions that call this function
|
||||
std::vector<SCall> calls; // addresses of functions that are called by this function
|
||||
u32 hash = 0; // use for HLE function finding
|
||||
|
|
|
@ -605,7 +605,9 @@ bool CBoot::BootUp(Core::System& system, const Core::CPUThreadGuard& guard,
|
|||
|
||||
ppc_state.pc = executable.reader->GetEntryPoint();
|
||||
|
||||
if (executable.reader->LoadSymbols(guard, system.GetPPCSymbolDB()))
|
||||
const std::string filename = PathToFileName(executable.path);
|
||||
|
||||
if (executable.reader->LoadSymbols(guard, system.GetPPCSymbolDB(), filename))
|
||||
{
|
||||
Host_PPCSymbolsChanged();
|
||||
HLE::PatchFunctions(system);
|
||||
|
|
|
@ -215,7 +215,8 @@ public:
|
|||
virtual bool IsValid() const = 0;
|
||||
virtual bool IsWii() const = 0;
|
||||
virtual bool LoadIntoMemory(Core::System& system, bool only_in_mem1 = false) const = 0;
|
||||
virtual bool LoadSymbols(const Core::CPUThreadGuard& guard, PPCSymbolDB& ppc_symbol_db) const = 0;
|
||||
virtual bool LoadSymbols(const Core::CPUThreadGuard& guard, PPCSymbolDB& ppc_symbol_db,
|
||||
const std::string& filename) const = 0;
|
||||
|
||||
protected:
|
||||
std::vector<u8> m_bytes;
|
||||
|
|
|
@ -27,7 +27,8 @@ public:
|
|||
bool IsAncast() const { return m_is_ancast; }
|
||||
u32 GetEntryPoint() const override { return m_dolheader.entryPoint; }
|
||||
bool LoadIntoMemory(Core::System& system, bool only_in_mem1 = false) const override;
|
||||
bool LoadSymbols(const Core::CPUThreadGuard& guard, PPCSymbolDB& ppc_symbol_db) const override
|
||||
bool LoadSymbols(const Core::CPUThreadGuard& guard, PPCSymbolDB& ppc_symbol_db,
|
||||
const std::string& filename) const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -180,7 +180,8 @@ SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const
|
|||
return -1;
|
||||
}
|
||||
|
||||
bool ElfReader::LoadSymbols(const Core::CPUThreadGuard& guard, PPCSymbolDB& ppc_symbol_db) const
|
||||
bool ElfReader::LoadSymbols(const Core::CPUThreadGuard& guard, PPCSymbolDB& ppc_symbol_db,
|
||||
const std::string& filename) const
|
||||
{
|
||||
bool hasSymbols = false;
|
||||
SectionID sec = GetSectionByName(".symtab");
|
||||
|
@ -218,7 +219,7 @@ bool ElfReader::LoadSymbols(const Core::CPUThreadGuard& guard, PPCSymbolDB& ppc_
|
|||
default:
|
||||
continue;
|
||||
}
|
||||
ppc_symbol_db.AddKnownSymbol(guard, value, size, name, symtype);
|
||||
ppc_symbol_db.AddKnownSymbol(guard, value, size, name, filename, symtype);
|
||||
hasSymbols = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,8 @@ public:
|
|||
u32 GetEntryPoint() const override { return entryPoint; }
|
||||
u32 GetFlags() const { return (u32)(header->e_flags); }
|
||||
bool LoadIntoMemory(Core::System& system, bool only_in_mem1 = false) const override;
|
||||
bool LoadSymbols(const Core::CPUThreadGuard& guard, PPCSymbolDB& ppc_symbol_db) const override;
|
||||
bool LoadSymbols(const Core::CPUThreadGuard& guard, PPCSymbolDB& ppc_symbol_db,
|
||||
const std::string& filename) const override;
|
||||
// TODO: actually check for validity.
|
||||
bool IsValid() const override { return true; }
|
||||
bool IsWii() const override;
|
||||
|
|
|
@ -375,6 +375,7 @@ void RSOView::LoadAll(const Core::CPUThreadGuard& guard, u32 address)
|
|||
|
||||
void RSOView::Apply(const Core::CPUThreadGuard& guard, PPCSymbolDB* symbol_db) const
|
||||
{
|
||||
const std::string rso_name = GetName();
|
||||
for (const RSOExport& rso_export : GetExports())
|
||||
{
|
||||
u32 address = GetExportAddress(rso_export);
|
||||
|
@ -389,15 +390,17 @@ void RSOView::Apply(const Core::CPUThreadGuard& guard, PPCSymbolDB* symbol_db) c
|
|||
{
|
||||
// Function symbol
|
||||
symbol->Rename(export_name);
|
||||
symbol->object_name = rso_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Data symbol
|
||||
symbol_db->AddKnownSymbol(guard, address, 0, export_name, Common::Symbol::Type::Data);
|
||||
symbol_db->AddKnownSymbol(guard, address, 0, export_name, rso_name,
|
||||
Common::Symbol::Type::Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
DEBUG_LOG_FMT(SYMBOLS, "RSO({}): {} symbols applied", GetName(), GetExportsCount());
|
||||
DEBUG_LOG_FMT(SYMBOLS, "RSO({}): {} symbols applied", rso_name, GetExportsCount());
|
||||
}
|
||||
|
||||
u32 RSOView::GetNextEntry() const
|
||||
|
|
|
@ -49,7 +49,8 @@ Common::Symbol* PPCSymbolDB::AddFunction(const Core::CPUThreadGuard& guard, u32
|
|||
}
|
||||
|
||||
void PPCSymbolDB::AddKnownSymbol(const Core::CPUThreadGuard& guard, u32 startAddr, u32 size,
|
||||
const std::string& name, Common::Symbol::Type type)
|
||||
const std::string& name, const std::string& object_name,
|
||||
Common::Symbol::Type type)
|
||||
{
|
||||
auto iter = m_functions.find(startAddr);
|
||||
if (iter != m_functions.end())
|
||||
|
@ -57,6 +58,7 @@ void PPCSymbolDB::AddKnownSymbol(const Core::CPUThreadGuard& guard, u32 startAdd
|
|||
// already got it, let's just update name, checksum & size to be sure.
|
||||
Common::Symbol* tempfunc = &iter->second;
|
||||
tempfunc->Rename(name);
|
||||
tempfunc->object_name = object_name;
|
||||
tempfunc->hash = HashSignatureDB::ComputeCodeChecksum(guard, startAddr, startAddr + size - 4);
|
||||
tempfunc->type = type;
|
||||
tempfunc->size = size;
|
||||
|
@ -65,6 +67,7 @@ void PPCSymbolDB::AddKnownSymbol(const Core::CPUThreadGuard& guard, u32 startAdd
|
|||
{
|
||||
// new symbol. run analyze.
|
||||
auto& new_symbol = m_functions.emplace(startAddr, name).first->second;
|
||||
new_symbol.object_name = object_name;
|
||||
new_symbol.type = type;
|
||||
new_symbol.address = startAddr;
|
||||
|
||||
|
@ -399,6 +402,13 @@ bool PPCSymbolDB::LoadMap(const Core::CPUThreadGuard& guard, const std::string&
|
|||
if (name[strlen(name) - 1] == '\r')
|
||||
name[strlen(name) - 1] = 0;
|
||||
|
||||
// Split the current name string into separate parts, and get the object name
|
||||
// if it exists.
|
||||
const std::vector<std::string> parts = SplitString(name, '\t');
|
||||
const std::string name_string(StripWhitespace(parts[0]));
|
||||
const std::string object_filename_string =
|
||||
parts.size() > 1 ? std::string(StripWhitespace(parts[1])) : "";
|
||||
|
||||
// Check if this is a valid entry.
|
||||
if (strlen(name) > 0)
|
||||
{
|
||||
|
@ -435,7 +445,7 @@ bool PPCSymbolDB::LoadMap(const Core::CPUThreadGuard& guard, const std::string&
|
|||
if (good)
|
||||
{
|
||||
++good_count;
|
||||
AddKnownSymbol(guard, vaddress, size, name, type);
|
||||
AddKnownSymbol(guard, vaddress, size, name_string, object_filename_string, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -473,8 +483,13 @@ bool PPCSymbolDB::SaveSymbolMap(const std::string& filename) const
|
|||
for (const auto& symbol : function_symbols)
|
||||
{
|
||||
// Write symbol address, size, virtual address, alignment, name
|
||||
f.WriteString(fmt::format("{0:08x} {1:08x} {2:08x} {3} {4}\n", symbol->address, symbol->size,
|
||||
symbol->address, 0, symbol->name));
|
||||
std::string line = fmt::format("{0:08x} {1:06x} {2:08x} {3} {4}", symbol->address, symbol->size,
|
||||
symbol->address, 0, symbol->name);
|
||||
// Also write the object name if it exists
|
||||
if (!symbol->object_name.empty())
|
||||
line += fmt::format(" \t{0}", symbol->object_name);
|
||||
line += "\n";
|
||||
f.WriteString(line);
|
||||
}
|
||||
|
||||
// Write .data section
|
||||
|
@ -482,8 +497,13 @@ bool PPCSymbolDB::SaveSymbolMap(const std::string& filename) const
|
|||
for (const auto& symbol : data_symbols)
|
||||
{
|
||||
// Write symbol address, size, virtual address, alignment, name
|
||||
f.WriteString(fmt::format("{0:08x} {1:08x} {2:08x} {3} {4}\n", symbol->address, symbol->size,
|
||||
symbol->address, 0, symbol->name));
|
||||
std::string line = fmt::format("{0:08x} {1:06x} {2:08x} {3} {4}", symbol->address, symbol->size,
|
||||
symbol->address, 0, symbol->name);
|
||||
// Also write the object name if it exists
|
||||
if (!symbol->object_name.empty())
|
||||
line += fmt::format(" \t{0}", symbol->object_name);
|
||||
line += "\n";
|
||||
f.WriteString(line);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
|
||||
Common::Symbol* AddFunction(const Core::CPUThreadGuard& guard, u32 start_addr) override;
|
||||
void AddKnownSymbol(const Core::CPUThreadGuard& guard, u32 startAddr, u32 size,
|
||||
const std::string& name,
|
||||
const std::string& name, const std::string& object_name,
|
||||
Common::Symbol::Type type = Common::Symbol::Type::Function);
|
||||
|
||||
Common::Symbol* GetSymbolFromAddr(u32 addr) override;
|
||||
|
|
|
@ -379,6 +379,12 @@ void CodeWidget::UpdateSymbols()
|
|||
{
|
||||
QString name = QString::fromStdString(symbol.second.name);
|
||||
|
||||
// If the symbol has an object name, add it to the entry name.
|
||||
if (!symbol.second.object_name.empty())
|
||||
{
|
||||
name += QString::fromStdString(fmt::format(" ({})", symbol.second.object_name));
|
||||
}
|
||||
|
||||
auto* item = new QListWidgetItem(name);
|
||||
if (name == selection)
|
||||
item->setSelected(true);
|
||||
|
@ -408,8 +414,17 @@ void CodeWidget::UpdateFunctionCalls(const Common::Symbol* symbol)
|
|||
|
||||
if (call_symbol)
|
||||
{
|
||||
const QString name =
|
||||
QString::fromStdString(fmt::format("> {} ({:08x})", call_symbol->name, addr));
|
||||
QString name;
|
||||
|
||||
if (!call_symbol->object_name.empty())
|
||||
{
|
||||
name = QString::fromStdString(
|
||||
fmt::format("< {} ({}, {:08x})", call_symbol->name, call_symbol->object_name, addr));
|
||||
}
|
||||
else
|
||||
{
|
||||
name = QString::fromStdString(fmt::format("< {} ({:08x})", call_symbol->name, addr));
|
||||
}
|
||||
|
||||
if (!name.contains(filter, Qt::CaseInsensitive))
|
||||
continue;
|
||||
|
@ -433,8 +448,17 @@ void CodeWidget::UpdateFunctionCallers(const Common::Symbol* symbol)
|
|||
|
||||
if (caller_symbol)
|
||||
{
|
||||
const QString name =
|
||||
QString::fromStdString(fmt::format("< {} ({:08x})", caller_symbol->name, addr));
|
||||
QString name;
|
||||
|
||||
if (!caller_symbol->object_name.empty())
|
||||
{
|
||||
name = QString::fromStdString(fmt::format("< {} ({}, {:08x})", caller_symbol->name,
|
||||
caller_symbol->object_name, addr));
|
||||
}
|
||||
else
|
||||
{
|
||||
name = QString::fromStdString(fmt::format("< {} ({:08x})", caller_symbol->name, addr));
|
||||
}
|
||||
|
||||
if (!name.contains(filter, Qt::CaseInsensitive))
|
||||
continue;
|
||||
|
|
Loading…
Reference in New Issue