Index: llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h =================================================================== --- llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h +++ llvm/include/llvm/DebugInfo/DWARF/DWARFVerifier.h @@ -14,6 +14,7 @@ #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h" #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h" #include "llvm/DebugInfo/DWARF/DWARFDie.h" +#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" #include #include @@ -113,20 +114,20 @@ /// \returns The number of errors that occurred during verification. unsigned verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev); - /// Verifies the header of a unit in the .debug_info section. + /// Verifies the header of a unit in a .debug_info or .debug_types section. /// /// This function currently checks for: /// - Unit is in 32-bit DWARF format. The function can be modified to /// support 64-bit format. /// - The DWARF version is valid /// - The unit type is valid (if unit is in version >=5) - /// - The unit doesn't extend beyond .debug_info section + /// - The unit doesn't extend beyond the containing section /// - The address size is valid /// - The offset in the .debug_abbrev section is valid /// - /// \param DebugInfoData The .debug_info section data + /// \param DebugInfoData The section data /// \param Offset A reference to the offset start of the unit. The offset will - /// be updated to point to the next unit in .debug_info + /// be updated to point to the next unit in the section /// \param UnitIndex The index of the unit to be verified /// \param UnitType A reference to the type of the unit /// \param isUnitDWARF64 A reference to a flag that shows whether the unit is @@ -137,7 +138,7 @@ uint32_t *Offset, unsigned UnitIndex, uint8_t &UnitType, bool &isUnitDWARF64); - /// Verifies the header of a unit in the .debug_info section. + /// Verifies the header of a unit in a .debug_info or .debug_types section. /// /// This function currently verifies: /// - The debug info attributes. @@ -147,13 +148,23 @@ /// - If a unit type is provided, that the unit DIE matches the unit type. /// - The DIE ranges. /// - /// \param Unit The DWARF Unit to verifiy. + /// \param Unit The DWARF Unit to verify. /// \param UnitType An optional unit type which will be used to verify the /// type of the unit DIE. /// /// \returns true if the content is verified successfully, false otherwise. bool verifyUnitContents(DWARFUnit &Unit, uint8_t UnitType = 0); + /// Verifies the unit headers and contents in a .debug_info or .debug_types + /// section. + /// + /// \param S The DWARF Section to verify. + /// \param SectionKind The object-file section kind that S comes from. + /// + /// \returns true if the header and content of all units in the section + /// verified successfully, false otherwise. + bool verifyUnitSection(const DWARFSection &S, DWARFSectionKind SectionKind); + /// Verify that all Die ranges are valid. /// /// This function currently checks for: @@ -172,7 +183,7 @@ /// \param AttrValue The DWARF attribute value to check /// /// \returns NumErrors The number of errors occurred during verification of - /// attributes' values in a .debug_info section unit + /// attributes' values in a unit unsigned verifyDebugInfoAttribute(const DWARFDie &Die, DWARFAttribute &AttrValue); @@ -180,14 +191,14 @@ /// /// This function currently checks for: /// - All DW_FORM_ref values that are CU relative have valid CU offsets - /// - All DW_FORM_ref_addr values have valid .debug_info offsets + /// - All DW_FORM_ref_addr values have valid section offsets /// - All DW_FORM_strp values have valid .debug_str offsets /// /// \param Die The DWARF DIE that owns the attribute value /// \param AttrValue The DWARF attribute value to check /// /// \returns NumErrors The number of errors occurred during verification of - /// attributes' forms in a .debug_info section unit + /// attributes' forms in a unit unsigned verifyDebugInfoForm(const DWARFDie &Die, DWARFAttribute &AttrValue); /// Verifies the all valid references that were found when iterating through @@ -199,7 +210,7 @@ /// CU relative and absolute references. /// /// \returns NumErrors The number of errors occurred during verification of - /// references for the .debug_info section + /// references for the .debug_info and .debug_types sections unsigned verifyDebugInfoReferences(); /// Verify the DW_AT_stmt_list encoding and value and ensure that no @@ -280,12 +291,12 @@ /// false otherwise. bool handleDebugAbbrev(); - /// Verify the information in the .debug_info section. + /// Verify the information in the .debug_info and .debug_types sections. /// - /// Any errors are reported to the stream that was this object was + /// Any errors are reported to the stream that this object was /// constructed with. /// - /// \returns true if the .debug_info verifies successfully, false otherwise. + /// \returns true if all sections verify successfully, false otherwise. bool handleDebugInfo(); /// Verify the information in the .debug_line section. Index: llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp =================================================================== --- llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -252,12 +252,10 @@ return NumErrors == 0; } -bool DWARFVerifier::handleDebugInfo() { - OS << "Verifying .debug_info Unit Header Chain...\n"; - +bool DWARFVerifier::verifyUnitSection(const DWARFSection &S, + DWARFSectionKind SectionKind) { const DWARFObject &DObj = DCtx.getDWARFObj(); - DWARFDataExtractor DebugInfoData(DObj, DObj.getInfoSection(), - DCtx.isLittleEndian(), 0); + DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0); uint32_t NumDebugInfoErrors = 0; uint32_t OffsetStart = 0, Offset = 0, UnitIdx = 0; uint8_t UnitType = 0; @@ -274,16 +272,16 @@ break; } else { DWARFUnitHeader Header; - Header.extract(DCtx, DebugInfoData, &OffsetStart); + Header.extract(DCtx, DebugInfoData, &OffsetStart, SectionKind); std::unique_ptr Unit; switch (UnitType) { case dwarf::DW_UT_type: case dwarf::DW_UT_split_type: { Unit.reset(new DWARFTypeUnit( - DCtx, DObj.getInfoSection(), Header, DCtx.getDebugAbbrev(), - &DObj.getRangeSection(), DObj.getStringSection(), - DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(), - DObj.getLineSection(), DCtx.isLittleEndian(), false, UnitVector)); + DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(), + DObj.getStringSection(), DObj.getStringOffsetSection(), + &DObj.getAppleObjCSection(), DObj.getLineSection(), + DCtx.isLittleEndian(), false, UnitVector)); break; } case dwarf::DW_UT_skeleton: @@ -294,10 +292,10 @@ // verifying a compile unit in DWARF v4. case 0: { Unit.reset(new DWARFCompileUnit( - DCtx, DObj.getInfoSection(), Header, DCtx.getDebugAbbrev(), - &DObj.getRangeSection(), DObj.getStringSection(), - DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(), - DObj.getLineSection(), DCtx.isLittleEndian(), false, UnitVector)); + DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(), + DObj.getStringSection(), DObj.getStringOffsetSection(), + &DObj.getAppleObjCSection(), DObj.getLineSection(), + DCtx.isLittleEndian(), false, UnitVector)); break; } default: { llvm_unreachable("Invalid UnitType."); } @@ -309,13 +307,26 @@ ++UnitIdx; } if (UnitIdx == 0 && !hasDIE) { - warn() << ".debug_info is empty.\n"; + warn() << "Section is empty.\n"; isHeaderChainValid = true; } NumDebugInfoErrors += verifyDebugInfoReferences(); return (isHeaderChainValid && NumDebugInfoErrors == 0); } +bool DWARFVerifier::handleDebugInfo() { + const DWARFObject &DObj = DCtx.getDWARFObj(); + + OS << "Verifying .debug_info Unit Header Chain...\n"; + bool result = verifyUnitSection(DObj.getInfoSection(), DW_SECT_INFO); + + OS << "Verifying .debug_types Unit Header Chain...\n"; + DObj.forEachTypesSections([&](const DWARFSection &S) { + result &= verifyUnitSection(S, DW_SECT_TYPES); + }); + return result; +} + unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die, DieRangeInfo &ParentRI) { unsigned NumErrors = 0; Index: llvm/test/DebugInfo/X86/dwarfdump-header.s =================================================================== --- llvm/test/DebugInfo/X86/dwarfdump-header.s +++ llvm/test/DebugInfo/X86/dwarfdump-header.s @@ -2,8 +2,9 @@ # We have a representative set of units: v4 CU, v5 CU, v4 TU, v5 split TU. # We have v4 and v5 line-table headers. # -# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o - | \ -# RUN: llvm-dwarfdump -v - | FileCheck %s +# RUN: llvm-mc -triple x86_64-unknown-linux %s -filetype=obj -o %t.o +# RUN: llvm-dwarfdump -v %t.o | FileCheck %s +# RUN: llvm-dwarfdump -verify %t.o | FileCheck %s --check-prefix=VERIFY .section .debug_str,"MS",@progbits,1 str_producer: @@ -435,3 +436,6 @@ # CHECK-NEXT: mod_time: 0x00000035 # CHECK-NEXT: length: 0x00000045 # CHECK-NOT: file_names + +# VERIFY: Verifying .debug_types +# VERIFY: No errors.