Skip to content

Commit 4841858

Browse files
authored
[BOLT][DWARF] Add support to debug_names for DW_AT_abstract_origin/DW_AT_specification (llvm#85485)
According to the DWARF spec a DIE that has DW_AT_specification or DW_AT_abstract_origin can be part of .debug_name if a DIE those attribute points to has DW_AT_name or DW_AT_linkage_name.
1 parent e0b19e9 commit 4841858

File tree

5 files changed

+897
-136
lines changed

5 files changed

+897
-136
lines changed

bolt/lib/Core/DebugNames.cpp

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,7 @@ DWARF5AcceleratorTable::addAccelTableEntry(
234234
addUnit(Unit, DWOID);
235235
}
236236

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

273+
auto addEntry =
274+
[&](DIEValue ValName) -> std::optional<BOLTDWARF5AccelTableData *> {
275+
std::optional<std::string> Name = getName(ValName);
276+
if (!Name)
277+
return std::nullopt;
278+
279+
auto &It = Entries[*Name];
272280
bool IsTU = false;
273281
uint32_t DieTag = 0;
274282
uint32_t UnitID = getUnitID(Unit, IsTU, DieTag);
@@ -278,7 +286,7 @@ DWARF5AcceleratorTable::addAccelTableEntry(
278286
if (Iter == CUOffsetsToPatch.end())
279287
BC.errs() << "BOLT-WARNING: [internal-dwarf-warning]: Could not find "
280288
"DWO ID in CU offsets for second Unit Index "
281-
<< Name << ". For DIE at offset: "
289+
<< *Name << ". For DIE at offset: "
282290
<< Twine::utohexstr(CurrentUnitOffset + Die.getOffset())
283291
<< ".\n";
284292
SecondIndex = Iter->second;
@@ -295,11 +303,36 @@ DWARF5AcceleratorTable::addAccelTableEntry(
295303
return It.Values.back();
296304
};
297305

298-
std::optional<BOLTDWARF5AccelTableData *> NameEntry =
299-
addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name));
300-
std::optional<BOLTDWARF5AccelTableData *> LinkageNameEntry =
301-
addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name));
302-
return NameEntry ? NameEntry : LinkageNameEntry;
306+
// Minor optimization not to add entry twice for DW_TAG_namespace if it has no
307+
// DW_AT_name.
308+
if (!(Die.getTag() == dwarf::DW_TAG_namespace &&
309+
!Die.findAttribute(dwarf::Attribute::DW_AT_name)))
310+
addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name));
311+
// For the purposes of determining whether a debugging information entry has a
312+
// particular attribute (such as DW_AT_name), if debugging information entry A
313+
// has a DW_AT_specification or DW_AT_abstract_origin attribute pointing to
314+
// another debugging information entry B, any attributes of B are considered
315+
// to be part of A.
316+
auto processReferencedDie = [&](const dwarf::Attribute &Attr)
317+
-> std::optional<BOLTDWARF5AccelTableData *> {
318+
const DIEValue Value = Die.findAttribute(Attr);
319+
if (!Value)
320+
return std::nullopt;
321+
const DIEEntry &DIEENtry = Value.getDIEEntry();
322+
DIE &EntryDie = DIEENtry.getEntry();
323+
addEntry(EntryDie.findAttribute(dwarf::Attribute::DW_AT_linkage_name));
324+
return addEntry(EntryDie.findAttribute(dwarf::Attribute::DW_AT_name));
325+
};
326+
327+
if (std::optional<BOLTDWARF5AccelTableData *> Entry =
328+
processReferencedDie(dwarf::Attribute::DW_AT_abstract_origin))
329+
return *Entry;
330+
if (std::optional<BOLTDWARF5AccelTableData *> Entry =
331+
processReferencedDie(dwarf::Attribute::DW_AT_specification))
332+
return *Entry;
333+
334+
return addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name));
335+
;
303336
}
304337

305338
/// Algorithm from llvm implementation.

0 commit comments

Comments
 (0)