Skip to content

[BOLT][DWARF] Add support to debug_names for DW_AT_abstract_origin/DW_AT_specification #85485

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 41 additions & 8 deletions bolt/lib/Core/DebugNames.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,8 +234,7 @@ DWARF5AcceleratorTable::addAccelTableEntry(
addUnit(Unit, DWOID);
}

auto addEntry =
[&](DIEValue ValName) -> std::optional<BOLTDWARF5AccelTableData *> {
auto getName = [&](DIEValue ValName) -> std::optional<std::string> {
if ((!ValName || ValName.getForm() == dwarf::DW_FORM_string) &&
NameToUse.empty())
return std::nullopt;
Expand Down Expand Up @@ -268,7 +267,16 @@ DWARF5AcceleratorTable::addAccelTableEntry(
// This the same hash function used in DWARF5AccelTableData.
It.HashValue = caseFoldingDjbHash(Name);
}
return Name;
};

auto addEntry =
[&](DIEValue ValName) -> std::optional<BOLTDWARF5AccelTableData *> {
std::optional<std::string> Name = getName(ValName);
if (!Name)
return std::nullopt;

auto &It = Entries[*Name];
bool IsTU = false;
uint32_t DieTag = 0;
uint32_t UnitID = getUnitID(Unit, IsTU, DieTag);
Expand All @@ -278,7 +286,7 @@ DWARF5AcceleratorTable::addAccelTableEntry(
if (Iter == CUOffsetsToPatch.end())
BC.errs() << "BOLT-WARNING: [internal-dwarf-warning]: Could not find "
"DWO ID in CU offsets for second Unit Index "
<< Name << ". For DIE at offset: "
<< *Name << ". For DIE at offset: "
<< Twine::utohexstr(CurrentUnitOffset + Die.getOffset())
<< ".\n";
SecondIndex = Iter->second;
Expand All @@ -295,11 +303,36 @@ DWARF5AcceleratorTable::addAccelTableEntry(
return It.Values.back();
};

std::optional<BOLTDWARF5AccelTableData *> NameEntry =
addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name));
std::optional<BOLTDWARF5AccelTableData *> LinkageNameEntry =
addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name));
return NameEntry ? NameEntry : LinkageNameEntry;
// Minor optimization not to add entry twice for DW_TAG_namespace if it has no
// DW_AT_name.
if (!(Die.getTag() == dwarf::DW_TAG_namespace &&
!Die.findAttribute(dwarf::Attribute::DW_AT_name)))
addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name));
// For the purposes of determining whether a debugging information entry has a
// particular attribute (such as DW_AT_name), if debugging information entry A
// has a DW_AT_specification or DW_AT_abstract_origin attribute pointing to
// another debugging information entry B, any attributes of B are considered
// to be part of A.
auto processReferencedDie = [&](const dwarf::Attribute &Attr)
-> std::optional<BOLTDWARF5AccelTableData *> {
const DIEValue Value = Die.findAttribute(Attr);
if (!Value)
return std::nullopt;
const DIEEntry &DIEENtry = Value.getDIEEntry();
DIE &EntryDie = DIEENtry.getEntry();
addEntry(EntryDie.findAttribute(dwarf::Attribute::DW_AT_linkage_name));
return addEntry(EntryDie.findAttribute(dwarf::Attribute::DW_AT_name));
};

if (std::optional<BOLTDWARF5AccelTableData *> Entry =
processReferencedDie(dwarf::Attribute::DW_AT_abstract_origin))
return *Entry;
if (std::optional<BOLTDWARF5AccelTableData *> Entry =
processReferencedDie(dwarf::Attribute::DW_AT_specification))
return *Entry;

return addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name));
;
}

/// Algorithm from llvm implementation.
Expand Down
Loading