diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h index 0117c90e77f99..9d7ac12cefdc8 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 getForeignTUTypeSignature() const override; std::optional 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 getRelatedCUOffset() const; @@ -468,12 +468,13 @@ class DWARFDebugNames : public DWARFAcceleratorTable { /// index for an entry that is a type unit. std::optional 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 getLocalTUIndex() const; + std::optional 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 NameIndices; - DenseMap CUToNameIndex; + DenseMap 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 455ccaab74d7e..0d6e2b076cc34 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 7fba00d0e457b..ea336378bebb3 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp @@ -635,7 +635,7 @@ std::optional DWARFDebugNames::Entry::getRelatedCUIndex() const { if (std::optional 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 DWARFDebugNames::Entry::getRelatedCUOffset() const { } std::optional DWARFDebugNames::Entry::getLocalTUOffset() const { - std::optional Index = getLocalTUIndex(); + std::optional Index = getTUIndex(); if (!Index || *Index >= NameIdx->getLocalTUCount()) return std::nullopt; return NameIdx->getLocalTUOffset(*Index); @@ -673,7 +673,7 @@ std::optional DWARFDebugNames::Entry::getLocalTUOffset() const { std::optional DWARFDebugNames::Entry::getForeignTUTypeSignature() const { - std::optional Index = getLocalTUIndex(); + std::optional 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 DWARFDebugNames::Entry::getLocalTUIndex() const { +std::optional DWARFDebugNames::Entry::getTUIndex() const { if (std::optional 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 bca0d179dacf2..e8337571fb2c0 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 9c26c4f8892b0..03172c6db3e37 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 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 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 fa3e8ad21dbd4..1fe3eb1e90fe6 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 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 CUIndex = EntryOr->getCUIndex(); - std::optional TUIndex = EntryOr->getLocalTUIndex(); + std::optional CUIndex = EntryOr->getRelatedCUIndex(); + std::optional 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 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 &U : DCtx.compile_units()) { + for (const std::unique_ptr &U : DCtx.info_section_units()) { if (const DWARFDebugNames::NameIndex *NI = - AccelTable.getCUNameIndex(U->getOffset())) { - auto *CU = cast(U.get()); - for (const DWARFDebugInfoEntry &Die : CU->dies()) - NumErrors += verifyNameIndexCompleteness(DWARFDie(CU, &Die), *NI); + AccelTable.getCUOrTUNameIndex(U->getOffset())) { + DWARFCompileUnit *CU = dyn_cast(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 0000000000000..3e0e8737291fe --- /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 0000000000000..dd87fdcd4b4c3 --- /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 0000000000000..03ba63bd9b0d7 --- /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.