Skip to content

Commit

Permalink
Disambiguate symbols by their address, not an index.
Browse files Browse the repository at this point in the history
Previously, duplicate symbols were disambiguated in output by writing
one of them as 'foo' and the rest as 'foo#1', 'foo#2', 'foo#3'...

This had two problems. Firstly, not _all_ the duplicate symbols were
visibly disambiguated, so if you happened to see just 'foo' by itself,
you might mistakenly think it was a unique name. Also, those indices
were made up while reading the symbol table, and have no meaning.

A nicer disambiguation strategy is to suffix duplicate symbols with
their address. Then at least you know where to find the symbol.

(It would be nicest to use a disambiguation suffix that had some
meaning in terms of the original source code, like which module the
function had come from. But unfortunately, no such thing survives into
the image.)
  • Loading branch information
statham-arm committed Jun 28, 2024
1 parent 3dd82f7 commit b144608
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 6 deletions.
2 changes: 1 addition & 1 deletion include/libtarmac/image.hh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ struct Symbol {

Addr addr;
size_t size;
int duplicateNr = 0; // disambiguates the symbol name, if needed
bool multiple = false; // are there multiple symbols with this name?
binding_type binding; // can be used for smarter symbol lookup
kind_type kind; // can be used for smarter symbol lookup

Expand Down
28 changes: 23 additions & 5 deletions lib/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ using std::vector;

string Symbol::getName() const
{
if (duplicateNr != 0) {
if (multiple) {
ostringstream oss;
oss << name << "#" << duplicateNr;
oss << name << "@0x" << std::hex << addr;
return oss.str();
}
return name;
Expand Down Expand Up @@ -80,7 +80,24 @@ void Image::add_symbol(const Symbol &sym_)

// name -> symbol map
auto &dups = symtab[sym.name];
sym.duplicateNr = dups.size();
if (dups.size() > 0) {
// There's already at least one symbol with this name. Mark
// the new one as multiple, meaning it will need
// disambiguation when the address is printed later.
sym.multiple = true;
if (dups.size() == 1) {
// And if there was previously only one symbol with the
// same name, then that one isn't yet marked as multiple,
// so do that too.
//
// The symbol pointer in 'dups' is a const pointer, but we
// know it's also an element of the 'symbols' list, which
// we're allowed to mutate in this function (indeed we
// already have done). So it's safe to cast away the const
// and modify it.
const_cast<Symbol *>(dups.front())->multiple = true;
}
}
dups.push_back(&sym);
}

Expand Down Expand Up @@ -214,8 +231,9 @@ void Image::dump()
{
printf(_("Image '%s':\n"), image_filename.c_str());
for (const auto &sym : symbols) {
printf(_("symbol '%s#%d' [0x%llx, 0x%llx)\n"), sym.name.c_str(),
sym.duplicateNr, sym.addr, sym.addr + sym.size);
std::string name = sym.getName();
printf(_("symbol '%s' [0x%llx, 0x%llx)\n"), name.c_str(),
sym.addr, sym.addr + sym.size);
}
}

Expand Down

0 comments on commit b144608

Please sign in to comment.