diff options
Diffstat (limited to 'llvm/lib/DebugInfo/DWARF')
20 files changed, 698 insertions, 508 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp index e2ea5910932d..5b5b887e2a50 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp @@ -8,8 +8,6 @@ #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" @@ -69,7 +67,7 @@ DWARFAbbreviationDeclaration::extract(DataExtractor Data, AttributeSpecs.push_back(AttributeSpec(A, F, V)); continue; } - Optional<uint8_t> ByteSize; + std::optional<uint8_t> ByteSize; // If this abbrevation still has a fixed byte size, then update the // FixedAttributeSize as needed. switch (F) { @@ -138,13 +136,13 @@ void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const { OS << '\n'; } -Optional<uint32_t> +std::optional<uint32_t> DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const { for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) { if (AttributeSpecs[i].Attr == Attr) return i; } - return None; + return std::nullopt; } uint64_t DWARFAbbreviationDeclaration::getAttributeOffsetFromIndex( @@ -164,7 +162,7 @@ uint64_t DWARFAbbreviationDeclaration::getAttributeOffsetFromIndex( return Offset; } -Optional<DWARFFormValue> +std::optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValueFromOffset( uint32_t AttrIndex, uint64_t Offset, const DWARFUnit &U) const { assert(AttributeSpecs.size() > AttrIndex && @@ -180,18 +178,18 @@ DWARFAbbreviationDeclaration::getAttributeValueFromOffset( DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor(); if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U)) return FormValue; - return None; + return std::nullopt; } -Optional<DWARFFormValue> +std::optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(const uint64_t DIEOffset, const dwarf::Attribute Attr, const DWARFUnit &U) const { // Check if this abbreviation has this attribute without needing to skip // any data so we can return quickly if it doesn't. - Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr); + std::optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr); if (!MatchAttrIndex) - return None; + return std::nullopt; uint64_t Offset = getAttributeOffsetFromIndex(*MatchAttrIndex, DIEOffset, U); @@ -210,22 +208,22 @@ size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize( return ByteSize; } -Optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize( +std::optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize( const DWARFUnit &U) const { if (isImplicitConst()) return 0; if (ByteSize.HasByteSize) return ByteSize.ByteSize; - Optional<int64_t> S; + std::optional<int64_t> S; auto FixedByteSize = dwarf::getFixedFormByteSize(Form, U.getFormParams()); if (FixedByteSize) S = *FixedByteSize; return S; } -Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize( +std::optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize( const DWARFUnit &U) const { if (FixedAttributeSize) return FixedAttributeSize->getByteSize(U); - return None; + return std::nullopt; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp index 5727b3bdb05c..889d3f0915b0 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp @@ -143,10 +143,10 @@ void AppleAcceleratorTable::Header::dump(ScopedPrinter &W) const { W.printNumber("HeaderData length", HeaderDataLength); } -Optional<uint64_t> AppleAcceleratorTable::HeaderData::extractOffset( - Optional<DWARFFormValue> Value) const { +std::optional<uint64_t> AppleAcceleratorTable::HeaderData::extractOffset( + std::optional<DWARFFormValue> Value) const { if (!Value) - return None; + return std::nullopt; switch (Value->getForm()) { case dwarf::DW_FORM_ref1: @@ -185,7 +185,7 @@ bool AppleAcceleratorTable::dumpName(ScopedPrinter &W, W.startLine() << format("Atom[%d]: ", i); if (Atom.extractValue(AccelSection, DataOffset, FormParams)) { Atom.dump(W.getOStream()); - if (Optional<uint64_t> Val = Atom.getAsUnsignedConstant()) { + if (std::optional<uint64_t> Val = Atom.getAsUnsignedConstant()) { StringRef Str = dwarf::AtomValueString(HdrData.Atoms[i].first, *Val); if (!Str.empty()) W.getOStream() << " (" << Str << ")"; @@ -272,7 +272,7 @@ void AppleAcceleratorTable::Entry::extract( Atom.extractValue(AccelTable.AccelSection, Offset, FormParams); } -Optional<DWARFFormValue> +std::optional<DWARFFormValue> AppleAcceleratorTable::Entry::lookup(HeaderData::AtomType Atom) const { assert(HdrData && "Dereferencing end iterator?"); assert(HdrData->Atoms.size() == Values.size()); @@ -280,24 +280,25 @@ AppleAcceleratorTable::Entry::lookup(HeaderData::AtomType Atom) const { if (std::get<0>(Tuple).first == Atom) return std::get<1>(Tuple); } - return None; + return std::nullopt; } -Optional<uint64_t> AppleAcceleratorTable::Entry::getDIESectionOffset() const { +std::optional<uint64_t> +AppleAcceleratorTable::Entry::getDIESectionOffset() const { return HdrData->extractOffset(lookup(dwarf::DW_ATOM_die_offset)); } -Optional<uint64_t> AppleAcceleratorTable::Entry::getCUOffset() const { +std::optional<uint64_t> AppleAcceleratorTable::Entry::getCUOffset() const { return HdrData->extractOffset(lookup(dwarf::DW_ATOM_cu_offset)); } -Optional<dwarf::Tag> AppleAcceleratorTable::Entry::getTag() const { - Optional<DWARFFormValue> Tag = lookup(dwarf::DW_ATOM_die_tag); +std::optional<dwarf::Tag> AppleAcceleratorTable::Entry::getTag() const { + std::optional<DWARFFormValue> Tag = lookup(dwarf::DW_ATOM_die_tag); if (!Tag) - return None; - if (Optional<uint64_t> Value = Tag->getAsUnsignedConstant()) + return std::nullopt; + if (std::optional<uint64_t> Value = Tag->getAsUnsignedConstant()) return dwarf::Tag(*Value); - return None; + return std::nullopt; } AppleAcceleratorTable::ValueIterator::ValueIterator( @@ -534,36 +535,36 @@ DWARFDebugNames::Entry::Entry(const NameIndex &NameIdx, const Abbrev &Abbr) Values.emplace_back(Attr.Form); } -Optional<DWARFFormValue> +std::optional<DWARFFormValue> DWARFDebugNames::Entry::lookup(dwarf::Index Index) const { assert(Abbr->Attributes.size() == Values.size()); for (auto Tuple : zip_first(Abbr->Attributes, Values)) { if (std::get<0>(Tuple).Index == Index) return std::get<1>(Tuple); } - return None; + return std::nullopt; } -Optional<uint64_t> DWARFDebugNames::Entry::getDIEUnitOffset() const { - if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_die_offset)) +std::optional<uint64_t> DWARFDebugNames::Entry::getDIEUnitOffset() const { + if (std::optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_die_offset)) return Off->getAsReferenceUVal(); - return None; + return std::nullopt; } -Optional<uint64_t> DWARFDebugNames::Entry::getCUIndex() const { - if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_compile_unit)) +std::optional<uint64_t> DWARFDebugNames::Entry::getCUIndex() const { + if (std::optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_compile_unit)) return Off->getAsUnsignedConstant(); // In a per-CU index, the entries without a DW_IDX_compile_unit attribute // implicitly refer to the single CU. if (NameIdx->getCUCount() == 1) return 0; - return None; + return std::nullopt; } -Optional<uint64_t> DWARFDebugNames::Entry::getCUOffset() const { - Optional<uint64_t> Index = getCUIndex(); +std::optional<uint64_t> DWARFDebugNames::Entry::getCUOffset() const { + std::optional<uint64_t> Index = getCUIndex(); if (!Index || *Index >= NameIdx->getCUCount()) - return None; + return std::nullopt; return NameIdx->getCUOffset(*Index); } @@ -683,7 +684,7 @@ bool DWARFDebugNames::NameIndex::dumpEntry(ScopedPrinter &W, void DWARFDebugNames::NameIndex::dumpName(ScopedPrinter &W, const NameTableEntry &NTE, - Optional<uint32_t> Hash) const { + std::optional<uint32_t> Hash) const { DictScope NameScope(W, ("Name " + Twine(NTE.getIndex())).str()); if (Hash) W.printHex("Hash", *Hash); @@ -767,7 +768,7 @@ LLVM_DUMP_METHOD void DWARFDebugNames::NameIndex::dump(ScopedPrinter &W) const { W.startLine() << "Hash table not present\n"; for (const NameTableEntry &NTE : *this) - dumpName(W, NTE, None); + dumpName(W, NTE, std::nullopt); } Error DWARFDebugNames::extract() { @@ -793,7 +794,7 @@ LLVM_DUMP_METHOD void DWARFDebugNames::dump(raw_ostream &OS) const { NI.dump(W); } -Optional<uint64_t> +std::optional<uint64_t> DWARFDebugNames::ValueIterator::findEntryOffsetInCurrentIndex() { const Header &Hdr = CurrentIndex->Hdr; if (Hdr.BucketCount == 0) { @@ -802,7 +803,7 @@ DWARFDebugNames::ValueIterator::findEntryOffsetInCurrentIndex() { if (NTE.getString() == Key) return NTE.getEntryOffset(); } - return None; + return std::nullopt; } // The Name Index has a Hash Table, so use that to speed up the search. @@ -812,18 +813,18 @@ DWARFDebugNames::ValueIterator::findEntryOffsetInCurrentIndex() { uint32_t Bucket = *Hash % Hdr.BucketCount; uint32_t Index = CurrentIndex->getBucketArrayEntry(Bucket); if (Index == 0) - return None; // Empty bucket + return std::nullopt; // Empty bucket for (; Index <= Hdr.NameCount; ++Index) { uint32_t Hash = CurrentIndex->getHashArrayEntry(Index); if (Hash % Hdr.BucketCount != Bucket) - return None; // End of bucket + return std::nullopt; // End of bucket NameTableEntry NTE = CurrentIndex->getNameTableEntry(Index); if (NTE.getString() == Key) return NTE.getEntryOffset(); } - return None; + return std::nullopt; } bool DWARFDebugNames::ValueIterator::getEntryAtCurrentOffset() { @@ -837,7 +838,7 @@ bool DWARFDebugNames::ValueIterator::getEntryAtCurrentOffset() { } bool DWARFDebugNames::ValueIterator::findInCurrentIndex() { - Optional<uint64_t> Offset = findEntryOffsetInCurrentIndex(); + std::optional<uint64_t> Offset = findEntryOffsetInCurrentIndex(); if (!Offset) return false; DataOffset = *Offset; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 19d7d659a86a..dd86144d16e0 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -38,7 +38,6 @@ #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h" #include "llvm/DebugInfo/DWARF/DWARFVerifier.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Object/Decompressor.h" #include "llvm/Object/MachO.h" @@ -103,7 +102,7 @@ static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) { } using ContributionCollection = - std::vector<Optional<StrOffsetsContributionDescriptor>>; + std::vector<std::optional<StrOffsetsContributionDescriptor>>; // Collect all the contributions to the string offsets table from all units, // sort them by their starting offsets and remove duplicates. @@ -117,8 +116,8 @@ collectContributionData(DWARFContext::unit_iterator_range Units) { // the start of the contributions vector. This way they are reported // first. llvm::sort(Contributions, - [](const Optional<StrOffsetsContributionDescriptor> &L, - const Optional<StrOffsetsContributionDescriptor> &R) { + [](const std::optional<StrOffsetsContributionDescriptor> &L, + const std::optional<StrOffsetsContributionDescriptor> &R) { if (L && R) return L->Base < R->Base; return R.has_value(); @@ -129,8 +128,8 @@ collectContributionData(DWARFContext::unit_iterator_range Units) { // to report them more than once. Contributions.erase( std::unique(Contributions.begin(), Contributions.end(), - [](const Optional<StrOffsetsContributionDescriptor> &L, - const Optional<StrOffsetsContributionDescriptor> &R) { + [](const std::optional<StrOffsetsContributionDescriptor> &L, + const std::optional<StrOffsetsContributionDescriptor> &R) { if (L && R) return L->Base == R->Base && L->Size == R->Size; return false; @@ -245,7 +244,7 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5). static void dumpRnglistsSection( raw_ostream &OS, DWARFDataExtractor &rnglistData, - llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)> + llvm::function_ref<std::optional<object::SectionedAddress>(uint32_t)> LookupPooledAddress, DIDumpOptions DumpOpts) { uint64_t Offset = 0; @@ -309,10 +308,8 @@ DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType) { } static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, - DWARFDataExtractor Data, - const MCRegisterInfo *MRI, - const DWARFObject &Obj, - Optional<uint64_t> DumpOffset) { + DWARFDataExtractor Data, const DWARFObject &Obj, + std::optional<uint64_t> DumpOffset) { uint64_t Offset = 0; while (Data.isValidOffset(Offset)) { @@ -330,13 +327,13 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts, if (DumpOffset) { if (DumpOffset >= Offset && DumpOffset < EndOffset) { Offset = *DumpOffset; - Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj, nullptr, - DumpOpts, /*Indent=*/0); + Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/std::nullopt, Obj, + nullptr, DumpOpts, /*Indent=*/0); OS << "\n"; return; } } else { - Loc.dumpRange(Offset, EndOffset - Offset, OS, MRI, Obj, DumpOpts); + Loc.dumpRange(Offset, EndOffset - Offset, OS, Obj, DumpOpts); } Offset = EndOffset; } @@ -351,7 +348,7 @@ static void dumpPubTableSection(raw_ostream &OS, DIDumpOptions DumpOpts, void DWARFContext::dump( raw_ostream &OS, DIDumpOptions DumpOpts, - std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) { + std::array<std::optional<uint64_t>, DIDT_ID_Count> DumpOffsets) { uint64_t DumpType = DumpOpts.DumpType; StringRef Extension = sys::path::extension(DObj->getFileName()); @@ -368,7 +365,7 @@ void DWARFContext::dump( bool Explicit = DumpType != DIDT_All && !IsDWO; bool ExplicitDWO = Explicit && IsDWO; auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID, - StringRef Section) -> Optional<uint64_t> * { + StringRef Section) -> std::optional<uint64_t> * { unsigned Mask = 1U << ID; bool Should = (DumpType & Mask) && (Explicit || !Section.empty()); if (!Should) @@ -424,21 +421,21 @@ void DWARFContext::dump( if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc, DObj->getLocSection().Data)) { - getDebugLoc()->dump(OS, getRegisterInfo(), *DObj, LLDumpOpts, *Off); + getDebugLoc()->dump(OS, *DObj, LLDumpOpts, *Off); } if (const auto *Off = shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists, DObj->getLoclistsSection().Data)) { DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(), 0); - dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off); + dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off); } if (const auto *Off = shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists, DObj->getLoclistsDWOSection().Data)) { DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(), isLittleEndian(), 0); - dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off); + dumpLoclistsSection(OS, LLDumpOpts, Data, *DObj, *Off); } if (const auto *Off = @@ -450,29 +447,29 @@ void DWARFContext::dump( if (*Off) { uint64_t Offset = **Off; Loc.dumpLocationList(&Offset, OS, - /*BaseAddr=*/None, getRegisterInfo(), *DObj, nullptr, - LLDumpOpts, /*Indent=*/0); + /*BaseAddr=*/std::nullopt, *DObj, nullptr, + LLDumpOpts, + /*Indent=*/0); OS << "\n"; } else { - Loc.dumpRange(0, Data.getData().size(), OS, getRegisterInfo(), *DObj, - LLDumpOpts); + Loc.dumpRange(0, Data.getData().size(), OS, *DObj, LLDumpOpts); } } - if (const Optional<uint64_t> *Off = + if (const std::optional<uint64_t> *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame, DObj->getFrameSection().Data)) { if (Expected<const DWARFDebugFrame *> DF = getDebugFrame()) - (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off); + (*DF)->dump(OS, DumpOpts, *Off); else RecoverableErrorHandler(DF.takeError()); } - if (const Optional<uint64_t> *Off = + if (const std::optional<uint64_t> *Off = shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame, DObj->getEHFrameSection().Data)) { if (Expected<const DWARFDebugFrame *> DF = getEHFrame()) - (*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off); + (*DF)->dump(OS, DumpOpts, *Off); else RecoverableErrorHandler(DF.takeError()); } @@ -519,7 +516,7 @@ void DWARFContext::dump( auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser, DIDumpOptions DumpOpts, - Optional<uint64_t> DumpOffset) { + std::optional<uint64_t> DumpOffset) { while (!Parser.done()) { if (DumpOffset && Parser.getOffset() != *DumpOffset) { Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler); @@ -612,11 +609,12 @@ void DWARFContext::dump( } } - auto LookupPooledAddress = [&](uint32_t Index) -> Optional<SectionedAddress> { + auto LookupPooledAddress = + [&](uint32_t Index) -> std::optional<SectionedAddress> { const auto &CUs = compile_units(); auto I = CUs.begin(); if (I == CUs.end()) - return None; + return std::nullopt; return (*I)->getAddrOffsetSectionItem(Index); }; @@ -712,7 +710,7 @@ DWARFTypeUnit *DWARFContext::getTypeUnitForHash(uint16_t Version, uint64_t Hash, struct UnitContainers { const DWARFUnitVector &Units; - Optional<DenseMap<uint64_t, DWARFTypeUnit *>> ⤅ + std::optional<DenseMap<uint64_t, DWARFTypeUnit *>> ⤅ }; UnitContainers Units = IsDWO ? UnitContainers{DWOUnits, DWOTypeUnits} : UnitContainers{NormalUnits, NormalTypeUnits}; @@ -744,8 +742,8 @@ DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) { for (const auto &DWOCU : dwo_compile_units()) { // Might not have parsed DWO ID yet. if (!DWOCU->getDWOId()) { - if (Optional<uint64_t> DWOId = - toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id))) + if (std::optional<uint64_t> DWOId = + toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id))) DWOCU->setDWOId(*DWOId); else // No DWO ID? @@ -781,14 +779,82 @@ bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) { return Success; } +void fixupIndex(const DWARFObject &DObj, DWARFContext &C, + DWARFUnitIndex &Index) { + using EntryType = DWARFUnitIndex::Entry::SectionContribution; + using EntryMap = DenseMap<uint32_t, EntryType>; + EntryMap Map; + if (DObj.getCUIndexSection().empty()) + return; + + uint64_t Offset = 0; + uint32_t TruncOffset = 0; + DObj.forEachInfoDWOSections([&](const DWARFSection &S) { + if (!(C.getParseCUTUIndexManually() || + S.Data.size() >= std::numeric_limits<uint32_t>::max())) + return; + + DWARFDataExtractor Data(DObj, S, C.isLittleEndian(), 0); + while (Data.isValidOffset(Offset)) { + DWARFUnitHeader Header; + if (!Header.extract(C, Data, &Offset, DWARFSectionKind::DW_SECT_INFO)) { + logAllUnhandledErrors( + createError("Failed to parse CU header in DWP file"), errs()); + Map.clear(); + break; + } + + auto Iter = Map.insert({TruncOffset, + {Header.getOffset(), Header.getNextUnitOffset() - + Header.getOffset()}}); + if (!Iter.second) { + logAllUnhandledErrors( + createError("Collision occured between for truncated offset 0x" + + Twine::utohexstr(TruncOffset)), + errs()); + Map.clear(); + return; + } + + Offset = Header.getNextUnitOffset(); + TruncOffset = Offset; + } + }); + + if (Map.empty()) + return; + + for (DWARFUnitIndex::Entry &E : Index.getMutableRows()) { + if (!E.isValid()) + continue; + DWARFUnitIndex::Entry::SectionContribution &CUOff = E.getContribution(); + auto Iter = Map.find(CUOff.getOffset()); + if (Iter == Map.end()) { + logAllUnhandledErrors(createError("Could not find CU offset 0x" + + Twine::utohexstr(CUOff.getOffset()) + + " in the Map"), + errs()); + break; + } + CUOff.setOffset(Iter->second.getOffset()); + if (CUOff.getOffset() != Iter->second.getOffset()) + logAllUnhandledErrors(createError("Length of CU in CU index doesn't " + "match calculated length at offset 0x" + + Twine::utohexstr(CUOff.getOffset())), + errs()); + } + + return; +} + const DWARFUnitIndex &DWARFContext::getCUIndex() { if (CUIndex) return *CUIndex; DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0); - CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO); CUIndex->parse(CUIndexData); + fixupIndex(*DObj, *this, *CUIndex.get()); return *CUIndex; } @@ -797,9 +863,12 @@ const DWARFUnitIndex &DWARFContext::getTUIndex() { return *TUIndex; DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0); - TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES); - TUIndex->parse(TUIndexData); + bool isParseSuccessful = TUIndex->parse(TUIndexData); + // If we are parsing TU-index and for .debug_types section we don't need + // to do anything. + if (isParseSuccessful && TUIndex->getVersion() != 2) + fixupIndex(*DObj, *this, *TUIndex.get()); return *TUIndex; } @@ -1111,7 +1180,7 @@ static bool getFunctionNameAndStartLineForAddress( DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, DILineInfoSpecifier::FileLineInfoKind FileNameKind, std::string &FunctionName, std::string &StartFile, uint32_t &StartLine, - Optional<uint64_t> &StartAddress) { + std::optional<uint64_t> &StartAddress) { // The address may correspond to instruction in some inlined function, // so we have to build the chain of inlined functions and take the // name of the topmost function in it. @@ -1141,9 +1210,9 @@ static bool getFunctionNameAndStartLineForAddress( return FoundResult; } -static Optional<int64_t> +static std::optional<int64_t> getExpressionFrameOffset(ArrayRef<uint8_t> Expr, - Optional<unsigned> FrameBaseReg) { + std::optional<unsigned> FrameBaseReg) { if (!Expr.empty() && (Expr[0] == DW_OP_fbreg || (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) { @@ -1157,7 +1226,7 @@ getExpressionFrameOffset(ArrayRef<uint8_t> Expr, return Offset; // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value) } - return None; + return std::nullopt; } void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, @@ -1168,9 +1237,9 @@ void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, if (const char *Name = Subprogram.getSubroutineName(DINameKind::ShortName)) Local.FunctionName = Name; - Optional<unsigned> FrameBaseReg; + std::optional<unsigned> FrameBaseReg; if (auto FrameBase = Subprogram.find(DW_AT_frame_base)) - if (Optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock()) + if (std::optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock()) if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 && (*Expr)[0] <= DW_OP_reg31) { FrameBaseReg = (*Expr)[0] - DW_OP_reg0; @@ -1179,7 +1248,7 @@ void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, if (Expected<std::vector<DWARFLocationExpression>> Loc = Die.getLocations(DW_AT_location)) { for (const auto &Entry : *Loc) { - if (Optional<int64_t> FrameOffset = + if (std::optional<int64_t> FrameOffset = getExpressionFrameOffset(Entry.Expr, FrameBaseReg)) { Local.FrameOffset = *FrameOffset; break; @@ -1198,20 +1267,19 @@ void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) Die = Origin; if (auto NameAttr = Die.find(DW_AT_name)) - if (Optional<const char *> Name = dwarf::toString(*NameAttr)) + if (std::optional<const char *> Name = dwarf::toString(*NameAttr)) Local.Name = *Name; if (auto Type = Die.getAttributeValueAsReferencedDie(DW_AT_type)) Local.Size = Type.getTypeSize(getCUAddrSize()); if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) { if (const auto *LT = CU->getContext().getLineTableForUnit(CU)) LT->getFileNameByIndex( - DeclFileAttr->getAsUnsignedConstant().value(), - CU->getCompilationDir(), + *DeclFileAttr->getAsUnsignedConstant(), CU->getCompilationDir(), DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, Local.DeclFile); } if (auto DeclLineAttr = Die.find(DW_AT_decl_line)) - Local.DeclLine = DeclLineAttr->getAsUnsignedConstant().value(); + Local.DeclLine = *DeclLineAttr->getAsUnsignedConstant(); Result.push_back(Local); return; @@ -1285,7 +1353,7 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange( uint32_t StartLine = 0; std::string StartFileName; std::string FunctionName(DILineInfo::BadString); - Optional<uint64_t> StartAddress; + std::optional<uint64_t> StartAddress; getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, Spec.FLIKind, FunctionName, StartFileName, StartLine, StartAddress); @@ -1846,9 +1914,9 @@ public: if (Supports && Supports(Reloc.getType())) { auto I = Map->try_emplace( Reloc.getOffset(), - RelocAddrEntry{SymInfoOrErr->SectionIndex, Reloc, - SymInfoOrErr->Address, - Optional<object::RelocationRef>(), 0, Resolver}); + RelocAddrEntry{ + SymInfoOrErr->SectionIndex, Reloc, SymInfoOrErr->Address, + std::optional<object::RelocationRef>(), 0, Resolver}); // If we didn't successfully insert that's because we already had a // relocation for that offset. Store it as a second relocation in the // same RelocAddrEntry instead. @@ -1877,12 +1945,12 @@ public: S.IsNameUnique = false; } - Optional<RelocAddrEntry> find(const DWARFSection &S, - uint64_t Pos) const override { + std::optional<RelocAddrEntry> find(const DWARFSection &S, + uint64_t Pos) const override { auto &Sec = static_cast<const DWARFSectionMap &>(S); RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos); if (AI == Sec.Relocs.end()) - return None; + return std::nullopt; return AI->second; } @@ -2019,23 +2087,6 @@ DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections, std::move(DObj), "", RecoverableErrorHandler, WarningHandler); } -Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) { - // Detect the architecture from the object file. We usually don't need OS - // info to lookup a target and create register info. - Triple TT; - TT.setArch(Triple::ArchType(Obj.getArch())); - TT.setVendor(Triple::UnknownVendor); - TT.setOS(Triple::UnknownOS); - std::string TargetLookupError; - const Target *TheTarget = - TargetRegistry::lookupTarget(TT.str(), TargetLookupError); - if (!TargetLookupError.empty()) - return createStringError(errc::invalid_argument, - TargetLookupError.c_str()); - RegInfo.reset(TheTarget->createMCRegInfo(TT.str())); - return Error::success(); -} - uint8_t DWARFContext::getCUAddrSize() { // In theory, different compile units may have different address byte // sizes, but for simplicity we just use the address byte size of the diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp index b18b64382b41..97434b3cfab8 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp @@ -54,7 +54,7 @@ uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off, return getUnsigned(Off, Size, Err); ErrorAsOutParameter ErrAsOut(Err); - Optional<RelocAddrEntry> E = Obj->find(*Section, *Off); + std::optional<RelocAddrEntry> E = Obj->find(*Section, *Off); uint64_t LocData = getUnsigned(Off, Size, Err); if (!E || (Err && *Err)) return LocData; @@ -68,11 +68,11 @@ uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off, return R; } -Optional<uint64_t> +std::optional<uint64_t> DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding, uint64_t PCRelOffset) const { if (Encoding == dwarf::DW_EH_PE_omit) - return None; + return std::nullopt; uint64_t Result = 0; uint64_t OldOffset = *Offset; @@ -86,7 +86,7 @@ DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding, Result = getUnsigned(Offset, getAddressSize()); break; default: - return None; + return std::nullopt; } break; case dwarf::DW_EH_PE_uleb128: @@ -114,7 +114,7 @@ DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding, Result = getRelocatedValue(8, Offset); break; default: - return None; + return std::nullopt; } // Then add relative offset, if required switch (Encoding & 0x70) { @@ -130,7 +130,7 @@ DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding, case dwarf::DW_EH_PE_aligned: default: *Offset = OldOffset; - return None; + return std::nullopt; } return Result; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp index ee54fc754803..3ea3818e7cc3 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp @@ -122,7 +122,7 @@ void DWARFDebugAbbrev::parse() const { break; AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls))); } - Data = None; + Data = std::nullopt; } void DWARFDebugAbbrev::dump(raw_ostream &OS) const { diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp index 81fac4763ec1..98eaf1a095d9 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp @@ -177,9 +177,8 @@ Expected<uint64_t> DWARFDebugAddrTable::getAddrEntry(uint32_t Index) const { Index, Offset); } -Optional<uint64_t> DWARFDebugAddrTable::getFullLength() const { +std::optional<uint64_t> DWARFDebugAddrTable::getFullLength() const { if (Length == 0) - return None; + return std::nullopt; return Length + dwarf::getUnitLengthFieldByteSize(Format); } - diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp index cf9057c99dbd..aae1668c1639 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -8,13 +8,11 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h" #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Errc.h" @@ -25,18 +23,18 @@ #include <cassert> #include <cinttypes> #include <cstdint> +#include <optional> using namespace llvm; using namespace dwarf; -static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, +static void printRegister(raw_ostream &OS, DIDumpOptions DumpOpts, unsigned RegNum) { - if (MRI) { - if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(RegNum, IsEH)) { - if (const char *RegName = MRI->getName(*LLVMRegNum)) { - OS << RegName; - return; - } + if (DumpOpts.GetNameForDWARFReg) { + auto RegName = DumpOpts.GetNameForDWARFReg(RegNum, DumpOpts.IsEH); + if (!RegName.empty()) { + OS << RegName; + return; } } OS << "reg" << RegNum; @@ -49,26 +47,26 @@ UnwindLocation UnwindLocation::createUndefined() { return {Undefined}; } UnwindLocation UnwindLocation::createSame() { return {Same}; } UnwindLocation UnwindLocation::createIsConstant(int32_t Value) { - return {Constant, InvalidRegisterNumber, Value, None, false}; + return {Constant, InvalidRegisterNumber, Value, std::nullopt, false}; } UnwindLocation UnwindLocation::createIsCFAPlusOffset(int32_t Offset) { - return {CFAPlusOffset, InvalidRegisterNumber, Offset, None, false}; + return {CFAPlusOffset, InvalidRegisterNumber, Offset, std::nullopt, false}; } UnwindLocation UnwindLocation::createAtCFAPlusOffset(int32_t Offset) { - return {CFAPlusOffset, InvalidRegisterNumber, Offset, None, true}; + return {CFAPlusOffset, InvalidRegisterNumber, Offset, std::nullopt, true}; } UnwindLocation UnwindLocation::createIsRegisterPlusOffset(uint32_t RegNum, int32_t Offset, - Optional<uint32_t> AddrSpace) { + std::optional<uint32_t> AddrSpace) { return {RegPlusOffset, RegNum, Offset, AddrSpace, false}; } UnwindLocation UnwindLocation::createAtRegisterPlusOffset(uint32_t RegNum, int32_t Offset, - Optional<uint32_t> AddrSpace) { + std::optional<uint32_t> AddrSpace) { return {RegPlusOffset, RegNum, Offset, AddrSpace, true}; } @@ -80,8 +78,7 @@ UnwindLocation UnwindLocation::createAtDWARFExpression(DWARFExpression Expr) { return {Expr, true}; } -void UnwindLocation::dump(raw_ostream &OS, const MCRegisterInfo *MRI, - bool IsEH) const { +void UnwindLocation::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { if (Dereference) OS << '['; switch (Kind) { @@ -103,7 +100,7 @@ void UnwindLocation::dump(raw_ostream &OS, const MCRegisterInfo *MRI, OS << Offset; break; case RegPlusOffset: - printRegister(OS, MRI, IsEH, RegNum); + printRegister(OS, DumpOpts, RegNum); if (Offset == 0 && !AddrSpace) break; if (Offset >= 0) @@ -112,9 +109,10 @@ void UnwindLocation::dump(raw_ostream &OS, const MCRegisterInfo *MRI, if (AddrSpace) OS << " in addrspace" << *AddrSpace; break; - case DWARFExpr: - Expr->print(OS, DIDumpOptions(), MRI, nullptr, IsEH); + case DWARFExpr: { + Expr->print(OS, DumpOpts, nullptr); break; + } case Constant: OS << Offset; break; @@ -125,7 +123,8 @@ void UnwindLocation::dump(raw_ostream &OS, const MCRegisterInfo *MRI, raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, const UnwindLocation &UL) { - UL.dump(OS, nullptr, false); + auto DumpOpts = DIDumpOptions(); + UL.dump(OS, DumpOpts); return OS; } @@ -150,53 +149,55 @@ bool UnwindLocation::operator==(const UnwindLocation &RHS) const { return false; } -void RegisterLocations::dump(raw_ostream &OS, const MCRegisterInfo *MRI, - bool IsEH) const { +void RegisterLocations::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { bool First = true; for (const auto &RegLocPair : Locations) { if (First) First = false; else OS << ", "; - printRegister(OS, MRI, IsEH, RegLocPair.first); + printRegister(OS, DumpOpts, RegLocPair.first); OS << '='; - RegLocPair.second.dump(OS, MRI, IsEH); + RegLocPair.second.dump(OS, DumpOpts); } } raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, const RegisterLocations &RL) { - RL.dump(OS, nullptr, false); + auto DumpOpts = DIDumpOptions(); + RL.dump(OS, DumpOpts); return OS; } -void UnwindRow::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, +void UnwindRow::dump(raw_ostream &OS, DIDumpOptions DumpOpts, unsigned IndentLevel) const { OS.indent(2 * IndentLevel); if (hasAddress()) OS << format("0x%" PRIx64 ": ", *Address); OS << "CFA="; - CFAValue.dump(OS, MRI, IsEH); + CFAValue.dump(OS, DumpOpts); if (RegLocs.hasLocations()) { OS << ": "; - RegLocs.dump(OS, MRI, IsEH); + RegLocs.dump(OS, DumpOpts); } OS << "\n"; } raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, const UnwindRow &Row) { - Row.dump(OS, nullptr, false, 0); + auto DumpOpts = DIDumpOptions(); + Row.dump(OS, DumpOpts, 0); return OS; } -void UnwindTable::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, +void UnwindTable::dump(raw_ostream &OS, DIDumpOptions DumpOpts, unsigned IndentLevel) const { for (const UnwindRow &Row : Rows) - Row.dump(OS, MRI, IsEH, IndentLevel); + Row.dump(OS, DumpOpts, IndentLevel); } raw_ostream &llvm::dwarf::operator<<(raw_ostream &OS, const UnwindTable &Rows) { - Rows.dump(OS, nullptr, false, 0); + auto DumpOpts = DIDumpOptions(); + Rows.dump(OS, DumpOpts, 0); return OS; } @@ -513,7 +514,8 @@ CFIProgram::Instruction::getOperandAsSigned(const CFIProgram &CFIP, Error UnwindTable::parseRows(const CFIProgram &CFIP, UnwindRow &Row, const RegisterLocations *InitialLocs) { - std::vector<RegisterLocations> RegisterStates; + // State consists of CFA value and register locations. + std::vector<std::pair<UnwindLocation, RegisterLocations>> States; for (const CFIProgram::Instruction &Inst : CFIP) { switch (Inst.Opcode) { case dwarf::DW_CFA_set_loc: { @@ -570,7 +572,7 @@ Error UnwindTable::parseRows(const CFIProgram &CFIP, UnwindRow &Row, llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0); if (!RegNum) return RegNum.takeError(); - if (Optional<UnwindLocation> O = + if (std::optional<UnwindLocation> O = InitialLocs->getRegisterLocation(*RegNum)) Row.getRegisterLocations().setRegisterLocation(*RegNum, *O); else @@ -596,16 +598,18 @@ Error UnwindTable::parseRows(const CFIProgram &CFIP, UnwindRow &Row, break; case dwarf::DW_CFA_remember_state: - RegisterStates.push_back(Row.getRegisterLocations()); + States.push_back( + std::make_pair(Row.getCFAValue(), Row.getRegisterLocations())); break; case dwarf::DW_CFA_restore_state: - if (RegisterStates.empty()) + if (States.empty()) return createStringError(errc::invalid_argument, "DW_CFA_restore_state without a matching " "previous DW_CFA_remember_state"); - Row.getRegisterLocations() = RegisterStates.back(); - RegisterStates.pop_back(); + Row.getCFAValue() = States.back().first; + Row.getRegisterLocations() = States.back().second; + States.pop_back(); break; case dwarf::DW_CFA_GNU_window_save: @@ -853,7 +857,6 @@ CFIProgram::getOperandTypes() { /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand. void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, bool IsEH, const Instruction &Instr, unsigned OperandIdx, uint64_t Operand) const { assert(OperandIdx < MaxOperands); @@ -901,7 +904,7 @@ void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts, break; case OT_Register: OS << ' '; - printRegister(OS, MRI, IsEH, Operand); + printRegister(OS, DumpOpts, Operand); break; case OT_AddressSpace: OS << format(" in addrspace%" PRId64, Operand); @@ -909,20 +912,19 @@ void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts, case OT_Expression: assert(Instr.Expression && "missing DWARFExpression object"); OS << " "; - Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH); + Instr.Expression->print(OS, DumpOpts, nullptr); break; } } void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, bool IsEH, unsigned IndentLevel) const { for (const auto &Instr : Instructions) { uint8_t Opcode = Instr.Opcode; OS.indent(2 * IndentLevel); OS << callFrameString(Opcode) << ":"; for (unsigned i = 0; i < Instr.Ops.size(); ++i) - printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]); + printOperand(OS, DumpOpts, Instr, i, Instr.Ops[i]); OS << '\n'; } } @@ -939,21 +941,20 @@ constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) { return DW_CIE_ID; } -void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, bool IsEH) const { +void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { // A CIE with a zero length is a terminator entry in the .eh_frame section. - if (IsEH && Length == 0) { + if (DumpOpts.IsEH && Length == 0) { OS << format("%08" PRIx64, Offset) << " ZERO terminator\n"; return; } OS << format("%08" PRIx64, Offset) << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length) - << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, - getCIEId(IsDWARF64, IsEH)) + << format(" %0*" PRIx64, IsDWARF64 && !DumpOpts.IsEH ? 16 : 8, + getCIEId(IsDWARF64, DumpOpts.IsEH)) << " CIE\n" << " Format: " << FormatString(IsDWARF64) << "\n"; - if (IsEH && Version != 1) + if (DumpOpts.IsEH && Version != 1) OS << "WARNING: unsupported CIE version\n"; OS << format(" Version: %d\n", Version) << " Augmentation: \"" << Augmentation << "\"\n"; @@ -974,11 +975,11 @@ void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, OS << "\n"; } OS << "\n"; - CFIs.dump(OS, DumpOpts, MRI, IsEH); + CFIs.dump(OS, DumpOpts); OS << "\n"; if (Expected<UnwindTable> RowsOrErr = UnwindTable::create(this)) - RowsOrErr->dump(OS, MRI, IsEH, 1); + RowsOrErr->dump(OS, DumpOpts, 1); else { DumpOpts.RecoverableErrorHandler(joinErrors( createStringError(errc::invalid_argument, @@ -988,11 +989,10 @@ void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, OS << "\n"; } -void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, bool IsEH) const { +void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { OS << format("%08" PRIx64, Offset) << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length) - << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer) + << format(" %0*" PRIx64, IsDWARF64 && !DumpOpts.IsEH ? 16 : 8, CIEPointer) << " FDE cie="; if (LinkedCIE) OS << format("%08" PRIx64, LinkedCIE->getOffset()); @@ -1003,11 +1003,11 @@ void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts, OS << " Format: " << FormatString(IsDWARF64) << "\n"; if (LSDAAddress) OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress); - CFIs.dump(OS, DumpOpts, MRI, IsEH); + CFIs.dump(OS, DumpOpts); OS << "\n"; if (Expected<UnwindTable> RowsOrErr = UnwindTable::create(this)) - RowsOrErr->dump(OS, MRI, IsEH, 1); + RowsOrErr->dump(OS, DumpOpts, 1); else { DumpOpts.RecoverableErrorHandler(joinErrors( createStringError(errc::invalid_argument, @@ -1051,7 +1051,7 @@ Error DWARFDebugFrame::parse(DWARFDataExtractor Data) { if (Length == 0) { auto Cie = std::make_unique<CIE>( IsDWARF64, StartOffset, 0, 0, SmallString<8>(), 0, 0, 0, 0, 0, - SmallString<8>(), 0, 0, None, None, Arch); + SmallString<8>(), 0, 0, std::nullopt, std::nullopt, Arch); CIEs[StartOffset] = Cie.get(); Entries.push_back(std::move(Cie)); break; @@ -1088,10 +1088,10 @@ Error DWARFDebugFrame::parse(DWARFDataExtractor Data) { StringRef AugmentationData(""); uint32_t FDEPointerEncoding = DW_EH_PE_absptr; uint32_t LSDAPointerEncoding = DW_EH_PE_omit; - Optional<uint64_t> Personality; - Optional<uint32_t> PersonalityEncoding; + std::optional<uint64_t> Personality; + std::optional<uint32_t> PersonalityEncoding; if (IsEH) { - Optional<uint64_t> AugmentationLength; + std::optional<uint64_t> AugmentationLength; uint64_t StartAugmentationOffset; uint64_t EndAugmentationOffset; @@ -1169,7 +1169,7 @@ Error DWARFDebugFrame::parse(DWARFDataExtractor Data) { uint64_t CIEPointer = Id; uint64_t InitialLocation = 0; uint64_t AddressRange = 0; - Optional<uint64_t> LSDAAddress; + std::optional<uint64_t> LSDAAddress; CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer]; if (IsEH) { @@ -1242,15 +1242,15 @@ FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const { } void DWARFDebugFrame::dump(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *MRI, - Optional<uint64_t> Offset) const { + std::optional<uint64_t> Offset) const { + DumpOpts.IsEH = IsEH; if (Offset) { if (auto *Entry = getEntryAtOffset(*Offset)) - Entry->dump(OS, DumpOpts, MRI, IsEH); + Entry->dump(OS, DumpOpts); return; } OS << "\n"; for (const auto &Entry : Entries) - Entry->dump(OS, DumpOpts, MRI, IsEH); + Entry->dump(OS, DumpOpts); } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp index 7dbeebc2770f..4f0a6d96ace9 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" -#include "llvm/ADT/Optional.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" @@ -67,7 +66,8 @@ bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr, } // See if all attributes in this DIE have fixed byte sizes. If so, we can // just add this size to the offset to skip to the next DIE. - if (Optional<size_t> FixedSize = AbbrevDecl->getFixedAttributesByteSize(U)) { + if (std::optional<size_t> FixedSize = + AbbrevDecl->getFixedAttributesByteSize(U)) { *OffsetPtr += *FixedSize; return true; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index d2ed4fe018b5..0725bd7744ae 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -7,7 +7,6 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" @@ -79,9 +78,10 @@ bool DWARFDebugLine::Prologue::hasFileAtIndex(uint64_t FileIndex) const { return FileIndex != 0 && FileIndex <= FileNames.size(); } -Optional<uint64_t> DWARFDebugLine::Prologue::getLastValidFileIndex() const { +std::optional<uint64_t> +DWARFDebugLine::Prologue::getLastValidFileIndex() const { if (FileNames.empty()) - return None; + return std::nullopt; uint16_t DwarfVersion = getVersion(); assert(DwarfVersion != 0 && "line table prologue has no dwarf version information"); @@ -323,20 +323,20 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, FileEntry.Source = Value; break; case DW_LNCT_directory_index: - FileEntry.DirIdx = Value.getAsUnsignedConstant().value(); + FileEntry.DirIdx = *Value.getAsUnsignedConstant(); break; case DW_LNCT_timestamp: - FileEntry.ModTime = Value.getAsUnsignedConstant().value(); + FileEntry.ModTime = *Value.getAsUnsignedConstant(); break; case DW_LNCT_size: - FileEntry.Length = Value.getAsUnsignedConstant().value(); + FileEntry.Length = *Value.getAsUnsignedConstant(); break; case DW_LNCT_MD5: - if (!Value.getAsBlock() || Value.getAsBlock().value().size() != 16) + if (!Value.getAsBlock() || Value.getAsBlock()->size() != 16) return createStringError( errc::invalid_argument, "failed to parse file entry because the MD5 hash is invalid"); - std::uninitialized_copy_n(Value.getAsBlock().value().begin(), 16, + std::uninitialized_copy_n(Value.getAsBlock()->begin(), 16, FileEntry.Checksum.begin()); break; default: @@ -715,14 +715,14 @@ DWARFDebugLine::ParsingState::handleSpecialOpcode(uint8_t Opcode, } /// Parse a ULEB128 using the specified \p Cursor. \returns the parsed value on -/// success, or None if \p Cursor is in a failing state. +/// success, or std::nullopt if \p Cursor is in a failing state. template <typename T> -static Optional<T> parseULEB128(DWARFDataExtractor &Data, - DataExtractor::Cursor &Cursor) { +static std::optional<T> parseULEB128(DWARFDataExtractor &Data, + DataExtractor::Cursor &Cursor) { T Value = Data.getULEB128(Cursor); if (Cursor) return Value; - return None; + return std::nullopt; } Error DWARFDebugLine::LineTable::parse( @@ -1005,7 +1005,7 @@ Error DWARFDebugLine::LineTable::parse( // Takes a single unsigned LEB128 operand, multiplies it by the // min_inst_length field of the prologue, and adds the // result to the address register of the state machine. - if (Optional<uint64_t> Operand = + if (std::optional<uint64_t> Operand = parseULEB128<uint64_t>(TableData, Cursor)) { uint64_t AddrOffset = State.advanceAddr(*Operand, Opcode, OpcodeOffset); @@ -1030,7 +1030,7 @@ Error DWARFDebugLine::LineTable::parse( case DW_LNS_set_file: // Takes a single unsigned LEB128 operand and stores it in the file // register of the state machine. - if (Optional<uint16_t> File = + if (std::optional<uint16_t> File = parseULEB128<uint16_t>(TableData, Cursor)) { State.Row.File = *File; if (Verbose) @@ -1041,7 +1041,7 @@ Error DWARFDebugLine::LineTable::parse( case DW_LNS_set_column: // Takes a single unsigned LEB128 operand and stores it in the // column register of the state machine. - if (Optional<uint16_t> Column = + if (std::optional<uint16_t> Column = parseULEB128<uint16_t>(TableData, Cursor)) { State.Row.Column = *Column; if (Verbose) @@ -1117,7 +1117,8 @@ Error DWARFDebugLine::LineTable::parse( case DW_LNS_set_isa: // Takes a single unsigned LEB128 operand and stores it in the // ISA register of the state machine. - if (Optional<uint8_t> Isa = parseULEB128<uint8_t>(TableData, Cursor)) { + if (std::optional<uint8_t> Isa = + parseULEB128<uint8_t>(TableData, Cursor)) { State.Row.Isa = *Isa; if (Verbose) *OS << " (" << (uint64_t)State.Row.Isa << ")"; @@ -1135,7 +1136,7 @@ Error DWARFDebugLine::LineTable::parse( uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1]; std::vector<uint64_t> Operands; for (uint8_t I = 0; I < OpcodeLength; ++I) { - if (Optional<uint64_t> Value = + if (std::optional<uint64_t> Value = parseULEB128<uint64_t>(TableData, Cursor)) Operands.push_back(*Value); else @@ -1330,14 +1331,15 @@ bool DWARFDebugLine::LineTable::lookupAddressRangeImpl( return true; } -Optional<StringRef> DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex, - FileLineInfoKind Kind) const { +std::optional<StringRef> +DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex, + FileLineInfoKind Kind) const { if (Kind == FileLineInfoKind::None || !Prologue.hasFileAtIndex(FileIndex)) - return None; + return std::nullopt; const FileNameEntry &Entry = Prologue.getFileNameEntry(FileIndex); if (auto E = dwarf::toString(Entry.Source)) return StringRef(*E); - return None; + return std::nullopt; } static bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) { @@ -1382,10 +1384,12 @@ bool DWARFDebugLine::Prologue::getFileNameByIndex( IncludeDir = dwarf::toStringRef(IncludeDirectories[Entry.DirIdx - 1]); } - // For absolute paths only, include the compilation directory of compile unit. - // 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 (Kind == FileLineInfoKind::AbsoluteFilePath && !CompDir.empty() && + // For absolute paths only, include the compilation directory of compile unit, + // unless v5 DirIdx == 0 (IncludeDir indicates the compilation directory). 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 (Kind == FileLineInfoKind::AbsoluteFilePath && + (getVersion() < 5 || Entry.DirIdx != 0) && !CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir)) sys::path::append(FilePath, Style, CompDir); @@ -1417,6 +1421,24 @@ bool DWARFDebugLine::LineTable::getFileLineInfoForAddress( return true; } +bool DWARFDebugLine::LineTable::getDirectoryForEntry( + const FileNameEntry &Entry, std::string &Directory) const { + if (Prologue.getVersion() >= 5) { + if (Entry.DirIdx < Prologue.IncludeDirectories.size()) { + Directory = + dwarf::toString(Prologue.IncludeDirectories[Entry.DirIdx], ""); + return true; + } + return false; + } + if (0 < Entry.DirIdx && Entry.DirIdx <= Prologue.IncludeDirectories.size()) { + Directory = + dwarf::toString(Prologue.IncludeDirectories[Entry.DirIdx - 1], ""); + return true; + } + return false; +} + // We want to supply the Unit associated with a .debug_line[.dwo] table when // we dump it, if possible, but still dump the table even if there isn't a Unit. // Therefore, collect up handles on all the Units that point into the diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp index b68af4cfafef..00c2823cee0a 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -30,16 +30,17 @@ class DWARFObject; namespace { class DWARFLocationInterpreter { - Optional<object::SectionedAddress> Base; - std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr; + std::optional<object::SectionedAddress> Base; + std::function<std::optional<object::SectionedAddress>(uint32_t)> LookupAddr; public: DWARFLocationInterpreter( - Optional<object::SectionedAddress> Base, - std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr) + std::optional<object::SectionedAddress> Base, + std::function<std::optional<object::SectionedAddress>(uint32_t)> + LookupAddr) : Base(Base), LookupAddr(std::move(LookupAddr)) {} - Expected<Optional<DWARFLocationExpression>> + Expected<std::optional<DWARFLocationExpression>> Interpret(const DWARFLocationEntry &E); }; } // namespace @@ -48,22 +49,22 @@ static Error createResolverError(uint32_t Index, unsigned Kind) { return make_error<ResolverError>(Index, (dwarf::LoclistEntries)Kind); } -Expected<Optional<DWARFLocationExpression>> +Expected<std::optional<DWARFLocationExpression>> DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) { switch (E.Kind) { case dwarf::DW_LLE_end_of_list: - return None; + return std::nullopt; case dwarf::DW_LLE_base_addressx: { Base = LookupAddr(E.Value0); if (!Base) return createResolverError(E.Value0, E.Kind); - return None; + return std::nullopt; } case dwarf::DW_LLE_startx_endx: { - Optional<SectionedAddress> LowPC = LookupAddr(E.Value0); + std::optional<SectionedAddress> LowPC = LookupAddr(E.Value0); if (!LowPC) return createResolverError(E.Value0, E.Kind); - Optional<SectionedAddress> HighPC = LookupAddr(E.Value1); + std::optional<SectionedAddress> HighPC = LookupAddr(E.Value1); if (!HighPC) return createResolverError(E.Value1, E.Kind); return DWARFLocationExpression{ @@ -71,7 +72,7 @@ DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) { E.Loc}; } case dwarf::DW_LLE_startx_length: { - Optional<SectionedAddress> LowPC = LookupAddr(E.Value0); + std::optional<SectionedAddress> LowPC = LookupAddr(E.Value0); if (!LowPC) return createResolverError(E.Value0, E.Kind); return DWARFLocationExpression{DWARFAddressRange{LowPC->Address, @@ -92,10 +93,10 @@ DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) { return DWARFLocationExpression{Range, E.Loc}; } case dwarf::DW_LLE_default_location: - return DWARFLocationExpression{None, E.Loc}; + return DWARFLocationExpression{std::nullopt, E.Loc}; case dwarf::DW_LLE_base_address: Base = SectionedAddress{E.Value0, E.SectionIndex}; - return None; + return std::nullopt; case dwarf::DW_LLE_start_end: return DWARFLocationExpression{ DWARFAddressRange{E.Value0, E.Value1, E.SectionIndex}, E.Loc}; @@ -110,31 +111,28 @@ DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) { static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts, ArrayRef<uint8_t> Data, bool IsLittleEndian, - unsigned AddressSize, const MCRegisterInfo *MRI, - DWARFUnit *U) { + unsigned AddressSize, DWARFUnit *U) { DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize); // Note. We do not pass any format to DWARFExpression, even if the // corresponding unit is known. For now, there is only one operation, // DW_OP_call_ref, which depends on the format; it is rarely used, and // is unexpected in location tables. - DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, MRI, U); + DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, U); } -bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS, - Optional<SectionedAddress> BaseAddr, - const MCRegisterInfo *MRI, - const DWARFObject &Obj, DWARFUnit *U, - DIDumpOptions DumpOpts, - unsigned Indent) const { +bool DWARFLocationTable::dumpLocationList( + uint64_t *Offset, raw_ostream &OS, std::optional<SectionedAddress> BaseAddr, + const DWARFObject &Obj, DWARFUnit *U, DIDumpOptions DumpOpts, + unsigned Indent) const { DWARFLocationInterpreter Interp( - BaseAddr, [U](uint32_t Index) -> Optional<SectionedAddress> { + BaseAddr, [U](uint32_t Index) -> std::optional<SectionedAddress> { if (U) return U->getAddrOffsetSectionItem(Index); - return None; + return std::nullopt; }); OS << format("0x%8.8" PRIx64 ": ", *Offset); Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) { - Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E); + Expected<std::optional<DWARFLocationExpression>> Loc = Interp.Interpret(E); if (!Loc || DumpOpts.DisplayRawContents) dumpRawEntry(E, OS, Indent, DumpOpts, Obj); if (Loc && *Loc) { @@ -158,7 +156,7 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS, E.Kind != dwarf::DW_LLE_end_of_list) { OS << ": "; dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(), - Data.getAddressSize(), MRI, U); + Data.getAddressSize(), U); } return true; }); @@ -170,12 +168,12 @@ bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS, } Error DWARFLocationTable::visitAbsoluteLocationList( - uint64_t Offset, Optional<SectionedAddress> BaseAddr, - std::function<Optional<SectionedAddress>(uint32_t)> LookupAddr, + uint64_t Offset, std::optional<SectionedAddress> BaseAddr, + std::function<std::optional<SectionedAddress>(uint32_t)> LookupAddr, function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const { DWARFLocationInterpreter Interp(BaseAddr, std::move(LookupAddr)); return visitLocationList(&Offset, [&](const DWARFLocationEntry &E) { - Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E); + Expected<std::optional<DWARFLocationExpression>> Loc = Interp.Interpret(E); if (!Loc) return Callback(Loc.takeError()); if (*Loc) @@ -184,13 +182,13 @@ Error DWARFLocationTable::visitAbsoluteLocationList( }); } -void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, - const DWARFObject &Obj, DIDumpOptions DumpOpts, - Optional<uint64_t> DumpOffset) const { - auto BaseAddr = None; +void DWARFDebugLoc::dump(raw_ostream &OS, const DWARFObject &Obj, + DIDumpOptions DumpOpts, + std::optional<uint64_t> DumpOffset) const { + auto BaseAddr = std::nullopt; unsigned Indent = 12; if (DumpOffset) { - dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts, + dumpLocationList(&*DumpOffset, OS, BaseAddr, Obj, nullptr, DumpOpts, Indent); } else { uint64_t Offset = 0; @@ -200,7 +198,7 @@ void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, OS << Separator; Separator = "\n"; - CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr, + CanContinue = dumpLocationList(&Offset, OS, BaseAddr, Obj, nullptr, DumpOpts, Indent); OS << '\n'; } @@ -387,8 +385,7 @@ void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry, } void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size, - raw_ostream &OS, const MCRegisterInfo *MRI, - const DWARFObject &Obj, + raw_ostream &OS, const DWARFObject &Obj, DIDumpOptions DumpOpts) { if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) { OS << "Invalid dump range\n"; @@ -401,7 +398,7 @@ void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size, OS << Separator; Separator = "\n"; - CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj, + CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/std::nullopt, Obj, nullptr, DumpOpts, /*Indent=*/12); OS << '\n'; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp index 80daea64814a..4d52046ba9ba 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp @@ -105,8 +105,8 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const { } Error DWARFDebugMacro::parseImpl( - Optional<DWARFUnitVector::compile_unit_range> Units, - Optional<DataExtractor> StringExtractor, DWARFDataExtractor Data, + std::optional<DWARFUnitVector::compile_unit_range> Units, + std::optional<DataExtractor> StringExtractor, DWARFDataExtractor Data, bool IsMacro) { uint64_t Offset = 0; MacroList *M = nullptr; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp index cad3dcab8a7e..db01719bed59 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp @@ -85,7 +85,7 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const { } DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges( - llvm::Optional<object::SectionedAddress> BaseAddr) const { + std::optional<object::SectionedAddress> BaseAddr) const { DWARFAddressRangesVector Res; // debug_addr can't use the max integer tombstone because that's used for the // base address specifier entry - so use max-1. diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp index d12acca1962e..b428c2adfe0b 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp @@ -86,15 +86,15 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t *OffsetPtr) { } DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges( - llvm::Optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const { + std::optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const { return getAbsoluteRanges( BaseAddr, U.getAddressByteSize(), [&](uint32_t Index) { return U.getAddrOffsetSectionItem(Index); }); } DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges( - Optional<object::SectionedAddress> BaseAddr, uint8_t AddressByteSize, - function_ref<Optional<object::SectionedAddress>(uint32_t)> + std::optional<object::SectionedAddress> BaseAddr, uint8_t AddressByteSize, + function_ref<std::optional<object::SectionedAddress>(uint32_t)> LookupPooledAddress) const { DWARFAddressRangesVector Res; uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressByteSize); @@ -175,7 +175,7 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges( void RangeListEntry::dump( raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength, uint64_t &CurrentBase, DIDumpOptions DumpOpts, - llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)> + llvm::function_ref<std::optional<object::SectionedAddress>(uint32_t)> LookupPooledAddress) const { auto PrintRawEntry = [](raw_ostream &OS, const RangeListEntry &Entry, uint8_t AddrSize, DIDumpOptions DumpOpts) { diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index 15a2d23c4fd2..26cef8713df1 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -7,8 +7,6 @@ //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/DWARF/DWARFDie.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" @@ -76,7 +74,6 @@ static void dumpLocationList(raw_ostream &OS, const DWARFFormValue &FormValue, assert(FormValue.isFormClass(DWARFFormValue::FC_SectionOffset) && "bad FORM for location list"); DWARFContext &Ctx = U->getContext(); - const MCRegisterInfo *MRI = Ctx.getRegisterInfo(); uint64_t Offset = *FormValue.getAsSectionOffset(); if (FormValue.getForm() == DW_FORM_loclistx) { @@ -87,9 +84,8 @@ static void dumpLocationList(raw_ostream &OS, const DWARFFormValue &FormValue, else return; } - U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(), MRI, - Ctx.getDWARFObj(), U, DumpOpts, - Indent); + U->getLocationTable().dumpLocationList( + &Offset, OS, U->getBaseAddress(), Ctx.getDWARFObj(), U, DumpOpts, Indent); } static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue, @@ -99,12 +95,11 @@ static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue, FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) && "bad FORM for location expression"); DWARFContext &Ctx = U->getContext(); - const MCRegisterInfo *MRI = Ctx.getRegisterInfo(); ArrayRef<uint8_t> Expr = *FormValue.getAsBlock(); DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()), Ctx.isLittleEndian(), 0); DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format) - .print(OS, DumpOpts, MRI, U); + .print(OS, DumpOpts, U); } static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) { @@ -137,7 +132,7 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) { Color = HighlightColor::String; if (const auto *LT = U->getContext().getLineTableForUnit(U)) { - if (Optional<uint64_t> Val = FormValue.getAsUnsignedConstant()) { + if (std::optional<uint64_t> Val = FormValue.getAsUnsignedConstant()) { if (LT->getFileNameByIndex( *Val, U->getCompilationDir(), DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, @@ -147,13 +142,13 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, } } } - } else if (Optional<uint64_t> Val = FormValue.getAsUnsignedConstant()) + } else if (std::optional<uint64_t> Val = FormValue.getAsUnsignedConstant()) Name = AttributeValueString(Attr, *Val); if (!Name.empty()) WithColor(OS, Color) << Name; else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line) { - if (Optional<uint64_t> Val = FormValue.getAsUnsignedConstant()) + if (std::optional<uint64_t> Val = FormValue.getAsUnsignedConstant()) OS << *Val; else FormValue.dump(OS, DumpOpts); @@ -207,7 +202,7 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, OS << '"'; } } else if (Attr == DW_AT_APPLE_property_attribute) { - if (Optional<uint64_t> OptVal = FormValue.getAsUnsignedConstant()) + if (std::optional<uint64_t> OptVal = FormValue.getAsUnsignedConstant()) dumpApplePropertyAttribute(OS, *OptVal); } else if (Attr == DW_AT_ranges) { const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj(); @@ -249,19 +244,19 @@ bool DWARFDie::isSubroutineDIE() const { return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine; } -Optional<DWARFFormValue> DWARFDie::find(dwarf::Attribute Attr) const { +std::optional<DWARFFormValue> DWARFDie::find(dwarf::Attribute Attr) const { if (!isValid()) - return None; + return std::nullopt; auto AbbrevDecl = getAbbreviationDeclarationPtr(); if (AbbrevDecl) return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U); - return None; + return std::nullopt; } -Optional<DWARFFormValue> +std::optional<DWARFFormValue> DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const { if (!isValid()) - return None; + return std::nullopt; auto AbbrevDecl = getAbbreviationDeclarationPtr(); if (AbbrevDecl) { for (auto Attr : Attrs) { @@ -269,10 +264,10 @@ DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const { return Value; } } - return None; + return std::nullopt; } -Optional<DWARFFormValue> +std::optional<DWARFFormValue> DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const { SmallVector<DWARFDie, 3> Worklist; Worklist.push_back(*this); @@ -302,12 +297,12 @@ DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const { Worklist.push_back(D); } - return None; + return std::nullopt; } DWARFDie DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const { - if (Optional<DWARFFormValue> F = find(Attr)) + if (std::optional<DWARFFormValue> F = find(Attr)) return getAttributeValueAsReferencedDie(*F); return DWARFDie(); } @@ -328,7 +323,7 @@ DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const { DWARFDie DWARFDie::resolveTypeUnitReference() const { if (auto Attr = find(DW_AT_signature)) { - if (Optional<uint64_t> Sig = Attr->getAsReferenceUVal()) { + if (std::optional<uint64_t> Sig = Attr->getAsReferenceUVal()) { if (DWARFTypeUnit *TU = U->getContext().getTypeUnitForHash( U->getVersion(), *Sig, U->isDWOUnit())) return TU->getDIEForOffset(TU->getTypeOffset() + TU->getOffset()); @@ -337,18 +332,18 @@ DWARFDie DWARFDie::resolveTypeUnitReference() const { return *this; } -Optional<uint64_t> DWARFDie::getRangesBaseAttribute() const { +std::optional<uint64_t> DWARFDie::getRangesBaseAttribute() const { return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base})); } -Optional<uint64_t> DWARFDie::getLocBaseAttribute() const { +std::optional<uint64_t> DWARFDie::getLocBaseAttribute() const { return toSectionOffset(find(DW_AT_loclists_base)); } -Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const { +std::optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const { uint64_t Tombstone = dwarf::computeTombstoneAddress(U->getAddressByteSize()); if (LowPC == Tombstone) - return None; + return std::nullopt; if (auto FormValue = find(DW_AT_high_pc)) { if (auto Address = FormValue->getAsAddress()) { // High PC is an address. @@ -359,7 +354,7 @@ Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const { return LowPC + *Offset; } } - return None; + return std::nullopt; } bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC, @@ -385,7 +380,7 @@ Expected<DWARFAddressRangesVector> DWARFDie::getAddressRanges() const { if (getLowAndHighPC(LowPC, HighPC, Index)) return DWARFAddressRangesVector{{LowPC, HighPC, Index}}; - Optional<DWARFFormValue> Value = find(DW_AT_ranges); + std::optional<DWARFFormValue> Value = find(DW_AT_ranges); if (Value) { if (Value->getForm() == DW_FORM_rnglistx) return U->findRnglistFromIndex(*Value->getAsSectionOffset()); @@ -409,12 +404,12 @@ bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const { Expected<DWARFLocationExpressionsVector> DWARFDie::getLocations(dwarf::Attribute Attr) const { - Optional<DWARFFormValue> Location = find(Attr); + std::optional<DWARFFormValue> Location = find(Attr); if (!Location) return createStringError(inconvertibleErrorCode(), "No %s", dwarf::AttributeString(Attr).data()); - if (Optional<uint64_t> Off = Location->getAsSectionOffset()) { + if (std::optional<uint64_t> Off = Location->getAsSectionOffset()) { uint64_t Offset = *Off; if (Location->getForm() == DW_FORM_loclistx) { @@ -427,9 +422,9 @@ DWARFDie::getLocations(dwarf::Attribute Attr) const { return U->findLoclistFromOffset(Offset); } - if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) { + if (std::optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) { return DWARFLocationExpressionsVector{ - DWARFLocationExpression{None, to_vector<4>(*Expr)}}; + DWARFLocationExpression{std::nullopt, to_vector<4>(*Expr)}}; } return createStringError( @@ -492,9 +487,9 @@ void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0); } -Optional<uint64_t> DWARFDie::getTypeSize(uint64_t PointerSize) { +std::optional<uint64_t> DWARFDie::getTypeSize(uint64_t PointerSize) { if (auto SizeAttr = find(DW_AT_byte_size)) - if (Optional<uint64_t> Size = SizeAttr->getAsUnsignedConstant()) + if (std::optional<uint64_t> Size = SizeAttr->getAsUnsignedConstant()) return Size; switch (getTag()) { @@ -520,21 +515,21 @@ Optional<uint64_t> DWARFDie::getTypeSize(uint64_t PointerSize) { case DW_TAG_array_type: { DWARFDie BaseType = getAttributeValueAsReferencedDie(DW_AT_type); if (!BaseType) - return None; - Optional<uint64_t> BaseSize = BaseType.getTypeSize(PointerSize); + return std::nullopt; + std::optional<uint64_t> BaseSize = BaseType.getTypeSize(PointerSize); if (!BaseSize) - return None; + return std::nullopt; uint64_t Size = *BaseSize; for (DWARFDie Child : *this) { if (Child.getTag() != DW_TAG_subrange_type) continue; if (auto ElemCountAttr = Child.find(DW_AT_count)) - if (Optional<uint64_t> ElemCount = + if (std::optional<uint64_t> ElemCount = ElemCountAttr->getAsUnsignedConstant()) Size *= *ElemCount; if (auto UpperBoundAttr = Child.find(DW_AT_upper_bound)) - if (Optional<int64_t> UpperBound = + if (std::optional<int64_t> UpperBound = UpperBoundAttr->getAsSignedConstant()) { int64_t LowerBound = 0; if (auto LowerBoundAttr = Child.find(DW_AT_lower_bound)) @@ -549,7 +544,7 @@ Optional<uint64_t> DWARFDie::getTypeSize(uint64_t PointerSize) { return BaseType.getTypeSize(PointerSize); break; } - return None; + return std::nullopt; } /// Helper to dump a DIE with all of its parents, but no siblings. @@ -592,7 +587,7 @@ void DWARFDie::dump(raw_ostream &OS, unsigned Indent, if (DumpOpts.Verbose) { OS << format(" [%u] %c", abbrCode, AbbrevDecl->hasChildren() ? '*' : ' '); - if (Optional<uint32_t> ParentIdx = Die->getParentIdx()) + if (std::optional<uint32_t> ParentIdx = Die->getParentIdx()) OS << format(" (0x%8.8" PRIx64 ")", U->getDIEAtIndex(*ParentIdx).getOffset()); } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp index e19f5b8138fa..523dee486d2d 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -8,7 +8,6 @@ #include "llvm/DebugInfo/DWARF/DWARFExpression.h" #include "llvm/DebugInfo/DWARF/DWARFUnit.h" -#include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/Format.h" #include <cassert> #include <cstdint> @@ -119,7 +118,7 @@ static DWARFExpression::Operation::Description getOpDesc(unsigned OpCode) { bool DWARFExpression::Operation::extract(DataExtractor Data, uint8_t AddressSize, uint64_t Offset, - Optional<DwarfFormat> Format) { + std::optional<DwarfFormat> Format) { EndOffset = Offset; Opcode = Data.getU8(&Offset); @@ -225,11 +224,11 @@ static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS, } } -static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, - DIDumpOptions DumpOpts, uint8_t Opcode, - const uint64_t Operands[2], - const MCRegisterInfo *MRI, bool isEH) { - if (!MRI) +bool DWARFExpression::prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, + DIDumpOptions DumpOpts, + uint8_t Opcode, + const uint64_t Operands[2]) { + if (!DumpOpts.GetNameForDWARFReg) return false; uint64_t DwarfRegNum; @@ -243,18 +242,17 @@ static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, else DwarfRegNum = Opcode - DW_OP_reg0; - 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]); - else - OS << ' ' << RegName; - - if (Opcode == DW_OP_regval_type) - prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1); - return true; - } + auto RegName = DumpOpts.GetNameForDWARFReg(DwarfRegNum, DumpOpts.IsEH); + if (!RegName.empty()) { + if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) || + Opcode == DW_OP_bregx) + OS << ' ' << RegName << format("%+" PRId64, Operands[OpNum]); + else + OS << ' ' << RegName.data(); + + if (Opcode == DW_OP_regval_type) + prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1); + return true; } return false; @@ -262,8 +260,7 @@ static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts, const DWARFExpression *Expr, - const MCRegisterInfo *RegInfo, - DWARFUnit *U, bool isEH) const { + DWARFUnit *U) const { if (Error) { OS << "<decoding error>"; return false; @@ -277,7 +274,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts, (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) || Opcode == DW_OP_bregx || Opcode == DW_OP_regx || Opcode == DW_OP_regval_type) - if (prettyPrintRegisterOp(U, OS, DumpOpts, Opcode, Operands, RegInfo, isEH)) + if (prettyPrintRegisterOp(U, OS, DumpOpts, Opcode, Operands)) return true; for (unsigned Operand = 0; Operand < 2; ++Operand) { @@ -323,15 +320,15 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts, } void DWARFExpression::print(raw_ostream &OS, DIDumpOptions DumpOpts, - const MCRegisterInfo *RegInfo, DWARFUnit *U, - bool IsEH) const { + DWARFUnit *U, bool IsEH) const { uint32_t EntryValExprSize = 0; uint64_t EntryValStartOffset = 0; if (Data.getData().empty()) OS << "<empty>"; for (auto &Op : *this) { - if (!Op.print(OS, DumpOpts, this, RegInfo, U, IsEH)) { + DumpOpts.IsEH = IsEH; + if (!Op.print(OS, DumpOpts, this, U)) { uint64_t FailOffset = Op.getEndOffset(); while (FailOffset < Data.getData().size()) OS << format(" %02x", Data.getU8(&FailOffset)); @@ -402,9 +399,11 @@ struct PrintedExpr { PrintedExpr(ExprKind K = Address) : Kind(K) {} }; -static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I, - const DWARFExpression::iterator E, - const MCRegisterInfo &MRI) { +static bool printCompactDWARFExpr( + raw_ostream &OS, DWARFExpression::iterator I, + const DWARFExpression::iterator E, + std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg = + nullptr) { SmallVector<PrintedExpr, 4> Stack; while (I != E) { @@ -415,25 +414,21 @@ static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I, // DW_OP_regx: A register, with the register num given as an operand. // Printed as the plain register name. uint64_t DwarfRegNum = Op.getRawOperand(0); - Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false); - if (!LLVMRegNum) { - OS << "<unknown register " << DwarfRegNum << ">"; + auto RegName = GetNameForDWARFReg(DwarfRegNum, false); + if (RegName.empty()) return false; - } raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String); - S << MRI.getName(*LLVMRegNum); + S << RegName; break; } case dwarf::DW_OP_bregx: { int DwarfRegNum = Op.getRawOperand(0); int64_t Offset = Op.getRawOperand(1); - Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false); - if (!LLVMRegNum) { - OS << "<unknown register " << DwarfRegNum << ">"; + auto RegName = GetNameForDWARFReg(DwarfRegNum, false); + if (RegName.empty()) return false; - } raw_svector_ostream S(Stack.emplace_back().String); - S << MRI.getName(*LLVMRegNum); + S << RegName; if (Offset) S << format("%+" PRId64, Offset); break; @@ -447,7 +442,7 @@ static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I, ++I; raw_svector_ostream S(Stack.emplace_back().String); S << "entry("; - printCompactDWARFExpr(S, I, SubExprEnd, MRI); + printCompactDWARFExpr(S, I, SubExprEnd, GetNameForDWARFReg); S << ")"; I = SubExprEnd; continue; @@ -464,24 +459,20 @@ static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I, // DW_OP_reg<N>: A register, with the register num implied by the // opcode. Printed as the plain register name. uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0; - Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false); - if (!LLVMRegNum) { - OS << "<unknown register " << DwarfRegNum << ">"; + auto RegName = GetNameForDWARFReg(DwarfRegNum, false); + if (RegName.empty()) return false; - } raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String); - S << MRI.getName(*LLVMRegNum); + S << RegName; } else if (Opcode >= dwarf::DW_OP_breg0 && Opcode <= dwarf::DW_OP_breg31) { int DwarfRegNum = Opcode - dwarf::DW_OP_breg0; int64_t Offset = Op.getRawOperand(0); - Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false); - if (!LLVMRegNum) { - OS << "<unknown register " << DwarfRegNum << ">"; + auto RegName = GetNameForDWARFReg(DwarfRegNum, false); + if (RegName.empty()) return false; - } raw_svector_ostream S(Stack.emplace_back().String); - S << MRI.getName(*LLVMRegNum); + S << RegName; if (Offset) S << format("%+" PRId64, Offset); } else { @@ -506,8 +497,10 @@ static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I, return true; } -bool DWARFExpression::printCompact(raw_ostream &OS, const MCRegisterInfo &MRI) { - return printCompactDWARFExpr(OS, begin(), end(), MRI); +bool DWARFExpression::printCompact( + raw_ostream &OS, + std::function<StringRef(uint64_t RegNum, bool IsEH)> GetNameForDWARFReg) { + return printCompactDWARFExpr(OS, begin(), end(), GetNameForDWARFReg); } bool DWARFExpression::operator==(const DWARFExpression &RHS) const { diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp index 1fecd5ee6902..5dd9515aafdb 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -8,8 +8,6 @@ #include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/None.h" -#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" @@ -25,6 +23,7 @@ #include <cinttypes> #include <cstdint> #include <limits> +#include <optional> using namespace llvm; using namespace dwarf; @@ -172,7 +171,7 @@ bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, case DW_FORM_GNU_ref_alt: case DW_FORM_GNU_strp_alt: case DW_FORM_implicit_const: - if (Optional<uint8_t> FixedSize = + if (std::optional<uint8_t> FixedSize = dwarf::getFixedFormByteSize(Form, Params)) { *OffsetPtr += *FixedSize; return true; @@ -214,7 +213,7 @@ bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { // First, check DWARF5 form classes. - if (Form < makeArrayRef(DWARF5FormClasses).size() && + if (Form < ArrayRef(DWARF5FormClasses).size() && DWARF5FormClasses[Form] == FC) return true; // Check more forms from extensions and proposals. @@ -426,7 +425,8 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { OS << "<invalid dwarf unit>"; break; } - Optional<object::SectionedAddress> A = U->getAddrOffsetSectionItem(UValue); + std::optional<object::SectionedAddress> A = + U->getAddrOffsetSectionItem(UValue); if (!A || DumpOpts.Verbose) AddrOS << format("indexed (%8.8x) address = ", (uint32_t)UValue); if (A) @@ -442,7 +442,8 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { } uint32_t Index = UValue >> 32; uint32_t Offset = UValue & 0xffffffff; - Optional<object::SectionedAddress> A = U->getAddrOffsetSectionItem(Index); + std::optional<object::SectionedAddress> A = + U->getAddrOffsetSectionItem(Index); if (!A || DumpOpts.Verbose) AddrOS << format("indexed (%8.8x) + 0x%x address = ", Index, Offset); if (A) { @@ -472,7 +473,7 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { OS << format("0x%016" PRIx64, UValue); break; case DW_FORM_data16: - OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), None, 16, 16); + OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), std::nullopt, 16, 16); break; case DW_FORM_string: OS << '"'; @@ -635,7 +636,7 @@ Expected<const char *> DWARFFormValue::getAsCString() const { return make_error<StringError>("Unsupported form for string attribute", inconvertibleErrorCode()); uint64_t Offset = Value.uval; - Optional<uint32_t> Index; + std::optional<uint32_t> Index; if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx || Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 || Form == DW_FORM_strx4) { @@ -665,25 +666,26 @@ Expected<const char *> DWARFFormValue::getAsCString() const { inconvertibleErrorCode()); } -Optional<uint64_t> DWARFFormValue::getAsAddress() const { +std::optional<uint64_t> DWARFFormValue::getAsAddress() const { if (auto SA = getAsSectionedAddress()) return SA->Address; - return None; + return std::nullopt; } -Optional<object::SectionedAddress> +std::optional<object::SectionedAddress> DWARFFormValue::getAsSectionedAddress() const { if (!isFormClass(FC_Address)) - return None; + return std::nullopt; bool AddrOffset = Form == dwarf::DW_FORM_LLVM_addrx_offset; if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx || AddrOffset) { uint32_t Index = AddrOffset ? (Value.uval >> 32) : Value.uval; if (!U) - return None; - Optional<object::SectionedAddress> SA = U->getAddrOffsetSectionItem(Index); + return std::nullopt; + std::optional<object::SectionedAddress> SA = + U->getAddrOffsetSectionItem(Index); if (!SA) - return None; + return std::nullopt; if (AddrOffset) SA->Address += (Value.uval & 0xffffffff); return SA; @@ -691,15 +693,16 @@ DWARFFormValue::getAsSectionedAddress() const { return {{Value.uval, Value.SectionIndex}}; } -Optional<uint64_t> DWARFFormValue::getAsReference() const { +std::optional<uint64_t> DWARFFormValue::getAsReference() const { if (auto R = getAsRelativeReference()) return R->Unit ? R->Unit->getOffset() + R->Offset : R->Offset; - return None; + return std::nullopt; } -Optional<DWARFFormValue::UnitOffset> DWARFFormValue::getAsRelativeReference() const { +std::optional<DWARFFormValue::UnitOffset> +DWARFFormValue::getAsRelativeReference() const { if (!isFormClass(FC_Reference)) - return None; + return std::nullopt; switch (Form) { case DW_FORM_ref1: case DW_FORM_ref2: @@ -707,35 +710,35 @@ Optional<DWARFFormValue::UnitOffset> DWARFFormValue::getAsRelativeReference() co case DW_FORM_ref8: case DW_FORM_ref_udata: if (!U) - return None; + return std::nullopt; return UnitOffset{const_cast<DWARFUnit*>(U), Value.uval}; case DW_FORM_ref_addr: case DW_FORM_ref_sig8: case DW_FORM_GNU_ref_alt: return UnitOffset{nullptr, Value.uval}; default: - return None; + return std::nullopt; } } -Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const { +std::optional<uint64_t> DWARFFormValue::getAsSectionOffset() const { if (!isFormClass(FC_SectionOffset)) - return None; + return std::nullopt; return Value.uval; } -Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const { +std::optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const { if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) || Form == DW_FORM_sdata) - return None; + return std::nullopt; return Value.uval; } -Optional<int64_t> DWARFFormValue::getAsSignedConstant() const { +std::optional<int64_t> DWARFFormValue::getAsSignedConstant() const { if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) || (Form == DW_FORM_udata && uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval)) - return None; + return std::nullopt; switch (Form) { case DW_FORM_data4: return int32_t(Value.uval); @@ -750,29 +753,29 @@ Optional<int64_t> DWARFFormValue::getAsSignedConstant() const { } } -Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const { +std::optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const { if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) && Form != DW_FORM_data16) - return None; - return makeArrayRef(Value.data, Value.uval); + return std::nullopt; + return ArrayRef(Value.data, Value.uval); } -Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const { +std::optional<uint64_t> DWARFFormValue::getAsCStringOffset() const { if (!isFormClass(FC_String) && Form == DW_FORM_string) - return None; + return std::nullopt; return Value.uval; } -Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const { +std::optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const { if (!isFormClass(FC_Reference)) - return None; + return std::nullopt; return Value.uval; } -Optional<std::string> +std::optional<std::string> DWARFFormValue::getAsFile(DILineInfoSpecifier::FileLineInfoKind Kind) const { if (U == nullptr || !isFormClass(FC_Constant)) - return None; + return std::nullopt; DWARFUnit *DLU = const_cast<DWARFUnit *>(U)->getLinkedUnit(); if (auto *LT = DLU->getContext().getLineTableForUnit(DLU)) { std::string FileName; @@ -780,5 +783,5 @@ DWARFFormValue::getAsFile(DILineInfoSpecifier::FileLineInfoKind Kind) const { FileName)) return FileName; } - return None; + return std::nullopt; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp b/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp index 86cc07b0d0f2..6a1423d37d9f 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp @@ -19,23 +19,23 @@ void DWARFTypePrinter::appendArrayType(const DWARFDie &D) { for (const DWARFDie &C : D.children()) { if (C.getTag() != DW_TAG_subrange_type) continue; - Optional<uint64_t> LB; - Optional<uint64_t> Count; - Optional<uint64_t> UB; - Optional<unsigned> DefaultLB; - if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound)) + std::optional<uint64_t> LB; + std::optional<uint64_t> Count; + std::optional<uint64_t> UB; + std::optional<unsigned> DefaultLB; + if (std::optional<DWARFFormValue> L = C.find(DW_AT_lower_bound)) LB = L->getAsUnsignedConstant(); - if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count)) + if (std::optional<DWARFFormValue> CountV = C.find(DW_AT_count)) Count = CountV->getAsUnsignedConstant(); - if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound)) + if (std::optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound)) UB = UpperV->getAsUnsignedConstant(); - if (Optional<DWARFFormValue> LV = + if (std::optional<DWARFFormValue> LV = D.getDwarfUnit()->getUnitDIE().find(DW_AT_language)) - if (Optional<uint64_t> LC = LV->getAsUnsignedConstant()) + if (std::optional<uint64_t> LC = LV->getAsUnsignedConstant()) if ((DefaultLB = LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC)))) if (LB && *LB == *DefaultLB) - LB = None; + LB = std::nullopt; if (!LB && !Count && !UB) OS << "[]"; else if (!LB && (Count || UB) && DefaultLB) @@ -143,6 +143,9 @@ DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D, Word = false; break; } + case DW_TAG_LLVM_ptrauth_type: + appendQualifiedNameBefore(Inner()); + break; case DW_TAG_const_type: case DW_TAG_volatile_type: appendConstVolatileQualifierBefore(D); @@ -238,6 +241,35 @@ void DWARFTypePrinter::appendUnqualifiedNameAfter( DW_TAG_ptr_to_member_type); break; } + case DW_TAG_LLVM_ptrauth_type: { + auto getValOrNull = [&](dwarf::Attribute Attr) -> uint64_t { + if (auto Form = D.find(Attr)) + return *Form->getAsUnsignedConstant(); + return 0; + }; + SmallVector<const char *, 2> optionsVec; + if (getValOrNull(DW_AT_LLVM_ptrauth_isa_pointer)) + optionsVec.push_back("isa-pointer"); + if (getValOrNull(DW_AT_LLVM_ptrauth_authenticates_null_values)) + optionsVec.push_back("authenticates-null-values"); + std::string options; + for (const auto *option : optionsVec) { + if (options.size()) + options += ","; + options += option; + } + if (options.size()) + options = ", \"" + options + "\""; + std::string PtrauthString; + llvm::raw_string_ostream PtrauthStream(PtrauthString); + PtrauthStream + << "__ptrauth(" << getValOrNull(DW_AT_LLVM_ptrauth_key) << ", " + << getValOrNull(DW_AT_LLVM_ptrauth_address_discriminated) << ", 0x0" + << utohexstr(getValOrNull(DW_AT_LLVM_ptrauth_extra_discriminator), true) + << options << ")"; + OS << PtrauthStream.str(); + break; + } /* case DW_TAG_structure_type: case DW_TAG_class_type: @@ -250,13 +282,27 @@ void DWARFTypePrinter::appendUnqualifiedNameAfter( } } +/// Returns True if the DIE TAG is one of the ones that is scopped. +static bool scopedTAGs(dwarf::Tag Tag) { + switch (Tag) { + case dwarf::DW_TAG_structure_type: + case dwarf::DW_TAG_class_type: + case dwarf::DW_TAG_union_type: + case dwarf::DW_TAG_namespace: + case dwarf::DW_TAG_enumeration_type: + return true; + default: + break; + } + return false; +} void DWARFTypePrinter::appendQualifiedName(DWARFDie D) { - if (D) + if (D && scopedTAGs(D.getTag())) appendScopes(D.getParent()); appendUnqualifiedName(D); } DWARFDie DWARFTypePrinter::appendQualifiedNameBefore(DWARFDie D) { - if (D) + if (D && scopedTAGs(D.getTag())) appendScopes(D.getParent()); return appendUnqualifiedNameBefore(D); } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index 74667fcb92bc..c199e0118a6f 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -134,11 +134,11 @@ void DWARFUnitVector::addUnitsImpl( } DWARFUnit *DWARFUnitVector::addUnit(std::unique_ptr<DWARFUnit> Unit) { - auto I = std::upper_bound(begin(), end(), Unit, - [](const std::unique_ptr<DWARFUnit> &LHS, - const std::unique_ptr<DWARFUnit> &RHS) { - return LHS->getOffset() < RHS->getOffset(); - }); + auto I = llvm::upper_bound(*this, Unit, + [](const std::unique_ptr<DWARFUnit> &LHS, + const std::unique_ptr<DWARFUnit> &RHS) { + return LHS->getOffset() < RHS->getOffset(); + }); return this->insert(I, std::move(Unit))->get(); } @@ -160,11 +160,11 @@ DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) { if (!CUOff) return nullptr; - auto Offset = CUOff->Offset; + uint64_t Offset = CUOff->getOffset(); auto end = begin() + getNumInfoUnits(); auto *CU = - std::upper_bound(begin(), end, CUOff->Offset, + std::upper_bound(begin(), end, CUOff->getOffset(), [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) { return LHS < RHS->getNextUnitOffset(); }); @@ -192,7 +192,7 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section, bool IsDWO, const DWARFUnitVector &UnitVector) : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA), RangeSection(RS), LineSection(LS), StringSection(SS), - StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE), + StringOffsetSection(SOS), AddrOffsetSection(AOS), IsLittleEndian(LE), IsDWO(IsDWO), UnitVector(UnitVector) { clear(); } @@ -200,11 +200,11 @@ DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section, DWARFUnit::~DWARFUnit() = default; DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const { - return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian, + return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, IsLittleEndian, getAddressByteSize()); } -Optional<object::SectionedAddress> +std::optional<object::SectionedAddress> DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const { if (!AddrOffsetSectionBase) { auto R = Context.info_section_units(); @@ -215,14 +215,14 @@ DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const { if (IsDWO && hasSingleElement(R)) return (*R.begin())->getAddrOffsetSectionItem(Index); - return None; + return std::nullopt; } uint64_t Offset = *AddrOffsetSectionBase + Index * getAddressByteSize(); if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize()) - return None; + return std::nullopt; DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection, - isLittleEndian, getAddressByteSize()); + IsLittleEndian, getAddressByteSize()); uint64_t Section; uint64_t Address = DA.getRelocatedAddress(&Offset, &Section); return {{Address, Section}}; @@ -240,7 +240,7 @@ Expected<uint64_t> DWARFUnit::getStringOffsetSectionItem(uint32_t Index) const { ", which is too large", inconvertibleErrorCode()); DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection, - isLittleEndian, 0); + IsLittleEndian, 0); return DA.getRelocatedValue(ItemSize, &Offset); } @@ -353,12 +353,12 @@ bool DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) { return false; auto *UnitContrib = IndexEntry->getContribution(); if (!UnitContrib || - UnitContrib->Length != (getLength() + getUnitLengthFieldByteSize())) + UnitContrib->getLength() != (getLength() + getUnitLengthFieldByteSize())) return false; auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV); if (!AbbrEntry) return false; - AbbrOffset = AbbrEntry->Offset; + AbbrOffset = AbbrEntry->getOffset(); return true; } @@ -367,7 +367,7 @@ Error DWARFUnit::extractRangeList(uint64_t RangeListOffset, // Require that compile unit is extracted. assert(!DieArray.empty()); DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection, - isLittleEndian, getAddressByteSize()); + IsLittleEndian, getAddressByteSize()); uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset; return RangeList.extract(RangesData, &ActualRangeListOffset); } @@ -377,7 +377,7 @@ void DWARFUnit::clear() { BaseAddr.reset(); RangeSectionBase = 0; LocSectionBase = 0; - AddrOffsetSectionBase = None; + AddrOffsetSectionBase = std::nullopt; SU = nullptr; clearDIEs(false); AddrDieMap.clear(); @@ -499,10 +499,11 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) { return Error::success(); DWARFDie UnitDie(this, &DieArray[0]); - if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id))) + if (std::optional<uint64_t> DWOId = + toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id))) Header.setDWOId(*DWOId); if (!IsDWO) { - assert(AddrOffsetSectionBase == None); + assert(AddrOffsetSectionBase == std::nullopt); assert(RangeSectionBase == 0); assert(LocSectionBase == 0); AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base)); @@ -521,7 +522,7 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) { // 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); + IsLittleEndian, 0); if (IsDWO || getVersion() >= 5) { auto StringOffsetOrError = IsDWO ? determineStringOffsetsTableContributionDWO(DA) @@ -543,7 +544,7 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) { uint64_t ContributionBaseOffset = 0; if (auto *IndexEntry = Header.getIndexEntry()) if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS)) - ContributionBaseOffset = Contrib->Offset; + ContributionBaseOffset = Contrib->getOffset(); setRangesSection( &Context.getDWARFObj().getRnglistsDWOSection(), ContributionBaseOffset + @@ -564,9 +565,9 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) { if (auto *IndexEntry = Header.getIndexEntry()) if (const auto *C = IndexEntry->getContribution( Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC)) - Data = Data.substr(C->Offset, C->Length); + Data = Data.substr(C->getOffset(), C->getLength()); - DWARFDataExtractor DWARFData(Data, isLittleEndian, getAddressByteSize()); + DWARFDataExtractor DWARFData(Data, IsLittleEndian, getAddressByteSize()); LocTable = std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion()); LocSectionBase = DWARFListTableHeader::getHeaderSize(Header.getFormat()); @@ -574,12 +575,12 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) { LocTable = std::make_unique<DWARFDebugLoclists>( DWARFDataExtractor(Context.getDWARFObj(), Context.getDWARFObj().getLoclistsSection(), - isLittleEndian, getAddressByteSize()), + IsLittleEndian, getAddressByteSize()), getVersion()); } else { LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor( Context.getDWARFObj(), Context.getDWARFObj().getLocSection(), - isLittleEndian, getAddressByteSize())); + IsLittleEndian, getAddressByteSize())); } // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for @@ -587,10 +588,10 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) { return Error::success(); } -bool DWARFUnit::parseDWO() { +bool DWARFUnit::parseDWO(StringRef DWOAlternativeLocation) { if (IsDWO) return false; - if (DWO.get()) + if (DWO) return false; DWARFDie UnitDie = getUnitDIE(); if (!UnitDie) @@ -611,8 +612,17 @@ bool DWARFUnit::parseDWO() { if (!DWOId) return false; auto DWOContext = Context.getDWOContext(AbsolutePath); - if (!DWOContext) - return false; + if (!DWOContext) { + // Use the alternative location to get the DWARF context for the DWO object. + if (DWOAlternativeLocation.empty()) + return false; + // If the alternative context does not correspond to the original DWO object + // (different hashes), the below 'getDWOCompileUnitForHash' call will catch + // the issue, with a returned null context. + DWOContext = Context.getDWOContext(DWOAlternativeLocation); + if (!DWOContext) + return false; + } DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId); if (!DWOCU) @@ -650,7 +660,7 @@ DWARFUnit::findRnglistFromOffset(uint64_t Offset) { return RangeList.getAbsoluteRanges(getBaseAddress()); } DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection, - isLittleEndian, Header.getAddressByteSize()); + IsLittleEndian, Header.getAddressByteSize()); DWARFDebugRnglistTable RnglistTable; auto RangeListOrError = RnglistTable.findList(RangesData, Offset); if (RangeListOrError) @@ -819,7 +829,7 @@ void DWARFUnit::updateVariableDieMap(DWARFDie Die) { // exact address. uint64_t GVSize = 1; if (DWARFDie BaseType = Die.getAttributeValueAsReferencedDie(DW_AT_type)) - if (Optional<uint64_t> Size = Die.getTypeSize(getAddressByteSize())) + if (std::optional<uint64_t> Size = Die.getTypeSize(getAddressByteSize())) GVSize = *Size; if (Address != UINT64_MAX) @@ -877,39 +887,66 @@ const DWARFUnitIndex &llvm::getDWARFUnitIndex(DWARFContext &Context, } DWARFDie DWARFUnit::getParent(const DWARFDebugInfoEntry *Die) { + if (const DWARFDebugInfoEntry *Entry = getParentEntry(Die)) + return DWARFDie(this, Entry); + + return DWARFDie(); +} + +const DWARFDebugInfoEntry * +DWARFUnit::getParentEntry(const DWARFDebugInfoEntry *Die) const { if (!Die) - return DWARFDie(); + return nullptr; + assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size()); - if (Optional<uint32_t> ParentIdx = Die->getParentIdx()) { + if (std::optional<uint32_t> ParentIdx = Die->getParentIdx()) { assert(*ParentIdx < DieArray.size() && "ParentIdx is out of DieArray boundaries"); - return DWARFDie(this, &DieArray[*ParentIdx]); + return getDebugInfoEntry(*ParentIdx); } - return DWARFDie(); + return nullptr; } DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) { + if (const DWARFDebugInfoEntry *Sibling = getSiblingEntry(Die)) + return DWARFDie(this, Sibling); + + return DWARFDie(); +} + +const DWARFDebugInfoEntry * +DWARFUnit::getSiblingEntry(const DWARFDebugInfoEntry *Die) const { if (!Die) - return DWARFDie(); + return nullptr; + assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size()); - if (Optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) { + if (std::optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) { assert(*SiblingIdx < DieArray.size() && "SiblingIdx is out of DieArray boundaries"); - return DWARFDie(this, &DieArray[*SiblingIdx]); + return &DieArray[*SiblingIdx]; } - return DWARFDie(); + return nullptr; } DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) { + if (const DWARFDebugInfoEntry *Sibling = getPreviousSiblingEntry(Die)) + return DWARFDie(this, Sibling); + + return DWARFDie(); +} + +const DWARFDebugInfoEntry * +DWARFUnit::getPreviousSiblingEntry(const DWARFDebugInfoEntry *Die) const { if (!Die) - return DWARFDie(); + return nullptr; + assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size()); - Optional<uint32_t> ParentIdx = Die->getParentIdx(); + std::optional<uint32_t> ParentIdx = Die->getParentIdx(); if (!ParentIdx) // Die is a root die, there is no previous sibling. - return DWARFDie(); + return nullptr; assert(*ParentIdx < DieArray.size() && "ParentIdx is out of DieArray boundaries"); @@ -918,7 +955,7 @@ DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) { uint32_t PrevDieIdx = getDIEIndex(Die) - 1; if (PrevDieIdx == *ParentIdx) // Immediately previous node is parent, there is no previous sibling. - return DWARFDie(); + return nullptr; while (DieArray[PrevDieIdx].getParentIdx() != *ParentIdx) { PrevDieIdx = *DieArray[PrevDieIdx].getParentIdx(); @@ -929,32 +966,56 @@ DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) { "PrevDieIdx is not a child of parent of Die"); } - return DWARFDie(this, &DieArray[PrevDieIdx]); + return &DieArray[PrevDieIdx]; } DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) { + if (const DWARFDebugInfoEntry *Child = getFirstChildEntry(Die)) + return DWARFDie(this, Child); + + return DWARFDie(); +} + +const DWARFDebugInfoEntry * +DWARFUnit::getFirstChildEntry(const DWARFDebugInfoEntry *Die) const { + if (!Die) + return nullptr; + assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size()); + if (!Die->hasChildren()) - return DWARFDie(); + return nullptr; // TODO: Instead of checking here for invalid die we might reject // invalid dies at parsing stage(DWARFUnit::extractDIEsToVector). // We do not want access out of bounds when parsing corrupted debug data. size_t I = getDIEIndex(Die) + 1; if (I >= DieArray.size()) - return DWARFDie(); - return DWARFDie(this, &DieArray[I]); + return nullptr; + return &DieArray[I]; } DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) { + if (const DWARFDebugInfoEntry *Child = getLastChildEntry(Die)) + return DWARFDie(this, Child); + + return DWARFDie(); +} + +const DWARFDebugInfoEntry * +DWARFUnit::getLastChildEntry(const DWARFDebugInfoEntry *Die) const { + if (!Die) + return nullptr; + assert(Die >= DieArray.data() && Die < DieArray.data() + DieArray.size()); + if (!Die->hasChildren()) - return DWARFDie(); + return nullptr; - if (Optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) { + if (std::optional<uint32_t> SiblingIdx = Die->getSiblingIdx()) { assert(*SiblingIdx < DieArray.size() && "SiblingIdx is out of DieArray boundaries"); assert(DieArray[*SiblingIdx - 1].getTag() == dwarf::DW_TAG_null && "Bad end of children marker"); - return DWARFDie(this, &DieArray[*SiblingIdx - 1]); + return &DieArray[*SiblingIdx - 1]; } // If SiblingIdx is set for non-root dies we could be sure that DWARF is @@ -969,11 +1030,13 @@ DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) { if (getDIEIndex(Die) == 0 && DieArray.size() > 1 && DieArray.back().getTag() == dwarf::DW_TAG_null) { // For the unit die we might take last item from DieArray. - assert(getDIEIndex(Die) == getDIEIndex(getUnitDIE()) && "Bad unit die"); - return DWARFDie(this, &DieArray.back()); + assert(getDIEIndex(Die) == + getDIEIndex(const_cast<DWARFUnit *>(this)->getUnitDIE()) && + "Bad unit die"); + return &DieArray.back(); } - return DWARFDie(); + return nullptr; } const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const { @@ -982,12 +1045,13 @@ const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const { return Abbrevs; } -llvm::Optional<object::SectionedAddress> DWARFUnit::getBaseAddress() { +std::optional<object::SectionedAddress> DWARFUnit::getBaseAddress() { if (BaseAddr) return BaseAddr; DWARFDie UnitDie = getUnitDIE(); - Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc}); + std::optional<DWARFFormValue> PC = + UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc}); BaseAddr = toSectionedAddress(PC); return BaseAddr; } @@ -1071,12 +1135,12 @@ parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA, return Desc.validateContributionSize(DA); } -Expected<Optional<StrOffsetsContributionDescriptor>> +Expected<std::optional<StrOffsetsContributionDescriptor>> DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) { assert(!IsDWO); auto OptOffset = toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base)); if (!OptOffset) - return None; + return std::nullopt; auto DescOrError = parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), *OptOffset); if (!DescOrError) @@ -1084,18 +1148,18 @@ DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) { return *DescOrError; } -Expected<Optional<StrOffsetsContributionDescriptor>> -DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) { +Expected<std::optional<StrOffsetsContributionDescriptor>> +DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA) { assert(IsDWO); uint64_t Offset = 0; auto IndexEntry = Header.getIndexEntry(); const auto *C = IndexEntry ? IndexEntry->getContribution(DW_SECT_STR_OFFSETS) : nullptr; if (C) - Offset = C->Offset; + Offset = C->getOffset(); if (getVersion() >= 5) { if (DA.getData().data() == nullptr) - return None; + return std::nullopt; Offset += Header.getFormat() == dwarf::DwarfFormat::DWARF32 ? 8 : 16; // Look for a valid contribution at the given offset. auto DescOrError = parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), Offset); @@ -1108,33 +1172,33 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) { // the length of the string offsets section. StrOffsetsContributionDescriptor Desc; if (C) - Desc = StrOffsetsContributionDescriptor(C->Offset, C->Length, 4, + Desc = StrOffsetsContributionDescriptor(C->getOffset(), C->getLength(), 4, Header.getFormat()); else if (!IndexEntry && !StringOffsetSection.Data.empty()) Desc = StrOffsetsContributionDescriptor(0, StringOffsetSection.Data.size(), 4, Header.getFormat()); else - return None; + return std::nullopt; auto DescOrError = Desc.validateContributionSize(DA); if (!DescOrError) return DescOrError.takeError(); return *DescOrError; } -Optional<uint64_t> DWARFUnit::getRnglistOffset(uint32_t Index) { - DataExtractor RangesData(RangeSection->Data, isLittleEndian, +std::optional<uint64_t> DWARFUnit::getRnglistOffset(uint32_t Index) { + DataExtractor RangesData(RangeSection->Data, IsLittleEndian, getAddressByteSize()); DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection, - isLittleEndian, 0); - if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry( + IsLittleEndian, 0); + if (std::optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry( RangesData, RangeSectionBase, getFormat(), Index)) return *Off + RangeSectionBase; - return None; + return std::nullopt; } -Optional<uint64_t> DWARFUnit::getLoclistOffset(uint32_t Index) { - if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry( +std::optional<uint64_t> DWARFUnit::getLoclistOffset(uint32_t Index) { + if (std::optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry( LocTable->getData(), LocSectionBase, getFormat(), Index)) return *Off + LocSectionBase; - return None; + return std::nullopt; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp index d161beef2202..a4487e2dc21b 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp @@ -181,14 +181,14 @@ bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) { for (unsigned i = 0; i != Header.NumUnits; ++i) { auto *Contrib = Contribs[i]; for (unsigned i = 0; i != Header.NumColumns; ++i) - Contrib[i].Offset = IndexData.getU32(&Offset); + Contrib[i].setOffset(IndexData.getU32(&Offset)); } // Read Table of Section Sizes for (unsigned i = 0; i != Header.NumUnits; ++i) { auto *Contrib = Contribs[i]; for (unsigned i = 0; i != Header.NumColumns; ++i) - Contrib[i].Length = IndexData.getU32(&Offset); + Contrib[i].setLength(IndexData.getU32(&Offset)); } return true; @@ -222,13 +222,21 @@ void DWARFUnitIndex::dump(raw_ostream &OS) const { DWARFSectionKind Kind = ColumnKinds[i]; StringRef Name = getColumnHeader(Kind); if (!Name.empty()) - OS << ' ' << left_justify(Name, 24); + OS << ' ' + << left_justify(Name, + Kind == DWARFSectionKind::DW_SECT_INFO ? 40 : 24); else OS << format(" Unknown: %-15" PRIu32, RawSectionIds[i]); } OS << "\n----- ------------------"; - for (unsigned i = 0; i != Header.NumColumns; ++i) - OS << " ------------------------"; + for (unsigned i = 0; i != Header.NumColumns; ++i) { + DWARFSectionKind Kind = ColumnKinds[i]; + if (Kind == DWARFSectionKind::DW_SECT_INFO || + Kind == DWARFSectionKind::DW_SECT_EXT_TYPES) + OS << " ----------------------------------------"; + else + OS << " ------------------------"; + } OS << '\n'; for (unsigned i = 0; i != Header.NumBuckets; ++i) { auto &Row = Rows[i]; @@ -236,8 +244,16 @@ void DWARFUnitIndex::dump(raw_ostream &OS) const { OS << format("%5u 0x%016" PRIx64 " ", i + 1, Row.Signature); for (unsigned i = 0; i != Header.NumColumns; ++i) { auto &Contrib = Contribs[i]; - OS << format("[0x%08x, 0x%08x) ", Contrib.Offset, - Contrib.Offset + Contrib.Length); + DWARFSectionKind Kind = ColumnKinds[i]; + if (Kind == DWARFSectionKind::DW_SECT_INFO || + Kind == DWARFSectionKind::DW_SECT_EXT_TYPES) + OS << format("[0x%016" PRIx64 ", 0x%016" PRIx64 ") ", + Contrib.getOffset(), + Contrib.getOffset() + Contrib.getLength()); + else + OS << format("[0x%08" PRIx32 ", 0x%08" PRIx32 ") ", + Contrib.getOffset32(), + Contrib.getOffset32() + Contrib.getLength32()); } OS << '\n'; } @@ -253,31 +269,36 @@ DWARFUnitIndex::Entry::getContribution(DWARFSectionKind Sec) const { return nullptr; } +DWARFUnitIndex::Entry::SectionContribution & +DWARFUnitIndex::Entry::getContribution() { + return Contributions[Index->InfoColumn]; +} + const DWARFUnitIndex::Entry::SectionContribution * DWARFUnitIndex::Entry::getContribution() const { return &Contributions[Index->InfoColumn]; } const DWARFUnitIndex::Entry * -DWARFUnitIndex::getFromOffset(uint32_t Offset) const { +DWARFUnitIndex::getFromOffset(uint64_t Offset) const { if (OffsetLookup.empty()) { for (uint32_t i = 0; i != Header.NumBuckets; ++i) if (Rows[i].Contributions) OffsetLookup.push_back(&Rows[i]); llvm::sort(OffsetLookup, [&](Entry *E1, Entry *E2) { - return E1->Contributions[InfoColumn].Offset < - E2->Contributions[InfoColumn].Offset; + return E1->Contributions[InfoColumn].getOffset() < + E2->Contributions[InfoColumn].getOffset(); }); } auto I = partition_point(OffsetLookup, [&](Entry *E2) { - return E2->Contributions[InfoColumn].Offset <= Offset; + return E2->Contributions[InfoColumn].getOffset() <= Offset; }); if (I == OffsetLookup.begin()) return nullptr; --I; const auto *E = *I; const auto &InfoContrib = E->Contributions[InfoColumn]; - if ((InfoContrib.Offset + InfoContrib.Length) <= Offset) + if ((InfoContrib.getOffset() + InfoContrib.getLength()) <= Offset) return nullptr; return E; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp index 2be2a12aa025..c90237d4cb77 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -43,7 +43,7 @@ namespace llvm { class DWARFDebugInfoEntry; } -Optional<DWARFAddressRange> +std::optional<DWARFAddressRange> DWARFVerifier::DieRangeInfo::insert(const DWARFAddressRange &R) { auto Begin = Ranges.begin(); auto End = Ranges.end(); @@ -62,7 +62,7 @@ DWARFVerifier::DieRangeInfo::insert(const DWARFAddressRange &R) { } Ranges.insert(Pos, R); - return None; + return std::nullopt; } DWARFVerifier::DieRangeInfo::die_range_info_iterator @@ -284,11 +284,10 @@ unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) { return 1; } - Optional<DWARFFormValue> CallAttr = - Curr.find({DW_AT_call_all_calls, DW_AT_call_all_source_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}); + std::optional<DWARFFormValue> CallAttr = Curr.find( + {DW_AT_call_all_calls, DW_AT_call_all_source_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); @@ -406,33 +405,33 @@ unsigned DWARFVerifier::verifyIndex(StringRef Name, DataExtractor D(IndexStr, DCtx.isLittleEndian(), 0); if (!Index.parse(D)) return 1; - using MapType = IntervalMap<uint32_t, uint64_t>; + using MapType = IntervalMap<uint64_t, uint64_t>; MapType::Allocator Alloc; std::vector<std::unique_ptr<MapType>> Sections(Index.getColumnKinds().size()); for (const DWARFUnitIndex::Entry &E : Index.getRows()) { uint64_t Sig = E.getSignature(); if (!E.getContributions()) continue; - for (auto E : enumerate(InfoColumnKind == DW_SECT_INFO - ? makeArrayRef(E.getContributions(), - Index.getColumnKinds().size()) - : makeArrayRef(E.getContribution(), 1))) { + for (auto E : enumerate( + InfoColumnKind == DW_SECT_INFO + ? ArrayRef(E.getContributions(), Index.getColumnKinds().size()) + : ArrayRef(E.getContribution(), 1))) { const DWARFUnitIndex::Entry::SectionContribution &SC = E.value(); int Col = E.index(); - if (SC.Length == 0) + if (SC.getLength() == 0) continue; if (!Sections[Col]) Sections[Col] = std::make_unique<MapType>(Alloc); auto &M = *Sections[Col]; - auto I = M.find(SC.Offset); - if (I != M.end() && I.start() < (SC.Offset + SC.Length)) { + auto I = M.find(SC.getOffset()); + if (I != M.end() && I.start() < (SC.getOffset() + SC.getLength())) { error() << llvm::formatv( "overlapping index entries for entries {0:x16} " "and {1:x16} for column {2}\n", *I, Sig, toString(Index.getColumnKinds()[Col])); return 1; } - M.insert(SC.Offset, SC.Offset + SC.Length - 1, Sig); + M.insert(SC.getOffset(), SC.getOffset() + SC.getLength() - 1, Sig); } } @@ -679,7 +678,8 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, if (LT) { if (!LT->hasFileAtIndex(*FileIdx)) { bool IsZeroIndexed = LT->Prologue.getVersion() >= 5; - if (Optional<uint64_t> LastFileIdx = LT->getLastValidFileIndex()) { + if (std::optional<uint64_t> LastFileIdx = + LT->getLastValidFileIndex()) { ReportError("DIE has " + AttributeString(Attr) + " with an invalid file index " + llvm::formatv("{0}", *FileIdx) + @@ -732,7 +732,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die, case DW_FORM_ref8: case DW_FORM_ref_udata: { // Verify all CU relative references are valid CU offsets. - Optional<uint64_t> RefVal = AttrValue.Value.getAsReference(); + std::optional<uint64_t> RefVal = AttrValue.Value.getAsReference(); assert(RefVal); if (RefVal) { auto CUSize = DieCU->getNextUnitOffset() - DieCU->getOffset(); @@ -756,7 +756,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die, case DW_FORM_ref_addr: { // Verify all absolute DIE references have valid offsets in the // .debug_info section. - Optional<uint64_t> RefVal = AttrValue.Value.getAsReference(); + std::optional<uint64_t> RefVal = AttrValue.Value.getAsReference(); assert(RefVal); if (RefVal) { if (*RefVal >= DieCU->getInfoSection().Data.size()) { |
