Index: include/llvm/DebugInfo/DWARF/DWARFDie.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDie.h +++ include/llvm/DebugInfo/DWARF/DWARFDie.h @@ -149,6 +149,16 @@ /// describes an address. uint64_t getAttributeValueAsAddress(dwarf::Attribute Attr, uint64_t FailValue) const; + + /// Extract the specified attribute from this DIE as an address. + /// + /// Extract an attribute value from this DIE only. This call doesn't look + /// for the attribute value in any DW_AT_specification or + /// DW_AT_abstract_origin referenced DIEs. + /// + /// \param Attr the attribute to extract. + /// \returns an optional value for the attribute. + Optional getAttributeValueAsAddress(dwarf::Attribute Attr) const; /// Extract the specified attribute from this DIE as a signed integer. /// @@ -164,6 +174,17 @@ /// that describes a signed integer. int64_t getAttributeValueAsSignedConstant(dwarf::Attribute Attr, int64_t FailValue) const; + + /// Extract the specified attribute from this DIE as a signed integer. + /// + /// Extract an attribute value from this DIE only. This call doesn't look + /// for the attribute value in any DW_AT_specification or + /// DW_AT_abstract_origin referenced DIEs. + /// + /// \param Attr the attribute to extract. + /// \returns an optional value for the attribute. + Optional + getAttributeValueAsSignedConstant(dwarf::Attribute Attr) const; /// Extract the specified attribute from this DIE as an unsigned integer. /// @@ -180,6 +201,17 @@ uint64_t getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr, uint64_t FailValue) const; + /// Extract the specified attribute from this DIE as an unsigned integer. + /// + /// Extract an attribute value from this DIE only. This call doesn't look + /// for the attribute value in any DW_AT_specification or + /// DW_AT_abstract_origin referenced DIEs. + /// + /// \param Attr the attribute to extract. + /// \returns an optional value for the attribute. + Optional + getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr) const; + /// Extract the specified attribute from this DIE as absolute DIE Offset. /// /// Extract an attribute value from this DIE only. This call doesn't look @@ -195,6 +227,16 @@ uint64_t getAttributeValueAsReference(dwarf::Attribute Attr, uint64_t FailValue) const; + /// Extract the specified attribute from this DIE as absolute DIE Offset. + /// + /// Extract an attribute value from this DIE only. This call doesn't look + /// for the attribute value in any DW_AT_specification or + /// DW_AT_abstract_origin referenced DIEs. + /// + /// \param Attr the attribute to extract. + /// \returns an optional value for the attribute. + Optional getAttributeValueAsReference(dwarf::Attribute Attr) const; + /// Extract the specified attribute from this DIE as absolute section offset. /// /// Extract an attribute value from this DIE only. This call doesn't look @@ -209,6 +251,16 @@ /// that describes a section offset. uint64_t getAttributeValueAsSectionOffset(dwarf::Attribute Attr, uint64_t FailValue) const; + /// Extract the specified attribute from this DIE as absolute section offset. + /// + /// Extract an attribute value from this DIE only. This call doesn't look + /// for the attribute value in any DW_AT_specification or + /// DW_AT_abstract_origin referenced DIEs. + /// + /// \param Attr the attribute to extract. + /// \returns an optional value for the attribute. + Optional + getAttributeValueAsSectionOffset(dwarf::Attribute Attr) const; /// Extract the specified attribute from this DIE as the referenced DIE. /// @@ -230,9 +282,8 @@ /// This is a utility function that checks for either the DW_AT_rnglists_base /// or DW_AT_GNU_ranges_base attribute. /// - /// \returns the absolute section offset value of the attribute or FailValue - /// if the attribute doesn't exist. - uint64_t getRangesBaseAttribute(uint64_t FailValue) const; + /// \returns anm optional absolute section offset value for the attribute. + Optional getRangesBaseAttribute() const; /// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU. /// Returns true if both attributes are present. Index: include/llvm/DebugInfo/DWARF/DWARFUnit.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -10,6 +10,7 @@ #ifndef LLVM_LIB_DEBUGINFO_DWARFUNIT_H #define LLVM_LIB_DEBUGINFO_DWARFUNIT_H +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" @@ -223,7 +224,7 @@ } const char *getCompilationDir(); - uint64_t getDWOId(); + Optional getDWOId(); void collectAddressRanges(DWARFAddressRangesVector &CURanges); Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -159,13 +159,13 @@ auto CUDIE = CU->getUnitDIE(); if (!CUDIE) continue; - unsigned stmtOffset = CUDIE.getAttributeValueAsSectionOffset( - DW_AT_stmt_list, -1U); - if (stmtOffset != -1U) { + if (auto StmtOffset = + CUDIE.getAttributeValueAsSectionOffset(DW_AT_stmt_list)) { DataExtractor lineData(getLineSection().Data, isLittleEndian(), savedAddressByteSize); DWARFDebugLine::LineTable LineTable; - LineTable.parse(lineData, &getLineSection().Relocs, &stmtOffset); + uint32_t Offset = *StmtOffset; + LineTable.parse(lineData, &getLineSection().Relocs, &Offset); LineTable.dump(OS); } } @@ -416,12 +416,11 @@ if (!UnitDIE) return nullptr; - unsigned stmtOffset = - UnitDIE.getAttributeValueAsSectionOffset(DW_AT_stmt_list, -1U); - if (stmtOffset == -1U) + auto Offset = UnitDIE.getAttributeValueAsSectionOffset(DW_AT_stmt_list); + if (!Offset) return nullptr; // No line table for this compile unit. - stmtOffset += U->getLineTableOffset(); + uint32_t stmtOffset = *Offset + U->getLineTableOffset(); // See if the line table is cached. if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset)) return lt; Index: lib/DebugInfo/DWARF/DWARFDie.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDie.cpp +++ lib/DebugInfo/DWARF/DWARFDie.cpp @@ -154,82 +154,110 @@ uint64_t DWARFDie::getAttributeValueAsAddress(dwarf::Attribute Attr, uint64_t FailValue) const { - auto FormValue = getAttributeValue(Attr); - if (!FormValue) - return FailValue; - Optional Result = FormValue->getAsAddress(); - return Result.hasValue() ? Result.getValue() : FailValue; + if (auto Value = getAttributeValueAsAddress(Attr)) + return *Value; + return FailValue; } +Optional +DWARFDie::getAttributeValueAsAddress(dwarf::Attribute Attr) const { + if (auto FormValue = getAttributeValue(Attr)) + return FormValue->getAsAddress(); + return None; +} + int64_t DWARFDie::getAttributeValueAsSignedConstant(dwarf::Attribute Attr, int64_t FailValue) const { - auto FormValue = getAttributeValue(Attr); - if (!FormValue) - return FailValue; - Optional Result = FormValue->getAsSignedConstant(); - return Result.hasValue() ? Result.getValue() : FailValue; + if (auto Value = getAttributeValueAsSignedConstant(Attr)) + return *Value; + return FailValue; } +Optional +DWARFDie::getAttributeValueAsSignedConstant(dwarf::Attribute Attr) const { + if (auto FormValue = getAttributeValue(Attr)) + return FormValue->getAsSignedConstant(); + return None; +} + uint64_t DWARFDie::getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr, uint64_t FailValue) const { - auto FormValue = getAttributeValue(Attr); - if (!FormValue) - return FailValue; - Optional Result = FormValue->getAsUnsignedConstant(); - return Result.hasValue() ? Result.getValue() : FailValue; + if (auto Value = getAttributeValueAsUnsignedConstant(Attr)) + return *Value; + return FailValue; } + +Optional +DWARFDie::getAttributeValueAsUnsignedConstant(dwarf::Attribute Attr) const { + if (auto FormValue = getAttributeValue(Attr)) + return FormValue->getAsUnsignedConstant(); + return None; +} + uint64_t DWARFDie::getAttributeValueAsReference(dwarf::Attribute Attr, uint64_t FailValue) const { - auto FormValue = getAttributeValue(Attr); - if (!FormValue) - return FailValue; - Optional Result = FormValue->getAsReference(); - return Result.hasValue() ? Result.getValue() : FailValue; + if (auto Value = getAttributeValueAsReference(Attr)) + return *Value; + return FailValue; } + +Optional +DWARFDie::getAttributeValueAsReference(dwarf::Attribute Attr) const { + if (auto FormValue = getAttributeValue(Attr)) + return FormValue->getAsReference(); + return None; +} + uint64_t DWARFDie::getAttributeValueAsSectionOffset(dwarf::Attribute Attr, uint64_t FailValue) const { - auto FormValue = getAttributeValue(Attr); - if (!FormValue) - return FailValue; - Optional Result = FormValue->getAsSectionOffset(); - return Result.hasValue() ? Result.getValue() : FailValue; + if (auto Value = getAttributeValueAsSectionOffset(Attr)) + return *Value; + return FailValue; } +Optional +DWARFDie::getAttributeValueAsSectionOffset(dwarf::Attribute Attr) const { + if (auto FormValue = getAttributeValue(Attr)) + return FormValue->getAsSectionOffset(); + return None; +} + + DWARFDie DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const { - uint32_t SpecRef = getAttributeValueAsReference(Attr, -1U); - if (SpecRef != -1U) { - auto SpecUnit = U->getUnitSection().getUnitForOffset(SpecRef); + auto SpecRef = getAttributeValueAsReference(Attr); + if (SpecRef) { + auto SpecUnit = U->getUnitSection().getUnitForOffset(*SpecRef); if (SpecUnit) - return SpecUnit->getDIEForOffset(SpecRef); + return SpecUnit->getDIEForOffset(*SpecRef); } return DWARFDie(); } -uint64_t -DWARFDie::getRangesBaseAttribute(uint64_t FailValue) const { - auto Result = getAttributeValueAsSectionOffset(DW_AT_rnglists_base, -1ULL); - if (Result != -1ULL) +Optional +DWARFDie::getRangesBaseAttribute() const { + auto Result = getAttributeValueAsSectionOffset(DW_AT_rnglists_base); + if (Result) return Result; - return getAttributeValueAsSectionOffset(DW_AT_GNU_ranges_base, FailValue); + return getAttributeValueAsSectionOffset(DW_AT_GNU_ranges_base); } bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC) const { - LowPC = getAttributeValueAsAddress(DW_AT_low_pc, -1ULL); - if (LowPC == -1ULL) + if (auto LowPCVal = getAttributeValueAsAddress(DW_AT_low_pc)) + LowPC = *LowPCVal; + else return false; - HighPC = getAttributeValueAsAddress(DW_AT_high_pc, -1ULL); - if (HighPC == -1ULL) { - // Since DWARF4, DW_AT_high_pc may also be of class constant, in which case - // it represents function size. - HighPC = getAttributeValueAsUnsignedConstant(DW_AT_high_pc, -1ULL); - if (HighPC != -1ULL) - HighPC += LowPC; - } - return (HighPC != -1ULL); + + if (auto HighPCVal = getAttributeValueAsAddress(DW_AT_high_pc)) + HighPC = *HighPCVal; // High PC is an address. + else if (auto Offset = getAttributeValueAsUnsignedConstant(DW_AT_high_pc)) + HighPC = LowPC + *Offset; // High PC is an offset from LowPC. + else + return false; + return true; } DWARFAddressRangesVector @@ -242,10 +270,10 @@ return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC)); } // Multiple ranges from .debug_ranges section. - uint32_t RangesOffset = getAttributeValueAsSectionOffset(DW_AT_ranges, -1U); - if (RangesOffset != -1U) { + auto RangesOffset = getAttributeValueAsSectionOffset(DW_AT_ranges); + if (RangesOffset) { DWARFDebugRangeList RangeList; - if (U->extractRangeList(RangesOffset, RangeList)) + if (U->extractRangeList(*RangesOffset, RangeList)) return RangeList.getAbsoluteRanges(U->getBaseAddress()); } return DWARFAddressRangesVector(); Index: lib/DebugInfo/DWARF/DWARFUnit.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFUnit.cpp +++ lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -154,9 +154,8 @@ return getUnitDIE().getAttributeValueAsString(DW_AT_comp_dir, nullptr); } -uint64_t DWARFUnit::getDWOId() { - return getUnitDIE().getAttributeValueAsUnsignedConstant(DW_AT_GNU_dwo_id, - -1ULL); +Optional DWARFUnit::getDWOId() { + return getUnitDIE().getAttributeValueAsUnsignedConstant(DW_AT_GNU_dwo_id); } void DWARFUnit::setDIERelations() { @@ -254,10 +253,11 @@ // If CU DIE was just parsed, copy several attribute values from it. if (!HasCUDie) { DWARFDie UnitDie = getUnitDIE(); - uint64_t BaseAddr = UnitDie.getAttributeValueAsAddress(DW_AT_low_pc, -1ULL); - if (BaseAddr == -1ULL) - BaseAddr = UnitDie.getAttributeValueAsAddress(DW_AT_entry_pc, 0); - setBaseAddress(BaseAddr); + auto BaseAddr = UnitDie.getAttributeValueAsAddress(DW_AT_low_pc); + if (!BaseAddr) + BaseAddr = UnitDie.getAttributeValueAsAddress(DW_AT_entry_pc); + if (BaseAddr) + setBaseAddress(*BaseAddr); AddrOffsetSectionBase = UnitDie.getAttributeValueAsSectionOffset( DW_AT_GNU_addr_base, 0); RangeSectionBase = UnitDie.getAttributeValueAsSectionOffset( @@ -313,8 +313,8 @@ } // Share .debug_addr and .debug_ranges section with compile unit in .dwo DWOCU->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase); - uint32_t DWORangesBase = UnitDie.getRangesBaseAttribute(0); - DWOCU->setRangesSection(RangeSection, DWORangesBase); + auto DWORangesBase = UnitDie.getRangesBaseAttribute(); + DWOCU->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0); return true; } Index: tools/dsymutil/DwarfLinker.cpp =================================================================== --- tools/dsymutil/DwarfLinker.cpp +++ tools/dsymutil/DwarfLinker.cpp @@ -841,10 +841,9 @@ DWARFUnit &OrigUnit = Unit.getOrigUnit(); auto OrigUnitDie = OrigUnit.getUnitDIE(false); int64_t UnitPcOffset = 0; - uint64_t OrigLowPc = OrigUnitDie.getAttributeValueAsAddress( - dwarf::DW_AT_low_pc, -1ULL); - if (OrigLowPc != -1ULL) - UnitPcOffset = int64_t(OrigLowPc) - Unit.getLowPc(); + auto OrigLowPc = OrigUnitDie.getAttributeValueAsAddress(dwarf::DW_AT_low_pc); + if (OrigLowPc) + UnitPcOffset = int64_t(*OrigLowPc) - Unit.getLowPc(); for (const auto &Attr : Attributes) { uint32_t Offset = Attr.first.get(); @@ -2124,10 +2123,9 @@ std::tie(LowPcOffset, LowPcEndOffset) = getAttributeOffsets(Abbrev, *LowPcIdx, Offset, OrigUnit); - uint64_t LowPc = - DIE.getAttributeValueAsAddress(dwarf::DW_AT_low_pc, -1ULL); - assert(LowPc != -1ULL && "low_pc attribute is not an address."); - if (LowPc == -1ULL || + auto LowPc = DIE.getAttributeValueAsAddress(dwarf::DW_AT_low_pc); + assert(LowPc.hasValue() && "low_pc attribute is not an address."); + if (!LowPc || !RelocMgr.hasValidRelocation(LowPcOffset, LowPcEndOffset, MyInfo)) return Flags; @@ -2148,12 +2146,12 @@ HighPc = *HighPcValue->getAsAddress(); } else { assert(HighPcValue->isFormClass(DWARFFormValue::FC_Constant)); - HighPc = LowPc + *HighPcValue->getAsUnsignedConstant(); + HighPc = *LowPc + *HighPcValue->getAsUnsignedConstant(); } // Replace the debug map range with a more accurate one. - Ranges[LowPc] = std::make_pair(HighPc, MyInfo.AddrAdjust); - Unit.addFunctionRange(LowPc, HighPc, MyInfo.AddrAdjust); + Ranges[*LowPc] = std::make_pair(HighPc, MyInfo.AddrAdjust); + Unit.addFunctionRange(*LowPc, HighPc, MyInfo.AddrAdjust); return Flags; } @@ -2974,9 +2972,8 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit, DWARFContext &OrigDwarf) { DWARFDie CUDie = Unit.getOrigUnit().getUnitDIE(); - uint64_t StmtList = CUDie.getAttributeValueAsSectionOffset( - dwarf::DW_AT_stmt_list, -1ULL); - if (StmtList == -1ULL) + auto StmtList = CUDie.getAttributeValueAsSectionOffset(dwarf::DW_AT_stmt_list); + if (!StmtList) return; // Update the cloned DW_AT_stmt_list with the correct debug_line offset. @@ -2985,7 +2982,7 @@ // Parse the original line info for the unit. DWARFDebugLine::LineTable LineTable; - uint32_t StmtOffset = StmtList; + uint32_t StmtOffset = *StmtList; StringRef LineData = OrigDwarf.getLineSection().Data; DataExtractor LineExtractor(LineData, OrigDwarf.isLittleEndian(), Unit.getOrigUnit().getAddressByteSize()); @@ -3079,7 +3076,7 @@ } // Finished extracting, now emit the line tables. - uint32_t PrologueEnd = StmtList + 10 + LineTable.Prologue.PrologueLength; + uint32_t PrologueEnd = *StmtList + 10 + LineTable.Prologue.PrologueLength; // FIXME: LLVM hardcodes it's prologue values. We just copy the // prologue over and that works because we act as both producer and // consumer. It would be nicer to have a real configurable line @@ -3094,7 +3091,7 @@ Params.DWARF2LineBase = LineTable.Prologue.LineBase; Params.DWARF2LineRange = LineTable.Prologue.LineRange; Streamer->emitLineTableForUnit(Params, - LineData.slice(StmtList + 4, PrologueEnd), + LineData.slice(*StmtList + 4, PrologueEnd), LineTable.Prologue.MinInstLength, NewRows, Unit.getOrigUnit().getAddressByteSize()); } @@ -3207,12 +3204,13 @@ static uint64_t getDwoId(const DWARFDie &CUDie, const DWARFUnit &Unit) { - uint64_t DwoId = - CUDie.getAttributeValueAsUnsignedConstant(dwarf::DW_AT_dwo_id, 0); - if (!DwoId) - DwoId = CUDie.getAttributeValueAsUnsignedConstant(dwarf::DW_AT_GNU_dwo_id, - 0); - return DwoId; + auto DwoId = CUDie.getAttributeValueAsUnsignedConstant(dwarf::DW_AT_dwo_id); + if (DwoId) + return *DwoId; + DwoId = CUDie.getAttributeValueAsUnsignedConstant(dwarf::DW_AT_GNU_dwo_id); + if (DwoId) + return *DwoId; + return 0; } bool DwarfLinker::registerModuleReference(