diff options
-rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h | 3 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h | 8 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h | 5 | ||||
-rw-r--r-- | llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h | 11 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DIE.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 16 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp | 28 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp | 23 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/debug_addr.ll | 3 | ||||
-rw-r--r-- | llvm/test/DebugInfo/X86/fission-ranges.ll | 1 |
17 files changed, 78 insertions, 48 deletions
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h index ce7436d9faa..bc26edf0064 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -18,7 +18,6 @@ namespace llvm { -struct BaseAddress; class raw_ostream; class DWARFDebugRangeList { @@ -78,7 +77,7 @@ public: /// list. Has to be passed base address of the compile unit referencing this /// range list. DWARFAddressRangesVector - getAbsoluteRanges(llvm::Optional<BaseAddress> BaseAddr) const; + getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr) const; }; } // end namespace llvm diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h index e2e8ab5ed21..0615bbf0308 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h @@ -44,7 +44,7 @@ class DWARFDebugRnglist : public DWARFListType<RangeListEntry> { public: /// Build a DWARFAddressRangesVector from a rangelist. DWARFAddressRangesVector - getAbsoluteRanges(llvm::Optional<BaseAddress> BaseAddr) const; + getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr) const; }; class DWARFDebugRnglistTable : public DWARFListTableBase<DWARFDebugRnglist> { diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index 1b5f71c946f..edf9442acd0 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -101,6 +101,7 @@ public: Optional<int64_t> getAsSignedConstant() const; Optional<const char *> getAsCString() const; Optional<uint64_t> getAsAddress() const; + Optional<SectionedAddress> getAsSectionedAddress() const; Optional<uint64_t> getAsSectionOffset() const; Optional<ArrayRef<uint8_t>> getAsBlock() const; Optional<uint64_t> getAsCStringOffset() const; @@ -238,6 +239,13 @@ inline Optional<uint64_t> toAddress(const Optional<DWARFFormValue> &V) { return None; } +inline Optional<SectionedAddress> +toSectionedAddress(const Optional<DWARFFormValue> &V) { + if (V) + return V->getAsSectionedAddress(); + return None; +} + /// Take an optional DWARFFormValue and extract a address. /// /// \param V and optional DWARFFormValue to attempt to extract the value from. diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h index 77045f0794a..7f823596529 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFSection.h @@ -23,6 +23,11 @@ struct SectionName { bool IsNameUnique; }; +struct SectionedAddress { + uint64_t Address; + uint64_t SectionIndex; +}; + } // end namespace llvm #endif // LLVM_DEBUGINFO_DWARF_DWARFSECTION_H diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h index c267cf173d1..ae0e8cc8db1 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -160,11 +160,6 @@ private: }; /// Represents base address of the CU. -struct BaseAddress { - uint64_t Address; - uint64_t SectionIndex; -}; - /// Represents a unit's contribution to the string offsets table. struct StrOffsetsContributionDescriptor { uint64_t Base = 0; @@ -221,7 +216,7 @@ class DWARFUnit { Optional<DWARFDebugRnglistTable> RngListTable; mutable const DWARFAbbreviationDeclarationSet *Abbrevs; - llvm::Optional<BaseAddress> BaseAddr; + llvm::Optional<SectionedAddress> BaseAddr; /// The compile unit debug information entry items. std::vector<DWARFDebugInfoEntry> DieArray; @@ -310,7 +305,7 @@ public: RangeSectionBase = Base; } - bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const; + Optional<SectionedAddress> getAddrOffsetSectionItem(uint32_t Index) const; bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const; DWARFDataExtractor getDebugInfoExtractor() const; @@ -381,7 +376,7 @@ public: llvm_unreachable("Invalid UnitType."); } - llvm::Optional<BaseAddress> getBaseAddress(); + llvm::Optional<SectionedAddress> getBaseAddress(); DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) { extractDIEsIfNeeded(ExtractUnitDIEOnly); diff --git a/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp b/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp index c21616766fa..f8143b903d5 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AddressPool.cpp @@ -39,6 +39,9 @@ void AddressPool::emitHeader(AsmPrinter &Asm, MCSection *Section) { // Emit addresses into the section given. void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) { + if (isEmpty()) + return; + // Start the dwarf addr section. Asm.OutStreamer->SwitchSection(AddrSection); @@ -49,9 +52,6 @@ void AddressPool::emit(AsmPrinter &Asm, MCSection *AddrSection) { // It is referenced via DW_AT_addr_base. Asm.OutStreamer->EmitLabel(AddressTableBaseSym); - if (Pool.empty()) - return; - // Order the address pool entries by ID SmallVector<const MCExpr *, 64> Entries(Pool.size()); diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp index 570424a79c8..6ffb6123509 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -414,6 +414,7 @@ void DIEInteger::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const { case dwarf::DW_FORM_GNU_addr_index: case dwarf::DW_FORM_ref_udata: case dwarf::DW_FORM_strx: + case dwarf::DW_FORM_addrx: case dwarf::DW_FORM_udata: Asm->EmitULEB128(Integer); return; @@ -440,6 +441,7 @@ unsigned DIEInteger::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { case dwarf::DW_FORM_GNU_addr_index: case dwarf::DW_FORM_ref_udata: case dwarf::DW_FORM_strx: + case dwarf::DW_FORM_addrx: case dwarf::DW_FORM_udata: return getULEB128Size(Integer); case dwarf::DW_FORM_sdata: diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 443c8879f13..5731541e595 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -69,14 +69,16 @@ void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute, // pool from the skeleton - maybe even in non-fission (possibly fewer // relocations by sharing them in the pool, but we have other ideas about how // to reduce the number of relocations as well/instead). - if (!DD->useSplitDwarf() || !Skeleton) + if ((!DD->useSplitDwarf() || !Skeleton) && DD->getDwarfVersion() < 5) return addLocalLabelAddress(Die, Attribute, Label); if (Label) DD->addArangeLabel(SymbolCU(this, Label)); unsigned idx = DD->getAddressPool().getIndex(Label); - Die.addValue(DIEValueAllocator, Attribute, dwarf::DW_FORM_GNU_addr_index, + Die.addValue(DIEValueAllocator, Attribute, + DD->getDwarfVersion() >= 5 ? dwarf::DW_FORM_addrx + : dwarf::DW_FORM_GNU_addr_index, DIEInteger(idx)); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 94e12658cfe..e16ca4c4608 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -851,10 +851,6 @@ void DwarfDebug::finalizeModuleInfo() { SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id, dwarf::DW_FORM_data8, ID); } - // We don't keep track of which addresses are used in which CU so this - // is a bit pessimistic under LTO. - if (!AddrPool.isEmpty()) - SkCU->addAddrTableBase(); if (getDwarfVersion() < 5 && !SkCU->getRangeLists().empty()) { const MCSymbol *Sym = TLOF.getDwarfRangesSection()->getBeginSymbol(); @@ -870,6 +866,12 @@ void DwarfDebug::finalizeModuleInfo() { // .subsections_via_symbols in mach-o. This would mean turning on // ranges for all subprogram DIEs for mach-o. DwarfCompileUnit &U = SkCU ? *SkCU : TheCU; + + // We don't keep track of which addresses are used in which CU so this + // is a bit pessimistic under LTO. + if (!AddrPool.isEmpty()) + U.addAddrTableBase(); + if (unsigned NumRanges = TheCU.getRanges().size()) { if (NumRanges > 1 && useRangesSection()) // A DW_AT_low_pc attribute may also be specified in combination with @@ -948,9 +950,10 @@ void DwarfDebug::endModule() { emitDebugInfoDWO(); emitDebugAbbrevDWO(); emitDebugLineDWO(); - emitDebugAddr(); } + emitDebugAddr(); + // Emit info into the dwarf accelerator table sections. switch (getAccelTableKind()) { case AccelTableKind::Apple: @@ -2439,9 +2442,8 @@ void DwarfDebug::emitDebugStrDWO() { OffSec, /* UseRelativeOffsets = */ false); } -// Emit DWO addresses. +// Emit address pool. void DwarfDebug::emitDebugAddr() { - assert(useSplitDwarf() && "No split dwarf?"); AddrPool.emit(*Asm, Asm->getObjFileLowering().getDwarfAddrSection()); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 14e59c3df27..8a168f4845d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1652,6 +1652,8 @@ void DwarfUnit::addRnglistsBase() { void DwarfUnit::addAddrTableBase() { const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); MCSymbol *Label = DD->getAddressPool().getLabel(); - addSectionLabel(getUnitDie(), dwarf::DW_AT_GNU_addr_base, Label, - TLOF.getDwarfAddrSection()->getBeginSymbol()); + addSectionLabel(getUnitDie(), + getDwarfVersion() >= 5 ? dwarf::DW_AT_addr_base + : dwarf::DW_AT_GNU_addr_base, + Label, TLOF.getDwarfAddrSection()->getBeginSymbol()); } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp index 84e3c634f54..dfb913000a4 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp @@ -69,7 +69,7 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const { } DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges( - llvm::Optional<BaseAddress> BaseAddr) const { + llvm::Optional<SectionedAddress> BaseAddr) const { DWARFAddressRangesVector Res; for (const RangeListEntry &RLE : Entries) { if (RLE.isBaseAddressSelectionEntry(AddressSize)) { diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp index eeb85edf5b2..72f84159957 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp @@ -101,7 +101,7 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End, } DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges( - llvm::Optional<BaseAddress> BaseAddr) const { + llvm::Optional<SectionedAddress> BaseAddr) const { DWARFAddressRangesVector Res; for (const RangeListEntry &RLE : Entries) { if (RLE.EntryKind == dwarf::DW_RLE_end_of_list) diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index 6b69b822aad..b4413653290 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -109,7 +109,7 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, auto LL = DebugLoc.parseOneLocationList(Data, &Offset); if (LL) { uint64_t BaseAddr = 0; - if (Optional<BaseAddress> BA = U->getBaseAddress()) + if (Optional<SectionedAddress> BA = U->getBaseAddress()) BaseAddr = BA->Address; LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, BaseAddr, Indent); diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp index 27895da8058..ed510a0e4cd 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -308,6 +308,7 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, break; case DW_FORM_GNU_addr_index: case DW_FORM_GNU_str_index: + case DW_FORM_addrx: case DW_FORM_strx: Value.uval = Data.getULEB128(OffsetPtr); break; @@ -340,13 +341,17 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { case DW_FORM_addr: AddrOS << format("0x%016" PRIx64, UValue); break; + case DW_FORM_addrx: + case DW_FORM_addrx1: + case DW_FORM_addrx2: + case DW_FORM_addrx3: + case DW_FORM_addrx4: case DW_FORM_GNU_addr_index: { AddrOS << format(" indexed (%8.8x) address = ", (uint32_t)UValue); - uint64_t Address; if (U == nullptr) OS << "<invalid dwarf unit>"; - else if (U->getAddrOffsetSectionItem(UValue, Address)) - AddrOS << format("0x%016" PRIx64, Address); + else if (Optional<SectionedAddress> A = U->getAddrOffsetSectionItem(UValue)) + AddrOS << format("0x%016" PRIx64, A->Address); else OS << "<no .debug_addr section>"; break; @@ -555,16 +560,23 @@ Optional<const char *> DWARFFormValue::getAsCString() const { } Optional<uint64_t> DWARFFormValue::getAsAddress() const { + if (auto SA = getAsSectionedAddress()) + return SA->Address; + return None; +} +Optional<SectionedAddress> DWARFFormValue::getAsSectionedAddress() const { if (!isFormClass(FC_Address)) return None; - if (Form == DW_FORM_GNU_addr_index) { + if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx) { uint32_t Index = Value.uval; - uint64_t Result; - if (!U || !U->getAddrOffsetSectionItem(Index, Result)) + if (!U) + return None; + Optional<SectionedAddress> SA = U->getAddrOffsetSectionItem(Index); + if (!SA) return None; - return Result; + return SA; } - return Value.uval; + return {{Value.uval, Value.SectionIndex}}; } Optional<uint64_t> DWARFFormValue::getAsReference() const { diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp index dbac5a82b57..081163ba61f 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -195,15 +195,16 @@ DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const { getAddressByteSize()); } -bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index, - uint64_t &Result) const { +Optional<SectionedAddress> +DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const { uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize(); if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize()) - return false; + return None; DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection, isLittleEndian, getAddressByteSize()); - Result = DA.getRelocatedAddress(&Offset); - return true; + uint64_t Section; + uint64_t Address = DA.getRelocatedAddress(&Offset, &Section); + return {{Address, Section}}; } bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index, @@ -401,8 +402,10 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) { if (!isDWO) { assert(AddrOffsetSectionBase == 0); assert(RangeSectionBase == 0); - AddrOffsetSectionBase = - toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0); + AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base), 0); + if (!AddrOffsetSectionBase) + AddrOffsetSectionBase = + toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0); RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0); } @@ -760,15 +763,13 @@ const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const { return Abbrevs; } -llvm::Optional<BaseAddress> DWARFUnit::getBaseAddress() { +llvm::Optional<SectionedAddress> DWARFUnit::getBaseAddress() { if (BaseAddr) return BaseAddr; DWARFDie UnitDie = getUnitDIE(); Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc}); - if (Optional<uint64_t> Addr = toAddress(PC)) - BaseAddr = {*Addr, PC->getSectionIndex()}; - + BaseAddr = toSectionedAddress(PC); return BaseAddr; } diff --git a/llvm/test/DebugInfo/X86/debug_addr.ll b/llvm/test/DebugInfo/X86/debug_addr.ll index ea7c8bda7bc..b50428a282c 100644 --- a/llvm/test/DebugInfo/X86/debug_addr.ll +++ b/llvm/test/DebugInfo/X86/debug_addr.ll @@ -31,7 +31,8 @@ ; DWARF5: DW_TAG_compile_unit ; DWARF5-NOT: DW_TAG_{{.*}} ; DWARF5: DW_AT_GNU_dwo_name{{.*}}test.dwo -; DWARF5: DW_AT_GNU_addr_base{{.*}}0x00000008 +; DWARF5: DW_AT_addr_base{{.*}}0x00000008 +; DWARF5: DW_AT_low_pc [DW_FORM_addrx] ( indexed (00000000) address = 0x0000000000000000) ; DWARF5: .debug_addr contents: ; DWARF5-NEXT: 0x00000000: Addr Section: length = 0x0000000c, version = 0x0005, addr_size = 0x04, seg_size = 0x00 ; DWARF5-NEXT: Addrs: [ diff --git a/llvm/test/DebugInfo/X86/fission-ranges.ll b/llvm/test/DebugInfo/X86/fission-ranges.ll index 3ea5aa2e350..e7402787dc3 100644 --- a/llvm/test/DebugInfo/X86/fission-ranges.ll +++ b/llvm/test/DebugInfo/X86/fission-ranges.ll @@ -11,6 +11,7 @@ ; CHECK-NEXT: DW_AT_GNU_dwo_name ; CHECK-NEXT: DW_AT_comp_dir ; CHECK-NEXT: DW_AT_GNU_dwo_id +; CHECK-NEXT: DW_AT_GNU_ranges_base ; CHECK-NEXT: DW_AT_GNU_addr_base [DW_FORM_sec_offset] (0x00000000) ; CHECK: .debug_info.dwo contents: |