[llvm] dc5c044 - Add verification support for .debug_names with foreign type units. (#109011)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 22 09:35:14 PDT 2024
Author: Greg Clayton
Date: 2024-10-22T09:35:10-07:00
New Revision: dc5c044193b31231dcb1d32c76bb03cbc9ed2c74
URL: https://github.com/llvm/llvm-project/commit/dc5c044193b31231dcb1d32c76bb03cbc9ed2c74
DIFF: https://github.com/llvm/llvm-project/commit/dc5c044193b31231dcb1d32c76bb03cbc9ed2c74.diff
LOG: Add verification support for .debug_names with foreign type units. (#109011)
This commit enables 'llvm-dwarfdump --veriy' to verify the DWARF in
foreign type units when using split DWARF for the .debug_names section.
Added:
llvm/test/tools/llvm-dwarfdump/Inputs/verify_split_dwarf_debug_names_ftus_dwo.yaml
llvm/test/tools/llvm-dwarfdump/Inputs/verify_split_dwarf_debug_names_ftus_exe.yaml
llvm/test/tools/llvm-dwarfdump/verify_split_dwarf_debug_names_ftus.test
Modified:
llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
index 0117c90e77f990..9d7ac12cefdc85 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
@@ -447,7 +447,7 @@ class DWARFDebugNames : public DWARFAcceleratorTable {
std::optional<uint64_t> getForeignTUTypeSignature() const override;
std::optional<dwarf::Tag> getTag() const override { return tag(); }
- // Special function that will return the related CU offset needed type
+ // Special function that will return the related CU offset needed type
// units. This gets used to find the .dwo file that originated the entries
// for a given type unit.
std::optional<uint64_t> getRelatedCUOffset() const;
@@ -468,12 +468,13 @@ class DWARFDebugNames : public DWARFAcceleratorTable {
/// index for an entry that is a type unit.
std::optional<uint64_t> getRelatedCUIndex() const;
- /// Returns the Index into the Local Type Unit list of the owning Name
+ /// Returns the index of the Type Unit of the owning
+ /// Name
/// Index or std::nullopt if this Accelerator Entry does not have an
/// associated Type Unit. It is up to the user to verify that the
- /// returned Index is valid in the owning NameIndex (or use
+ /// returned Index is a valid index in the owning NameIndex (or use
/// getLocalTUOffset(), which will handle that check itself).
- std::optional<uint64_t> getLocalTUIndex() const;
+ std::optional<uint64_t> getTUIndex() const;
/// .debug_names-specific getter, which always succeeds (DWARF v5 index
/// entries always have a tag).
@@ -803,7 +804,7 @@ class DWARFDebugNames : public DWARFAcceleratorTable {
private:
SmallVector<NameIndex, 0> NameIndices;
- DenseMap<uint64_t, const NameIndex *> CUToNameIndex;
+ DenseMap<uint64_t, const NameIndex *> UnitOffsetToNameIndex;
public:
DWARFDebugNames(const DWARFDataExtractor &AccelSection,
@@ -820,9 +821,9 @@ class DWARFDebugNames : public DWARFAcceleratorTable {
const_iterator begin() const { return NameIndices.begin(); }
const_iterator end() const { return NameIndices.end(); }
- /// Return the Name Index covering the compile unit at CUOffset, or nullptr if
- /// there is no Name Index covering that unit.
- const NameIndex *getCUNameIndex(uint64_t CUOffset);
+ /// Return the Name Index covering the compile unit or local type unit at
+ /// UnitOffset, or nullptr if there is no Name Index covering that unit.
+ const NameIndex *getCUOrTUNameIndex(uint64_t UnitOffset);
};
/// Calculates the starting offsets for various sections within the
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
index 455ccaab74d7e0..0d6e2b076cc344 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -209,6 +209,9 @@ class DWARFContext : public DIContext {
return State->getDWOUnits();
}
+ /// Return true of this DWARF context is a DWP file.
+ bool isDWP() const;
+
/// Get units from .debug_types.dwo in the DWO context.
unit_iterator_range dwo_types_section_units() {
DWARFUnitVector &DWOUnits = State->getDWOUnits();
@@ -262,7 +265,7 @@ class DWARFContext : public DIContext {
}
DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
- DWARFTypeUnit *getTypeUnitForHash(uint16_t Version, uint64_t Hash, bool IsDWO);
+ DWARFTypeUnit *getTypeUnitForHash(uint64_t Hash, bool IsDWO);
/// Return the DWARF unit that includes an offset (relative to .debug_info).
DWARFUnit *getUnitForOffset(uint64_t Offset);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
index 7fba00d0e457b6..ea336378bebb33 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
@@ -635,7 +635,7 @@ std::optional<uint64_t> DWARFDebugNames::Entry::getRelatedCUIndex() const {
if (std::optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_compile_unit))
return Off->getAsUnsignedConstant();
// In a per-CU index, the entries without a DW_IDX_compile_unit attribute
- // implicitly refer to the single CU.
+ // implicitly refer to the single CU.
if (NameIdx->getCUCount() == 1)
return 0;
return std::nullopt;
@@ -665,7 +665,7 @@ std::optional<uint64_t> DWARFDebugNames::Entry::getRelatedCUOffset() const {
}
std::optional<uint64_t> DWARFDebugNames::Entry::getLocalTUOffset() const {
- std::optional<uint64_t> Index = getLocalTUIndex();
+ std::optional<uint64_t> Index = getTUIndex();
if (!Index || *Index >= NameIdx->getLocalTUCount())
return std::nullopt;
return NameIdx->getLocalTUOffset(*Index);
@@ -673,7 +673,7 @@ std::optional<uint64_t> DWARFDebugNames::Entry::getLocalTUOffset() const {
std::optional<uint64_t>
DWARFDebugNames::Entry::getForeignTUTypeSignature() const {
- std::optional<uint64_t> Index = getLocalTUIndex();
+ std::optional<uint64_t> Index = getTUIndex();
const uint32_t NumLocalTUs = NameIdx->getLocalTUCount();
if (!Index || *Index < NumLocalTUs)
return std::nullopt; // Invalid TU index or TU index is for a local TU
@@ -684,7 +684,7 @@ DWARFDebugNames::Entry::getForeignTUTypeSignature() const {
return NameIdx->getForeignTUSignature(ForeignTUIndex);
}
-std::optional<uint64_t> DWARFDebugNames::Entry::getLocalTUIndex() const {
+std::optional<uint64_t> DWARFDebugNames::Entry::getTUIndex() const {
if (std::optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_type_unit))
return Off->getAsUnsignedConstant();
return std::nullopt;
@@ -1061,14 +1061,16 @@ DWARFDebugNames::equal_range(StringRef Key) const {
}
const DWARFDebugNames::NameIndex *
-DWARFDebugNames::getCUNameIndex(uint64_t CUOffset) {
- if (CUToNameIndex.size() == 0 && NameIndices.size() > 0) {
+DWARFDebugNames::getCUOrTUNameIndex(uint64_t UnitOffset) {
+ if (UnitOffsetToNameIndex.size() == 0 && NameIndices.size() > 0) {
for (const auto &NI : *this) {
for (uint32_t CU = 0; CU < NI.getCUCount(); ++CU)
- CUToNameIndex.try_emplace(NI.getCUOffset(CU), &NI);
+ UnitOffsetToNameIndex.try_emplace(NI.getCUOffset(CU), &NI);
+ for (uint32_t TU = 0; TU < NI.getLocalTUCount(); ++TU)
+ UnitOffsetToNameIndex.try_emplace(NI.getLocalTUOffset(TU), &NI);
}
}
- return CUToNameIndex.lookup(CUOffset);
+ return UnitOffsetToNameIndex.lookup(UnitOffset);
}
static bool isObjCSelector(StringRef Name) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index bca0d179dacf21..e8337571fb2c0f 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1345,8 +1345,7 @@ void DWARFContext::dump(
getDebugNames().dump(OS);
}
-DWARFTypeUnit *DWARFContext::getTypeUnitForHash(uint16_t Version, uint64_t Hash,
- bool IsDWO) {
+DWARFTypeUnit *DWARFContext::getTypeUnitForHash(uint64_t Hash, bool IsDWO) {
DWARFUnitVector &DWOUnits = State->getDWOUnits();
if (const auto &TUI = getTUIndex()) {
if (const auto *R = TUI.getFromHash(Hash))
@@ -2478,3 +2477,5 @@ uint8_t DWARFContext::getCUAddrSize() {
auto CUs = compile_units();
return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
}
+
+bool DWARFContext::isDWP() const { return !DObj->getCUIndexSection().empty(); }
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 6e7b5870dfa29f..c1cd587877de0c 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -319,8 +319,8 @@ DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const {
if (DWARFUnit *SpecUnit = U->getUnitVector().getUnitForOffset(*Offset))
Result = SpecUnit->getDIEForOffset(*Offset);
} else if (std::optional<uint64_t> Sig = V.getAsSignatureReference()) {
- if (DWARFTypeUnit *TU = U->getContext().getTypeUnitForHash(
- U->getVersion(), *Sig, U->isDWOUnit()))
+ if (DWARFTypeUnit *TU =
+ U->getContext().getTypeUnitForHash(*Sig, U->isDWOUnit()))
Result = TU->getDIEForOffset(TU->getTypeOffset() + TU->getOffset());
}
return Result;
@@ -329,8 +329,8 @@ DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const {
DWARFDie DWARFDie::resolveTypeUnitReference() const {
if (auto Attr = find(DW_AT_signature)) {
if (std::optional<uint64_t> Sig = Attr->getAsReferenceUVal()) {
- if (DWARFTypeUnit *TU = U->getContext().getTypeUnitForHash(
- U->getVersion(), *Sig, U->isDWOUnit()))
+ if (DWARFTypeUnit *TU =
+ U->getContext().getTypeUnitForHash(*Sig, U->isDWOUnit()))
return TU->getDIEForOffset(TU->getTypeOffset() + TU->getOffset());
}
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index fa3e8ad21dbd4d..1fe3eb1e90fe65 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -24,6 +24,7 @@
#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
#include "llvm/DebugInfo/DWARF/DWARFObject.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
#include "llvm/Object/Error.h"
#include "llvm/Support/DJB.h"
@@ -1479,13 +1480,6 @@ unsigned DWARFVerifier::verifyNameIndexAttribute(
unsigned
DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
- if (NI.getForeignTUCount() > 0) {
- warn() << formatv("Name Index @ {0:x}: Verifying indexes of foreign type "
- "units is not currently supported.\n",
- NI.getUnitOffset());
- return 0;
- }
-
unsigned NumErrors = 0;
for (const auto &Abbrev : NI.getAbbrevs()) {
StringRef TagName = dwarf::TagString(Abbrev.Tag);
@@ -1573,10 +1567,6 @@ static SmallVector<std::string, 3> getNames(const DWARFDie &DIE,
unsigned DWARFVerifier::verifyNameIndexEntries(
const DWARFDebugNames::NameIndex &NI,
const DWARFDebugNames::NameTableEntry &NTE) {
- // Verifying foreign type unit indexes not supported.
- if (NI.getForeignTUCount() > 0)
- return 0;
-
const char *CStr = NTE.getString();
if (!CStr) {
ErrorCategory.Report("Unable to get string associated with name", [&]() {
@@ -1596,8 +1586,8 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
for (; EntryOr; ++NumEntries, EntryID = NextEntryID,
EntryOr = NI.getEntry(&NextEntryID)) {
- std::optional<uint64_t> CUIndex = EntryOr->getCUIndex();
- std::optional<uint64_t> TUIndex = EntryOr->getLocalTUIndex();
+ std::optional<uint64_t> CUIndex = EntryOr->getRelatedCUIndex();
+ std::optional<uint64_t> TUIndex = EntryOr->getTUIndex();
if (CUIndex && *CUIndex >= NI.getCUCount()) {
ErrorCategory.Report("Name Index entry contains invalid CU index", [&]() {
error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
@@ -1607,7 +1597,9 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
++NumErrors;
continue;
}
- if (TUIndex && *TUIndex >= NI.getLocalTUCount()) {
+ const uint32_t NumLocalTUs = NI.getLocalTUCount();
+ const uint32_t NumForeignTUs = NI.getForeignTUCount();
+ if (TUIndex && *TUIndex >= (NumLocalTUs + NumForeignTUs)) {
ErrorCategory.Report("Name Index entry contains invalid TU index", [&]() {
error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
"invalid TU index ({2}).\n",
@@ -1617,11 +1609,44 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
continue;
}
std::optional<uint64_t> UnitOffset;
- if (TUIndex)
- UnitOffset = NI.getLocalTUOffset(*TUIndex);
- else if (CUIndex)
+ if (TUIndex) {
+ // We have a local or foreign type unit.
+ if (*TUIndex >= NumLocalTUs) {
+ // This is a foreign type unit, we will find the right type unit by
+ // type unit signature later in this function.
+
+ // Foreign type units must have a valid CU index, either from a
+ // DW_IDX_comp_unit attribute value or from the .debug_names table only
+ // having a single compile unit. We need the originating compile unit
+ // because foreign type units can come from any .dwo file, yet only one
+ // copy of the type unit will end up in the .dwp file.
+ if (CUIndex) {
+ // We need the local skeleton unit offset for the code below.
+ UnitOffset = NI.getCUOffset(*CUIndex);
+ } else {
+ ErrorCategory.Report(
+ "Name Index entry contains foreign TU index with invalid CU "
+ "index",
+ [&]() {
+ error() << formatv(
+ "Name Index @ {0:x}: Entry @ {1:x} contains an "
+ "foreign TU index ({2}) with no CU index.\n",
+ NI.getUnitOffset(), EntryID, *TUIndex);
+ });
+ ++NumErrors;
+ continue;
+ }
+ } else {
+ // Local type unit, get the DWARF unit offset for the type unit.
+ UnitOffset = NI.getLocalTUOffset(*TUIndex);
+ }
+ } else if (CUIndex) {
+ // Local CU entry, get the DWARF unit offset for the CU.
UnitOffset = NI.getCUOffset(*CUIndex);
- if (!UnitOffset)
+ }
+
+ // Watch for tombstoned type unit entries.
+ if (!UnitOffset || UnitOffset == UINT32_MAX)
continue;
// For split DWARF entries we need to make sure we find the non skeleton
// DWARF unit that is needed and use that's DWARF unit offset as the
@@ -1633,7 +1658,7 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
ErrorCategory.Report(
"Name Index entry contains invalid CU or TU offset", [&]() {
error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
- "invalid CU or TU offset {1:x}.\n",
+ "invalid CU or TU offset {2:x}.\n",
NI.getUnitOffset(), EntryID, *UnitOffset);
});
++NumErrors;
@@ -1650,20 +1675,52 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
// call to properly deal with it. It isn't clear that getNonSkeletonUnitDIE
// will return the unit DIE of DU if we aren't able to get the .dwo file,
// but that is what the function currently does.
+ DWARFDie UnitDie = DU->getUnitDIE();
DWARFDie NonSkeletonUnitDie = DU->getNonSkeletonUnitDIE();
- if (DU->getDWOId() && DU->getUnitDIE() == NonSkeletonUnitDie) {
+ if (DU->getDWOId() && UnitDie == NonSkeletonUnitDie) {
ErrorCategory.Report("Unable to get load .dwo file", [&]() {
- error() << formatv("Name Index @ {0:x}: Entry @ {1:x} unable to load "
- ".dwo file \"{2}\" for DWARF unit @ {3:x}.\n",
- NI.getUnitOffset(), EntryID,
- dwarf::toString(DU->getUnitDIE().find(
- {DW_AT_dwo_name, DW_AT_GNU_dwo_name})),
- *UnitOffset);
+ error() << formatv(
+ "Name Index @ {0:x}: Entry @ {1:x} unable to load "
+ ".dwo file \"{2}\" for DWARF unit @ {3:x}.\n",
+ NI.getUnitOffset(), EntryID,
+ dwarf::toString(UnitDie.find({DW_AT_dwo_name, DW_AT_GNU_dwo_name})),
+ *UnitOffset);
});
++NumErrors;
continue;
}
- DWARFUnit *NonSkeletonUnit = NonSkeletonUnitDie.getDwarfUnit();
+ DWARFUnit *NonSkeletonUnit = nullptr;
+ if (TUIndex && *TUIndex >= NumLocalTUs) {
+ // We have a foreign TU index, which either means we have a .dwo file
+ // that has one or more type units, or we have a .dwp file with one or
+ // more type units. We need to get the type unit from the DWARFContext
+ // of the .dwo. We got the NonSkeletonUnitDie above that has the .dwo
+ // or .dwp DWARF context, so we have to get the type unit from that file.
+ // We have also verified that NonSkeletonUnitDie points to a DWO file
+ // above, so we know we have the right file.
+ const uint32_t ForeignTUIdx = *TUIndex - NumLocalTUs;
+ const uint64_t TypeSig = NI.getForeignTUSignature(ForeignTUIdx);
+ llvm::DWARFContext &SkeletonDCtx =
+ NonSkeletonUnitDie.getDwarfUnit()->getContext();
+ // Now find the type unit from the type signature and then update the
+ // NonSkeletonUnitDie to point to the actual type unit in the .dwo/.dwp.
+ NonSkeletonUnit =
+ SkeletonDCtx.getTypeUnitForHash(TypeSig, /*IsDWO=*/true);
+ NonSkeletonUnitDie = NonSkeletonUnit->getUnitDIE(true);
+ // If we have foreign type unit in a DWP file, then we need to ignore
+ // any entries from type units that don't match the one that made it into
+ // the .dwp file.
+ if (SkeletonDCtx.isDWP()) {
+ StringRef DUDwoName = dwarf::toStringRef(
+ UnitDie.find({DW_AT_dwo_name, DW_AT_GNU_dwo_name}));
+ StringRef TUDwoName = dwarf::toStringRef(
+ NonSkeletonUnitDie.find({DW_AT_dwo_name, DW_AT_GNU_dwo_name}));
+ if (DUDwoName != TUDwoName)
+ continue; // Skip this TU, it isn't the one in the .dwp file.
+ }
+ } else {
+ NonSkeletonUnit = NonSkeletonUnitDie.getDwarfUnit();
+ }
uint64_t DIEOffset =
NonSkeletonUnit->getOffset() + *EntryOr->getDIEUnitOffset();
const uint64_t NextUnitOffset = NonSkeletonUnit->getNextUnitOffset();
@@ -1920,15 +1977,26 @@ unsigned DWARFVerifier::verifyDebugNames(const DWARFSection &AccelSection,
for (const DWARFDebugNames::NameTableEntry &NTE : NI)
NumErrors += verifyNameIndexEntries(NI, NTE);
- if (NumErrors > 0)
- return NumErrors;
-
- for (const std::unique_ptr<DWARFUnit> &U : DCtx.compile_units()) {
+ for (const std::unique_ptr<DWARFUnit> &U : DCtx.info_section_units()) {
if (const DWARFDebugNames::NameIndex *NI =
- AccelTable.getCUNameIndex(U->getOffset())) {
- auto *CU = cast<DWARFCompileUnit>(U.get());
- for (const DWARFDebugInfoEntry &Die : CU->dies())
- NumErrors += verifyNameIndexCompleteness(DWARFDie(CU, &Die), *NI);
+ AccelTable.getCUOrTUNameIndex(U->getOffset())) {
+ DWARFCompileUnit *CU = dyn_cast<DWARFCompileUnit>(U.get());
+ if (CU) {
+ if (CU->getDWOId()) {
+ DWARFDie CUDie = CU->getUnitDIE(true);
+ DWARFDie NonSkeletonUnitDie =
+ CUDie.getDwarfUnit()->getNonSkeletonUnitDIE(false);
+ if (CUDie != NonSkeletonUnitDie) {
+ for (const DWARFDebugInfoEntry &Die :
+ NonSkeletonUnitDie.getDwarfUnit()->dies())
+ NumErrors += verifyNameIndexCompleteness(
+ DWARFDie(NonSkeletonUnitDie.getDwarfUnit(), &Die), *NI);
+ }
+ } else {
+ for (const DWARFDebugInfoEntry &Die : CU->dies())
+ NumErrors += verifyNameIndexCompleteness(DWARFDie(CU, &Die), *NI);
+ }
+ }
}
}
return NumErrors;
diff --git a/llvm/test/tools/llvm-dwarfdump/Inputs/verify_split_dwarf_debug_names_ftus_dwo.yaml b/llvm/test/tools/llvm-dwarfdump/Inputs/verify_split_dwarf_debug_names_ftus_dwo.yaml
new file mode 100644
index 00000000000000..3e0e8737291fe3
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/Inputs/verify_split_dwarf_debug_names_ftus_dwo.yaml
@@ -0,0 +1,44 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_REL
+ Machine: EM_X86_64
+ SectionHeaderStringTable: .strtab
+Sections:
+ - Name: .debug_info.dwo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_EXCLUDE ]
+ AddressAlign: 0x1
+ Content: 3A0000000500060800000000F25C0974DC2049EF210000000121000304000000000205070400020305300000000004000439000000060003000501050400320000000500060800000000F111DEDB09E62F8A2100000001210003040000000002050A0400070309310000000008000005010504005300000005000508000000004F3AF08A9CD57502060B21000C04070021000000015600000B400000000802917802000C440000000802917408000D4D000000000501050409F25C0974DC2049EF09F111DEDB09E62F8A00
+ - Name: .debug_str_offsets.dwo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_EXCLUDE ]
+ AddressAlign: 0x1
+ Content: 38000000050000000000000005000000090000000B0000000D0000001600000018000000240000002F00000034000000360000003F000000AF000000
+ - Name: .debug_str.dwo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_EXCLUDE, SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Content: 6D61696E00696E740063002E006D61696E2E64776F007800496E74656765725479706500437573746F6D547970650063617270006100436172705479706500636C616E672076657273696F6E2032302E302E30676974202868747470733A2F2F6769746875622E636F6D2F636C6179626F72672F6C6C766D2D70726F6A6563742E676974203937383833363863333763333139623131656239613331616630663130616163363262613466373229006D61696E2E63707000
+ - Name: .debug_abbrev.dwo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_EXCLUDE ]
+ AddressAlign: 0x1
+ Content: 01410113051B25762510170000021301360B03250B0B3A0B3B0B0000030D00032549133A0B3B0B380B0000041600491303253A0B3B0B000005240003253E0B0B0B000006110125251305032576250000072E01111B1206401803253A0B3B0B49133F190000083400021803253A0B3B0B491300000913003C196920000000
+ - Name: .debug_line.dwo
+ Type: SHT_PROGBITS
+ Flags: [ SHF_EXCLUDE ]
+ AddressAlign: 0x1
+ Content: 36000000050008002E000000010101FB0E01010108012E00030108020F051E016D61696E2E6370700000D76E37CBD0032FAB59BE5997238B5EB3
+ - Type: SectionHeaderTable
+ Sections:
+ - Name: .strtab
+ - Name: .debug_info.dwo
+ - Name: .debug_str_offsets.dwo
+ - Name: .debug_str.dwo
+ - Name: .debug_abbrev.dwo
+ - Name: .debug_line.dwo
+...
+
diff --git a/llvm/test/tools/llvm-dwarfdump/Inputs/verify_split_dwarf_debug_names_ftus_exe.yaml b/llvm/test/tools/llvm-dwarfdump/Inputs/verify_split_dwarf_debug_names_ftus_exe.yaml
new file mode 100644
index 00000000000000..dd87fdcd4b4c3a
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/Inputs/verify_split_dwarf_debug_names_ftus_exe.yaml
@@ -0,0 +1,109 @@
+--- !ELF
+FileHeader:
+ Class: ELFCLASS64
+ Data: ELFDATA2LSB
+ Type: ET_EXEC
+ Machine: EM_X86_64
+ProgramHeaders:
+ - Type: PT_PHDR
+ Flags: [ PF_R ]
+ VAddr: 0x200040
+ Align: 0x8
+ Offset: 0x40
+ - Type: PT_LOAD
+ Flags: [ PF_R ]
+ FirstSec: .rodata
+ LastSec: .eh_frame
+ VAddr: 0x200000
+ Align: 0x1000
+ Offset: 0x0
+ - Type: PT_LOAD
+ Flags: [ PF_X, PF_R ]
+ FirstSec: .text
+ LastSec: .text
+ VAddr: 0x201170
+ Align: 0x1000
+ Offset: 0x170
+ - Type: PT_GNU_STACK
+ Flags: [ PF_W, PF_R ]
+ Align: 0x0
+ Offset: 0x0
+Sections:
+ - Name: .rodata
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_MERGE ]
+ Address: 0x200120
+ AddressAlign: 0x4
+ EntSize: 0x4
+ Content: '0200000001000000'
+ - Name: .eh_frame
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC ]
+ Address: 0x200128
+ AddressAlign: 0x8
+ Content: 1400000000000000017A5200017810011B0C0708900100001C0000001C000000281000002100000000410E108602430D065C0C070800000000000000
+ - Name: .text
+ Type: SHT_PROGBITS
+ Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
+ Address: 0x201170
+ AddressAlign: 0x10
+ Content: 554889E5C745FC000000008B05A3EFFFFF8945F88B0596EFFFFF8945F431C05DC3
+ - Name: .debug_abbrev
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 014A00101772171B257625111B12067317000000
+ - Name: .debug_info
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 2400000005000408000000004F3AF08A9CD575020100000000080000000001002100000008000000
+ - Name: .debug_str_offsets
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 0C000000050000001200000009000000
+ - Name: .debug_names
+ Type: SHT_PROGBITS
+ AddressAlign: 0x4
+ Content: EC0000000500000001000000000000000200000005000000050000002F000000080000004C4C564D3037303000000000F25C0974DC2049EFF111DEDB09E62F8A000000000100000004000000050000000000000042877C10CD1F12166A7F9A7C15BDEE453080880B14000000000000001F000000280000002400000000000000070000000E000000140000001F0000000113020B031304190000022E0313041900000316020B0313041300000424020B0313041900000524031304190000000100210000000001012100000000021A000000000300300000000000000000040131000000040039000000054000000000
+ - Name: .comment
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Content: 4C696E6B65723A204C4C442032302E302E30202868747470733A2F2F6769746875622E636F6D2F636C6179626F72672F6C6C766D2D70726F6A6563742E6769742039373838333638633337633331396231316562396133316166306631306161633632626134663732290000636C616E672076657273696F6E2032302E302E30676974202868747470733A2F2F6769746875622E636F6D2F636C6179626F72672F6C6C766D2D70726F6A6563742E67697420393738383336386333376333313962313165623961333161663066313061616336326261346637322900
+ - Name: .debug_line
+ Type: SHT_PROGBITS
+ AddressAlign: 0x1
+ Content: 610000000500080037000000010101FB0E0D00010101010000000100000101011F010000000003011F020F051E010200000000D76E37CBD0032FAB59BE5997238B5EB304000009027011200000000000030A01050E0AAD050C91050391060B2E0202000101
+ - Name: .debug_line_str
+ Type: SHT_PROGBITS
+ Flags: [ SHF_MERGE, SHF_STRINGS ]
+ AddressAlign: 0x1
+ EntSize: 0x1
+ Content: 2E006D61696E2E63707000
+Symbols:
+ - Name: main.cpp
+ Type: STT_FILE
+ Index: SHN_ABS
+ - Name: main
+ Type: STT_FUNC
+ Section: .text
+ Binding: STB_GLOBAL
+ Value: 0x201170
+ Size: 0x21
+DWARF:
+ debug_str:
+ - CarpType
+ - main.dwo
+ - .
+ - CustomType
+ - main
+ - int
+ - IntegerType
+ debug_addr:
+ - Length: 0xC
+ Version: 0x5
+ AddressSize: 0x8
+ Entries:
+ - Address: 0x201170
+...
+
diff --git a/llvm/test/tools/llvm-dwarfdump/verify_split_dwarf_debug_names_ftus.test b/llvm/test/tools/llvm-dwarfdump/verify_split_dwarf_debug_names_ftus.test
new file mode 100644
index 00000000000000..03ba63bd9b0d77
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/verify_split_dwarf_debug_names_ftus.test
@@ -0,0 +1,36 @@
+# Verify we can successfully verify .debug_names with split DWARF.
+#
+# RUN: rm -rf %t1/
+# RUN: mkdir %t1
+# RUN: yaml2obj %p/Inputs/verify_split_dwarf_debug_names_ftus_exe.yaml > %t1/a.out
+# RUN: yaml2obj %p/Inputs/verify_split_dwarf_debug_names_ftus_dwo.yaml > %t1/main.dwo
+# RUN: cd %t1
+# RUN: llvm-dwarfdump --verify %t1/a.out | FileCheck %s
+
+# CHECK: Verifying unit: 1 / 1
+# CHECK: Verifying dwo Units...
+# CHECK: Verifying .debug_line...
+# CHECK: Verifying .debug_str_offsets...
+# CHECK: Verifying .debug_names...
+# CHECK: No errors.
+
+# Now verify if we remove the "main.dwo" file that we get an error letting us
+# know that the .dwo file was not able to be found.
+# RUN: rm %t1/main.dwo
+# RUN: not llvm-dwarfdump --verify %t1/a.out | FileCheck --check-prefix=NODWO %s
+
+# NODWO: Verifying unit: 1 / 1
+# NODWO: Verifying dwo Units...
+# NODWO: Verifying .debug_line...
+# NODWO: Verifying .debug_str_offsets...
+# NODWO: Verifying .debug_names...
+# NODWO: error: Name Index @ 0x0: Entry @ 0xbf unable to load .dwo file "main.dwo" for DWARF unit @ 0x0.
+# NODWO: error: Name Index @ 0x0: Entry @ 0xc6 unable to load .dwo file "main.dwo" for DWARF unit @ 0x0.
+# NODWO: error: Name Index @ 0x0: Entry @ 0xcd unable to load .dwo file "main.dwo" for DWARF unit @ 0x0.
+# NODWO: error: Name Index @ 0x0: Entry @ 0xd3 unable to load .dwo file "main.dwo" for DWARF unit @ 0x0.
+# NODWO: error: Name Index @ 0x0: Entry @ 0xde unable to load .dwo file "main.dwo" for DWARF unit @ 0x0.
+# NODWO: error: Name Index @ 0x0: Entry @ 0xe4 unable to load .dwo file "main.dwo" for DWARF unit @ 0x0.
+# NODWO: error: Name Index @ 0x0: Entry @ 0xea unable to load .dwo file "main.dwo" for DWARF unit @ 0x0.
+# NODWO: error: Aggregated error counts:
+# NODWO: error: Unable to get load .dwo file occurred 7 time(s).
+# NODWO: Errors detected.
More information about the llvm-commits
mailing list