Index: include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -18,6 +18,7 @@ namespace llvm { +struct BaseAddress; class raw_ostream; struct DWARFAddressRange { @@ -85,7 +86,8 @@ /// getAbsoluteRanges - Returns absolute address ranges defined by this range /// list. Has to be passed base address of the compile unit referencing this /// range list. - DWARFAddressRangesVector getAbsoluteRanges(uint64_t BaseAddress) const; + DWARFAddressRangesVector + getAbsoluteRanges(llvm::Optional BaseAddr) const; }; } // end namespace llvm Index: include/llvm/DebugInfo/DWARF/DWARFUnit.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -110,6 +110,11 @@ } }; +struct BaseAddress { + uint64_t Address; + uint64_t SectionIndex; +}; + class DWARFUnit { DWARFContext &Context; /// Section containing this DWARFUnit. @@ -135,7 +140,7 @@ uint32_t Length; const DWARFAbbreviationDeclarationSet *Abbrevs; uint8_t UnitType; - uint64_t BaseAddr; + llvm::Optional BaseAddr; /// The compile unit debug information entry items. std::vector DieArray; @@ -259,10 +264,12 @@ llvm_unreachable("Invalid UnitType."); } - uint64_t getBaseAddress() const { return BaseAddr; } + llvm::Optional getBaseAddress() const { return BaseAddr; } - void setBaseAddress(uint64_t base_addr) { - BaseAddr = base_addr; + void setBaseAddress(BaseAddress BaseAddr) { + if (!BaseAddr.Address && BaseAddr.SectionIndex == -1ULL) + return; + this->BaseAddr = BaseAddr; } DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) { Index: lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp +++ lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp @@ -63,16 +63,28 @@ OS << format("%08x \n", Offset); } -DWARFAddressRangesVector -DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const { +DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges( + llvm::Optional BaseAddr) const { DWARFAddressRangesVector Res; for (const RangeListEntry &RLE : Entries) { if (RLE.isBaseAddressSelectionEntry(AddressSize)) { - BaseAddress = RLE.EndAddress; - } else { - Res.push_back({BaseAddress + RLE.StartAddress, - BaseAddress + RLE.EndAddress, RLE.SectionIndex}); + BaseAddr = { RLE.EndAddress, RLE.SectionIndex }; + continue; } + + DWARFAddressRange E; + E.LowPC = RLE.StartAddress; + E.HighPC = RLE.EndAddress; + E.SectionIndex = RLE.SectionIndex; + // Base address of a range list entry is determined by the closest preceding + // base address selection entry in the same range list. It defaults to the + // base address of the compilation unit if there is no such entry. + if (BaseAddr) { + E.LowPC += BaseAddr->Address; + E.HighPC += BaseAddr->Address; + E.SectionIndex = BaseAddr->SectionIndex; + } + Res.push_back(E); } return Res; } Index: lib/DebugInfo/DWARF/DWARFFormValue.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -292,6 +292,7 @@ return false; uint16_t Size = (Form == DW_FORM_addr) ? U->getAddressByteSize() : U->getRefAddrByteSize(); + Value.SectionIndex = -1ULL; Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex); break; } Index: lib/DebugInfo/DWARF/DWARFUnit.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFUnit.cpp +++ lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -160,7 +160,7 @@ Length = 0; Abbrevs = nullptr; FormParams = DWARFFormParams({0, 0, DWARF32}); - BaseAddr = 0; + BaseAddr.reset(); RangeSectionBase = 0; AddrOffsetSectionBase = 0; clearDIEs(false); @@ -242,9 +242,10 @@ // If CU DIE was just parsed, copy several attribute values from it. if (!HasCUDie) { DWARFDie UnitDie = getUnitDIE(); - auto BaseAddr = toAddress(UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc})); - if (BaseAddr) - setBaseAddress(*BaseAddr); + if (Optional PC = + UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc})) + if (Optional Addr = PC->getAsAddress()) + setBaseAddress({*Addr, PC->getSectionIndex()}); if (!isDWO) { assert(AddrOffsetSectionBase == 0); assert(RangeSectionBase == 0);