diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:51:42 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:51:42 +0000 |
commit | 1d5ae1026e831016fc29fd927877c86af904481f (patch) | |
tree | 2cdfd12620fcfa5d9e4a0389f85368e8e36f63f9 /lib/DebugInfo/DWARF | |
parent | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (diff) |
Notes
Diffstat (limited to 'lib/DebugInfo/DWARF')
26 files changed, 873 insertions, 731 deletions
diff --git a/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp index f4dd79937608..abbea3a868c8 100644 --- a/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp @@ -38,9 +38,9 @@ DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() { bool DWARFAbbreviationDeclaration::extract(DataExtractor Data, - uint32_t* OffsetPtr) { + uint64_t* OffsetPtr) { clear(); - const uint32_t Offset = *OffsetPtr; + const uint64_t Offset = *OffsetPtr; Code = Data.getULEB128(OffsetPtr); if (Code == 0) { return false; @@ -148,7 +148,7 @@ DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const { } Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue( - const uint32_t DIEOffset, const dwarf::Attribute Attr, + const uint64_t DIEOffset, const dwarf::Attribute Attr, const DWARFUnit &U) const { Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr); if (!MatchAttrIndex) @@ -158,7 +158,7 @@ Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue( // Add the byte size of ULEB that for the abbrev Code so we can start // skipping the attribute data. - uint32_t Offset = DIEOffset + CodeByteSize; + uint64_t Offset = DIEOffset + CodeByteSize; uint32_t AttrIndex = 0; for (const auto &Spec : AttributeSpecs) { if (*MatchAttrIndex == AttrIndex) { diff --git a/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp index 0721efb40f6a..875f5e9989a0 100644 --- a/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp +++ b/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp @@ -42,7 +42,7 @@ static Atom formatAtom(unsigned Atom) { return {Atom}; } DWARFAcceleratorTable::~DWARFAcceleratorTable() = default; Error AppleAcceleratorTable::extract() { - uint32_t Offset = 0; + uint64_t Offset = 0; // Check that we can at least read the header. if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength) + 4)) @@ -111,15 +111,15 @@ bool AppleAcceleratorTable::validateForms() { return true; } -std::pair<uint32_t, dwarf::Tag> -AppleAcceleratorTable::readAtoms(uint32_t &HashDataOffset) { - uint32_t DieOffset = dwarf::DW_INVALID_OFFSET; +std::pair<uint64_t, dwarf::Tag> +AppleAcceleratorTable::readAtoms(uint64_t *HashDataOffset) { + uint64_t DieOffset = dwarf::DW_INVALID_OFFSET; dwarf::Tag DieTag = dwarf::DW_TAG_null; dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32}; for (auto Atom : getAtomsDesc()) { DWARFFormValue FormValue(Atom.second); - FormValue.extractValue(AccelSection, &HashDataOffset, FormParams); + FormValue.extractValue(AccelSection, HashDataOffset, FormParams); switch (Atom.first) { case dwarf::DW_ATOM_die_offset: DieOffset = *FormValue.getAsUnsignedConstant(); @@ -163,19 +163,19 @@ Optional<uint64_t> AppleAcceleratorTable::HeaderData::extractOffset( bool AppleAcceleratorTable::dumpName(ScopedPrinter &W, SmallVectorImpl<DWARFFormValue> &AtomForms, - uint32_t *DataOffset) const { + uint64_t *DataOffset) const { dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32}; - uint32_t NameOffset = *DataOffset; + uint64_t NameOffset = *DataOffset; if (!AccelSection.isValidOffsetForDataOfSize(*DataOffset, 4)) { W.printString("Incorrectly terminated list."); return false; } - unsigned StringOffset = AccelSection.getRelocatedValue(4, DataOffset); + uint64_t StringOffset = AccelSection.getRelocatedValue(4, DataOffset); if (!StringOffset) return false; // End of list DictScope NameScope(W, ("Name@0x" + Twine::utohexstr(NameOffset)).str()); - W.startLine() << format("String: 0x%08x", StringOffset); + W.startLine() << format("String: 0x%08" PRIx64, StringOffset); W.getOStream() << " \"" << StringSection.getCStr(&StringOffset) << "\"\n"; unsigned NumData = AccelSection.getU32(DataOffset); @@ -223,9 +223,9 @@ LLVM_DUMP_METHOD void AppleAcceleratorTable::dump(raw_ostream &OS) const { } // Now go through the actual tables and dump them. - uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength; - unsigned HashesBase = Offset + Hdr.BucketCount * 4; - unsigned OffsetsBase = HashesBase + Hdr.HashCount * 4; + uint64_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength; + uint64_t HashesBase = Offset + Hdr.BucketCount * 4; + uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4; for (unsigned Bucket = 0; Bucket < Hdr.BucketCount; ++Bucket) { unsigned Index = AccelSection.getU32(&Offset); @@ -237,14 +237,14 @@ LLVM_DUMP_METHOD void AppleAcceleratorTable::dump(raw_ostream &OS) const { } for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) { - unsigned HashOffset = HashesBase + HashIdx*4; - unsigned OffsetsOffset = OffsetsBase + HashIdx*4; + uint64_t HashOffset = HashesBase + HashIdx*4; + uint64_t OffsetsOffset = OffsetsBase + HashIdx*4; uint32_t Hash = AccelSection.getU32(&HashOffset); if (Hash % Hdr.BucketCount != Bucket) break; - unsigned DataOffset = AccelSection.getU32(&OffsetsOffset); + uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset); ListScope HashScope(W, ("Hash 0x" + Twine::utohexstr(Hash)).str()); if (!AccelSection.isValidOffset(DataOffset)) { W.printString("Invalid section offset"); @@ -265,7 +265,7 @@ AppleAcceleratorTable::Entry::Entry( } void AppleAcceleratorTable::Entry::extract( - const AppleAcceleratorTable &AccelTable, uint32_t *Offset) { + const AppleAcceleratorTable &AccelTable, uint64_t *Offset) { dwarf::FormParams FormParams = {AccelTable.Hdr.Version, 0, dwarf::DwarfFormat::DWARF32}; @@ -302,7 +302,7 @@ Optional<dwarf::Tag> AppleAcceleratorTable::Entry::getTag() const { } AppleAcceleratorTable::ValueIterator::ValueIterator( - const AppleAcceleratorTable &AccelTable, unsigned Offset) + const AppleAcceleratorTable &AccelTable, uint64_t Offset) : AccelTable(&AccelTable), Current(AccelTable.HdrData), DataOffset(Offset) { if (!AccelTable.AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) return; @@ -333,25 +333,25 @@ AppleAcceleratorTable::equal_range(StringRef Key) const { // Find the bucket. unsigned HashValue = djbHash(Key); unsigned Bucket = HashValue % Hdr.BucketCount; - unsigned BucketBase = sizeof(Hdr) + Hdr.HeaderDataLength; - unsigned HashesBase = BucketBase + Hdr.BucketCount * 4; - unsigned OffsetsBase = HashesBase + Hdr.HashCount * 4; + uint64_t BucketBase = sizeof(Hdr) + Hdr.HeaderDataLength; + uint64_t HashesBase = BucketBase + Hdr.BucketCount * 4; + uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4; - unsigned BucketOffset = BucketBase + Bucket * 4; + uint64_t BucketOffset = BucketBase + Bucket * 4; unsigned Index = AccelSection.getU32(&BucketOffset); // Search through all hashes in the bucket. for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) { - unsigned HashOffset = HashesBase + HashIdx * 4; - unsigned OffsetsOffset = OffsetsBase + HashIdx * 4; + uint64_t HashOffset = HashesBase + HashIdx * 4; + uint64_t OffsetsOffset = OffsetsBase + HashIdx * 4; uint32_t Hash = AccelSection.getU32(&HashOffset); if (Hash % Hdr.BucketCount != Bucket) // We are already in the next bucket. break; - unsigned DataOffset = AccelSection.getU32(&OffsetsOffset); - unsigned StringOffset = AccelSection.getRelocatedValue(4, &DataOffset); + uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset); + uint64_t StringOffset = AccelSection.getRelocatedValue(4, &DataOffset); if (!StringOffset) break; @@ -377,7 +377,7 @@ void DWARFDebugNames::Header::dump(ScopedPrinter &W) const { } Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS, - uint32_t *Offset) { + uint64_t *Offset) { // Check that we can read the fixed-size part. if (!AS.isValidOffset(*Offset + sizeof(HeaderPOD) - 1)) return createStringError(errc::illegal_byte_sequence, @@ -437,7 +437,7 @@ DWARFDebugNames::Abbrev DWARFDebugNames::AbbrevMapInfo::getTombstoneKey() { } Expected<DWARFDebugNames::AttributeEncoding> -DWARFDebugNames::NameIndex::extractAttributeEncoding(uint32_t *Offset) { +DWARFDebugNames::NameIndex::extractAttributeEncoding(uint64_t *Offset) { if (*Offset >= EntriesBase) { return createStringError(errc::illegal_byte_sequence, "Incorrectly terminated abbreviation table."); @@ -449,7 +449,7 @@ DWARFDebugNames::NameIndex::extractAttributeEncoding(uint32_t *Offset) { } Expected<std::vector<DWARFDebugNames::AttributeEncoding>> -DWARFDebugNames::NameIndex::extractAttributeEncodings(uint32_t *Offset) { +DWARFDebugNames::NameIndex::extractAttributeEncodings(uint64_t *Offset) { std::vector<AttributeEncoding> Result; for (;;) { auto AttrEncOr = extractAttributeEncoding(Offset); @@ -463,7 +463,7 @@ DWARFDebugNames::NameIndex::extractAttributeEncodings(uint32_t *Offset) { } Expected<DWARFDebugNames::Abbrev> -DWARFDebugNames::NameIndex::extractAbbrev(uint32_t *Offset) { +DWARFDebugNames::NameIndex::extractAbbrev(uint64_t *Offset) { if (*Offset >= EntriesBase) { return createStringError(errc::illegal_byte_sequence, "Incorrectly terminated abbreviation table."); @@ -482,7 +482,7 @@ DWARFDebugNames::NameIndex::extractAbbrev(uint32_t *Offset) { Error DWARFDebugNames::NameIndex::extract() { const DWARFDataExtractor &AS = Section.AccelSection; - uint32_t Offset = Base; + uint64_t Offset = Base; if (Error E = Hdr.extract(AS, &Offset)) return E; @@ -577,27 +577,27 @@ std::error_code DWARFDebugNames::SentinelError::convertToErrorCode() const { return inconvertibleErrorCode(); } -uint32_t DWARFDebugNames::NameIndex::getCUOffset(uint32_t CU) const { +uint64_t DWARFDebugNames::NameIndex::getCUOffset(uint32_t CU) const { assert(CU < Hdr.CompUnitCount); - uint32_t Offset = CUsBase + 4 * CU; + uint64_t Offset = CUsBase + 4 * CU; return Section.AccelSection.getRelocatedValue(4, &Offset); } -uint32_t DWARFDebugNames::NameIndex::getLocalTUOffset(uint32_t TU) const { +uint64_t DWARFDebugNames::NameIndex::getLocalTUOffset(uint32_t TU) const { assert(TU < Hdr.LocalTypeUnitCount); - uint32_t Offset = CUsBase + 4 * (Hdr.CompUnitCount + TU); + uint64_t Offset = CUsBase + 4 * (Hdr.CompUnitCount + TU); return Section.AccelSection.getRelocatedValue(4, &Offset); } uint64_t DWARFDebugNames::NameIndex::getForeignTUSignature(uint32_t TU) const { assert(TU < Hdr.ForeignTypeUnitCount); - uint32_t Offset = + uint64_t Offset = CUsBase + 4 * (Hdr.CompUnitCount + Hdr.LocalTypeUnitCount) + 8 * TU; return Section.AccelSection.getU64(&Offset); } Expected<DWARFDebugNames::Entry> -DWARFDebugNames::NameIndex::getEntry(uint32_t *Offset) const { +DWARFDebugNames::NameIndex::getEntry(uint64_t *Offset) const { const DWARFDataExtractor &AS = Section.AccelSection; if (!AS.isValidOffset(*Offset)) return createStringError(errc::illegal_byte_sequence, @@ -625,12 +625,12 @@ DWARFDebugNames::NameIndex::getEntry(uint32_t *Offset) const { DWARFDebugNames::NameTableEntry DWARFDebugNames::NameIndex::getNameTableEntry(uint32_t Index) const { assert(0 < Index && Index <= Hdr.NameCount); - uint32_t StringOffsetOffset = StringOffsetsBase + 4 * (Index - 1); - uint32_t EntryOffsetOffset = EntryOffsetsBase + 4 * (Index - 1); + uint64_t StringOffsetOffset = StringOffsetsBase + 4 * (Index - 1); + uint64_t EntryOffsetOffset = EntryOffsetsBase + 4 * (Index - 1); const DWARFDataExtractor &AS = Section.AccelSection; - uint32_t StringOffset = AS.getRelocatedValue(4, &StringOffsetOffset); - uint32_t EntryOffset = AS.getU32(&EntryOffsetOffset); + uint64_t StringOffset = AS.getRelocatedValue(4, &StringOffsetOffset); + uint64_t EntryOffset = AS.getU32(&EntryOffsetOffset); EntryOffset += EntriesBase; return {Section.StringSection, Index, StringOffset, EntryOffset}; } @@ -638,13 +638,13 @@ DWARFDebugNames::NameIndex::getNameTableEntry(uint32_t Index) const { uint32_t DWARFDebugNames::NameIndex::getBucketArrayEntry(uint32_t Bucket) const { assert(Bucket < Hdr.BucketCount); - uint32_t BucketOffset = BucketsBase + 4 * Bucket; + uint64_t BucketOffset = BucketsBase + 4 * Bucket; return Section.AccelSection.getU32(&BucketOffset); } uint32_t DWARFDebugNames::NameIndex::getHashArrayEntry(uint32_t Index) const { assert(0 < Index && Index <= Hdr.NameCount); - uint32_t HashOffset = HashesBase + 4 * (Index - 1); + uint64_t HashOffset = HashesBase + 4 * (Index - 1); return Section.AccelSection.getU32(&HashOffset); } @@ -653,8 +653,8 @@ uint32_t DWARFDebugNames::NameIndex::getHashArrayEntry(uint32_t Index) const { // it's not possible to recover this entry list (but the other lists may still // parse OK). bool DWARFDebugNames::NameIndex::dumpEntry(ScopedPrinter &W, - uint32_t *Offset) const { - uint32_t EntryId = *Offset; + uint64_t *Offset) const { + uint64_t EntryId = *Offset; auto EntryOr = getEntry(Offset); if (!EntryOr) { handleAllErrors(EntryOr.takeError(), [](const SentinelError &) {}, @@ -674,10 +674,10 @@ void DWARFDebugNames::NameIndex::dumpName(ScopedPrinter &W, if (Hash) W.printHex("Hash", *Hash); - W.startLine() << format("String: 0x%08x", NTE.getStringOffset()); + W.startLine() << format("String: 0x%08" PRIx64, NTE.getStringOffset()); W.getOStream() << " \"" << NTE.getString() << "\"\n"; - uint32_t EntryOffset = NTE.getEntryOffset(); + uint64_t EntryOffset = NTE.getEntryOffset(); while (dumpEntry(W, &EntryOffset)) /*empty*/; } @@ -685,7 +685,7 @@ void DWARFDebugNames::NameIndex::dumpName(ScopedPrinter &W, void DWARFDebugNames::NameIndex::dumpCUs(ScopedPrinter &W) const { ListScope CUScope(W, "Compilation Unit offsets"); for (uint32_t CU = 0; CU < Hdr.CompUnitCount; ++CU) - W.startLine() << format("CU[%u]: 0x%08x\n", CU, getCUOffset(CU)); + W.startLine() << format("CU[%u]: 0x%08" PRIx64 "\n", CU, getCUOffset(CU)); } void DWARFDebugNames::NameIndex::dumpLocalTUs(ScopedPrinter &W) const { @@ -694,7 +694,8 @@ void DWARFDebugNames::NameIndex::dumpLocalTUs(ScopedPrinter &W) const { ListScope TUScope(W, "Local Type Unit offsets"); for (uint32_t TU = 0; TU < Hdr.LocalTypeUnitCount; ++TU) - W.startLine() << format("LocalTU[%u]: 0x%08x\n", TU, getLocalTUOffset(TU)); + W.startLine() << format("LocalTU[%u]: 0x%08" PRIx64 "\n", TU, + getLocalTUOffset(TU)); } void DWARFDebugNames::NameIndex::dumpForeignTUs(ScopedPrinter &W) const { @@ -756,7 +757,7 @@ LLVM_DUMP_METHOD void DWARFDebugNames::NameIndex::dump(ScopedPrinter &W) const { } Error DWARFDebugNames::extract() { - uint32_t Offset = 0; + uint64_t Offset = 0; while (AccelSection.isValidOffset(Offset)) { NameIndex Next(*this, Offset); if (Error E = Next.extract()) @@ -778,7 +779,7 @@ LLVM_DUMP_METHOD void DWARFDebugNames::dump(raw_ostream &OS) const { NI.dump(W); } -Optional<uint32_t> +Optional<uint64_t> DWARFDebugNames::ValueIterator::findEntryOffsetInCurrentIndex() { const Header &Hdr = CurrentIndex->Hdr; if (Hdr.BucketCount == 0) { @@ -822,7 +823,7 @@ bool DWARFDebugNames::ValueIterator::getEntryAtCurrentOffset() { } bool DWARFDebugNames::ValueIterator::findInCurrentIndex() { - Optional<uint32_t> Offset = findEntryOffsetInCurrentIndex(); + Optional<uint64_t> Offset = findEntryOffsetInCurrentIndex(); if (!Offset) return false; DataOffset = *Offset; @@ -877,7 +878,7 @@ DWARFDebugNames::equal_range(StringRef Key) const { } const DWARFDebugNames::NameIndex * -DWARFDebugNames::getCUNameIndex(uint32_t CUOffset) { +DWARFDebugNames::getCUNameIndex(uint64_t CUOffset) { if (CUToNameIndex.size() == 0 && NameIndices.size() > 0) { for (const auto &NI : *this) { for (uint32_t CU = 0; CU < NI.getCUCount(); ++CU) diff --git a/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp index 74cce42466dd..f59e49268288 100644 --- a/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp @@ -15,16 +15,18 @@ using namespace llvm; void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { - OS << format("0x%08x", getOffset()) << ": Compile Unit:" - << " length = " << format("0x%08x", getLength()) + OS << format("0x%08" PRIx64, getOffset()) << ": Compile Unit:" + << " length = " << format("0x%08" PRIx64, getLength()) << " version = " << format("0x%04x", getVersion()); if (getVersion() >= 5) OS << " unit_type = " << dwarf::UnitTypeString(getUnitType()); - OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset()) + OS << " abbr_offset = " + << format("0x%04" PRIx64, getAbbreviations()->getOffset()) << " addr_size = " << format("0x%02x", getAddressByteSize()); if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile) OS << " DWO_id = " << format("0x%016" PRIx64, *getDWOId()); - OS << " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n"; + OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset()) + << ")\n"; if (DWARFDie CUDie = getUnitDIE(false)) CUDie.dump(OS, 0, DumpOpts); diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp index 5ede9bf59619..c06d85d50609 100644 --- a/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -138,7 +138,7 @@ static void dumpDWARFv5StringOffsetsSection( DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0); DataExtractor StrData(StringSection, LittleEndian, 0); uint64_t SectionSize = StringOffsetsSection.Data.size(); - uint32_t Offset = 0; + uint64_t Offset = 0; for (auto &Contribution : Contributions) { // Report an ill-formed contribution. if (!Contribution) { @@ -166,10 +166,10 @@ static void dumpDWARFv5StringOffsetsSection( } // Report a gap in the table. if (Offset < ContributionHeader) { - OS << format("0x%8.8x: Gap, length = ", Offset); + OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset); OS << (ContributionHeader - Offset) << "\n"; } - OS << format("0x%8.8x: ", (uint32_t)ContributionHeader); + OS << format("0x%8.8" PRIx64 ": ", ContributionHeader); // In DWARF v5 the contribution size in the descriptor does not equal // the originally encoded length (it does not contain the length of the // version field and the padding, a total of 4 bytes). Add them back in @@ -181,26 +181,19 @@ static void dumpDWARFv5StringOffsetsSection( Offset = Contribution->Base; unsigned EntrySize = Contribution->getDwarfOffsetByteSize(); while (Offset - Contribution->Base < Contribution->Size) { - OS << format("0x%8.8x: ", Offset); - // FIXME: We can only extract strings if the offset fits in 32 bits. + OS << format("0x%8.8" PRIx64 ": ", Offset); uint64_t StringOffset = StrOffsetExt.getRelocatedValue(EntrySize, &Offset); - // Extract the string if we can and display it. Otherwise just report - // the offset. - if (StringOffset <= std::numeric_limits<uint32_t>::max()) { - uint32_t StringOffset32 = (uint32_t)StringOffset; - OS << format("%8.8x ", StringOffset32); - const char *S = StrData.getCStr(&StringOffset32); - if (S) - OS << format("\"%s\"", S); - } else - OS << format("%16.16" PRIx64 " ", StringOffset); + OS << format("%8.8" PRIx64 " ", StringOffset); + const char *S = StrData.getCStr(&StringOffset); + if (S) + OS << format("\"%s\"", S); OS << "\n"; } } // Report a gap at the end of the table. if (Offset < SectionSize) { - OS << format("0x%8.8x: Gap, length = ", Offset); + OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset); OS << (SectionSize - Offset) << "\n"; } } @@ -225,7 +218,7 @@ static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName, StringSection, Units, LittleEndian); else { DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0); - uint32_t offset = 0; + uint64_t offset = 0; uint64_t size = StringOffsetsSection.Data.size(); // Ensure that size is a multiple of the size of an entry. if (size & ((uint64_t)(sizeof(uint32_t) - 1))) { @@ -235,9 +228,9 @@ static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName, } DataExtractor StrData(StringSection, LittleEndian, 0); while (offset < size) { - OS << format("0x%8.8x: ", offset); - uint32_t StringOffset = strOffsetExt.getU32(&offset); - OS << format("%8.8x ", StringOffset); + OS << format("0x%8.8" PRIx64 ": ", offset); + uint64_t StringOffset = strOffsetExt.getU32(&offset); + OS << format("%8.8" PRIx64 " ", StringOffset); const char *S = StrData.getCStr(&StringOffset); if (S) OS << format("\"%s\"", S); @@ -250,10 +243,10 @@ static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName, static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, DIDumpOptions DumpOpts, uint16_t Version, uint8_t AddrSize) { - uint32_t Offset = 0; + uint64_t Offset = 0; while (AddrData.isValidOffset(Offset)) { DWARFDebugAddrTable AddrTable; - uint32_t TableOffset = Offset; + uint64_t TableOffset = Offset; if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize, DWARFContext::dumpWarning)) { WithColor::error() << toString(std::move(Err)) << '\n'; @@ -261,8 +254,7 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, // could be read. If it couldn't, stop reading the section. if (!AddrTable.hasValidLength()) break; - uint64_t Length = AddrTable.getLength(); - Offset = TableOffset + Length; + Offset = TableOffset + AddrTable.getLength(); } else { AddrTable.dump(OS, DumpOpts); } @@ -275,10 +267,10 @@ static void dumpRnglistsSection( llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts) { - uint32_t Offset = 0; + uint64_t Offset = 0; while (rnglistData.isValidOffset(Offset)) { llvm::DWARFDebugRnglistTable Rnglists; - uint32_t TableOffset = Offset; + uint64_t TableOffset = Offset; if (Error Err = Rnglists.extract(rnglistData, &Offset)) { WithColor::error() << toString(std::move(Err)) << '\n'; uint64_t Length = Rnglists.length(); @@ -297,21 +289,25 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, DWARFDataExtractor Data, const MCRegisterInfo *MRI, Optional<uint64_t> DumpOffset) { - uint32_t Offset = 0; - DWARFDebugLoclists Loclists; + uint64_t Offset = 0; - DWARFListTableHeader Header(".debug_loclists", "locations"); - if (Error E = Header.extract(Data, &Offset)) { - WithColor::error() << toString(std::move(E)) << '\n'; - return; - } + while (Data.isValidOffset(Offset)) { + DWARFListTableHeader Header(".debug_loclists", "locations"); + if (Error E = Header.extract(Data, &Offset)) { + WithColor::error() << toString(std::move(E)) << '\n'; + return; + } - Header.dump(OS, DumpOpts); - DataExtractor LocData(Data.getData().drop_front(Offset), - Data.isLittleEndian(), Header.getAddrSize()); + Header.dump(OS, DumpOpts); + DataExtractor LocData(Data.getData(), + Data.isLittleEndian(), Header.getAddrSize()); - Loclists.parse(LocData, Header.getVersion()); - Loclists.dump(OS, 0, MRI, DumpOffset); + DWARFDebugLoclists Loclists; + uint64_t EndOffset = Header.length() + Header.getHeaderOffset(); + Loclists.parse(LocData, Offset, EndOffset, Header.getVersion()); + Loclists.dump(OS, 0, MRI, DumpOpts, DumpOffset); + Offset = EndOffset; + } } void DWARFContext::dump( @@ -386,7 +382,7 @@ void DWARFContext::dump( if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc, DObj->getLocSection().Data)) { - getDebugLoc()->dump(OS, getRegisterInfo(), *Off); + getDebugLoc()->dump(OS, getRegisterInfo(), DumpOpts, *Off); } if (const auto *Off = shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists, @@ -398,15 +394,15 @@ void DWARFContext::dump( if (const auto *Off = shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc, DObj->getLocDWOSection().Data)) { - getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), *Off); + getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), DumpOpts, *Off); } if (const auto *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame, - DObj->getDebugFrameSection())) + DObj->getFrameSection().Data)) getDebugFrame()->dump(OS, getRegisterInfo(), *Off); if (const auto *Off = shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame, - DObj->getEHFrameSection())) + DObj->getEHFrameSection().Data)) getEHFrame()->dump(OS, getRegisterInfo(), *Off); if (DumpType & DIDT_DebugMacro) { @@ -417,9 +413,9 @@ void DWARFContext::dump( } if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges, - DObj->getARangeSection())) { - uint32_t offset = 0; - DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0); + DObj->getArangesSection())) { + uint64_t offset = 0; + DataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(), 0); DWARFDebugArangeSet set; while (set.extract(arangesData, &offset)) set.dump(OS); @@ -433,7 +429,8 @@ void DWARFContext::dump( Parser.skip(dumpWarning); continue; } - OS << "debug_line[" << format("0x%8.8x", Parser.getOffset()) << "]\n"; + OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset()) + << "]\n"; if (DumpOpts.Verbose) { Parser.parseNext(dumpWarning, dumpWarning, &OS); } else { @@ -474,32 +471,32 @@ void DWARFContext::dump( } if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr, - DObj->getStringSection())) { - DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0); - uint32_t offset = 0; - uint32_t strOffset = 0; + DObj->getStrSection())) { + DataExtractor strData(DObj->getStrSection(), isLittleEndian(), 0); + uint64_t offset = 0; + uint64_t strOffset = 0; while (const char *s = strData.getCStr(&offset)) { - OS << format("0x%8.8x: \"%s\"\n", strOffset, s); + OS << format("0x%8.8" PRIx64 ": \"%s\"\n", strOffset, s); strOffset = offset; } } if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr, - DObj->getStringDWOSection())) { - DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0); - uint32_t offset = 0; - uint32_t strDWOOffset = 0; + DObj->getStrDWOSection())) { + DataExtractor strDWOData(DObj->getStrDWOSection(), isLittleEndian(), 0); + uint64_t offset = 0; + uint64_t strDWOOffset = 0; while (const char *s = strDWOData.getCStr(&offset)) { - OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s); + OS << format("0x%8.8" PRIx64 ": \"%s\"\n", strDWOOffset, s); strDWOOffset = offset; } } if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr, - DObj->getLineStringSection())) { - DataExtractor strData(DObj->getLineStringSection(), isLittleEndian(), 0); - uint32_t offset = 0; - uint32_t strOffset = 0; + DObj->getLineStrSection())) { + DataExtractor strData(DObj->getLineStrSection(), isLittleEndian(), 0); + uint64_t offset = 0; + uint64_t strOffset = 0; while (const char *s = strData.getCStr(&offset)) { - OS << format("0x%8.8x: \"", strOffset); + OS << format("0x%8.8" PRIx64 ": \"", strOffset); OS.write_escaped(s); OS << "\"\n"; strOffset = offset; @@ -514,11 +511,11 @@ void DWARFContext::dump( } if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges, - DObj->getRangeSection().Data)) { + DObj->getRangesSection().Data)) { uint8_t savedAddressByteSize = getCUAddrSize(); - DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(), + DWARFDataExtractor rangesData(*DObj, DObj->getRangesSection(), isLittleEndian(), savedAddressByteSize); - uint32_t offset = 0; + uint64_t offset = 0; DWARFDebugRangeList rangeList; while (rangesData.isValidOffset(offset)) { if (Error E = rangeList.extract(rangesData, &offset)) { @@ -552,38 +549,38 @@ void DWARFContext::dump( } if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames, - DObj->getPubNamesSection().Data)) - DWARFDebugPubTable(*DObj, DObj->getPubNamesSection(), isLittleEndian(), false) + DObj->getPubnamesSection().Data)) + DWARFDebugPubTable(*DObj, DObj->getPubnamesSection(), isLittleEndian(), false) .dump(OS); if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes, - DObj->getPubTypesSection().Data)) - DWARFDebugPubTable(*DObj, DObj->getPubTypesSection(), isLittleEndian(), false) + DObj->getPubtypesSection().Data)) + DWARFDebugPubTable(*DObj, DObj->getPubtypesSection(), isLittleEndian(), false) .dump(OS); if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames, - DObj->getGnuPubNamesSection().Data)) - DWARFDebugPubTable(*DObj, DObj->getGnuPubNamesSection(), isLittleEndian(), + DObj->getGnuPubnamesSection().Data)) + DWARFDebugPubTable(*DObj, DObj->getGnuPubnamesSection(), isLittleEndian(), true /* GnuStyle */) .dump(OS); if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes, - DObj->getGnuPubTypesSection().Data)) - DWARFDebugPubTable(*DObj, DObj->getGnuPubTypesSection(), isLittleEndian(), + DObj->getGnuPubtypesSection().Data)) + DWARFDebugPubTable(*DObj, DObj->getGnuPubtypesSection(), isLittleEndian(), true /* GnuStyle */) .dump(OS); if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets, - DObj->getStringOffsetSection().Data)) + DObj->getStrOffsetsSection().Data)) dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj, - DObj->getStringOffsetSection(), - DObj->getStringSection(), normal_units(), + DObj->getStrOffsetsSection(), + DObj->getStrSection(), normal_units(), isLittleEndian(), getMaxVersion()); if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets, - DObj->getStringOffsetDWOSection().Data)) + DObj->getStrOffsetsDWOSection().Data)) dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj, - DObj->getStringOffsetDWOSection(), - DObj->getStringDWOSection(), dwo_units(), + DObj->getStrOffsetsDWOSection(), + DObj->getStrDWOSection(), dwo_units(), isLittleEndian(), getMaxDWOVersion()); if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex, @@ -607,7 +604,7 @@ void DWARFContext::dump( DObj->getAppleObjCSection().Data)) getAppleObjC().dump(OS); if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames, - DObj->getDebugNamesSection().Data)) + DObj->getNamesSection().Data)) getDebugNames().dump(OS); } @@ -641,7 +638,7 @@ DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) { return nullptr; } -DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) { +DWARFDie DWARFContext::getDIEForOffset(uint64_t Offset) { parseNormalUnits(); if (auto *CU = NormalUnits.getUnitForOffset(Offset)) return CU->getDIEForOffset(Offset); @@ -667,7 +664,7 @@ const DWARFUnitIndex &DWARFContext::getCUIndex() { DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0); - CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO); + CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO); CUIndex->parse(CUIndexData); return *CUIndex; } @@ -678,7 +675,7 @@ const DWARFUnitIndex &DWARFContext::getTUIndex() { DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0); - TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES); + TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_TYPES); TUIndex->parse(TUIndexData); return *TUIndex; } @@ -688,7 +685,7 @@ DWARFGdbIndex &DWARFContext::getGdbIndex() { return *GdbIndex; DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0); - GdbIndex = llvm::make_unique<DWARFGdbIndex>(); + GdbIndex = std::make_unique<DWARFGdbIndex>(); GdbIndex->parse(GdbIndexData); return *GdbIndex; } @@ -740,7 +737,7 @@ const DWARFDebugLoclists *DWARFContext::getDebugLocDWO() { // Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and // that means we are parsing the new style .debug_loc (pre-standatized version // of the .debug_loclists). - LocDWO->parse(LocData, 4 /* Version */); + LocDWO->parse(LocData, 0, LocData.getData().size(), 4 /* Version */); return LocDWO.get(); } @@ -766,7 +763,7 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() { // provides this information). This problem is fixed in DWARFv4 // See this dwarf-discuss discussion for more details: // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html - DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(), + DWARFDataExtractor debugFrameData(*DObj, DObj->getFrameSection(), isLittleEndian(), DObj->getAddressSize()); DebugFrame.reset(new DWARFDebugFrame(getArch(), false /* IsEH */)); DebugFrame->parse(debugFrameData); @@ -777,8 +774,8 @@ const DWARFDebugFrame *DWARFContext::getEHFrame() { if (EHFrame) return EHFrame.get(); - DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(), - DObj->getAddressSize()); + DWARFDataExtractor debugFrameData(*DObj, DObj->getEHFrameSection(), + isLittleEndian(), DObj->getAddressSize()); DebugFrame.reset(new DWARFDebugFrame(getArch(), true /* IsEH */)); DebugFrame->parse(debugFrameData); return DebugFrame.get(); @@ -809,29 +806,29 @@ static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj, } const DWARFDebugNames &DWARFContext::getDebugNames() { - return getAccelTable(Names, *DObj, DObj->getDebugNamesSection(), - DObj->getStringSection(), isLittleEndian()); + return getAccelTable(Names, *DObj, DObj->getNamesSection(), + DObj->getStrSection(), isLittleEndian()); } const AppleAcceleratorTable &DWARFContext::getAppleNames() { return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(), - DObj->getStringSection(), isLittleEndian()); + DObj->getStrSection(), isLittleEndian()); } const AppleAcceleratorTable &DWARFContext::getAppleTypes() { return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(), - DObj->getStringSection(), isLittleEndian()); + DObj->getStrSection(), isLittleEndian()); } const AppleAcceleratorTable &DWARFContext::getAppleNamespaces() { return getAccelTable(AppleNamespaces, *DObj, DObj->getAppleNamespacesSection(), - DObj->getStringSection(), isLittleEndian()); + DObj->getStrSection(), isLittleEndian()); } const AppleAcceleratorTable &DWARFContext::getAppleObjC() { return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(), - DObj->getStringSection(), isLittleEndian()); + DObj->getStrSection(), isLittleEndian()); } const DWARFDebugLine::LineTable * @@ -858,7 +855,7 @@ Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit( if (!Offset) return nullptr; // No line table for this compile unit. - uint32_t stmtOffset = *Offset + U->getLineTableOffset(); + uint64_t stmtOffset = *Offset + U->getLineTableOffset(); // See if the line table is cached. if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset)) return lt; @@ -898,7 +895,7 @@ void DWARFContext::parseDWOUnits(bool Lazy) { }); } -DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) { +DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint64_t Offset) { parseNormalUnits(); return dyn_cast_or_null<DWARFCompileUnit>( NormalUnits.getUnitForOffset(Offset)); @@ -906,7 +903,7 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) { DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) { // First, get the offset of the compile unit. - uint32_t CUOffset = getDebugAranges()->findAddress(Address); + uint64_t CUOffset = getDebugAranges()->findAddress(Address); // Retrieve the compile unit. return getCompileUnitForOffset(CUOffset); } @@ -1118,8 +1115,8 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange( if (!CU) return Lines; - std::string FunctionName = "<invalid>"; uint32_t StartLine = 0; + std::string FunctionName(DILineInfo::BadString); getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, FunctionName, StartLine); @@ -1379,46 +1376,50 @@ class DWARFObjInMemory final : public DWARFObject { InfoSectionMap TypesDWOSections; DWARFSectionMap LocSection; - DWARFSectionMap LocListsSection; + DWARFSectionMap LoclistsSection; DWARFSectionMap LineSection; - DWARFSectionMap RangeSection; + DWARFSectionMap RangesSection; DWARFSectionMap RnglistsSection; - DWARFSectionMap StringOffsetSection; + DWARFSectionMap StrOffsetsSection; DWARFSectionMap LineDWOSection; + DWARFSectionMap FrameSection; + DWARFSectionMap EHFrameSection; DWARFSectionMap LocDWOSection; - DWARFSectionMap StringOffsetDWOSection; - DWARFSectionMap RangeDWOSection; + DWARFSectionMap StrOffsetsDWOSection; + DWARFSectionMap RangesDWOSection; DWARFSectionMap RnglistsDWOSection; DWARFSectionMap AddrSection; DWARFSectionMap AppleNamesSection; DWARFSectionMap AppleTypesSection; DWARFSectionMap AppleNamespacesSection; DWARFSectionMap AppleObjCSection; - DWARFSectionMap DebugNamesSection; - DWARFSectionMap PubNamesSection; - DWARFSectionMap PubTypesSection; - DWARFSectionMap GnuPubNamesSection; - DWARFSectionMap GnuPubTypesSection; + DWARFSectionMap NamesSection; + DWARFSectionMap PubnamesSection; + DWARFSectionMap PubtypesSection; + DWARFSectionMap GnuPubnamesSection; + DWARFSectionMap GnuPubtypesSection; DWARFSectionMap *mapNameToDWARFSection(StringRef Name) { return StringSwitch<DWARFSectionMap *>(Name) .Case("debug_loc", &LocSection) - .Case("debug_loclists", &LocListsSection) + .Case("debug_loclists", &LoclistsSection) .Case("debug_line", &LineSection) - .Case("debug_str_offsets", &StringOffsetSection) - .Case("debug_ranges", &RangeSection) + .Case("debug_frame", &FrameSection) + .Case("eh_frame", &EHFrameSection) + .Case("debug_str_offsets", &StrOffsetsSection) + .Case("debug_ranges", &RangesSection) .Case("debug_rnglists", &RnglistsSection) .Case("debug_loc.dwo", &LocDWOSection) .Case("debug_line.dwo", &LineDWOSection) - .Case("debug_names", &DebugNamesSection) + .Case("debug_names", &NamesSection) .Case("debug_rnglists.dwo", &RnglistsDWOSection) - .Case("debug_str_offsets.dwo", &StringOffsetDWOSection) + .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection) .Case("debug_addr", &AddrSection) .Case("apple_names", &AppleNamesSection) - .Case("debug_pubnames", &PubNamesSection) - .Case("debug_pubtypes", &PubTypesSection) - .Case("debug_gnu_pubnames", &GnuPubNamesSection) - .Case("debug_gnu_pubtypes", &GnuPubTypesSection) + .Case("debug_pubnames", &PubnamesSection) + .Case("debug_pubtypes", &PubtypesSection) + .Case("debug_gnu_pubnames", &GnuPubnamesSection) + .Case("debug_gnu_pubtypes", &GnuPubtypesSection) .Case("apple_types", &AppleTypesSection) .Case("apple_namespaces", &AppleNamespacesSection) .Case("apple_namespac", &AppleNamespacesSection) @@ -1427,17 +1428,15 @@ class DWARFObjInMemory final : public DWARFObject { } StringRef AbbrevSection; - StringRef ARangeSection; - StringRef DebugFrameSection; - StringRef EHFrameSection; - StringRef StringSection; + StringRef ArangesSection; + StringRef StrSection; StringRef MacinfoSection; StringRef AbbrevDWOSection; - StringRef StringDWOSection; + StringRef StrDWOSection; StringRef CUIndexSection; StringRef GdbIndexSection; StringRef TUIndexSection; - StringRef LineStringSection; + StringRef LineStrSection; // A deque holding section data whose iterators are not invalidated when // new decompressed sections are inserted at the end. @@ -1448,17 +1447,15 @@ class DWARFObjInMemory final : public DWARFObject { return &Sec->Data; return StringSwitch<StringRef *>(Name) .Case("debug_abbrev", &AbbrevSection) - .Case("debug_aranges", &ARangeSection) - .Case("debug_frame", &DebugFrameSection) - .Case("eh_frame", &EHFrameSection) - .Case("debug_str", &StringSection) + .Case("debug_aranges", &ArangesSection) + .Case("debug_str", &StrSection) .Case("debug_macinfo", &MacinfoSection) .Case("debug_abbrev.dwo", &AbbrevDWOSection) - .Case("debug_str.dwo", &StringDWOSection) + .Case("debug_str.dwo", &StrDWOSection) .Case("debug_cu_index", &CUIndexSection) .Case("debug_tu_index", &TUIndexSection) .Case("gdb_index", &GdbIndexSection) - .Case("debug_line_str", &LineStringSection) + .Case("debug_line_str", &LineStrSection) // Any more debug info sections go here. .Default(nullptr); } @@ -1513,7 +1510,11 @@ public: StringMap<unsigned> SectionAmountMap; for (const SectionRef &Section : Obj.sections()) { StringRef Name; - Section.getName(Name); + if (auto NameOrErr = Section.getName()) + Name = *NameOrErr; + else + consumeError(NameOrErr.takeError()); + ++SectionAmountMap[Name]; SectionNames.push_back({ Name, true }); @@ -1526,10 +1527,19 @@ public: continue; StringRef Data; - section_iterator RelocatedSection = Section.getRelocatedSection(); + Expected<section_iterator> SecOrErr = Section.getRelocatedSection(); + if (!SecOrErr) { + ErrorPolicy EP = HandleError(createError( + "failed to get relocated section: ", SecOrErr.takeError())); + if (EP == ErrorPolicy::Halt) + return; + continue; + } + // Try to obtain an already relocated version of this section. // Else use the unrelocated section from the object file. We'll have to // apply relocations ourselves later. + section_iterator RelocatedSection = *SecOrErr; if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) { Expected<StringRef> E = Section.getContents(); if (E) @@ -1560,7 +1570,7 @@ public: *SectionData = Data; if (Name == "debug_ranges") { // FIXME: Use the other dwo range section when we emit it. - RangeDWOSection.Data = Data; + RangesDWOSection.Data = Data; } } else if (Name == "debug_info") { // Find debug_info and debug_types data by section rather than name as @@ -1578,12 +1588,15 @@ public: continue; StringRef RelSecName; - StringRef RelSecData; - RelocatedSection->getName(RelSecName); + if (auto NameOrErr = RelocatedSection->getName()) + RelSecName = *NameOrErr; + else + consumeError(NameOrErr.takeError()); // If the section we're relocating was relocated already by the JIT, // then we used the relocated version above, so we do not need to process // relocations for it now. + StringRef RelSecData; if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData)) continue; @@ -1710,12 +1723,12 @@ public: const DWARFSection &getLocDWOSection() const override { return LocDWOSection; } - StringRef getStringDWOSection() const override { return StringDWOSection; } - const DWARFSection &getStringOffsetDWOSection() const override { - return StringOffsetDWOSection; + StringRef getStrDWOSection() const override { return StrDWOSection; } + const DWARFSection &getStrOffsetsDWOSection() const override { + return StrOffsetsDWOSection; } - const DWARFSection &getRangeDWOSection() const override { - return RangeDWOSection; + const DWARFSection &getRangesDWOSection() const override { + return RangesDWOSection; } const DWARFSection &getRnglistsDWOSection() const override { return RnglistsDWOSection; @@ -1726,10 +1739,10 @@ public: StringRef getTUIndexSection() const override { return TUIndexSection; } // DWARF v5 - const DWARFSection &getStringOffsetSection() const override { - return StringOffsetSection; + const DWARFSection &getStrOffsetsSection() const override { + return StrOffsetsSection; } - StringRef getLineStringSection() const override { return LineStringSection; } + StringRef getLineStrSection() const override { return LineStrSection; } // Sections for DWARF5 split dwarf proposal. void forEachInfoDWOSections( @@ -1745,24 +1758,28 @@ public: StringRef getAbbrevSection() const override { return AbbrevSection; } const DWARFSection &getLocSection() const override { return LocSection; } - const DWARFSection &getLoclistsSection() const override { return LocListsSection; } - StringRef getARangeSection() const override { return ARangeSection; } - StringRef getDebugFrameSection() const override { return DebugFrameSection; } - StringRef getEHFrameSection() const override { return EHFrameSection; } + const DWARFSection &getLoclistsSection() const override { return LoclistsSection; } + StringRef getArangesSection() const override { return ArangesSection; } + const DWARFSection &getFrameSection() const override { + return FrameSection; + } + const DWARFSection &getEHFrameSection() const override { + return EHFrameSection; + } const DWARFSection &getLineSection() const override { return LineSection; } - StringRef getStringSection() const override { return StringSection; } - const DWARFSection &getRangeSection() const override { return RangeSection; } + StringRef getStrSection() const override { return StrSection; } + const DWARFSection &getRangesSection() const override { return RangesSection; } const DWARFSection &getRnglistsSection() const override { return RnglistsSection; } StringRef getMacinfoSection() const override { return MacinfoSection; } - const DWARFSection &getPubNamesSection() const override { return PubNamesSection; } - const DWARFSection &getPubTypesSection() const override { return PubTypesSection; } - const DWARFSection &getGnuPubNamesSection() const override { - return GnuPubNamesSection; + const DWARFSection &getPubnamesSection() const override { return PubnamesSection; } + const DWARFSection &getPubtypesSection() const override { return PubtypesSection; } + const DWARFSection &getGnuPubnamesSection() const override { + return GnuPubnamesSection; } - const DWARFSection &getGnuPubTypesSection() const override { - return GnuPubTypesSection; + const DWARFSection &getGnuPubtypesSection() const override { + return GnuPubtypesSection; } const DWARFSection &getAppleNamesSection() const override { return AppleNamesSection; @@ -1776,8 +1793,8 @@ public: const DWARFSection &getAppleObjCSection() const override { return AppleObjCSection; } - const DWARFSection &getDebugNamesSection() const override { - return DebugNamesSection; + const DWARFSection &getNamesSection() const override { + return NamesSection; } StringRef getFileName() const override { return FileName; } @@ -1799,16 +1816,16 @@ std::unique_ptr<DWARFContext> DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L, function_ref<ErrorPolicy(Error)> HandleError, std::string DWPName) { - auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError); - return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName)); + auto DObj = std::make_unique<DWARFObjInMemory>(Obj, L, HandleError); + return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName)); } std::unique_ptr<DWARFContext> DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, uint8_t AddrSize, bool isLittleEndian) { auto DObj = - llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian); - return llvm::make_unique<DWARFContext>(std::move(DObj), ""); + std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian); + return std::make_unique<DWARFContext>(std::move(DObj), ""); } Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) { diff --git a/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp index b9adf8cb1d99..53e676bc7031 100644 --- a/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp +++ b/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp @@ -12,14 +12,15 @@ using namespace llvm; -uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, - uint64_t *SecNdx) const { +uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off, + uint64_t *SecNdx, + Error *Err) const { if (SecNdx) *SecNdx = object::SectionedAddress::UndefSection; if (!Section) - return getUnsigned(Off, Size); + return getUnsigned(Off, Size, Err); Optional<RelocAddrEntry> E = Obj->find(*Section, *Off); - uint64_t A = getUnsigned(Off, Size); + uint64_t A = getUnsigned(Off, Size, Err); if (!E) return A; if (SecNdx) @@ -31,13 +32,13 @@ uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, } Optional<uint64_t> -DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding, +DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding, uint64_t PCRelOffset) const { if (Encoding == dwarf::DW_EH_PE_omit) return None; uint64_t Result = 0; - uint32_t OldOffset = *Offset; + uint64_t OldOffset = *Offset; // First get value switch (Encoding & 0x0F) { case dwarf::DW_EH_PE_absptr: diff --git a/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp b/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp index 31b324e5eb27..4afac2f99503 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp @@ -26,9 +26,9 @@ void DWARFAbbreviationDeclarationSet::clear() { } bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data, - uint32_t *OffsetPtr) { + uint64_t *OffsetPtr) { clear(); - const uint32_t BeginOffset = *OffsetPtr; + const uint64_t BeginOffset = *OffsetPtr; Offset = BeginOffset; DWARFAbbreviationDeclaration AbbrDecl; uint32_t PrevAbbrCode = 0; @@ -82,12 +82,12 @@ void DWARFDebugAbbrev::extract(DataExtractor Data) { void DWARFDebugAbbrev::parse() const { if (!Data) return; - uint32_t Offset = 0; + uint64_t Offset = 0; auto I = AbbrDeclSets.begin(); while (Data->isValidOffset(Offset)) { while (I != AbbrDeclSets.end() && I->first < Offset) ++I; - uint32_t CUAbbrOffset = Offset; + uint64_t CUAbbrOffset = Offset; DWARFAbbreviationDeclarationSet AbbrDecls; if (!AbbrDecls.extract(*Data, &Offset)) break; @@ -124,7 +124,7 @@ DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const { } if (Data && CUAbbrOffset < Data->getData().size()) { - uint32_t Offset = CUAbbrOffset; + uint64_t Offset = CUAbbrOffset; DWARFAbbreviationDeclarationSet AbbrDecls; if (!AbbrDecls.extract(*Data, &Offset)) return nullptr; diff --git a/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp b/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp index 58626539bba4..f71543799e28 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp @@ -19,7 +19,7 @@ void DWARFDebugAddrTable::clear() { } Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data, - uint32_t *OffsetPtr, + uint64_t *OffsetPtr, uint16_t Version, uint8_t AddrSize, std::function<void(Error)> WarnCallback) { @@ -30,7 +30,7 @@ Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data, return createStringError(errc::invalid_argument, "section is not large enough to contain a " ".debug_addr table length at offset 0x%" - PRIx32, *OffsetPtr); + PRIx64, *OffsetPtr); uint16_t UnitVersion; if (Version == 0) { WarnCallback(createStringError(errc::invalid_argument, @@ -44,28 +44,28 @@ Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data, Format = dwarf::DwarfFormat::DWARF32; if (UnitVersion >= 5) { HeaderData.Length = Data.getU32(OffsetPtr); - if (HeaderData.Length == 0xffffffffu) { + if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) { invalidateLength(); return createStringError(errc::not_supported, - "DWARF64 is not supported in .debug_addr at offset 0x%" PRIx32, + "DWARF64 is not supported in .debug_addr at offset 0x%" PRIx64, HeaderOffset); } if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header)) { uint32_t TmpLength = getLength(); invalidateLength(); return createStringError(errc::invalid_argument, - ".debug_addr table at offset 0x%" PRIx32 + ".debug_addr table at offset 0x%" PRIx64 " has too small length (0x%" PRIx32 ") to contain a complete header", HeaderOffset, TmpLength); } - uint32_t End = HeaderOffset + getLength(); + uint64_t End = HeaderOffset + getLength(); if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset)) { uint32_t TmpLength = getLength(); invalidateLength(); return createStringError(errc::invalid_argument, "section is not large enough to contain a .debug_addr table " - "of length 0x%" PRIx32 " at offset 0x%" PRIx32, + "of length 0x%" PRIx32 " at offset 0x%" PRIx64, TmpLength, HeaderOffset); } @@ -88,7 +88,7 @@ Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data, // and consists only of a series of addresses. if (HeaderData.Version > 5) { return createStringError(errc::not_supported, "version %" PRIu16 - " of .debug_addr section at offset 0x%" PRIx32 " is not supported", + " of .debug_addr section at offset 0x%" PRIx64 " is not supported", HeaderData.Version, HeaderOffset); } // FIXME: For now we just treat version mismatch as an error, @@ -97,19 +97,19 @@ Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data, // attribute in the info table. if (HeaderData.Version != UnitVersion) return createStringError(errc::invalid_argument, - ".debug_addr table at offset 0x%" PRIx32 + ".debug_addr table at offset 0x%" PRIx64 " has version %" PRIu16 " which is different from the version suggested" " by the DWARF unit header: %" PRIu16, HeaderOffset, HeaderData.Version, UnitVersion); if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8) return createStringError(errc::not_supported, - ".debug_addr table at offset 0x%" PRIx32 + ".debug_addr table at offset 0x%" PRIx64 " has unsupported address size %" PRIu8, HeaderOffset, HeaderData.AddrSize); if (HeaderData.AddrSize != AddrSize && AddrSize != 0) return createStringError(errc::invalid_argument, - ".debug_addr table at offset 0x%" PRIx32 + ".debug_addr table at offset 0x%" PRIx64 " has address size %" PRIu8 " which is different from CU address size %" PRIu8, HeaderOffset, HeaderData.AddrSize, AddrSize); @@ -117,13 +117,13 @@ Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data, // TODO: add support for non-zero segment selector size. if (HeaderData.SegSize != 0) return createStringError(errc::not_supported, - ".debug_addr table at offset 0x%" PRIx32 + ".debug_addr table at offset 0x%" PRIx64 " has unsupported segment selector size %" PRIu8, HeaderOffset, HeaderData.SegSize); if (DataSize % HeaderData.AddrSize != 0) { invalidateLength(); return createStringError(errc::invalid_argument, - ".debug_addr table at offset 0x%" PRIx32 + ".debug_addr table at offset 0x%" PRIx64 " contains data of size %" PRIu32 " which is not a multiple of addr size %" PRIu8, HeaderOffset, DataSize, HeaderData.AddrSize); @@ -162,7 +162,7 @@ Expected<uint64_t> DWARFDebugAddrTable::getAddrEntry(uint32_t Index) const { return Addrs[Index]; return createStringError(errc::invalid_argument, "Index %" PRIu32 " is out of range of the " - ".debug_addr table at offset 0x%" PRIx32, + ".debug_addr table at offset 0x%" PRIx64, Index, HeaderOffset); } diff --git a/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp b/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp index 6551b61accb8..200b2d52a02b 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp @@ -24,13 +24,13 @@ void DWARFDebugArangeSet::Descriptor::dump(raw_ostream &OS, } void DWARFDebugArangeSet::clear() { - Offset = -1U; + Offset = -1ULL; std::memset(&HeaderData, 0, sizeof(Header)); ArangeDescriptors.clear(); } bool -DWARFDebugArangeSet::extract(DataExtractor data, uint32_t *offset_ptr) { +DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) { if (data.isValidOffset(*offset_ptr)) { ArangeDescriptors.clear(); Offset = *offset_ptr; diff --git a/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp index 6460c9feeab8..ca6043109cdb 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp @@ -23,11 +23,11 @@ using namespace llvm; void DWARFDebugAranges::extract(DataExtractor DebugArangesData) { if (!DebugArangesData.isValidOffset(0)) return; - uint32_t Offset = 0; + uint64_t Offset = 0; DWARFDebugArangeSet Set; while (Set.extract(DebugArangesData, &Offset)) { - uint32_t CUOffset = Set.getCompileUnitDIEOffset(); + uint64_t CUOffset = Set.getCompileUnitDIEOffset(); for (const auto &Desc : Set.descriptors()) { uint64_t LowPC = Desc.Address; uint64_t HighPC = Desc.getEndAddress(); @@ -43,7 +43,7 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) { return; // Extract aranges from .debug_aranges section. - DataExtractor ArangesData(CTX->getDWARFObj().getARangeSection(), + DataExtractor ArangesData(CTX->getDWARFObj().getArangesSection(), CTX->isLittleEndian(), 0); extract(ArangesData); @@ -51,7 +51,7 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) { // it may describe only a small subset of compilation units, so we need to // manually build aranges for the rest of them. for (const auto &CU : CTX->compile_units()) { - uint32_t CUOffset = CU->getOffset(); + uint64_t CUOffset = CU->getOffset(); if (ParsedCUOffsets.insert(CUOffset).second) { Expected<DWARFAddressRangesVector> CURanges = CU->collectAddressRanges(); if (!CURanges) @@ -71,7 +71,7 @@ void DWARFDebugAranges::clear() { ParsedCUOffsets.clear(); } -void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC, +void DWARFDebugAranges::appendRange(uint64_t CUOffset, uint64_t LowPC, uint64_t HighPC) { if (LowPC >= HighPC) return; @@ -80,7 +80,7 @@ void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC, } void DWARFDebugAranges::construct() { - std::multiset<uint32_t> ValidCUs; // Maintain the set of CUs describing + std::multiset<uint64_t> ValidCUs; // Maintain the set of CUs describing // a current address range. llvm::sort(Endpoints); uint64_t PrevAddress = -1ULL; diff --git a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp index b3f23366f2a2..81b00f65741b 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -34,10 +34,10 @@ using namespace dwarf; const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0; const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f; -Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset, - uint32_t EndOffset) { +Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset, + uint64_t EndOffset) { while (*Offset < EndOffset) { - uint8_t Opcode = Data.getU8(Offset); + uint8_t Opcode = Data.getRelocatedValue(1, Offset); // Some instructions have a primary opcode encoded in the top bits. uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK; @@ -74,19 +74,19 @@ Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset, break; case DW_CFA_set_loc: // Operands: Address - addInstruction(Opcode, Data.getAddress(Offset)); + addInstruction(Opcode, Data.getRelocatedAddress(Offset)); break; case DW_CFA_advance_loc1: // Operands: 1-byte delta - addInstruction(Opcode, Data.getU8(Offset)); + addInstruction(Opcode, Data.getRelocatedValue(1, Offset)); break; case DW_CFA_advance_loc2: // Operands: 2-byte delta - addInstruction(Opcode, Data.getU16(Offset)); + addInstruction(Opcode, Data.getRelocatedValue(2, Offset)); break; case DW_CFA_advance_loc4: // Operands: 4-byte delta - addInstruction(Opcode, Data.getU32(Offset)); + addInstruction(Opcode, Data.getRelocatedValue(4, Offset)); break; case DW_CFA_restore_extended: case DW_CFA_undefined: @@ -331,7 +331,7 @@ DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch, DWARFDebugFrame::~DWARFDebugFrame() = default; static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, - uint32_t Offset, int Length) { + uint64_t Offset, int Length) { errs() << "DUMP: "; for (int i = 0; i < Length; ++i) { uint8_t c = Data.getU8(&Offset); @@ -344,7 +344,7 @@ static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, // noreturn attribute usage in lambdas. Once the support for those // compilers are phased out, we can remove this and return back to // a ReportError lambda: [StartOffset](const char *ErrorMsg). -static void LLVM_ATTRIBUTE_NORETURN ReportError(uint32_t StartOffset, +static void LLVM_ATTRIBUTE_NORETURN ReportError(uint64_t StartOffset, const char *ErrorMsg) { std::string Str; raw_string_ostream OS(Str); @@ -354,32 +354,30 @@ static void LLVM_ATTRIBUTE_NORETURN ReportError(uint32_t StartOffset, } void DWARFDebugFrame::parse(DWARFDataExtractor Data) { - uint32_t Offset = 0; - DenseMap<uint32_t, CIE *> CIEs; + uint64_t Offset = 0; + DenseMap<uint64_t, CIE *> CIEs; while (Data.isValidOffset(Offset)) { - uint32_t StartOffset = Offset; + uint64_t StartOffset = Offset; bool IsDWARF64 = false; - uint64_t Length = Data.getU32(&Offset); + uint64_t Length = Data.getRelocatedValue(4, &Offset); uint64_t Id; - if (Length == UINT32_MAX) { + if (Length == dwarf::DW_LENGTH_DWARF64) { // DWARF-64 is distinguished by the first 32 bits of the initial length // field being 0xffffffff. Then, the next 64 bits are the actual entry // length. IsDWARF64 = true; - Length = Data.getU64(&Offset); + Length = Data.getRelocatedValue(8, &Offset); } // At this point, Offset points to the next field after Length. // Length is the structure size excluding itself. Compute an offset one // past the end of the structure (needed to know how many instructions to // read). - // TODO: For honest DWARF64 support, DataExtractor will have to treat - // offset_ptr as uint64_t* - uint32_t StartStructureOffset = Offset; - uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length); + uint64_t StartStructureOffset = Offset; + uint64_t EndStructureOffset = Offset + Length; // The Id field's size depends on the DWARF format Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4); @@ -407,22 +405,23 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) { Optional<uint32_t> PersonalityEncoding; if (IsEH) { Optional<uint64_t> AugmentationLength; - uint32_t StartAugmentationOffset; - uint32_t EndAugmentationOffset; + uint64_t StartAugmentationOffset; + uint64_t EndAugmentationOffset; // Walk the augmentation string to get all the augmentation data. for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) { switch (AugmentationString[i]) { default: - ReportError(StartOffset, - "Unknown augmentation character in entry at %lx"); + ReportError( + StartOffset, + "Unknown augmentation character in entry at %" PRIx64); case 'L': LSDAPointerEncoding = Data.getU8(&Offset); break; case 'P': { if (Personality) ReportError(StartOffset, - "Duplicate personality in entry at %lx"); + "Duplicate personality in entry at %" PRIx64); PersonalityEncoding = Data.getU8(&Offset); Personality = Data.getEncodedPointer( &Offset, *PersonalityEncoding, @@ -438,13 +437,12 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) { case 'z': if (i) ReportError(StartOffset, - "'z' must be the first character at %lx"); + "'z' must be the first character at %" PRIx64); // Parse the augmentation length first. We only parse it if // the string contains a 'z'. AugmentationLength = Data.getULEB128(&Offset); StartAugmentationOffset = Offset; - EndAugmentationOffset = Offset + - static_cast<uint32_t>(*AugmentationLength); + EndAugmentationOffset = Offset + *AugmentationLength; break; case 'B': // B-Key is used for signing functions associated with this @@ -455,14 +453,15 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) { if (AugmentationLength.hasValue()) { if (Offset != EndAugmentationOffset) - ReportError(StartOffset, "Parsing augmentation data at %lx failed"); + ReportError(StartOffset, + "Parsing augmentation data at %" PRIx64 " failed"); AugmentationData = Data.getData().slice(StartAugmentationOffset, EndAugmentationOffset); } } - auto Cie = llvm::make_unique<CIE>( + auto Cie = std::make_unique<CIE>( StartOffset, Length, Version, AugmentationString, AddressSize, SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor, ReturnAddressRegister, AugmentationData, FDEPointerEncoding, @@ -480,8 +479,8 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) { if (IsEH) { // The address size is encoded in the CIE we reference. if (!Cie) - ReportError(StartOffset, - "Parsing FDE data at %lx failed due to missing CIE"); + ReportError(StartOffset, "Parsing FDE data at %" PRIx64 + " failed due to missing CIE"); if (auto Val = Data.getEncodedPointer( &Offset, Cie->getFDEPointerEncoding(), @@ -498,8 +497,7 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) { // Parse the augmentation length and data for this FDE. uint64_t AugmentationLength = Data.getULEB128(&Offset); - uint32_t EndAugmentationOffset = - Offset + static_cast<uint32_t>(AugmentationLength); + uint64_t EndAugmentationOffset = Offset + AugmentationLength; // Decode the LSDA if the CIE augmentation string said we should. if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) { @@ -509,11 +507,12 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) { } if (Offset != EndAugmentationOffset) - ReportError(StartOffset, "Parsing augmentation data at %lx failed"); + ReportError(StartOffset, + "Parsing augmentation data at %" PRIx64 " failed"); } } else { - InitialLocation = Data.getAddress(&Offset); - AddressRange = Data.getAddress(&Offset); + InitialLocation = Data.getRelocatedAddress(&Offset); + AddressRange = Data.getRelocatedAddress(&Offset); } Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer, @@ -527,7 +526,8 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) { } if (Offset != EndStructureOffset) - ReportError(StartOffset, "Parsing entry instructions at %lx failed"); + ReportError(StartOffset, + "Parsing entry instructions at %" PRIx64 " failed"); } } diff --git a/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp index d8a755e90df4..87eab34d58ee 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp @@ -19,15 +19,15 @@ using namespace llvm; using namespace dwarf; bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, - uint32_t *OffsetPtr) { + uint64_t *OffsetPtr) { DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor(); - const uint32_t UEndOffset = U.getNextUnitOffset(); + const uint64_t UEndOffset = U.getNextUnitOffset(); return extractFast(U, OffsetPtr, DebugInfoData, UEndOffset, 0); } -bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint32_t *OffsetPtr, +bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr, const DWARFDataExtractor &DebugInfoData, - uint32_t UEndOffset, uint32_t D) { + uint64_t UEndOffset, uint32_t D) { Offset = *OffsetPtr; Depth = D; if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset)) diff --git a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index a1cb1e8582ed..dbee28ff5ab1 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -16,7 +16,6 @@ #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Format.h" -#include "llvm/Support/Path.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> @@ -156,7 +155,7 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS, // Parse v2-v4 directory and file tables. static void parseV2DirFileTables(const DWARFDataExtractor &DebugLineData, - uint32_t *OffsetPtr, uint64_t EndPrologueOffset, + uint64_t *OffsetPtr, uint64_t EndPrologueOffset, DWARFDebugLine::ContentTypeTracker &ContentTypes, std::vector<DWARFFormValue> &IncludeDirectories, std::vector<DWARFDebugLine::FileNameEntry> &FileNames) { @@ -187,18 +186,24 @@ parseV2DirFileTables(const DWARFDataExtractor &DebugLineData, } // Parse v5 directory/file entry content descriptions. -// Returns the descriptors, or an empty vector if we did not find a path or -// ran off the end of the prologue. -static ContentDescriptors -parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t - *OffsetPtr, uint64_t EndPrologueOffset, DWARFDebugLine::ContentTypeTracker - *ContentTypes) { +// Returns the descriptors, or an error if we did not find a path or ran off +// the end of the prologue. +static llvm::Expected<ContentDescriptors> +parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, + uint64_t EndPrologueOffset, + DWARFDebugLine::ContentTypeTracker *ContentTypes) { ContentDescriptors Descriptors; int FormatCount = DebugLineData.getU8(OffsetPtr); bool HasPath = false; for (int I = 0; I != FormatCount; ++I) { if (*OffsetPtr >= EndPrologueOffset) - return ContentDescriptors(); + return createStringError( + errc::invalid_argument, + "failed to parse entry content descriptions at offset " + "0x%8.8" PRIx64 + " because offset extends beyond the prologue end at offset " + "0x%8.8" PRIx64, + *OffsetPtr, EndPrologueOffset); ContentDescriptor Descriptor; Descriptor.Type = dwarf::LineNumberEntryFormat(DebugLineData.getULEB128(OffsetPtr)); @@ -209,60 +214,82 @@ parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t ContentTypes->trackContentType(Descriptor.Type); Descriptors.push_back(Descriptor); } - return HasPath ? Descriptors : ContentDescriptors(); + + if (!HasPath) + return createStringError(errc::invalid_argument, + "failed to parse entry content descriptions" + " because no path was found"); + return Descriptors; } -static bool +static Error parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, - uint32_t *OffsetPtr, uint64_t EndPrologueOffset, + uint64_t *OffsetPtr, uint64_t EndPrologueOffset, const dwarf::FormParams &FormParams, const DWARFContext &Ctx, const DWARFUnit *U, DWARFDebugLine::ContentTypeTracker &ContentTypes, std::vector<DWARFFormValue> &IncludeDirectories, std::vector<DWARFDebugLine::FileNameEntry> &FileNames) { // Get the directory entry description. - ContentDescriptors DirDescriptors = + llvm::Expected<ContentDescriptors> DirDescriptors = parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, nullptr); - if (DirDescriptors.empty()) - return false; + if (!DirDescriptors) + return DirDescriptors.takeError(); // Get the directory entries, according to the format described above. int DirEntryCount = DebugLineData.getU8(OffsetPtr); for (int I = 0; I != DirEntryCount; ++I) { if (*OffsetPtr >= EndPrologueOffset) - return false; - for (auto Descriptor : DirDescriptors) { + return createStringError( + errc::invalid_argument, + "failed to parse directory entry at offset " + "0x%8.8" PRIx64 + " because offset extends beyond the prologue end at offset " + "0x%8.8" PRIx64, + *OffsetPtr, EndPrologueOffset); + for (auto Descriptor : *DirDescriptors) { DWARFFormValue Value(Descriptor.Form); switch (Descriptor.Type) { case DW_LNCT_path: if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U)) - return false; + return createStringError(errc::invalid_argument, + "failed to parse directory entry because " + "extracting the form value failed."); IncludeDirectories.push_back(Value); break; default: if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams)) - return false; + return createStringError(errc::invalid_argument, + "failed to parse directory entry because " + "skipping the form value failed."); } } } // Get the file entry description. - ContentDescriptors FileDescriptors = - parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, - &ContentTypes); - if (FileDescriptors.empty()) - return false; + llvm::Expected<ContentDescriptors> FileDescriptors = parseV5EntryFormat( + DebugLineData, OffsetPtr, EndPrologueOffset, &ContentTypes); + if (!FileDescriptors) + return FileDescriptors.takeError(); // Get the file entries, according to the format described above. int FileEntryCount = DebugLineData.getU8(OffsetPtr); for (int I = 0; I != FileEntryCount; ++I) { if (*OffsetPtr >= EndPrologueOffset) - return false; + return createStringError( + errc::invalid_argument, + "failed to parse file entry at offset " + "0x%8.8" PRIx64 + " because offset extends beyond the prologue end at offset " + "0x%8.8" PRIx64, + *OffsetPtr, EndPrologueOffset); DWARFDebugLine::FileNameEntry FileEntry; - for (auto Descriptor : FileDescriptors) { + for (auto Descriptor : *FileDescriptors) { DWARFFormValue Value(Descriptor.Form); if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U)) - return false; + return createStringError(errc::invalid_argument, + "failed to parse file entry because " + "extracting the form value failed."); switch (Descriptor.Type) { case DW_LNCT_path: FileEntry.Name = Value; @@ -280,7 +307,10 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, FileEntry.Length = Value.getAsUnsignedConstant().getValue(); break; case DW_LNCT_MD5: - assert(Value.getAsBlock().getValue().size() == 16); + if (!Value.getAsBlock() || Value.getAsBlock().getValue().size() != 16) + return createStringError( + errc::invalid_argument, + "failed to parse file entry because the MD5 hash is invalid"); std::uninitialized_copy_n(Value.getAsBlock().getValue().begin(), 16, FileEntry.Checksum.Bytes.begin()); break; @@ -290,21 +320,21 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, } FileNames.push_back(FileEntry); } - return true; + return Error::success(); } Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData, - uint32_t *OffsetPtr, + uint64_t *OffsetPtr, const DWARFContext &Ctx, const DWARFUnit *U) { const uint64_t PrologueOffset = *OffsetPtr; clear(); TotalLength = DebugLineData.getRelocatedValue(4, OffsetPtr); - if (TotalLength == UINT32_MAX) { + if (TotalLength == dwarf::DW_LENGTH_DWARF64) { FormParams.Format = dwarf::DWARF64; TotalLength = DebugLineData.getU64(OffsetPtr); - } else if (TotalLength >= 0xfffffff0) { + } else if (TotalLength >= dwarf::DW_LENGTH_lo_reserved) { return createStringError(errc::invalid_argument, "parsing line table prologue at offset 0x%8.8" PRIx64 " unsupported reserved unit length found of value 0x%8.8" PRIx64, @@ -343,14 +373,17 @@ Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData, } if (getVersion() >= 5) { - if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset, - FormParams, Ctx, U, ContentTypes, - IncludeDirectories, FileNames)) { - return createStringError(errc::invalid_argument, - "parsing line table prologue at 0x%8.8" PRIx64 - " found an invalid directory or file table description at" - " 0x%8.8" PRIx64, - PrologueOffset, (uint64_t)*OffsetPtr); + if (Error e = parseV5DirFileTables( + DebugLineData, OffsetPtr, EndPrologueOffset, FormParams, Ctx, U, + ContentTypes, IncludeDirectories, FileNames)) { + return joinErrors( + createStringError( + errc::invalid_argument, + "parsing line table prologue at 0x%8.8" PRIx64 + " found an invalid directory or file table description at" + " 0x%8.8" PRIx64, + PrologueOffset, *OffsetPtr), + std::move(e)); } } else parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset, @@ -361,7 +394,7 @@ Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData, "parsing line table prologue at 0x%8.8" PRIx64 " should have ended at 0x%8.8" PRIx64 " but it ended at 0x%8.8" PRIx64, - PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr); + PrologueOffset, EndPrologueOffset, *OffsetPtr); return Error::success(); } @@ -468,7 +501,7 @@ void DWARFDebugLine::ParsingState::appendRowToMatrix() { } const DWARFDebugLine::LineTable * -DWARFDebugLine::getLineTable(uint32_t Offset) const { +DWARFDebugLine::getLineTable(uint64_t Offset) const { LineTableConstIter Pos = LineTableMap.find(Offset); if (Pos != LineTableMap.end()) return &Pos->second; @@ -476,10 +509,10 @@ DWARFDebugLine::getLineTable(uint32_t Offset) const { } Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable( - DWARFDataExtractor &DebugLineData, uint32_t Offset, const DWARFContext &Ctx, + DWARFDataExtractor &DebugLineData, uint64_t Offset, const DWARFContext &Ctx, const DWARFUnit *U, std::function<void(Error)> RecoverableErrorCallback) { if (!DebugLineData.isValidOffset(Offset)) - return createStringError(errc::invalid_argument, "offset 0x%8.8" PRIx32 + return createStringError(errc::invalid_argument, "offset 0x%8.8" PRIx64 " is not a valid debug line section offset", Offset); @@ -496,10 +529,10 @@ Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable( } Error DWARFDebugLine::LineTable::parse( - DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, + DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr, const DWARFContext &Ctx, const DWARFUnit *U, std::function<void(Error)> RecoverableErrorCallback, raw_ostream *OS) { - const uint32_t DebugLineOffset = *OffsetPtr; + const uint64_t DebugLineOffset = *OffsetPtr; clear(); @@ -515,7 +548,7 @@ Error DWARFDebugLine::LineTable::parse( if (PrologueErr) return PrologueErr; - const uint32_t EndOffset = + const uint64_t EndOffset = DebugLineOffset + Prologue.TotalLength + Prologue.sizeofTotalLength(); // See if we should tell the data extractor the address size. @@ -529,7 +562,7 @@ Error DWARFDebugLine::LineTable::parse( while (*OffsetPtr < EndOffset) { if (OS) - *OS << format("0x%08.08" PRIx32 ": ", *OffsetPtr); + *OS << format("0x%08.08" PRIx64 ": ", *OffsetPtr); uint8_t Opcode = DebugLineData.getU8(OffsetPtr); @@ -540,7 +573,7 @@ Error DWARFDebugLine::LineTable::parse( // Extended Opcodes always start with a zero opcode followed by // a uleb128 length so you can skip ones you don't know about uint64_t Len = DebugLineData.getULEB128(OffsetPtr); - uint32_t ExtOffset = *OffsetPtr; + uint64_t ExtOffset = *OffsetPtr; // Tolerate zero-length; assume length is correct and soldier on. if (Len == 0) { @@ -585,7 +618,7 @@ Error DWARFDebugLine::LineTable::parse( DebugLineData.setAddressSize(Len - 1); else if (DebugLineData.getAddressSize() != Len - 1) { return createStringError(errc::invalid_argument, - "mismatching address size at offset 0x%8.8" PRIx32 + "mismatching address size at offset 0x%8.8" PRIx64 " expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64, ExtOffset, DebugLineData.getAddressSize(), Len - 1); @@ -652,8 +685,8 @@ Error DWARFDebugLine::LineTable::parse( // Otherwise we have an unparseable line-number program. if (*OffsetPtr - ExtOffset != Len) return createStringError(errc::illegal_byte_sequence, - "unexpected line op length at offset 0x%8.8" PRIx32 - " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx32, + "unexpected line op length at offset 0x%8.8" PRIx64 + " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64, ExtOffset, Len, *OffsetPtr - ExtOffset); } else if (Opcode < Prologue.OpcodeBase) { if (OS) @@ -1007,10 +1040,9 @@ static bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) { sys::path::is_absolute(Path, sys::path::Style::windows); } -bool DWARFDebugLine::Prologue::getFileNameByIndex(uint64_t FileIndex, - StringRef CompDir, - FileLineInfoKind Kind, - std::string &Result) const { +bool DWARFDebugLine::Prologue::getFileNameByIndex( + uint64_t FileIndex, StringRef CompDir, FileLineInfoKind Kind, + std::string &Result, sys::path::Style Style) const { if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex)) return false; const FileNameEntry &Entry = getFileNameEntry(FileIndex); @@ -1036,11 +1068,11 @@ bool DWARFDebugLine::Prologue::getFileNameByIndex(uint64_t FileIndex, // We know that FileName is not absolute, the only way to have an // absolute path at this point would be if IncludeDir is absolute. if (!CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir)) - sys::path::append(FilePath, CompDir); + sys::path::append(FilePath, Style, CompDir); } // sys::path::append skips empty strings. - sys::path::append(FilePath, IncludeDir, FileName); + sys::path::append(FilePath, Style, IncludeDir, FileName); Result = FilePath.str(); return true; } @@ -1092,7 +1124,8 @@ DWARFDebugLine::SectionParser::SectionParser(DWARFDataExtractor &Data, } bool DWARFDebugLine::Prologue::totalLengthIsValid() const { - return TotalLength == 0xffffffff || TotalLength < 0xfffffff0; + return TotalLength == dwarf::DW_LENGTH_DWARF64 || + TotalLength < dwarf::DW_LENGTH_lo_reserved; } DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext( @@ -1101,7 +1134,7 @@ DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext( assert(DebugLineData.isValidOffset(Offset) && "parsing should have terminated"); DWARFUnit *U = prepareToParse(Offset); - uint32_t OldOffset = Offset; + uint64_t OldOffset = Offset; LineTable LT; if (Error Err = LT.parse(DebugLineData, &Offset, Context, U, RecoverableErrorCallback, OS)) @@ -1115,14 +1148,14 @@ void DWARFDebugLine::SectionParser::skip( assert(DebugLineData.isValidOffset(Offset) && "parsing should have terminated"); DWARFUnit *U = prepareToParse(Offset); - uint32_t OldOffset = Offset; + uint64_t OldOffset = Offset; LineTable LT; if (Error Err = LT.Prologue.parse(DebugLineData, &Offset, Context, U)) ErrorCallback(std::move(Err)); moveToNextTable(OldOffset, LT.Prologue); } -DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint32_t Offset) { +DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint64_t Offset) { DWARFUnit *U = nullptr; auto It = LineToUnit.find(Offset); if (It != LineToUnit.end()) @@ -1131,7 +1164,7 @@ DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint32_t Offset) { return U; } -void DWARFDebugLine::SectionParser::moveToNextTable(uint32_t OldOffset, +void DWARFDebugLine::SectionParser::moveToNextTable(uint64_t OldOffset, const Prologue &P) { // If the length field is not valid, we don't know where the next table is, so // cannot continue to parse. Mark the parser as done, and leave the Offset diff --git a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp index 6d8f4bee77c4..4f7b01130a47 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -28,19 +28,18 @@ using namespace llvm; // expression that LLVM doesn't produce. Guessing the wrong version means we // won't be able to pretty print expressions in DWARF2 binaries produced by // non-LLVM tools. -static void dumpExpression(raw_ostream &OS, ArrayRef<char> Data, +static void dumpExpression(raw_ostream &OS, ArrayRef<uint8_t> Data, bool IsLittleEndian, unsigned AddressSize, const MCRegisterInfo *MRI, DWARFUnit *U) { - DWARFDataExtractor Extractor(StringRef(Data.data(), Data.size()), - IsLittleEndian, AddressSize); + DWARFDataExtractor Extractor(toStringRef(Data), IsLittleEndian, AddressSize); DWARFExpression(Extractor, dwarf::DWARF_VERSION, AddressSize).print(OS, MRI, U); } -void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, bool IsLittleEndian, +void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, uint64_t BaseAddress, + bool IsLittleEndian, unsigned AddressSize, - const MCRegisterInfo *MRI, - DWARFUnit *U, - uint64_t BaseAddress, + const MCRegisterInfo *MRI, DWARFUnit *U, + DIDumpOptions DumpOpts, unsigned Indent) const { for (const Entry &E : Entries) { OS << '\n'; @@ -64,12 +63,12 @@ DWARFDebugLoc::getLocationListAtOffset(uint64_t Offset) const { return nullptr; } -void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, +void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, DIDumpOptions DumpOpts, Optional<uint64_t> Offset) const { auto DumpLocationList = [&](const LocationList &L) { - OS << format("0x%8.8x: ", L.Offset); - L.dump(OS, IsLittleEndian, AddressSize, MRI, nullptr, 0, 12); - OS << "\n\n"; + OS << format("0x%8.8" PRIx64 ": ", L.Offset); + L.dump(OS, 0, IsLittleEndian, AddressSize, MRI, nullptr, DumpOpts, 12); + OS << "\n"; }; if (Offset) { @@ -80,50 +79,47 @@ void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, for (const LocationList &L : Locations) { DumpLocationList(L); + if (&L != &Locations.back()) + OS << '\n'; } } -Optional<DWARFDebugLoc::LocationList> -DWARFDebugLoc::parseOneLocationList(DWARFDataExtractor Data, unsigned *Offset) { +Expected<DWARFDebugLoc::LocationList> +DWARFDebugLoc::parseOneLocationList(const DWARFDataExtractor &Data, + uint64_t *Offset) { LocationList LL; LL.Offset = *Offset; + AddressSize = Data.getAddressSize(); + DataExtractor::Cursor C(*Offset); // 2.6.2 Location Lists // A location list entry consists of: while (true) { Entry E; - if (!Data.isValidOffsetForDataOfSize(*Offset, 2 * Data.getAddressSize())) { - WithColor::error() << "location list overflows the debug_loc section.\n"; - return None; - } // 1. A beginning address offset. ... - E.Begin = Data.getRelocatedAddress(Offset); + E.Begin = Data.getRelocatedAddress(C); // 2. An ending address offset. ... - E.End = Data.getRelocatedAddress(Offset); + E.End = Data.getRelocatedAddress(C); + + if (Error Err = C.takeError()) + return std::move(Err); // The end of any given location list is marked by an end of list entry, // which consists of a 0 for the beginning address offset and a 0 for the // ending address offset. - if (E.Begin == 0 && E.End == 0) + if (E.Begin == 0 && E.End == 0) { + *Offset = C.tell(); return LL; - - if (!Data.isValidOffsetForDataOfSize(*Offset, 2)) { - WithColor::error() << "location list overflows the debug_loc section.\n"; - return None; } - unsigned Bytes = Data.getU16(Offset); - if (!Data.isValidOffsetForDataOfSize(*Offset, Bytes)) { - WithColor::error() << "location list overflows the debug_loc section.\n"; - return None; + if (E.Begin != (AddressSize == 4 ? -1U : -1ULL)) { + unsigned Bytes = Data.getU16(C); + // A single location description describing the location of the object... + Data.getU8(C, E.Loc, Bytes); } - // A single location description describing the location of the object... - StringRef str = Data.getData().substr(*Offset, Bytes); - *Offset += Bytes; - E.Loc.reserve(str.size()); - llvm::copy(str, std::back_inserter(E.Loc)); + LL.Entries.push_back(std::move(E)); } } @@ -132,81 +128,89 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) { IsLittleEndian = data.isLittleEndian(); AddressSize = data.getAddressSize(); - uint32_t Offset = 0; - while (data.isValidOffset(Offset + data.getAddressSize() - 1)) { + uint64_t Offset = 0; + while (Offset < data.getData().size()) { if (auto LL = parseOneLocationList(data, &Offset)) Locations.push_back(std::move(*LL)); - else + else { + logAllUnhandledErrors(LL.takeError(), WithColor::error()); break; + } } - if (data.isValidOffset(Offset)) - WithColor::error() << "failed to consume entire .debug_loc section\n"; } -Optional<DWARFDebugLoclists::LocationList> -DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset, - unsigned Version) { +Expected<DWARFDebugLoclists::LocationList> +DWARFDebugLoclists::parseOneLocationList(const DataExtractor &Data, + uint64_t *Offset, unsigned Version) { LocationList LL; LL.Offset = *Offset; + DataExtractor::Cursor C(*Offset); // dwarf::DW_LLE_end_of_list_entry is 0 and indicates the end of the list. - while (auto Kind = - static_cast<dwarf::LocationListEntry>(Data.getU8(Offset))) { - + while (auto Kind = Data.getU8(C)) { Entry E; E.Kind = Kind; + E.Offset = C.tell() - 1; switch (Kind) { + case dwarf::DW_LLE_base_addressx: + E.Value0 = Data.getULEB128(C); + break; case dwarf::DW_LLE_startx_length: - E.Value0 = Data.getULEB128(Offset); + E.Value0 = Data.getULEB128(C); // Pre-DWARF 5 has different interpretation of the length field. We have // to support both pre- and standartized styles for the compatibility. if (Version < 5) - E.Value1 = Data.getU32(Offset); + E.Value1 = Data.getU32(C); else - E.Value1 = Data.getULEB128(Offset); + E.Value1 = Data.getULEB128(C); break; case dwarf::DW_LLE_start_length: - E.Value0 = Data.getAddress(Offset); - E.Value1 = Data.getULEB128(Offset); + E.Value0 = Data.getAddress(C); + E.Value1 = Data.getULEB128(C); break; case dwarf::DW_LLE_offset_pair: - E.Value0 = Data.getULEB128(Offset); - E.Value1 = Data.getULEB128(Offset); + E.Value0 = Data.getULEB128(C); + E.Value1 = Data.getULEB128(C); break; case dwarf::DW_LLE_base_address: - E.Value0 = Data.getAddress(Offset); + E.Value0 = Data.getAddress(C); break; default: - WithColor::error() << "dumping support for LLE of kind " << (int)Kind - << " not implemented\n"; - return None; + cantFail(C.takeError()); + return createStringError(errc::illegal_byte_sequence, + "LLE of kind %x not supported", (int)Kind); } - if (Kind != dwarf::DW_LLE_base_address) { - unsigned Bytes = - Version >= 5 ? Data.getULEB128(Offset) : Data.getU16(Offset); + if (Kind != dwarf::DW_LLE_base_address && + Kind != dwarf::DW_LLE_base_addressx) { + unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : Data.getU16(C); // A single location description describing the location of the object... - StringRef str = Data.getData().substr(*Offset, Bytes); - *Offset += Bytes; - E.Loc.resize(str.size()); - llvm::copy(str, E.Loc.begin()); + Data.getU8(C, E.Loc, Bytes); } LL.Entries.push_back(std::move(E)); } + if (Error Err = C.takeError()) + return std::move(Err); + Entry E; + E.Kind = dwarf::DW_LLE_end_of_list; + E.Offset = C.tell() - 1; + LL.Entries.push_back(E); + *Offset = C.tell(); return LL; } -void DWARFDebugLoclists::parse(DataExtractor data, unsigned Version) { +void DWARFDebugLoclists::parse(DataExtractor data, uint64_t Offset, uint64_t EndOffset, uint16_t Version) { IsLittleEndian = data.isLittleEndian(); AddressSize = data.getAddressSize(); - uint32_t Offset = 0; - while (data.isValidOffset(Offset)) { + while (Offset < EndOffset) { if (auto LL = parseOneLocationList(data, &Offset, Version)) Locations.push_back(std::move(*LL)); - else + else { + logAllUnhandledErrors(LL.takeError(), WithColor::error()); return; + } } } @@ -219,51 +223,106 @@ DWARFDebugLoclists::getLocationListAtOffset(uint64_t Offset) const { return nullptr; } -void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr, - bool IsLittleEndian, - unsigned AddressSize, - const MCRegisterInfo *MRI, - DWARFUnit *U, - unsigned Indent) const { - for (const Entry &E : Entries) { - switch (E.Kind) { +void DWARFDebugLoclists::Entry::dump(raw_ostream &OS, uint64_t &BaseAddr, + bool IsLittleEndian, unsigned AddressSize, + const MCRegisterInfo *MRI, DWARFUnit *U, + DIDumpOptions DumpOpts, unsigned Indent, + size_t MaxEncodingStringLength) const { + if (DumpOpts.Verbose) { + OS << "\n"; + OS.indent(Indent); + auto EncodingString = dwarf::LocListEncodingString(Kind); + // Unsupported encodings should have been reported during parsing. + assert(!EncodingString.empty() && "Unknown loclist entry encoding"); + OS << format("%s%*c", EncodingString.data(), + MaxEncodingStringLength - EncodingString.size() + 1, '('); + switch (Kind) { case dwarf::DW_LLE_startx_length: - OS << '\n'; - OS.indent(Indent); - OS << "Addr idx " << E.Value0 << " (w/ length " << E.Value1 << "): "; - break; case dwarf::DW_LLE_start_length: - OS << '\n'; - OS.indent(Indent); - OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 "): ", AddressSize * 2, - AddressSize * 2, E.Value0, AddressSize * 2, AddressSize * 2, - E.Value0 + E.Value1); - break; case dwarf::DW_LLE_offset_pair: - OS << '\n'; - OS.indent(Indent); - OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 "): ", AddressSize * 2, - AddressSize * 2, BaseAddr + E.Value0, AddressSize * 2, - AddressSize * 2, BaseAddr + E.Value1); + OS << format("0x%*.*" PRIx64 ", 0x%*.*" PRIx64, AddressSize * 2, + AddressSize * 2, Value0, AddressSize * 2, AddressSize * 2, + Value1); break; + case dwarf::DW_LLE_base_addressx: case dwarf::DW_LLE_base_address: - BaseAddr = E.Value0; + OS << format("0x%*.*" PRIx64, AddressSize * 2, AddressSize * 2, + Value0); + break; + case dwarf::DW_LLE_end_of_list: break; - default: - llvm_unreachable("unreachable locations list kind"); } - - dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, U); + OS << ')'; } + auto PrintPrefix = [&] { + OS << "\n"; + OS.indent(Indent); + if (DumpOpts.Verbose) + OS << format("%*s", MaxEncodingStringLength, (const char *)"=> "); + }; + switch (Kind) { + case dwarf::DW_LLE_startx_length: + PrintPrefix(); + OS << "Addr idx " << Value0 << " (w/ length " << Value1 << "): "; + break; + case dwarf::DW_LLE_start_length: + PrintPrefix(); + DWARFAddressRange(Value0, Value0 + Value1) + .dump(OS, AddressSize, DumpOpts); + OS << ": "; + break; + case dwarf::DW_LLE_offset_pair: + PrintPrefix(); + DWARFAddressRange(BaseAddr + Value0, BaseAddr + Value1) + .dump(OS, AddressSize, DumpOpts); + OS << ": "; + break; + case dwarf::DW_LLE_base_addressx: + if (!DumpOpts.Verbose) + return; + break; + case dwarf::DW_LLE_end_of_list: + if (!DumpOpts.Verbose) + return; + break; + case dwarf::DW_LLE_base_address: + BaseAddr = Value0; + if (!DumpOpts.Verbose) + return; + break; + default: + llvm_unreachable("unreachable locations list kind"); + } + + dumpExpression(OS, Loc, IsLittleEndian, AddressSize, MRI, U); +} +void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr, + bool IsLittleEndian, + unsigned AddressSize, + const MCRegisterInfo *MRI, + DWARFUnit *U, + DIDumpOptions DumpOpts, + unsigned Indent) const { + size_t MaxEncodingStringLength = 0; + if (DumpOpts.Verbose) + for (const auto &Entry : Entries) + MaxEncodingStringLength = + std::max(MaxEncodingStringLength, + dwarf::LocListEncodingString(Entry.Kind).size()); + + for (const Entry &E : Entries) + E.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, U, DumpOpts, Indent, + MaxEncodingStringLength); } void DWARFDebugLoclists::dump(raw_ostream &OS, uint64_t BaseAddr, - const MCRegisterInfo *MRI, + const MCRegisterInfo *MRI, DIDumpOptions DumpOpts, Optional<uint64_t> Offset) const { auto DumpLocationList = [&](const LocationList &L) { - OS << format("0x%8.8x: ", L.Offset); - L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, nullptr, /*Indent=*/12); - OS << "\n\n"; + OS << format("0x%8.8" PRIx64 ": ", L.Offset); + L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, nullptr, DumpOpts, + /*Indent=*/12); + OS << "\n"; }; if (Offset) { @@ -274,5 +333,7 @@ void DWARFDebugLoclists::dump(raw_ostream &OS, uint64_t BaseAddr, for (const LocationList &L : Locations) { DumpLocationList(L); + if (&L != &Locations.back()) + OS << '\n'; } } diff --git a/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp index 3317a778cc70..9a0e770aed3d 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp @@ -53,7 +53,7 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const { } void DWARFDebugMacro::parse(DataExtractor data) { - uint32_t Offset = 0; + uint64_t Offset = 0; while (data.isValidOffset(Offset)) { // A macro list entry consists of: Entry E; diff --git a/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp b/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp index 963ec64f5e91..ab71b239cb67 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp @@ -23,7 +23,7 @@ DWARFDebugPubTable::DWARFDebugPubTable(const DWARFObject &Obj, bool LittleEndian, bool GnuStyle) : GnuStyle(GnuStyle) { DWARFDataExtractor PubNames(Obj, Sec, LittleEndian, 0); - uint32_t Offset = 0; + uint64_t Offset = 0; while (PubNames.isValidOffset(Offset)) { Sets.push_back({}); Set &SetData = Sets.back(); @@ -49,13 +49,13 @@ void DWARFDebugPubTable::dump(raw_ostream &OS) const { for (const Set &S : Sets) { OS << "length = " << format("0x%08x", S.Length); OS << " version = " << format("0x%04x", S.Version); - OS << " unit_offset = " << format("0x%08x", S.Offset); + OS << " unit_offset = " << format("0x%08" PRIx64, S.Offset); OS << " unit_size = " << format("0x%08x", S.Size) << '\n'; OS << (GnuStyle ? "Offset Linkage Kind Name\n" : "Offset Name\n"); for (const Entry &E : S.Entries) { - OS << format("0x%8.8x ", E.SecOffset); + OS << format("0x%8.8" PRIx64 " ", E.SecOffset); if (GnuStyle) { StringRef EntryLinkage = GDBIndexEntryLinkageString(E.Descriptor.Linkage); diff --git a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp index d8df81a0aa0b..1a1857d8cd79 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp @@ -17,17 +17,17 @@ using namespace llvm; void DWARFDebugRangeList::clear() { - Offset = -1U; + Offset = -1ULL; AddressSize = 0; Entries.clear(); } Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data, - uint32_t *offset_ptr) { + uint64_t *offset_ptr) { clear(); if (!data.isValidOffset(*offset_ptr)) return createStringError(errc::invalid_argument, - "invalid range list offset 0x%" PRIx32, *offset_ptr); + "invalid range list offset 0x%" PRIx64, *offset_ptr); AddressSize = data.getAddressSize(); if (AddressSize != 4 && AddressSize != 8) @@ -38,7 +38,7 @@ Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data, RangeListEntry Entry; Entry.SectionIndex = -1ULL; - uint32_t prev_offset = *offset_ptr; + uint64_t prev_offset = *offset_ptr; Entry.StartAddress = data.getRelocatedAddress(offset_ptr); Entry.EndAddress = data.getRelocatedAddress(offset_ptr, &Entry.SectionIndex); @@ -47,7 +47,7 @@ Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data, if (*offset_ptr != prev_offset + 2 * AddressSize) { clear(); return createStringError(errc::invalid_argument, - "invalid range list entry at offset 0x%" PRIx32, + "invalid range list entry at offset 0x%" PRIx64, prev_offset); } if (Entry.isEndOfListEntry()) @@ -59,12 +59,12 @@ Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data, void DWARFDebugRangeList::dump(raw_ostream &OS) const { for (const RangeListEntry &RLE : Entries) { - const char *format_str = (AddressSize == 4 - ? "%08x %08" PRIx64 " %08" PRIx64 "\n" - : "%08x %016" PRIx64 " %016" PRIx64 "\n"); + const char *format_str = + (AddressSize == 4 ? "%08" PRIx64 " %08" PRIx64 " %08" PRIx64 "\n" + : "%08" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n"); OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress); } - OS << format("%08x <End of list>\n", Offset); + OS << format("%08" PRIx64 " <End of list>\n", Offset); } DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges( diff --git a/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp index 5ac3326f6681..f6785b89e86d 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp @@ -16,8 +16,8 @@ using namespace llvm; -Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End, - uint32_t *OffsetPtr) { +Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t End, + uint64_t *OffsetPtr) { Offset = *OffsetPtr; SectionIndex = -1ULL; // The caller should guarantee that we have at least 1 byte available, so @@ -32,41 +32,41 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End, break; // TODO: Support other encodings. case dwarf::DW_RLE_base_addressx: { - uint32_t PreviousOffset = *OffsetPtr - 1; + uint64_t PreviousOffset = *OffsetPtr - 1; Value0 = Data.getULEB128(OffsetPtr); if (End < *OffsetPtr) return createStringError( errc::invalid_argument, "read past end of table when reading " - "DW_RLE_base_addressx encoding at offset 0x%" PRIx32, + "DW_RLE_base_addressx encoding at offset 0x%" PRIx64, PreviousOffset); break; } case dwarf::DW_RLE_startx_endx: return createStringError(errc::not_supported, "unsupported rnglists encoding DW_RLE_startx_endx at " - "offset 0x%" PRIx32, + "offset 0x%" PRIx64, *OffsetPtr - 1); case dwarf::DW_RLE_startx_length: { - uint32_t PreviousOffset = *OffsetPtr - 1; + uint64_t PreviousOffset = *OffsetPtr - 1; Value0 = Data.getULEB128(OffsetPtr); Value1 = Data.getULEB128(OffsetPtr); if (End < *OffsetPtr) return createStringError( errc::invalid_argument, "read past end of table when reading " - "DW_RLE_startx_length encoding at offset 0x%" PRIx32, + "DW_RLE_startx_length encoding at offset 0x%" PRIx64, PreviousOffset); break; } case dwarf::DW_RLE_offset_pair: { - uint32_t PreviousOffset = *OffsetPtr - 1; + uint64_t PreviousOffset = *OffsetPtr - 1; Value0 = Data.getULEB128(OffsetPtr); Value1 = Data.getULEB128(OffsetPtr); if (End < *OffsetPtr) return createStringError(errc::invalid_argument, "read past end of table when reading " - "DW_RLE_offset_pair encoding at offset 0x%" PRIx32, + "DW_RLE_offset_pair encoding at offset 0x%" PRIx64, PreviousOffset); break; } @@ -74,7 +74,7 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End, if ((End - *OffsetPtr) < Data.getAddressSize()) return createStringError(errc::invalid_argument, "insufficient space remaining in table for " - "DW_RLE_base_address encoding at offset 0x%" PRIx32, + "DW_RLE_base_address encoding at offset 0x%" PRIx64, *OffsetPtr - 1); Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex); break; @@ -84,27 +84,27 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End, return createStringError(errc::invalid_argument, "insufficient space remaining in table for " "DW_RLE_start_end encoding " - "at offset 0x%" PRIx32, + "at offset 0x%" PRIx64, *OffsetPtr - 1); Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex); Value1 = Data.getRelocatedAddress(OffsetPtr); break; } case dwarf::DW_RLE_start_length: { - uint32_t PreviousOffset = *OffsetPtr - 1; + uint64_t PreviousOffset = *OffsetPtr - 1; Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex); Value1 = Data.getULEB128(OffsetPtr); if (End < *OffsetPtr) return createStringError(errc::invalid_argument, "read past end of table when reading " - "DW_RLE_start_length encoding at offset 0x%" PRIx32, + "DW_RLE_start_length encoding at offset 0x%" PRIx64, PreviousOffset); break; } default: return createStringError(errc::not_supported, "unknown rnglists encoding 0x%" PRIx32 - " at offset 0x%" PRIx32, + " at offset 0x%" PRIx64, uint32_t(Encoding), *OffsetPtr - 1); } @@ -187,7 +187,7 @@ void RangeListEntry::dump( if (DumpOpts.Verbose) { // Print the section offset in verbose mode. - OS << format("0x%8.8" PRIx32 ":", Offset); + OS << format("0x%8.8" PRIx64 ":", Offset); auto EncodingString = dwarf::RangeListEncodingString(EntryKind); // Unsupported encodings should have been reported during parsing. assert(!EncodingString.empty() && "Unknown range entry encoding"); diff --git a/lib/DebugInfo/DWARF/DWARFDie.cpp b/lib/DebugInfo/DWARF/DWARFDie.cpp index d638dc4239f4..cec194e8b6b3 100644 --- a/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -21,6 +21,7 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Format.h" +#include "llvm/Support/FormatAdapters.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/WithColor.h" @@ -91,21 +92,29 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, } FormValue.dump(OS, DumpOpts); + const auto &DumpLL = [&](auto ExpectedLL) { + if (ExpectedLL) { + uint64_t BaseAddr = 0; + if (Optional<object::SectionedAddress> BA = U->getBaseAddress()) + BaseAddr = BA->Address; + auto LLDumpOpts = DumpOpts; + LLDumpOpts.Verbose = false; + ExpectedLL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), + MRI, U, LLDumpOpts, Indent); + } else { + OS << '\n'; + OS.indent(Indent); + OS << formatv("error extracting location list: {0}", + fmt_consume(ExpectedLL.takeError())); + } + }; if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) { - uint32_t Offset = *FormValue.getAsSectionOffset(); + uint64_t Offset = *FormValue.getAsSectionOffset(); if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) { DWARFDebugLoc DebugLoc; DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(), Obj.getAddressSize()); - auto LL = DebugLoc.parseOneLocationList(Data, &Offset); - if (LL) { - uint64_t BaseAddr = 0; - if (Optional<object::SectionedAddress> BA = U->getBaseAddress()) - BaseAddr = BA->Address; - LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U, - BaseAddr, Indent); - } else - OS << "error extracting location list."; + DumpLL(DebugLoc.parseOneLocationList(Data, &Offset)); return; } @@ -121,18 +130,8 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, // Modern locations list (.debug_loclists) are used starting from v5. // Ideally we should take the version from the .debug_loclists section // header, but using CU's version for simplicity. - auto LL = DWARFDebugLoclists::parseOneLocationList( - Data, &Offset, UseLocLists ? U->getVersion() : 4); - - uint64_t BaseAddr = 0; - if (Optional<object::SectionedAddress> BA = U->getBaseAddress()) - BaseAddr = BA->Address; - - if (LL) - LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, - U, Indent); - else - OS << "error extracting location list."; + DumpLL(DWARFDebugLoclists::parseOneLocationList( + Data, &Offset, UseLocLists ? U->getVersion() : 4)); } } } @@ -264,7 +263,7 @@ static void dumpTypeName(raw_ostream &OS, const DWARFDie &D) { } static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, - uint32_t *OffsetPtr, dwarf::Attribute Attr, + uint64_t *OffsetPtr, dwarf::Attribute Attr, dwarf::Form Form, unsigned Indent, DIDumpOptions DumpOpts) { if (!Die.isValid()) @@ -568,8 +567,8 @@ void DWARFDie::dump(raw_ostream &OS, unsigned Indent, if (!isValid()) return; DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor(); - const uint32_t Offset = getOffset(); - uint32_t offset = Offset; + const uint64_t Offset = getOffset(); + uint64_t offset = Offset; if (DumpOpts.ShowParents) { DIDumpOptions ParentDumpOpts = DumpOpts; ParentDumpOpts.ShowParents = false; @@ -581,7 +580,7 @@ void DWARFDie::dump(raw_ostream &OS, unsigned Indent, uint32_t abbrCode = debug_info_data.getULEB128(&offset); if (DumpOpts.ShowAddresses) WithColor(OS, HighlightColor::Address).get() - << format("\n0x%8.8x: ", Offset); + << format("\n0x%8.8" PRIx64 ": ", Offset); if (abbrCode) { auto AbbrevDecl = getAbbreviationDeclarationPtr(); @@ -685,7 +684,7 @@ void DWARFDie::attribute_iterator::updateForIndex( AttrValue.Attr = AbbrDecl.getAttrByIndex(Index); // Add the previous byte size of any previous attribute value. AttrValue.Offset += AttrValue.ByteSize; - uint32_t ParseOffset = AttrValue.Offset; + uint64_t ParseOffset = AttrValue.Offset; auto U = Die.getDwarfUnit(); assert(U && "Die must have valid DWARF unit"); AttrValue.Value = DWARFFormValue::createFromUnit( @@ -733,6 +732,7 @@ bool DWARFAttribute::mayHaveLocationDescription(dwarf::Attribute Attr) { case DW_AT_call_data_value: // Extensions. case DW_AT_GNU_call_site_value: + case DW_AT_GNU_call_site_target: return true; default: return false; diff --git a/lib/DebugInfo/DWARF/DWARFExpression.cpp b/lib/DebugInfo/DWARF/DWARFExpression.cpp index 470d4b5364b4..5009b1b7b412 100644 --- a/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -119,7 +119,7 @@ static uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) { } bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version, - uint8_t AddressSize, uint32_t Offset) { + uint8_t AddressSize, uint64_t Offset) { Opcode = Data.getU8(&Offset); Desc = getOpDesc(Opcode); @@ -218,9 +218,8 @@ static bool prettyPrintRegisterOp(raw_ostream &OS, uint8_t Opcode, else DwarfRegNum = Opcode - DW_OP_reg0; - int LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH); - if (LLVMRegNum >= 0) { - if (const char *RegName = MRI->getName(LLVMRegNum)) { + if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH)) { + if (const char *RegName = MRI->getName(*LLVMRegNum)) { if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) || Opcode == DW_OP_bregx) OS << format(" %s%+" PRId64, RegName, Operands[OpNum]); @@ -263,7 +262,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, if (Size == Operation::BaseTypeRef && U) { auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]); if (Die && Die.getTag() == dwarf::DW_TAG_base_type) { - OS << format(" (0x%08x)", U->getOffset() + Operands[Operand]); + OS << format(" (0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]); if (auto Name = Die.find(dwarf::DW_AT_name)) OS << " \"" << Name->getAsCString() << "\""; } else { @@ -271,7 +270,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, Operands[Operand]); } } else if (Size == Operation::SizeBlock) { - uint32_t Offset = Operands[Operand]; + uint64_t Offset = Operands[Operand]; for (unsigned i = 0; i < Operands[Operand - 1]; ++i) OS << format(" 0x%02x", Expr->Data.getU8(&Offset)); } else { @@ -290,7 +289,7 @@ void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo, uint32_t EntryValExprSize = 0; for (auto &Op : *this) { if (!Op.print(OS, this, RegInfo, U, IsEH)) { - uint32_t FailOffset = Op.getEndOffset(); + uint64_t FailOffset = Op.getEndOffset(); while (FailOffset < Data.getData().size()) OS << format(" %02x", Data.getU8(&FailOffset)); return; diff --git a/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/lib/DebugInfo/DWARF/DWARFFormValue.cpp index 290d35511cdb..26090638b34c 100644 --- a/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -98,7 +98,7 @@ DWARFFormValue DWARFFormValue::createFromBlockValue(dwarf::Form F, } DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U, - uint32_t *OffsetPtr) { + uint64_t *OffsetPtr) { DWARFFormValue FormValue(F); FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, U->getFormParams(), U); @@ -106,7 +106,7 @@ DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U, } bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, - uint32_t *OffsetPtr, + uint64_t *OffsetPtr, const dwarf::FormParams Params) { bool Indirect = false; do { @@ -234,7 +234,7 @@ bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { } bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, - uint32_t *OffsetPtr, dwarf::FormParams FP, + uint64_t *OffsetPtr, dwarf::FormParams FP, const DWARFContext *Ctx, const DWARFUnit *CU) { if (!Ctx && CU) @@ -590,7 +590,7 @@ Optional<const char *> DWARFFormValue::getAsCString() const { // FIXME: Add support for DW_FORM_GNU_strp_alt if (Form == DW_FORM_GNU_strp_alt || C == nullptr) return None; - uint32_t Offset = Value.uval; + uint64_t Offset = Value.uval; if (Form == DW_FORM_line_strp) { // .debug_line_str is tracked in the Context. if (const char *Str = C->getLineStringExtractor().getCStr(&Offset)) @@ -624,6 +624,7 @@ Optional<uint64_t> DWARFFormValue::getAsAddress() const { return SA->Address; return None; } + Optional<object::SectionedAddress> DWARFFormValue::getAsSectionedAddress() const { if (!isFormClass(FC_Address)) diff --git a/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp index f5f975578082..252b58e5a591 100644 --- a/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp +++ b/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp @@ -112,7 +112,7 @@ void DWARFGdbIndex::dump(raw_ostream &OS) { } bool DWARFGdbIndex::parseImpl(DataExtractor Data) { - uint32_t Offset = 0; + uint64_t Offset = 0; // Only version 7 is supported at this moment. Version = Data.getU32(&Offset); diff --git a/lib/DebugInfo/DWARF/DWARFListTable.cpp b/lib/DebugInfo/DWARF/DWARFListTable.cpp index e38e706227da..269ea9f79a6e 100644 --- a/lib/DebugInfo/DWARF/DWARFListTable.cpp +++ b/lib/DebugInfo/DWARF/DWARFListTable.cpp @@ -16,33 +16,42 @@ using namespace llvm; Error DWARFListTableHeader::extract(DWARFDataExtractor Data, - uint32_t *OffsetPtr) { + uint64_t *OffsetPtr) { HeaderOffset = *OffsetPtr; // Read and verify the length field. if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t))) return createStringError(errc::invalid_argument, "section is not large enough to contain a " - "%s table length at offset 0x%" PRIx32, + "%s table length at offset 0x%" PRIx64, SectionName.data(), *OffsetPtr); - // TODO: Add support for DWARF64. - HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr); - if (HeaderData.Length == 0xffffffffu) - return createStringError(errc::not_supported, - "DWARF64 is not supported in %s at offset 0x%" PRIx32, - SectionName.data(), HeaderOffset); Format = dwarf::DwarfFormat::DWARF32; - if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header)) + uint8_t OffsetByteSize = 4; + HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr); + if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) { + Format = dwarf::DwarfFormat::DWARF64; + OffsetByteSize = 8; + HeaderData.Length = Data.getU64(OffsetPtr); + } else if (HeaderData.Length >= dwarf::DW_LENGTH_lo_reserved) { + return createStringError(errc::invalid_argument, + "%s table at offset 0x%" PRIx64 + " has unsupported reserved unit length of value 0x%8.8" PRIx64, + SectionName.data(), HeaderOffset, HeaderData.Length); + } + uint64_t FullLength = + HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format); + assert(FullLength == length()); + if (FullLength < getHeaderSize(Format)) return createStringError(errc::invalid_argument, - "%s table at offset 0x%" PRIx32 - " has too small length (0x%" PRIx32 + "%s table at offset 0x%" PRIx64 + " has too small length (0x%" PRIx64 ") to contain a complete header", - SectionName.data(), HeaderOffset, length()); - uint32_t End = HeaderOffset + length(); - if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset)) + SectionName.data(), HeaderOffset, FullLength); + uint64_t End = HeaderOffset + FullLength; + if (!Data.isValidOffsetForDataOfSize(HeaderOffset, FullLength)) return createStringError(errc::invalid_argument, "section is not large enough to contain a %s table " - "of length 0x%" PRIx32 " at offset 0x%" PRIx32, - SectionName.data(), length(), HeaderOffset); + "of length 0x%" PRIx64 " at offset 0x%" PRIx64, + SectionName.data(), FullLength, HeaderOffset); HeaderData.Version = Data.getU16(OffsetPtr); HeaderData.AddrSize = Data.getU8(OffsetPtr); @@ -53,35 +62,35 @@ Error DWARFListTableHeader::extract(DWARFDataExtractor Data, if (HeaderData.Version != 5) return createStringError(errc::invalid_argument, "unrecognised %s table version %" PRIu16 - " in table at offset 0x%" PRIx32, + " in table at offset 0x%" PRIx64, SectionName.data(), HeaderData.Version, HeaderOffset); if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8) return createStringError(errc::not_supported, - "%s table at offset 0x%" PRIx32 + "%s table at offset 0x%" PRIx64 " has unsupported address size %" PRIu8, SectionName.data(), HeaderOffset, HeaderData.AddrSize); if (HeaderData.SegSize != 0) return createStringError(errc::not_supported, - "%s table at offset 0x%" PRIx32 + "%s table at offset 0x%" PRIx64 " has unsupported segment selector size %" PRIu8, SectionName.data(), HeaderOffset, HeaderData.SegSize); - if (End < HeaderOffset + sizeof(HeaderData) + - HeaderData.OffsetEntryCount * sizeof(uint32_t)) + if (End < HeaderOffset + getHeaderSize(Format) + + HeaderData.OffsetEntryCount * OffsetByteSize) return createStringError(errc::invalid_argument, - "%s table at offset 0x%" PRIx32 " has more offset entries (%" PRIu32 + "%s table at offset 0x%" PRIx64 " has more offset entries (%" PRIu32 ") than there is space for", SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount); Data.setAddressSize(HeaderData.AddrSize); for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) - Offsets.push_back(Data.getRelocatedValue(4, OffsetPtr)); + Offsets.push_back(Data.getRelocatedValue(OffsetByteSize, OffsetPtr)); return Error::success(); } void DWARFListTableHeader::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { if (DumpOpts.Verbose) - OS << format("0x%8.8" PRIx32 ": ", HeaderOffset); + OS << format("0x%8.8" PRIx64 ": ", HeaderOffset); OS << format( - "%s list header: length = 0x%8.8" PRIx32 ", version = 0x%4.4" PRIx16 ", " + "%s list header: length = 0x%8.8" PRIx64 ", version = 0x%4.4" PRIx16 ", " "addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8 ", offset_entry_count = " "0x%8.8" PRIx32 "\n", @@ -91,18 +100,17 @@ void DWARFListTableHeader::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { if (HeaderData.OffsetEntryCount > 0) { OS << "offsets: ["; for (const auto &Off : Offsets) { - OS << format("\n0x%8.8" PRIx32, Off); + OS << format("\n0x%8.8" PRIx64, Off); if (DumpOpts.Verbose) - OS << format(" => 0x%8.8" PRIx32, - Off + HeaderOffset + sizeof(HeaderData)); + OS << format(" => 0x%8.8" PRIx64, + Off + HeaderOffset + getHeaderSize(Format)); } OS << "\n]\n"; } } -uint32_t DWARFListTableHeader::length() const { +uint64_t DWARFListTableHeader::length() const { if (HeaderData.Length == 0) return 0; - // TODO: DWARF64 support. - return HeaderData.Length + sizeof(uint32_t); + return HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format); } diff --git a/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp index 844920ba5b11..bb81090ba25c 100644 --- a/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp @@ -24,21 +24,23 @@ void DWARFTypeUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) { if (DumpOpts.SummarizeTypes) { OS << "name = '" << Name << "'" << " type_signature = " << format("0x%016" PRIx64, getTypeHash()) - << " length = " << format("0x%08x", getLength()) << '\n'; + << " length = " << format("0x%08" PRIx64, getLength()) << '\n'; return; } - OS << format("0x%08x", getOffset()) << ": Type Unit:" - << " length = " << format("0x%08x", getLength()) + OS << format("0x%08" PRIx64, getOffset()) << ": Type Unit:" + << " length = " << format("0x%08" PRIx64, getLength()) << " version = " << format("0x%04x", getVersion()); if (getVersion() >= 5) OS << " unit_type = " << dwarf::UnitTypeString(getUnitType()); - OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset()) + OS << " abbr_offset = " + << format("0x%04" PRIx64, getAbbreviations()->getOffset()) << " addr_size = " << format("0x%02x", getAddressByteSize()) << " name = '" << Name << "'" << " type_signature = " << format("0x%016" PRIx64, getTypeHash()) - << " type_offset = " << format("0x%04x", getTypeOffset()) - << " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n"; + << " type_offset = " << format("0x%04" PRIx64, getTypeOffset()) + << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset()) + << ")\n"; if (DWARFDie TU = getUnitDIE(false)) TU.dump(OS, 0, DumpOpts); diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp index b74acf60c747..a56402a707ad 100644 --- a/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -37,9 +37,9 @@ void DWARFUnitVector::addUnitsForSection(DWARFContext &C, const DWARFSection &Section, DWARFSectionKind SectionKind) { const DWARFObject &D = C.getDWARFObj(); - addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(), - &D.getLocSection(), D.getStringSection(), - D.getStringOffsetSection(), &D.getAddrSection(), + addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangesSection(), + &D.getLocSection(), D.getStrSection(), + D.getStrOffsetsSection(), &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false, false, SectionKind); } @@ -49,9 +49,9 @@ void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C, DWARFSectionKind SectionKind, bool Lazy) { const DWARFObject &D = C.getDWARFObj(); - addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(), - &D.getLocDWOSection(), D.getStringDWOSection(), - D.getStringOffsetDWOSection(), &D.getAddrSection(), + addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangesDWOSection(), + &D.getLocDWOSection(), D.getStrDWOSection(), + D.getStrOffsetsDWOSection(), &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(), true, Lazy, SectionKind); } @@ -66,7 +66,7 @@ void DWARFUnitVector::addUnitsImpl( // Lazy initialization of Parser, now that we have all section info. if (!Parser) { Parser = [=, &Context, &Obj, &Section, &SOS, - &LS](uint32_t Offset, DWARFSectionKind SectionKind, + &LS](uint64_t Offset, DWARFSectionKind SectionKind, const DWARFSection *CurSection, const DWARFUnitIndex::Entry *IndexEntry) -> std::unique_ptr<DWARFUnit> { @@ -83,11 +83,11 @@ void DWARFUnitVector::addUnitsImpl( return nullptr; std::unique_ptr<DWARFUnit> U; if (Header.isTypeUnit()) - U = llvm::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA, + U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA, RS, LocSection, SS, SOS, AOS, LS, LE, IsDWO, *this); else - U = llvm::make_unique<DWARFCompileUnit>(Context, InfoSection, Header, + U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header, DA, RS, LocSection, SS, SOS, AOS, LS, LE, IsDWO, *this); return U; @@ -101,7 +101,7 @@ void DWARFUnitVector::addUnitsImpl( // within a section, although not necessarily within the object file, // even if we do lazy parsing. auto I = this->begin(); - uint32_t Offset = 0; + uint64_t Offset = 0; while (Data.isValidOffset(Offset)) { if (I != this->end() && (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) { @@ -126,11 +126,11 @@ DWARFUnit *DWARFUnitVector::addUnit(std::unique_ptr<DWARFUnit> Unit) { return this->insert(I, std::move(Unit))->get(); } -DWARFUnit *DWARFUnitVector::getUnitForOffset(uint32_t Offset) const { +DWARFUnit *DWARFUnitVector::getUnitForOffset(uint64_t Offset) const { auto end = begin() + getNumInfoUnits(); auto *CU = std::upper_bound(begin(), end, Offset, - [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) { + [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) { return LHS < RHS->getNextUnitOffset(); }); if (CU != end && (*CU)->getOffset() <= Offset) @@ -149,7 +149,7 @@ DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) { auto *CU = std::upper_bound(begin(), end, CUOff->Offset, - [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) { + [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) { return LHS < RHS->getNextUnitOffset(); }); if (CU != end && (*CU)->getOffset() <= Offset) @@ -209,7 +209,7 @@ DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const { if (I != R.end() && std::next(I) == R.end()) return (*I)->getAddrOffsetSectionItem(Index); } - uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize(); + uint64_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize(); if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize()) return None; DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection, @@ -223,7 +223,7 @@ Optional<uint64_t> DWARFUnit::getStringOffsetSectionItem(uint32_t Index) const { if (!StringOffsetsTableContribution) return None; unsigned ItemSize = getDwarfStringOffsetsByteSize(); - uint32_t Offset = getStringOffsetsBase() + Index * ItemSize; + uint64_t Offset = getStringOffsetsBase() + Index * ItemSize; if (StringOffsetSection.Data.size() < Offset + ItemSize) return None; DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection, @@ -233,7 +233,7 @@ Optional<uint64_t> DWARFUnit::getStringOffsetSectionItem(uint32_t Index) const { bool DWARFUnitHeader::extract(DWARFContext &Context, const DWARFDataExtractor &debug_info, - uint32_t *offset_ptr, + uint64_t *offset_ptr, DWARFSectionKind SectionKind, const DWARFUnitIndex *Index, const DWARFUnitIndex::Entry *Entry) { @@ -243,11 +243,9 @@ bool DWARFUnitHeader::extract(DWARFContext &Context, IndexEntry = Index->getFromOffset(*offset_ptr); Length = debug_info.getRelocatedValue(4, offset_ptr); FormParams.Format = DWARF32; - unsigned SizeOfLength = 4; - if (Length == 0xffffffff) { + if (Length == dwarf::DW_LENGTH_DWARF64) { Length = debug_info.getU64(offset_ptr); FormParams.Format = DWARF64; - SizeOfLength = 8; } FormParams.Version = debug_info.getU16(offset_ptr); if (FormParams.Version >= 5) { @@ -277,7 +275,8 @@ bool DWARFUnitHeader::extract(DWARFContext &Context, } if (isTypeUnit()) { TypeHash = debug_info.getU64(offset_ptr); - TypeOffset = debug_info.getU32(offset_ptr); + TypeOffset = + debug_info.getUnsigned(offset_ptr, FormParams.getDwarfOffsetByteSize()); } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton) DWOId = debug_info.getU64(offset_ptr); @@ -290,7 +289,8 @@ bool DWARFUnitHeader::extract(DWARFContext &Context, bool TypeOffsetOK = !isTypeUnit() ? true - : TypeOffset >= Size && TypeOffset < getLength() + SizeOfLength; + : TypeOffset >= Size && + TypeOffset < getLength() + getUnitLengthFieldByteSize(); bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1); bool VersionOK = DWARFContext::isSupportedVersion(getVersion()); bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8; @@ -306,16 +306,18 @@ bool DWARFUnitHeader::extract(DWARFContext &Context, // Parse the rangelist table header, including the optional array of offsets // following it (DWARF v5 and later). static Expected<DWARFDebugRnglistTable> -parseRngListTableHeader(DWARFDataExtractor &DA, uint32_t Offset) { - // TODO: Support DWARF64 +parseRngListTableHeader(DWARFDataExtractor &DA, uint64_t Offset, + DwarfFormat Format) { // We are expected to be called with Offset 0 or pointing just past the table - // header, which is 12 bytes long for DWARF32. + // header. Correct Offset in the latter case so that it points to the start + // of the header. if (Offset > 0) { - if (Offset < 12U) + uint64_t HeaderSize = DWARFListTableHeader::getHeaderSize(Format); + if (Offset < HeaderSize) return createStringError(errc::invalid_argument, "Did not detect a valid" - " range list table with base = 0x%" PRIu32, + " range list table with base = 0x%" PRIx64 "\n", Offset); - Offset -= 12U; + Offset -= HeaderSize; } llvm::DWARFDebugRnglistTable Table; if (Error E = Table.extractHeaderAndOffsets(DA, &Offset)) @@ -323,13 +325,13 @@ parseRngListTableHeader(DWARFDataExtractor &DA, uint32_t Offset) { return Table; } -Error DWARFUnit::extractRangeList(uint32_t RangeListOffset, +Error DWARFUnit::extractRangeList(uint64_t RangeListOffset, DWARFDebugRangeList &RangeList) const { // Require that compile unit is extracted. assert(!DieArray.empty()); DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection, isLittleEndian, getAddressByteSize()); - uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset; + uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset; return RangeList.extract(RangesData, &ActualRangeListOffset); } @@ -354,8 +356,8 @@ void DWARFUnit::extractDIEsToVector( // Set the offset to that of the first DIE and calculate the start of the // next compilation unit header. - uint32_t DIEOffset = getOffset() + getHeaderSize(); - uint32_t NextCUOffset = getNextUnitOffset(); + uint64_t DIEOffset = getOffset() + getHeaderSize(); + uint64_t NextCUOffset = getNextUnitOffset(); DWARFDebugInfoEntry DIE; DWARFDataExtractor DebugInfoData = getDebugInfoExtractor(); uint32_t Depth = 0; @@ -396,90 +398,98 @@ void DWARFUnit::extractDIEsToVector( // unit header). if (DIEOffset > NextCUOffset) WithColor::warning() << format("DWARF compile unit extends beyond its " - "bounds cu 0x%8.8x at 0x%8.8x\n", + "bounds cu 0x%8.8" PRIx64 " " + "at 0x%8.8" PRIx64 "\n", getOffset(), DIEOffset); } -size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) { +void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) { + if (Error e = tryExtractDIEsIfNeeded(CUDieOnly)) + WithColor::error() << toString(std::move(e)); +} + +Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) { if ((CUDieOnly && !DieArray.empty()) || DieArray.size() > 1) - return 0; // Already parsed. + return Error::success(); // Already parsed. bool HasCUDie = !DieArray.empty(); extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray); if (DieArray.empty()) - return 0; + return Error::success(); // If CU DIE was just parsed, copy several attribute values from it. - if (!HasCUDie) { - DWARFDie UnitDie = getUnitDIE(); - if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id))) - Header.setDWOId(*DWOId); - if (!IsDWO) { - assert(AddrOffsetSectionBase == 0); - assert(RangeSectionBase == 0); - AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base), 0); - if (!AddrOffsetSectionBase) - AddrOffsetSectionBase = - toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0); - RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0); - } - - // In general, in DWARF v5 and beyond we derive the start of the unit's - // contribution to the string offsets table from the unit DIE's - // DW_AT_str_offsets_base attribute. Split DWARF units do not use this - // attribute, so we assume that there is a contribution to the string - // offsets table starting at offset 0 of the debug_str_offsets.dwo section. - // In both cases we need to determine the format of the contribution, - // which may differ from the unit's format. - DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection, - isLittleEndian, 0); - if (IsDWO || getVersion() >= 5) { - auto StringOffsetOrError = - IsDWO ? determineStringOffsetsTableContributionDWO(DA) - : determineStringOffsetsTableContribution(DA); - if (!StringOffsetOrError) { - WithColor::error() << "invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: " - << toString(StringOffsetOrError.takeError()) << '\n'; - } else { - StringOffsetsTableContribution = *StringOffsetOrError; - } - } + if (HasCUDie) + return Error::success(); + + DWARFDie UnitDie(this, &DieArray[0]); + if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id))) + Header.setDWOId(*DWOId); + if (!IsDWO) { + assert(AddrOffsetSectionBase == 0); + assert(RangeSectionBase == 0); + AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base), 0); + if (!AddrOffsetSectionBase) + AddrOffsetSectionBase = + toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0); + RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0); + } - // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to - // describe address ranges. - if (getVersion() >= 5) { - if (IsDWO) - setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0); - else - setRangesSection(&Context.getDWARFObj().getRnglistsSection(), - toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0)); - if (RangeSection->Data.size()) { - // Parse the range list table header. Individual range lists are - // extracted lazily. - DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection, - isLittleEndian, 0); - if (auto TableOrError = - parseRngListTableHeader(RangesDA, RangeSectionBase)) - RngListTable = TableOrError.get(); - else - WithColor::error() << "parsing a range list table: " - << toString(TableOrError.takeError()) - << '\n'; - - // In a split dwarf unit, there is no DW_AT_rnglists_base attribute. - // Adjust RangeSectionBase to point past the table header. - if (IsDWO && RngListTable) - RangeSectionBase = RngListTable->getHeaderSize(); - } - } + // In general, in DWARF v5 and beyond we derive the start of the unit's + // contribution to the string offsets table from the unit DIE's + // DW_AT_str_offsets_base attribute. Split DWARF units do not use this + // attribute, so we assume that there is a contribution to the string + // offsets table starting at offset 0 of the debug_str_offsets.dwo section. + // In both cases we need to determine the format of the contribution, + // which may differ from the unit's format. + DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection, + isLittleEndian, 0); + if (IsDWO || getVersion() >= 5) { + auto StringOffsetOrError = + IsDWO ? determineStringOffsetsTableContributionDWO(DA) + : determineStringOffsetsTableContribution(DA); + if (!StringOffsetOrError) + return createStringError(errc::invalid_argument, + "invalid reference to or invalid content in " + ".debug_str_offsets[.dwo]: " + + toString(StringOffsetOrError.takeError())); + + StringOffsetsTableContribution = *StringOffsetOrError; + } - // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for - // skeleton CU DIE, so that DWARF users not aware of it are not broken. + // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to + // describe address ranges. + if (getVersion() >= 5) { + if (IsDWO) + setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0); + else + setRangesSection(&Context.getDWARFObj().getRnglistsSection(), + toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0)); + if (RangeSection->Data.size()) { + // Parse the range list table header. Individual range lists are + // extracted lazily. + DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection, + isLittleEndian, 0); + auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase, + Header.getFormat()); + if (!TableOrError) + return createStringError(errc::invalid_argument, + "parsing a range list table: " + + toString(TableOrError.takeError())); + + RngListTable = TableOrError.get(); + + // In a split dwarf unit, there is no DW_AT_rnglists_base attribute. + // Adjust RangeSectionBase to point past the table header. + if (IsDWO && RngListTable) + RangeSectionBase = RngListTable->getHeaderSize(); } + } - return DieArray.size(); + // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for + // skeleton CU DIE, so that DWARF users not aware of it are not broken. + return Error::success(); } bool DWARFUnit::parseDWO() { @@ -517,7 +527,8 @@ bool DWARFUnit::parseDWO() { DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0); DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection, isLittleEndian, 0); - if (auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase)) + if (auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase, + Header.getFormat())) DWO->RngListTable = TableOrError.get(); else WithColor::error() << "parsing a range list table: " @@ -541,7 +552,7 @@ void DWARFUnit::clearDIEs(bool KeepCUDie) { } Expected<DWARFAddressRangesVector> -DWARFUnit::findRnglistFromOffset(uint32_t Offset) { +DWARFUnit::findRnglistFromOffset(uint64_t Offset) { if (getVersion() <= 4) { DWARFDebugRangeList RangeList; if (Error E = extractRangeList(Offset, RangeList)) @@ -569,9 +580,9 @@ DWARFUnit::findRnglistFromIndex(uint32_t Index) { if (RngListTable) return createStringError(errc::invalid_argument, "invalid range list table index %d", Index); - else - return createStringError(errc::invalid_argument, - "missing or invalid range list table"); + + return createStringError(errc::invalid_argument, + "missing or invalid range list table"); } Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() { @@ -780,11 +791,11 @@ StrOffsetsContributionDescriptor::validateContributionSize( // Look for a DWARF64-formatted contribution to the string offsets table // starting at a given offset and record it in a descriptor. static Expected<StrOffsetsContributionDescriptor> -parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) { +parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) { if (!DA.isValidOffsetForDataOfSize(Offset, 16)) return createStringError(errc::invalid_argument, "section offset exceeds section size"); - if (DA.getU32(&Offset) != 0xffffffff) + if (DA.getU32(&Offset) != dwarf::DW_LENGTH_DWARF64) return createStringError(errc::invalid_argument, "32 bit contribution referenced from a 64 bit unit"); uint64_t Size = DA.getU64(&Offset); @@ -798,12 +809,12 @@ parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) { // Look for a DWARF32-formatted contribution to the string offsets table // starting at a given offset and record it in a descriptor. static Expected<StrOffsetsContributionDescriptor> -parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) { +parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) { if (!DA.isValidOffsetForDataOfSize(Offset, 8)) return createStringError(errc::invalid_argument, "section offset exceeds section size"); uint32_t ContributionSize = DA.getU32(&Offset); - if (ContributionSize >= 0xfffffff0) + if (ContributionSize >= dwarf::DW_LENGTH_lo_reserved) return createStringError(errc::invalid_argument, "invalid length"); uint8_t Version = DA.getU16(&Offset); @@ -823,7 +834,7 @@ parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA, case dwarf::DwarfFormat::DWARF64: { if (Offset < 16) return createStringError(errc::invalid_argument, "insufficient space for 64 bit header prefix"); - auto DescOrError = parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset - 16); + auto DescOrError = parseDWARF64StringOffsetsTableHeader(DA, Offset - 16); if (!DescOrError) return DescOrError.takeError(); Desc = *DescOrError; @@ -832,7 +843,7 @@ parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA, case dwarf::DwarfFormat::DWARF32: { if (Offset < 8) return createStringError(errc::invalid_argument, "insufficient space for 32 bit header prefix"); - auto DescOrError = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset - 8); + auto DescOrError = parseDWARF32StringOffsetsTableHeader(DA, Offset - 8); if (!DescOrError) return DescOrError.takeError(); Desc = *DescOrError; diff --git a/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp index 047c63461ccf..f29c1e6cc5c7 100644 --- a/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp +++ b/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp @@ -18,7 +18,7 @@ using namespace llvm; bool DWARFUnitIndex::Header::parse(DataExtractor IndexData, - uint32_t *OffsetPtr) { + uint64_t *OffsetPtr) { if (!IndexData.isValidOffsetForDataOfSize(*OffsetPtr, 16)) return false; Version = IndexData.getU32(OffsetPtr); @@ -45,7 +45,7 @@ bool DWARFUnitIndex::parse(DataExtractor IndexData) { } bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) { - uint32_t Offset = 0; + uint64_t Offset = 0; if (!Header.parse(IndexData, &Offset)) return false; @@ -54,10 +54,10 @@ bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) { (2 * Header.NumUnits + 1) * 4 * Header.NumColumns)) return false; - Rows = llvm::make_unique<Entry[]>(Header.NumBuckets); + Rows = std::make_unique<Entry[]>(Header.NumBuckets); auto Contribs = - llvm::make_unique<Entry::SectionContribution *[]>(Header.NumUnits); - ColumnKinds = llvm::make_unique<DWARFSectionKind[]>(Header.NumColumns); + std::make_unique<Entry::SectionContribution *[]>(Header.NumUnits); + ColumnKinds = std::make_unique<DWARFSectionKind[]>(Header.NumColumns); // Read Hash Table of Signatures for (unsigned i = 0; i != Header.NumBuckets; ++i) @@ -70,7 +70,7 @@ bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) { continue; Rows[i].Index = this; Rows[i].Contributions = - llvm::make_unique<Entry::SectionContribution[]>(Header.NumColumns); + std::make_unique<Entry::SectionContribution[]>(Header.NumColumns); Contribs[Index - 1] = Rows[i].Contributions.get(); } diff --git a/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/lib/DebugInfo/DWARF/DWARFVerifier.cpp index c2b3189514a8..bf499b6ee092 100644 --- a/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ b/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -34,11 +34,11 @@ DWARFVerifier::DieRangeInfo::insert(const DWARFAddressRange &R) { if (Pos != End) { if (Pos->intersects(R)) - return Pos; + return std::move(Pos); if (Pos != Begin) { auto Iter = Pos - 1; if (Iter->intersects(R)) - return Iter; + return std::move(Iter); } } @@ -98,7 +98,7 @@ bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const { } bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData, - uint32_t *Offset, unsigned UnitIndex, + uint64_t *Offset, unsigned UnitIndex, uint8_t &UnitType, bool &isUnitDWARF64) { uint64_t AbbrOffset, Length; uint8_t AddrSize = 0; @@ -111,9 +111,9 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData, bool ValidType = true; bool ValidAbbrevOffset = true; - uint32_t OffsetStart = *Offset; + uint64_t OffsetStart = *Offset; Length = DebugInfoData.getU32(Offset); - if (Length == UINT32_MAX) { + if (Length == dwarf::DW_LENGTH_DWARF64) { Length = DebugInfoData.getU64(Offset); isUnitDWARF64 = true; } @@ -139,7 +139,7 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData, if (!ValidLength || !ValidVersion || !ValidAddrSize || !ValidAbbrevOffset || !ValidType) { Success = false; - error() << format("Units[%d] - start offset: 0x%08x \n", UnitIndex, + error() << format("Units[%d] - start offset: 0x%08" PRIx64 " \n", UnitIndex, OffsetStart); if (!ValidLength) note() << "The length for this unit is too " @@ -203,7 +203,7 @@ unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) { } unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) { - if (Die.getTag() != DW_TAG_call_site) + if (Die.getTag() != DW_TAG_call_site && Die.getTag() != DW_TAG_GNU_call_site) return 0; DWARFDie Curr = Die.getParent(); @@ -223,7 +223,9 @@ unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) { Optional<DWARFFormValue> CallAttr = Curr.find({DW_AT_call_all_calls, DW_AT_call_all_source_calls, - DW_AT_call_all_tail_calls}); + DW_AT_call_all_tail_calls, DW_AT_GNU_all_call_sites, + DW_AT_GNU_all_source_call_sites, + DW_AT_GNU_all_tail_call_sites}); if (!CallAttr) { error() << "Subprogram with call site entry has no DW_AT_call attribute:"; Curr.dump(OS); @@ -273,7 +275,7 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S, const DWARFObject &DObj = DCtx.getDWARFObj(); DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0); unsigned NumDebugInfoErrors = 0; - uint32_t OffsetStart = 0, Offset = 0, UnitIdx = 0; + uint64_t OffsetStart = 0, Offset = 0, UnitIdx = 0; uint8_t UnitType = 0; bool isUnitDWARF64 = false; bool isHeaderChainValid = true; @@ -294,10 +296,10 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S, switch (UnitType) { case dwarf::DW_UT_type: case dwarf::DW_UT_split_type: { - Unit = TypeUnitVector.addUnit(llvm::make_unique<DWARFTypeUnit>( - DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(), - &DObj.getLocSection(), DObj.getStringSection(), - DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(), + Unit = TypeUnitVector.addUnit(std::make_unique<DWARFTypeUnit>( + DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangesSection(), + &DObj.getLocSection(), DObj.getStrSection(), + DObj.getStrOffsetsSection(), &DObj.getAppleObjCSection(), DObj.getLineSection(), DCtx.isLittleEndian(), false, TypeUnitVector)); break; @@ -308,10 +310,10 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S, case dwarf::DW_UT_partial: // UnitType = 0 means that we are verifying a compile unit in DWARF v4. case 0: { - Unit = CompileUnitVector.addUnit(llvm::make_unique<DWARFCompileUnit>( - DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(), - &DObj.getLocSection(), DObj.getStringSection(), - DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(), + Unit = CompileUnitVector.addUnit(std::make_unique<DWARFCompileUnit>( + DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangesSection(), + &DObj.getLocSection(), DObj.getStrSection(), + DObj.getStrOffsetsSection(), &DObj.getAppleObjCSection(), DObj.getLineSection(), DCtx.isLittleEndian(), false, CompileUnitVector)); break; @@ -449,7 +451,7 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, case DW_AT_ranges: // Make sure the offset in the DW_AT_ranges attribute is valid. if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) { - if (*SectionOffset >= DObj.getRangeSection().Data.size()) + if (*SectionOffset >= DObj.getRangesSection().Data.size()) ReportError("DW_AT_ranges offset is beyond .debug_ranges bounds:"); break; } @@ -466,9 +468,9 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, ReportError("DIE has invalid DW_AT_stmt_list encoding:"); break; case DW_AT_location: { - auto VerifyLocationExpr = [&](StringRef D) { + auto VerifyLocationExpr = [&](ArrayRef<uint8_t> D) { DWARFUnit *U = Die.getDwarfUnit(); - DataExtractor Data(D, DCtx.isLittleEndian(), 0); + DataExtractor Data(toStringRef(D), DCtx.isLittleEndian(), 0); DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize()); bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) { @@ -479,13 +481,13 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, }; if (Optional<ArrayRef<uint8_t>> Expr = AttrValue.Value.getAsBlock()) { // Verify inlined location. - VerifyLocationExpr(llvm::toStringRef(*Expr)); + VerifyLocationExpr(*Expr); } else if (auto LocOffset = AttrValue.Value.getAsSectionOffset()) { // Verify location list. if (auto DebugLoc = DCtx.getDebugLoc()) if (auto LocList = DebugLoc->getLocationListAtOffset(*LocOffset)) for (const auto &Entry : LocList->Entries) - VerifyLocationExpr({Entry.Loc.data(), Entry.Loc.size()}); + VerifyLocationExpr(Entry.Loc); } break; } @@ -500,6 +502,9 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, break; if (DieTag == DW_TAG_variable && RefTag == DW_TAG_member) break; + // This might be reference to a function declaration. + if (DieTag == DW_TAG_GNU_call_site && RefTag == DW_TAG_subprogram) + break; ReportError("DIE with tag " + TagString(DieTag) + " has " + AttributeString(Attr) + " that points to DIE with " @@ -545,7 +550,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die, error() << FormEncodingString(Form) << " CU offset " << format("0x%08" PRIx64, CUOffset) << " is invalid (must be less than CU size of " - << format("0x%08" PRIx32, CUSize) << "):\n"; + << format("0x%08" PRIx64, CUSize) << "):\n"; Die.dump(OS, 0, DumpOpts); dump(Die) << '\n'; } else { @@ -578,7 +583,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die, case DW_FORM_strp: { auto SecOffset = AttrValue.Value.getAsSectionOffset(); assert(SecOffset); // DW_FORM_strp is a section offset. - if (SecOffset && *SecOffset >= DObj.getStringSection().size()) { + if (SecOffset && *SecOffset >= DObj.getStrSection().size()) { ++NumErrors; error() << "DW_FORM_strp offset beyond .debug_str bounds:\n"; dump(Die) << '\n'; @@ -605,7 +610,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die, // Use a 64-bit type to calculate the offset to guard against overflow. uint64_t Offset = (uint64_t)DieCU->getStringOffsetsBase() + Index * ItemSize; - if (DObj.getStringOffsetSection().Data.size() < Offset + ItemSize) { + if (DObj.getStrOffsetsSection().Data.size() < Offset + ItemSize) { ++NumErrors; error() << FormEncodingString(Form) << " uses index " << format("%" PRIu64, Index) << ", which is too large:\n"; @@ -614,7 +619,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die, } // Check that the string offset is valid. uint64_t StringOffset = *DieCU->getStringOffsetSectionItem(Index); - if (StringOffset >= DObj.getStringSection().size()) { + if (StringOffset >= DObj.getStrSection().size()) { ++NumErrors; error() << FormEncodingString(Form) << " uses index " << format("%" PRIu64, Index) @@ -635,7 +640,7 @@ unsigned DWARFVerifier::verifyDebugInfoReferences() { // getting the DIE by offset and emitting an error OS << "Verifying .debug_info references...\n"; unsigned NumErrors = 0; - for (const std::pair<uint64_t, std::set<uint32_t>> &Pair : + for (const std::pair<uint64_t, std::set<uint64_t>> &Pair : ReferenceToDIEOffsets) { if (DCtx.getDIEForOffset(Pair.first)) continue; @@ -659,12 +664,12 @@ void DWARFVerifier::verifyDebugLineStmtOffsets() { auto StmtSectionOffset = toSectionOffset(Die.find(DW_AT_stmt_list)); if (!StmtSectionOffset) continue; - const uint32_t LineTableOffset = *StmtSectionOffset; + const uint64_t LineTableOffset = *StmtSectionOffset; auto LineTable = DCtx.getLineTableForUnit(CU.get()); if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) { if (!LineTable) { ++NumDebugLineErrors; - error() << ".debug_line[" << format("0x%08" PRIx32, LineTableOffset) + error() << ".debug_line[" << format("0x%08" PRIx64, LineTableOffset) << "] was not able to be parsed for CU:\n"; dump(Die) << '\n'; continue; @@ -680,8 +685,8 @@ void DWARFVerifier::verifyDebugLineStmtOffsets() { if (Iter != StmtListToDie.end()) { ++NumDebugLineErrors; error() << "two compile unit DIEs, " - << format("0x%08" PRIx32, Iter->second.getOffset()) << " and " - << format("0x%08" PRIx32, Die.getOffset()) + << format("0x%08" PRIx64, Iter->second.getOffset()) << " and " + << format("0x%08" PRIx64, Die.getOffset()) << ", have the same DW_AT_stmt_list section offset:\n"; dump(Iter->second); dump(Die) << '\n'; @@ -826,10 +831,10 @@ unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection, uint32_t NumBuckets = AccelTable.getNumBuckets(); uint32_t NumHashes = AccelTable.getNumHashes(); - uint32_t BucketsOffset = + uint64_t BucketsOffset = AccelTable.getSizeHdr() + AccelTable.getHeaderDataLength(); - uint32_t HashesBase = BucketsOffset + NumBuckets * 4; - uint32_t OffsetsBase = HashesBase + NumHashes * 4; + uint64_t HashesBase = BucketsOffset + NumBuckets * 4; + uint64_t OffsetsBase = HashesBase + NumHashes * 4; for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) { uint32_t HashIdx = AccelSectionData.getU32(&BucketsOffset); if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) { @@ -849,28 +854,29 @@ unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection, } for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) { - uint32_t HashOffset = HashesBase + 4 * HashIdx; - uint32_t DataOffset = OffsetsBase + 4 * HashIdx; + uint64_t HashOffset = HashesBase + 4 * HashIdx; + uint64_t DataOffset = OffsetsBase + 4 * HashIdx; uint32_t Hash = AccelSectionData.getU32(&HashOffset); - uint32_t HashDataOffset = AccelSectionData.getU32(&DataOffset); + uint64_t HashDataOffset = AccelSectionData.getU32(&DataOffset); if (!AccelSectionData.isValidOffsetForDataOfSize(HashDataOffset, sizeof(uint64_t))) { - error() << format("Hash[%d] has invalid HashData offset: 0x%08x.\n", + error() << format("Hash[%d] has invalid HashData offset: " + "0x%08" PRIx64 ".\n", HashIdx, HashDataOffset); ++NumErrors; } - uint32_t StrpOffset; - uint32_t StringOffset; + uint64_t StrpOffset; + uint64_t StringOffset; uint32_t StringCount = 0; - unsigned Offset; + uint64_t Offset; unsigned Tag; while ((StrpOffset = AccelSectionData.getU32(&HashDataOffset)) != 0) { const uint32_t NumHashDataObjects = AccelSectionData.getU32(&HashDataOffset); for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects; ++HashDataIdx) { - std::tie(Offset, Tag) = AccelTable.readAtoms(HashDataOffset); + std::tie(Offset, Tag) = AccelTable.readAtoms(&HashDataOffset); auto Die = DCtx.getDIEForOffset(Offset); if (!Die) { const uint32_t BucketIdx = @@ -882,8 +888,8 @@ unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection, error() << format( "%s Bucket[%d] Hash[%d] = 0x%08x " - "Str[%u] = 0x%08x " - "DIE[%d] = 0x%08x is not a valid DIE offset for \"%s\".\n", + "Str[%u] = 0x%08" PRIx64 " DIE[%d] = 0x%08" PRIx64 " " + "is not a valid DIE offset for \"%s\".\n", SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset, HashDataIdx, Offset, Name); @@ -908,8 +914,8 @@ unsigned DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) { // A map from CU offset to the (first) Name Index offset which claims to index // this CU. - DenseMap<uint32_t, uint32_t> CUMap; - const uint32_t NotIndexed = std::numeric_limits<uint32_t>::max(); + DenseMap<uint64_t, uint64_t> CUMap; + const uint64_t NotIndexed = std::numeric_limits<uint64_t>::max(); CUMap.reserve(DCtx.getNumCompileUnits()); for (const auto &CU : DCtx.compile_units()) @@ -924,7 +930,7 @@ DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) { continue; } for (uint32_t CU = 0, End = NI.getCUCount(); CU < End; ++CU) { - uint32_t Offset = NI.getCUOffset(CU); + uint64_t Offset = NI.getCUOffset(CU); auto Iter = CUMap.find(Offset); if (Iter == CUMap.end()) { @@ -1205,8 +1211,8 @@ unsigned DWARFVerifier::verifyNameIndexEntries( unsigned NumErrors = 0; unsigned NumEntries = 0; - uint32_t EntryID = NTE.getEntryOffset(); - uint32_t NextEntryID = EntryID; + uint64_t EntryID = NTE.getEntryOffset(); + uint64_t NextEntryID = EntryID; Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NextEntryID); for (; EntryOr; ++NumEntries, EntryID = NextEntryID, EntryOr = NI.getEntry(&NextEntryID)) { @@ -1218,7 +1224,7 @@ unsigned DWARFVerifier::verifyNameIndexEntries( ++NumErrors; continue; } - uint32_t CUOffset = NI.getCUOffset(CUIndex); + uint64_t CUOffset = NI.getCUOffset(CUIndex); uint64_t DIEOffset = CUOffset + *EntryOr->getDIEUnitOffset(); DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset); if (!DIE) { @@ -1276,9 +1282,9 @@ static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) { if (!Location) return false; - auto ContainsInterestingOperators = [&](StringRef D) { + auto ContainsInterestingOperators = [&](ArrayRef<uint8_t> D) { DWARFUnit *U = Die.getDwarfUnit(); - DataExtractor Data(D, DCtx.isLittleEndian(), U->getAddressByteSize()); + DataExtractor Data(toStringRef(D), DCtx.isLittleEndian(), U->getAddressByteSize()); DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize()); return any_of(Expression, [](DWARFExpression::Operation &Op) { return !Op.isError() && (Op.getCode() == DW_OP_addr || @@ -1289,7 +1295,7 @@ static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) { if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) { // Inlined location. - if (ContainsInterestingOperators(toStringRef(*Expr))) + if (ContainsInterestingOperators(*Expr)) return true; } else if (Optional<uint64_t> Offset = Location->getAsSectionOffset()) { // Location list. @@ -1297,7 +1303,7 @@ static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) { if (const DWARFDebugLoc::LocationList *LocList = DebugLoc->getLocationListAtOffset(*Offset)) { if (any_of(LocList->Entries, [&](const DWARFDebugLoc::Entry &E) { - return ContainsInterestingOperators({E.Loc.data(), E.Loc.size()}); + return ContainsInterestingOperators(E.Loc); })) return true; } @@ -1455,7 +1461,7 @@ unsigned DWARFVerifier::verifyDebugNames(const DWARFSection &AccelSection, bool DWARFVerifier::handleAccelTables() { const DWARFObject &D = DCtx.getDWARFObj(); - DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0); + DataExtractor StrData(D.getStrSection(), DCtx.isLittleEndian(), 0); unsigned NumErrors = 0; if (!D.getAppleNamesSection().Data.empty()) NumErrors += verifyAppleAccelTable(&D.getAppleNamesSection(), &StrData, @@ -1470,8 +1476,8 @@ bool DWARFVerifier::handleAccelTables() { NumErrors += verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData, ".apple_objc"); - if (!D.getDebugNamesSection().Data.empty()) - NumErrors += verifyDebugNames(D.getDebugNamesSection(), StrData); + if (!D.getNamesSection().Data.empty()) + NumErrors += verifyDebugNames(D.getNamesSection(), StrData); return NumErrors == 0; } |