Index: include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -61,11 +61,11 @@ /// performing a lookup by name. /// /// \param HashDataOffset an offset into the hash data table - /// \returns DIEOffset the offset into the .debug_info section for the DIE - /// related to the input hash data offset. Currently this function returns - /// only the DIEOffset but it can be modified to return more data regarding - /// the DIE - uint32_t readAtoms(uint32_t &HashDataOffset); + /// \returns + /// DieOffset is the offset into the .debug_info section for the DIE + /// related to the input hash data offset. + /// DieTag is the tag of the DIE + std::tuple readAtoms(uint32_t &HashDataOffset); void dump(raw_ostream &OS) const; }; Index: include/llvm/DebugInfo/DWARF/DWARFVerifier.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFVerifier.h +++ include/llvm/DebugInfo/DWARF/DWARFVerifier.h @@ -141,10 +141,11 @@ /// - The size of the section is as large as what the header describes /// - There is at least one atom /// - The form for each atom is valid + /// - The tag for each DIE in the table is valid /// - The buckets have a valid index, or they are empty /// - Each hashdata offset is valid /// - Each DIE is valid - /// + /// /// \param AccelSection pointer to the section containing the acceleration table /// \param StrData pointer to the string section /// \param SectionName the name of the table we're verifying Index: lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp +++ lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp @@ -73,6 +73,8 @@ DWARFFormValue FormValue(Atom.second); switch (Atom.first) { case dwarf::DW_ATOM_die_offset: + case dwarf::DW_ATOM_die_tag: + case dwarf::DW_ATOM_type_flags: if ((!FormValue.isFormClass(DWARFFormValue::FC_Constant) && !FormValue.isFormClass(DWARFFormValue::FC_Flag)) || FormValue.getForm() == dwarf::DW_FORM_sdata) @@ -84,8 +86,10 @@ return true; } -uint32_t DWARFAcceleratorTable::readAtoms(uint32_t &HashDataOffset) { +std::tuple +DWARFAcceleratorTable::readAtoms(uint32_t &HashDataOffset) { uint32_t DieOffset = dwarf::DW_INVALID_OFFSET; + dwarf::Tag DieTag = dwarf::DW_TAG_null; for (auto Atom : getAtomsDesc()) { DWARFFormValue FormValue(Atom.second); @@ -94,11 +98,14 @@ case dwarf::DW_ATOM_die_offset: DieOffset = *FormValue.getAsUnsignedConstant(); break; + case dwarf::DW_ATOM_die_tag: + DieTag = (dwarf::Tag)*FormValue.getAsUnsignedConstant(); + break; default: break; } } - return DieOffset; + return std::make_tuple(DieOffset, DieTag); } LLVM_DUMP_METHOD void DWARFAcceleratorTable::dump(raw_ostream &OS) const { Index: lib/DebugInfo/DWARF/DWARFVerifier.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -525,15 +525,14 @@ uint32_t StrpOffset; uint32_t StringOffset; uint32_t StringCount = 0; - uint32_t DieOffset = dwarf::DW_INVALID_OFFSET; - while ((StrpOffset = AccelSectionData.getU32(&HashDataOffset)) != 0) { const uint32_t NumHashDataObjects = AccelSectionData.getU32(&HashDataOffset); for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects; ++HashDataIdx) { - DieOffset = AccelTable.readAtoms(HashDataOffset); - if (!DCtx.getDIEForOffset(DieOffset)) { + auto Atoms = AccelTable.readAtoms(HashDataOffset); + auto Die = DCtx.getDIEForOffset(std::get<0>(Atoms)); + if (!Die) { const uint32_t BucketIdx = NumBuckets ? (Hash % NumBuckets) : UINT32_MAX; StringOffset = StrpOffset; @@ -546,9 +545,13 @@ "Str[%u] = 0x%08x " "DIE[%d] = 0x%08x is not a valid DIE offset for \"%s\".\n", SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset, - HashDataIdx, DieOffset, Name); + HashDataIdx, std::get<0>(Atoms), Name); ++NumErrors; + } else if ((std::get<1>(Atoms) != dwarf::DW_TAG_null) && + (Die.getTag() != std::get<1>(Atoms))) { + OS << "\terror: Tag " << dwarf::TagString(std::get<1>(Atoms)) + << " is not a valid tag for DIE[" << HashDataIdx << "].\n"; } } ++StringCount;