-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[BOLT][DWARF] Add support for transitive DW_AT_name/DW_AT_linkage_name resolution for DW_AT_name/DW_AT_linkage_name. #119493
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
Conversation
@llvm/pr-subscribers-bolt Author: Alexander Yermolovich (ayermolo) ChangesThis fix handles a case where a DIE that does not have DW_AT_name/DW_AT_linkage_name, but has a reference to another DIE using DW_AT_abstract_origin/DW_AT_specification. It also fixes a bug where there are cross CU references for those attributes. Previously it would use a DWARF Unit of a DIE which was being processed The warf5-debug-names-cross-cu.s test just happened to work because how it was constructed where string section was shared by both DWARF Units. To resolve DW_AT_name/DW_AT_linkage_name this patch iterates over references until it either reaches the final DIE or finds both of those names. Patch is 84.36 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119493.diff 6 Files Affected:
diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h
index d1acba0f26c78f..bd22c536c56fca 100644
--- a/bolt/include/bolt/Core/DIEBuilder.h
+++ b/bolt/include/bolt/Core/DIEBuilder.h
@@ -162,7 +162,7 @@ class DIEBuilder {
/// Clone an attribute in reference format.
void cloneDieOffsetReferenceAttribute(
- DIE &Die, const DWARFUnit &U, const DWARFDie &InputDIE,
+ DIE &Die, DWARFUnit &U, const DWARFDie &InputDIE,
const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec, uint64_t Ref);
/// Clone an attribute in block format.
diff --git a/bolt/include/bolt/Core/DebugNames.h b/bolt/include/bolt/Core/DebugNames.h
index 0e61a0e4f9d9f0..cc4e13a481b2d6 100644
--- a/bolt/include/bolt/Core/DebugNames.h
+++ b/bolt/include/bolt/Core/DebugNames.h
@@ -72,8 +72,8 @@ class DWARF5AcceleratorTable {
return std::move(FullTableBuffer);
}
/// Adds a DIE that is referenced across CUs.
- void addCrossCUDie(const DIE *Die) {
- CrossCUDies.insert({Die->getOffset(), Die});
+ void addCrossCUDie(DWARFUnit *Unit, const DIE *Die) {
+ CrossCUDies.insert({Die->getOffset(), {Unit, Die}});
}
/// Returns true if the DIE can generate an entry for a cross cu reference.
/// This only checks TAGs of a DIE because when this is invoked DIE might not
@@ -145,7 +145,7 @@ class DWARF5AcceleratorTable {
llvm::DenseMap<uint64_t, uint32_t> CUOffsetsToPatch;
// Contains a map of Entry ID to Entry relative offset.
llvm::DenseMap<uint64_t, uint32_t> EntryRelativeOffsets;
- llvm::DenseMap<uint64_t, const DIE *> CrossCUDies;
+ llvm::DenseMap<uint64_t, std::pair<DWARFUnit *, const DIE *>> CrossCUDies;
/// Adds Unit to either CUList, LocalTUList or ForeignTUList.
/// Input Unit being processed, and DWO ID if Unit is being processed comes
/// from a DWO section.
@@ -191,6 +191,29 @@ class DWARF5AcceleratorTable {
void emitData();
/// Emit augmentation string.
void emitAugmentationString() const;
+ /// Creates a new entry for a given DIE.
+ std::optional<BOLTDWARF5AccelTableData *>
+ addEntry(DWARFUnit &DU, const DIE &CurrDie,
+ const std::optional<uint64_t> &DWOID,
+ const std::optional<BOLTDWARF5AccelTableData *> &Parent,
+ const std::optional<std::string> &Name,
+ const uint32_t NumberParentsInChain);
+ /// Returns UnitID for a given DWARFUnit.
+ uint32_t getUnitID(const DWARFUnit &Unit,
+ const std::optional<uint64_t> &DWOID, bool &IsTU);
+ std::optional<std::string> getName(DWARFUnit &DU,
+ const std::optional<uint64_t> &DWOID,
+ const std::string &NameToUse,
+ DIEValue ValName);
+ /// Processes a DIE with references to other DIEs for DW_AT_name and
+ /// DW_AT_linkage_name resolution.
+ /// If DW_AT_name exists method creates a new entry for this DIE and returns
+ /// it.
+ std::optional<BOLTDWARF5AccelTableData *> processReferencedDie(
+ DWARFUnit &Unit, const DIE &Die, const std::optional<uint64_t> &DWOID,
+ const std::optional<BOLTDWARF5AccelTableData *> &Parent,
+ const std::string &NameToUse, const uint32_t NumberParentsInChain,
+ const dwarf::Attribute &Attr);
};
} // namespace bolt
} // namespace llvm
diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp
index 414912ea1c2076..80ad583e079d49 100644
--- a/bolt/lib/Core/DIEBuilder.cpp
+++ b/bolt/lib/Core/DIEBuilder.cpp
@@ -622,7 +622,7 @@ DWARFDie DIEBuilder::resolveDIEReference(
}
void DIEBuilder::cloneDieOffsetReferenceAttribute(
- DIE &Die, const DWARFUnit &U, const DWARFDie &InputDIE,
+ DIE &Die, DWARFUnit &U, const DWARFDie &InputDIE,
const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec, uint64_t Ref) {
DIE *NewRefDie = nullptr;
DWARFUnit *RefUnit = nullptr;
@@ -654,7 +654,7 @@ void DIEBuilder::cloneDieOffsetReferenceAttribute(
// Adding referenced DIE to DebugNames to be used when entries are created
// that contain cross cu references.
if (DebugNamesTable.canGenerateEntryWithCrossCUReference(U, Die, AttrSpec))
- DebugNamesTable.addCrossCUDie(DieInfo.Die);
+ DebugNamesTable.addCrossCUDie(&U, DieInfo.Die);
// no matter forward reference or backward reference, we are supposed
// to calculate them in `finish` due to the possible modification of
// the DIE.
diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp
index 280c7c505eeda1..b9ea1765e39b6f 100644
--- a/bolt/lib/Core/DebugNames.cpp
+++ b/bolt/lib/Core/DebugNames.cpp
@@ -222,134 +222,114 @@ static uint64_t getEntryID(const BOLTDWARF5AccelTableData &Entry) {
return reinterpret_cast<uint64_t>(&Entry);
}
-std::optional<BOLTDWARF5AccelTableData *>
-DWARF5AcceleratorTable::addAccelTableEntry(
- DWARFUnit &Unit, const DIE &Die, const std::optional<uint64_t> &DWOID,
- const uint32_t NumberParentsInChain,
- std::optional<BOLTDWARF5AccelTableData *> &Parent) {
- if (Unit.getVersion() < 5 || !NeedToCreate)
- return std::nullopt;
- std::string NameToUse = "";
-
- auto getUnitID = [&](const DWARFUnit &Unit, bool &IsTU,
- uint32_t &DieTag) -> uint32_t {
- IsTU = Unit.isTypeUnit();
- DieTag = Die.getTag();
- if (IsTU) {
- if (DWOID) {
- const uint64_t TUHash = cast<DWARFTypeUnit>(&Unit)->getTypeHash();
- auto Iter = TUHashToIndexMap.find(TUHash);
- assert(Iter != TUHashToIndexMap.end() &&
- "Could not find TU hash in map");
- return Iter->second;
- }
- return LocalTUList.size() - 1;
+uint32_t DWARF5AcceleratorTable::getUnitID(const DWARFUnit &Unit,
+ const std::optional<uint64_t> &DWOID,
+ bool &IsTU) {
+ IsTU = Unit.isTypeUnit();
+ if (IsTU) {
+ if (DWOID) {
+ const uint64_t TUHash = cast<DWARFTypeUnit>(&Unit)->getTypeHash();
+ auto Iter = TUHashToIndexMap.find(TUHash);
+ assert(Iter != TUHashToIndexMap.end() && "Could not find TU hash in map");
+ return Iter->second;
}
- return CUList.size() - 1;
- };
+ return LocalTUList.size() - 1;
+ }
+ return CUList.size() - 1;
+}
- if (!canProcess(Unit, Die, NameToUse, false))
+std::optional<std::string> DWARF5AcceleratorTable::getName(
+ DWARFUnit &Unit, const std::optional<uint64_t> &DWOID,
+ const std::string &NameToUse, DIEValue ValName) {
+ if ((!ValName || ValName.getForm() == dwarf::DW_FORM_string) &&
+ NameToUse.empty())
return std::nullopt;
-
- // Addes a Unit to either CU, LocalTU or ForeignTU list the first time we
- // encounter it.
- // Invoking it here so that we don't add Units that don't have any entries.
- if (&Unit != CurrentUnit) {
- CurrentUnit = &Unit;
- addUnit(Unit, DWOID);
+ std::string Name = "";
+ uint64_t NameIndexOffset = 0;
+ if (NameToUse.empty()) {
+ NameIndexOffset = ValName.getDIEInteger().getValue();
+ if (ValName.getForm() != dwarf::DW_FORM_strp)
+ NameIndexOffset = getNameOffset(BC, Unit, NameIndexOffset);
+ // Counts on strings end with '\0'.
+ Name = std::string(&StrSection.data()[NameIndexOffset]);
+ } else {
+ Name = NameToUse;
}
-
- auto getName = [&](DIEValue ValName) -> std::optional<std::string> {
- if ((!ValName || ValName.getForm() == dwarf::DW_FORM_string) &&
- NameToUse.empty())
- return std::nullopt;
- std::string Name = "";
- uint64_t NameIndexOffset = 0;
- if (NameToUse.empty()) {
- NameIndexOffset = ValName.getDIEInteger().getValue();
- if (ValName.getForm() != dwarf::DW_FORM_strp)
- NameIndexOffset = getNameOffset(BC, Unit, NameIndexOffset);
- // Counts on strings end with '\0'.
- Name = std::string(&StrSection.data()[NameIndexOffset]);
- } else {
- Name = NameToUse;
- }
- auto &It = Entries[Name];
- if (It.Values.empty()) {
- if (DWOID && NameToUse.empty()) {
- // For DWO Unit the offset is in the .debug_str.dwo section.
- // Need to find offset for the name in the .debug_str section.
- llvm::hash_code Hash = llvm::hash_value(llvm::StringRef(Name));
- auto ItCache = StrCacheToOffsetMap.find(Hash);
- if (ItCache == StrCacheToOffsetMap.end())
- NameIndexOffset = MainBinaryStrWriter.addString(Name);
- else
- NameIndexOffset = ItCache->second;
- }
- if (!NameToUse.empty())
+ auto &It = Entries[Name];
+ if (It.Values.empty()) {
+ if (DWOID && NameToUse.empty()) {
+ // For DWO Unit the offset is in the .debug_str.dwo section.
+ // Need to find offset for the name in the .debug_str section.
+ llvm::hash_code Hash = llvm::hash_value(llvm::StringRef(Name));
+ auto ItCache = StrCacheToOffsetMap.find(Hash);
+ if (ItCache == StrCacheToOffsetMap.end())
NameIndexOffset = MainBinaryStrWriter.addString(Name);
- It.StrOffset = NameIndexOffset;
- // This the same hash function used in DWARF5AccelTableData.
- It.HashValue = caseFoldingDjbHash(Name);
+ else
+ NameIndexOffset = ItCache->second;
}
- return Name;
- };
+ if (!NameToUse.empty())
+ NameIndexOffset = MainBinaryStrWriter.addString(Name);
+ It.StrOffset = NameIndexOffset;
+ // 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;
+std::optional<BOLTDWARF5AccelTableData *> DWARF5AcceleratorTable::addEntry(
+ DWARFUnit &DU, const DIE &CurrDie, const std::optional<uint64_t> &DWOID,
+ const std::optional<BOLTDWARF5AccelTableData *> &Parent,
+ const std::optional<std::string> &Name,
+ const uint32_t NumberParentsInChain) {
+ if (!Name)
+ return std::nullopt;
- auto &It = Entries[*Name];
- bool IsTU = false;
- uint32_t DieTag = 0;
- uint32_t UnitID = getUnitID(Unit, IsTU, DieTag);
- std::optional<unsigned> SecondIndex = std::nullopt;
- if (IsTU && DWOID) {
- auto Iter = CUOffsetsToPatch.find(*DWOID);
- 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: "
- << Twine::utohexstr(CurrentUnitOffset + Die.getOffset())
- << ".\n";
- SecondIndex = Iter->second;
- }
- std::optional<uint64_t> ParentOffset =
- (Parent ? std::optional<uint64_t>(getEntryID(**Parent)) : std::nullopt);
- // This will be populated later in writeEntry.
- // This way only parent entries get tracked.
- // Keeping memory footprint down.
- if (ParentOffset)
- EntryRelativeOffsets.insert({*ParentOffset, 0});
- bool IsParentRoot = false;
- // If there is no parent and no valid Entries in parent chain this is a root
- // to be marked with a flag.
- if (!Parent && !NumberParentsInChain)
- IsParentRoot = true;
- It.Values.push_back(new (Allocator) BOLTDWARF5AccelTableData(
- Die.getOffset(), ParentOffset, DieTag, UnitID, IsParentRoot, IsTU,
- SecondIndex));
- return It.Values.back();
- };
+ auto &It = Entries[*Name];
+ bool IsTU = false;
+ uint32_t DieTag = CurrDie.getTag();
+ uint32_t UnitID = getUnitID(DU, DWOID, IsTU);
+ std::optional<unsigned> SecondIndex = std::nullopt;
+ if (IsTU && DWOID) {
+ auto Iter = CUOffsetsToPatch.find(*DWOID);
+ 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: "
+ << Twine::utohexstr(CurrentUnitOffset + CurrDie.getOffset())
+ << ".\n";
+ SecondIndex = Iter->second;
+ }
+ std::optional<uint64_t> ParentOffset =
+ (Parent ? std::optional<uint64_t>(getEntryID(**Parent)) : std::nullopt);
+ // This will be populated later in writeEntry.
+ // This way only parent entries get tracked.
+ // Keeping memory footprint down.
+ if (ParentOffset)
+ EntryRelativeOffsets.insert({*ParentOffset, 0});
+ bool IsParentRoot = false;
+ // If there is no parent and no valid Entries in parent chain this is a root
+ // to be marked with a flag.
+ if (!Parent && !NumberParentsInChain)
+ IsParentRoot = true;
+ It.Values.push_back(new (Allocator) BOLTDWARF5AccelTableData(
+ CurrDie.getOffset(), ParentOffset, DieTag, UnitID, IsParentRoot, IsTU,
+ SecondIndex));
+ return It.Values.back();
+}
- // 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);
+std::optional<BOLTDWARF5AccelTableData *>
+DWARF5AcceleratorTable::processReferencedDie(
+ DWARFUnit &Unit, const DIE &Die, const std::optional<uint64_t> &DWOID,
+ const std::optional<BOLTDWARF5AccelTableData *> &Parent,
+ const std::string &NameToUse, const uint32_t NumberParentsInChain,
+ const dwarf::Attribute &Attr) {
+ DIEValue Value = Die.findAttribute(Attr);
+ if (!Value)
+ return std::nullopt;
+ auto getReferenceDie = [&](const DIEValue &Value, const DIE *RefDieUsed)
+ -> std::optional<std::pair<DWARFUnit *, const DIE *>> {
if (!Value)
return std::nullopt;
- const DIE *EntryDie = nullptr;
if (Value.getForm() == dwarf::DW_FORM_ref_addr) {
auto Iter = CrossCUDies.find(Value.getDIEInteger().getValue());
if (Iter == CrossCUDies.end()) {
@@ -359,24 +339,97 @@ DWARF5AcceleratorTable::addAccelTableEntry(
<< ".\n";
return std::nullopt;
}
- EntryDie = Iter->second;
- } else {
- const DIEEntry &DIEENtry = Value.getDIEEntry();
- EntryDie = &DIEENtry.getEntry();
+ return Iter->second;
}
-
- addEntry(EntryDie->findAttribute(dwarf::Attribute::DW_AT_linkage_name));
- return addEntry(EntryDie->findAttribute(dwarf::Attribute::DW_AT_name));
+ const DIEEntry &DIEENtry = Value.getDIEEntry();
+ return {{&Unit, &DIEENtry.getEntry()}};
};
- if (std::optional<BOLTDWARF5AccelTableData *> Entry =
- processReferencedDie(dwarf::Attribute::DW_AT_abstract_origin))
+ DIEValue AttrValLinkageName;
+ DIEValue AttrValName = Die.findAttribute(dwarf::Attribute::DW_AT_name);
+ DWARFUnit *RefUnit = &Unit;
+ const DIE *RefDieUsed = &Die;
+ // It is possible to have DW_TAG_subprogram only with DW_AT_linkage_name that
+ // DW_AT_abstract_origin/DW_AT_specification point to.
+ while (!AttrValName) {
+ std::optional<std::pair<DWARFUnit *, const DIE *>> RefDUDie =
+ getReferenceDie(Value, RefDieUsed);
+ if (!RefDUDie)
+ break;
+ RefUnit = RefDUDie->first;
+ const DIE &RefDie = *RefDUDie->second;
+ RefDieUsed = &RefDie;
+ if (!AttrValLinkageName)
+ AttrValLinkageName =
+ RefDie.findAttribute(dwarf::Attribute::DW_AT_linkage_name);
+ AttrValName = RefDie.findAttribute(dwarf::Attribute::DW_AT_name);
+ Value = RefDie.findAttribute(dwarf::Attribute::DW_AT_abstract_origin);
+ if (!Value)
+ Value = RefDie.findAttribute(dwarf::Attribute::DW_AT_specification);
+ }
+ addEntry(Unit, Die, DWOID, Parent,
+ getName(*RefUnit, DWOID, NameToUse, AttrValLinkageName),
+ NumberParentsInChain);
+ return addEntry(Unit, Die, DWOID, Parent,
+ getName(*RefUnit, DWOID, NameToUse, AttrValName),
+ NumberParentsInChain);
+}
+
+std::optional<BOLTDWARF5AccelTableData *>
+DWARF5AcceleratorTable::addAccelTableEntry(
+ DWARFUnit &Unit, const DIE &Die, const std::optional<uint64_t> &DWOID,
+ const uint32_t NumberParentsInChain,
+ std::optional<BOLTDWARF5AccelTableData *> &Parent) {
+ if (Unit.getVersion() < 5 || !NeedToCreate)
+ return std::nullopt;
+ std::string NameToUse = "";
+
+ if (!canProcess(Unit, Die, NameToUse, false))
+ return std::nullopt;
+
+ // Addes a Unit to either CU, LocalTU or ForeignTU list the first time we
+ // encounter it.
+ // Invoking it here so that we don't add Units that don't have any entries.
+ if (&Unit != CurrentUnit) {
+ CurrentUnit = &Unit;
+ addUnit(Unit, DWOID);
+ }
+
+ // Minor optimization not to add entry twice for DW_TAG_namespace if it has no
+ // DW_AT_name.
+ std::optional<BOLTDWARF5AccelTableData *> LinkageEntry = std::nullopt;
+ DIEValue NameVal = Die.findAttribute(dwarf::Attribute::DW_AT_name);
+ DIEValue LinkageNameVal =
+ Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name);
+ if (!(Die.getTag() == dwarf::DW_TAG_namespace && !NameVal))
+ LinkageEntry = addEntry(Unit, Die, DWOID, Parent,
+ getName(Unit, DWOID, NameToUse, LinkageNameVal),
+ NumberParentsInChain);
+
+ std::optional<BOLTDWARF5AccelTableData *> NameEntry =
+ addEntry(Unit, Die, DWOID, Parent,
+ getName(Unit, DWOID, NameToUse, NameVal), NumberParentsInChain);
+ if (NameEntry)
+ return NameEntry;
+
+ // The DIE doesn't have DW_AT_name or DW_AT_linkage_name, so we need to see if
+ // we can follow other attributes to find them. 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.
+ if (std::optional<BOLTDWARF5AccelTableData *> Entry = processReferencedDie(
+ Unit, Die, DWOID, Parent, NameToUse, NumberParentsInChain,
+ dwarf::Attribute::DW_AT_abstract_origin))
return *Entry;
- if (std::optional<BOLTDWARF5AccelTableData *> Entry =
- processReferencedDie(dwarf::Attribute::DW_AT_specification))
+ if (std::optional<BOLTDWARF5AccelTableData *> Entry = processReferencedDie(
+ Unit, Die, DWOID, Parent, NameToUse, NumberParentsInChain,
+ dwarf::Attribute::DW_AT_specification))
return *Entry;
- return addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name));
+ // This point can be hit by DW_TAG_varialbe that has no DW_AT_name.
+ return std::nullopt;
}
/// Algorithm from llvm implementation.
diff --git a/bolt/test/X86/dwarf5-debug-names-abstract-origin-linkage-name-only.s b/bolt/test/X86/dwarf5-debug-names-abstract-origin-linkage-name-only.s
new file mode 100644
index 00000000000000..8c9817ce91edb3
--- /dev/null
+++ b/bolt/test/X86/dwarf5-debug-names-abstract-origin-linkage-name-only.s
@@ -0,0 +1,568 @@
+# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %tmain.o
+# RUN: %clang %cflags -gdwarf-5 %tmain.o -o %tmain.exe
+# RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections
+# RUN: llvm-dwarfdump --debug-names %tmain.exe.bolt > %tlog.txt
+# RUN: cat %tlog.txt | FileCheck -check-prefix=BOLT %s
+
+## Tests that bolt can correctly generate debug_names when there is an DW_TAG_inlined_subroutine
+## with DW_AT_abstract_origin that points to DW_TAG_subprogram that only has DW_AT_linkage_name.
+
+# BOLT: Name Index @ 0x0 {
+# BOLT-NEXT: Header {
+# BOLT-NEXT: Length: 0xA2
+# BOLT-NEXT: Format: DWARF32
+# BOLT-NEXT: Version: 5
+# BOLT-NEXT: CU count: 1
+# BOLT-NEXT: Local TU count: 0
+# BOLT-NEXT: Foreign TU count: 0
+# BOLT-NEXT: Bucket count: 4
+# BOLT-NEXT: Name count: 4
+# BOLT-NEXT: Abbreviations table size: 0x19
+# BOLT-NEXT: Augmentation: 'BOLT'...
[truncated]
|
Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: Differential Revision: https://phabricator.intern.facebook.com/D67007861
f6fbef2
to
16c93ba
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine to me, but please change the commit message to match the title rather than using refactor + support abstr chain
That will be automatically be used when Squash and merge through UI. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This fix handles a case where a DIE that does not have DW_AT_name/DW_AT_linkage_name, but has a reference to another DIE using DW_AT_abstract_origin/DW_AT_specification. It also fixes a bug where there are cross CU references for those attributes. Previously it would use a DWARF Unit of a DIE which was being processed The warf5-debug-names-cross-cu.s test just happened to work because how it was constructed where string section was shared by both DWARF Units.
To resolve DW_AT_name/DW_AT_linkage_name this patch iterates over references until it either reaches the final DIE or finds both of those names.