Skip to content

Commit

Permalink
Core: Store object name separately for symbols
Browse files Browse the repository at this point in the history
  • Loading branch information
CelestialAmber committed Oct 24, 2024
1 parent 9b8df48 commit ce68a03
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 20 deletions.
1 change: 1 addition & 0 deletions Source/Core/Common/SymbolDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 3 additions & 1 deletion Source/Core/Core/Boot/Boot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
std::string filename = PathToFileName(executable.path);

if (executable.reader->LoadSymbols(guard, system.GetPPCSymbolDB(), filename))
{
Host_PPCSymbolsChanged();
HLE::PatchFunctions(system);
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/Boot/Boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ class BootExecutableReader
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;
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/Boot/DolReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ class DolReader final : public BootExecutableReader
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;
}
Expand Down
5 changes: 3 additions & 2 deletions Source/Core/Core/Boot/ElfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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;
}
}
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/Boot/ElfReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class ElfReader final : public BootExecutableReader
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;
Expand Down
3 changes: 2 additions & 1 deletion Source/Core/Core/Debugger/RSO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,8 @@ void RSOView::Apply(const Core::CPUThreadGuard& guard, PPCSymbolDB* symbol_db) c
else
{
// Data symbol
symbol_db->AddKnownSymbol(guard, address, 0, export_name, Common::Symbol::Type::Data);
symbol_db->AddKnownSymbol(guard, address, 0, export_name, GetName(),
Common::Symbol::Type::Data);
}
}
}
Expand Down
80 changes: 74 additions & 6 deletions Source/Core/Core/PowerPC/PPCSymbolDB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,16 @@ 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())
{
// 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;
Expand All @@ -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;

Expand Down Expand Up @@ -399,6 +402,61 @@ 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.
std::string processed_name = TabsToSpaces(0, name); // Remove tabs
std::vector<std::string> parts = SplitString(processed_name, ' ');
size_t num_parts = parts.size();

std::string object_filename_string = "";
std::string name_string = name; // Default to the full line

if (num_parts > 0)
{
// If the first part does not contain a left bracket (not a demangled symbol), use the first
// part
size_t parenthesisOffset = parts[0].find('(');
if (parenthesisOffset == std::string::npos)
{
name_string = parts[0];
}
else
{
// If it does, the symbol is likely demangled, so look for the end of the name
size_t nameEndOffset = parenthesisOffset;
int depth = 0; // Current parenthesis depth
while (true)
{
char curChar = processed_name[nameEndOffset];
if (curChar == '(')
depth++;
else if (curChar == ')')
depth--;

nameEndOffset++;

if (depth == 0)
break;
}

nameEndOffset++; // Advance past the ending parenthesis

// If the name ends with const, advance past it
if (processed_name.find(") const") != std::string::npos)
{
nameEndOffset += 6;
}

name_string = processed_name.substr(0, nameEndOffset);
}

// If the last part contains a ., it has to be the object name
if (num_parts > 1 && parts[num_parts - 1].find('.') != std::string::npos)
{
object_filename_string = parts[num_parts - 1];
}
}

// Check if this is a valid entry.
if (strlen(name) > 0)
{
Expand Down Expand Up @@ -435,7 +493,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
{
Expand Down Expand Up @@ -473,17 +531,27 @@ 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:08x} {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(" {0}", symbol->object_name);
line += "\n";
f.WriteString(line);
}

// Write .data section
f.WriteString("\n.data section layout\n");
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:08x} {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(" {0}", symbol->object_name);
line += "\n";
f.WriteString(line);
}

return true;
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/Core/PowerPC/PPCSymbolDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PPCSymbolDB : public Common::SymbolDB

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;
Expand Down
25 changes: 19 additions & 6 deletions Source/Core/DolphinQt/Debugger/CodeWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,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 += fmt::format(" ({})", symbol.second.object_name);
}

auto* item = new QListWidgetItem(name);
if (name == selection)
item->setSelected(true);
Expand Down Expand Up @@ -403,11 +409,13 @@ 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 (!name.contains(filter, Qt::CaseInsensitive))
continue;
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));

auto* item = new QListWidgetItem(name);
item->setData(Qt::UserRole, addr);
Expand All @@ -428,8 +436,13 @@ 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;
Expand Down

0 comments on commit ce68a03

Please sign in to comment.