Index: include/llvm/DebugInfo/DWARF/DWARFContext.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFContext.h +++ include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -21,18 +21,12 @@ #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h" +#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/DebugInfo/DWARF/DWARFSection.h" #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h" namespace llvm { -// In place of applying the relocations to the data we've read from disk we use -// a separate mapping table to the side and checking that at locations in the -// dwarf where we expect relocated values. This adds a bit of complexity to the -// dwarf parsing/extraction at the benefit of not allocating memory for the -// entire size of the debug info sections. -typedef DenseMap > RelocAddrMap; - /// DWARFContext /// This data structure is the top level entity that deals with dwarf debug /// information parsing. The actual data is supplied through pure virtual Index: include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h @@ -93,7 +93,8 @@ const char *FailValue) const; uint64_t getAttributeValueAsAddress(const DWARFUnit *U, const uint16_t Attr, - uint64_t FailValue) const; + uint64_t FailValue, + uint64_t *SecNdx = nullptr) const; uint64_t getAttributeValueAsUnsignedConstant(const DWARFUnit *U, const uint16_t Attr, @@ -110,8 +111,8 @@ /// Retrieves DW_AT_low_pc and DW_AT_high_pc from CU. /// Returns true if both attributes are present. - bool getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC, - uint64_t &HighPC) const; + bool getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC, uint64_t &HighPC, + uint64_t &SecNdx) const; DWARFAddressRangesVector getAddressRanges(const DWARFUnit *U) const; Index: include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -17,8 +17,13 @@ class raw_ostream; +struct DWARFAddress { + uint64_t LowPC; + uint64_t HighPC; + uint64_t SecNdx; +}; /// DWARFAddressRangesVector - represents a set of absolute address ranges. -typedef std::vector> DWARFAddressRangesVector; +typedef std::vector DWARFAddressRangesVector; class DWARFDebugRangeList { public: Index: include/llvm/DebugInfo/DWARF/DWARFFormValue.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -36,9 +36,7 @@ private: struct ValueType { - ValueType() : data(nullptr) { - uval = 0; - } + ValueType() : data(nullptr), SecNdx((uint64_t)-1) { uval = 0; } union { uint64_t uval; @@ -46,6 +44,8 @@ const char* cstr; }; const uint8_t* data; + + uint64_t SecNdx; // Section index for reference forms. }; uint16_t Form; // Form for this value. @@ -76,7 +76,8 @@ Optional getAsUnsignedConstant() const; Optional getAsSignedConstant() const; Optional getAsCString(const DWARFUnit *U) const; - Optional getAsAddress(const DWARFUnit *U) const; + Optional getAsAddress(const DWARFUnit *U, + uint64_t *SecNdx = nullptr) const; Optional getAsSectionOffset() const; Optional> getAsBlock() const; Index: include/llvm/DebugInfo/DWARF/DWARFRelocMap.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFRelocMap.h +++ include/llvm/DebugInfo/DWARF/DWARFRelocMap.h @@ -14,9 +14,18 @@ namespace llvm { -typedef DenseMap > RelocAddrMap; +struct RelocAddrEntry { + uint64_t SecNdx; + int64_t Value; +}; + +// In place of applying the relocations to the data we've read from disk we use +// a separate mapping table to the side and checking that at locations in the +// dwarf where we expect relocated values. This adds a bit of complexity to the +// dwarf parsing/extraction at the benefit of not allocating memory for the +// entire size of the debug info sections. +typedef DenseMap RelocAddrMap; } // namespace llvm #endif - Index: include/llvm/Object/COFF.h =================================================================== --- include/llvm/Object/COFF.h +++ include/llvm/Object/COFF.h @@ -724,6 +724,7 @@ std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override; uint64_t getSectionAddress(DataRefImpl Sec) const override; + uint64_t getSectionIndex(DataRefImpl Sec) const override; uint64_t getSectionSize(DataRefImpl Sec) const override; std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override; Index: include/llvm/Object/ELFObjectFile.h =================================================================== --- include/llvm/Object/ELFObjectFile.h +++ include/llvm/Object/ELFObjectFile.h @@ -223,6 +223,7 @@ std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override; uint64_t getSectionAddress(DataRefImpl Sec) const override; + uint64_t getSectionIndex(DataRefImpl Sec) const override; uint64_t getSectionSize(DataRefImpl Sec) const override; std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override; @@ -576,6 +577,11 @@ } template +uint64_t ELFObjectFile::getSectionIndex(DataRefImpl Sec) const { + return getSection(Sec) - EF.section_begin(); +} + +template uint64_t ELFObjectFile::getSectionSize(DataRefImpl Sec) const { return getSection(Sec)->sh_size; } Index: include/llvm/Object/MachO.h =================================================================== --- include/llvm/Object/MachO.h +++ include/llvm/Object/MachO.h @@ -218,6 +218,7 @@ std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const override; uint64_t getSectionAddress(DataRefImpl Sec) const override; + uint64_t getSectionIndex(DataRefImpl Sec) const override; uint64_t getSectionSize(DataRefImpl Sec) const override; std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const override; Index: include/llvm/Object/ObjectFile.h =================================================================== --- include/llvm/Object/ObjectFile.h +++ include/llvm/Object/ObjectFile.h @@ -84,6 +84,7 @@ std::error_code getName(StringRef &Result) const; uint64_t getAddress() const; + uint64_t getIndex() const; uint64_t getSize() const; std::error_code getContents(StringRef &Result) const; @@ -212,6 +213,7 @@ virtual std::error_code getSectionName(DataRefImpl Sec, StringRef &Res) const = 0; virtual uint64_t getSectionAddress(DataRefImpl Sec) const = 0; + virtual uint64_t getSectionIndex(DataRefImpl Sec) const = 0; virtual uint64_t getSectionSize(DataRefImpl Sec) const = 0; virtual std::error_code getSectionContents(DataRefImpl Sec, StringRef &Res) const = 0; @@ -372,6 +374,10 @@ return OwningObject->getSectionAddress(SectionPimpl); } +inline uint64_t SectionRef::getIndex() const { + return OwningObject->getSectionIndex(SectionPimpl); +} + inline uint64_t SectionRef::getSize() const { return OwningObject->getSectionSize(SectionPimpl); } Index: lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp +++ lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp @@ -108,7 +108,7 @@ unsigned StringOffset = AccelSection.getU32(&DataOffset); RelocAddrMap::const_iterator Reloc = Relocs.find(DataOffset-4); if (Reloc != Relocs.end()) - StringOffset += Reloc->second.second; + StringOffset += Reloc->second.Value; if (!StringOffset) break; OS << format(" Name: %08x \"%s\"\n", StringOffset, Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -895,7 +895,9 @@ << " at " << format("%p", Address) << " with width " << format("%d", R.Width) << "\n"); - Map->insert(std::make_pair(Address, std::make_pair(R.Width, R.Value))); + + llvm::RelocAddrEntry Rel = {RSec->getIndex(), R.Value}; + Map->insert(std::make_pair(Address, Rel)); } } } Index: lib/DebugInfo/DWARF/DWARFDebugAranges.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugAranges.cpp +++ lib/DebugInfo/DWARF/DWARFDebugAranges.cpp @@ -53,7 +53,7 @@ DWARFAddressRangesVector CURanges; CU->collectAddressRanges(CURanges); for (const auto &R : CURanges) { - appendRange(CUOffset, R.first, R.second); + appendRange(CUOffset, R.LowPC, R.HighPC); } } } Index: lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp +++ lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp @@ -104,8 +104,8 @@ OS << '\n'; OS.indent(Indent); OS << format("[0x%0*" PRIx64 " - 0x%0*" PRIx64 ")", - AddressSize*2, Range.first, - AddressSize*2, Range.second); + AddressSize*2, Range.LowPC, + AddressSize*2, Range.HighPC); } } @@ -267,11 +267,12 @@ } uint64_t DWARFDebugInfoEntryMinimal::getAttributeValueAsAddress( - const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue) const { + const DWARFUnit *U, const uint16_t Attr, uint64_t FailValue, + uint64_t *SecNdx) const { DWARFFormValue FormValue; if (!getAttributeValue(U, Attr, FormValue)) return FailValue; - Optional Result = FormValue.getAsAddress(U); + Optional Result = FormValue.getAsAddress(U, SecNdx); return Result.hasValue() ? Result.getValue() : FailValue; } @@ -314,8 +315,9 @@ bool DWARFDebugInfoEntryMinimal::getLowAndHighPC(const DWARFUnit *U, uint64_t &LowPC, - uint64_t &HighPC) const { - LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL); + uint64_t &HighPC, + uint64_t &SecNdx) const { + LowPC = getAttributeValueAsAddress(U, DW_AT_low_pc, -1ULL, &SecNdx); if (LowPC == -1ULL) return false; HighPC = getAttributeValueAsAddress(U, DW_AT_high_pc, -1ULL); @@ -334,10 +336,10 @@ if (isNULL()) return DWARFAddressRangesVector(); // Single range specified by low/high PC. - uint64_t LowPC, HighPC; - if (getLowAndHighPC(U, LowPC, HighPC)) { - return DWARFAddressRangesVector(1, std::make_pair(LowPC, HighPC)); - } + uint64_t LowPC, HighPC, SecNdx; + if (getLowAndHighPC(U, LowPC, HighPC, SecNdx)) + return DWARFAddressRangesVector(1, {LowPC, HighPC, SecNdx}); + // Multiple ranges from .debug_ranges section. uint32_t RangesOffset = getAttributeValueAsSectionOffset(U, DW_AT_ranges, -1U); @@ -368,7 +370,7 @@ bool DWARFDebugInfoEntryMinimal::addressRangeContainsAddress( const DWARFUnit *U, const uint64_t Address) const { for (const auto& R : getAddressRanges(U)) { - if (R.first <= Address && Address < R.second) + if (R.LowPC <= Address && Address < R.HighPC) return true; } return false; Index: lib/DebugInfo/DWARF/DWARFDebugLine.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -297,9 +297,9 @@ // If this address is in our relocation map, apply the relocation. RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr); if (AI != RMap->end()) { - const std::pair &R = AI->second; + const RelocAddrEntry &R = AI->second; State.Row.Address = - debug_line_data.getAddress(offset_ptr) + R.second; + debug_line_data.getAddress(offset_ptr) + R.Value; } else State.Row.Address = debug_line_data.getAddress(offset_ptr); } Index: lib/DebugInfo/DWARF/DWARFDebugLoc.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -48,13 +48,13 @@ // 1. A beginning address offset. ... E.Begin = data.getUnsigned(&Offset, AddressSize); if (AI != RelocMap.end()) - E.Begin += AI->second.second; + E.Begin += AI->second.Value; AI = RelocMap.find(Offset); // 2. An ending address offset. ... E.End = data.getUnsigned(&Offset, AddressSize); if (AI != RelocMap.end()) - E.End += AI->second.second; + E.End += AI->second.Value; // The end of any given location list is marked by an end of list entry, // which consists of a 0 for the beginning address offset and a 0 for the Index: lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp +++ lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp @@ -61,8 +61,8 @@ if (RLE.isBaseAddressSelectionEntry(AddressSize)) { BaseAddress = RLE.EndAddress; } else { - Res.push_back(std::make_pair(BaseAddress + RLE.StartAddress, - BaseAddress + RLE.EndAddress)); + Res.push_back({BaseAddress + RLE.StartAddress, + BaseAddress + RLE.EndAddress, (uint64_t)-1}); } } return Res; Index: lib/DebugInfo/DWARF/DWARFFormValue.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -151,8 +151,9 @@ : getRefAddrSize(cu->getAddressByteSize(), cu->getVersion()); RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr); if (AI != cu->getRelocMap()->end()) { - const std::pair &R = AI->second; - Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.second; + const RelocAddrEntry &R = AI->second; + Value.SecNdx = R.SecNdx; + Value.uval = data.getUnsigned(offset_ptr, AddrSize) + R.Value; } else Value.uval = data.getUnsigned(offset_ptr, AddrSize); break; @@ -190,7 +191,7 @@ break; RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr-4); if (AI != cu->getRelocMap()->end()) - Value.uval += AI->second.second; + Value.uval += AI->second.Value; break; } case DW_FORM_data8: @@ -222,7 +223,7 @@ RelocAddrMap::const_iterator AI = cu->getRelocMap()->find(*offset_ptr - 4); if (AI != cu->getRelocMap()->end()) - Value.uval += AI->second.second; + Value.uval += AI->second.Value; break; } case DW_FORM_flag_present: @@ -523,7 +524,8 @@ return None; } -Optional DWARFFormValue::getAsAddress(const DWARFUnit *U) const { +Optional DWARFFormValue::getAsAddress(const DWARFUnit *U, + uint64_t *SecNdx) const { if (!isFormClass(FC_Address)) return None; if (Form == DW_FORM_GNU_addr_index) { @@ -533,6 +535,8 @@ return None; return Result; } + if (SecNdx) + *SecNdx = Value.SecNdx; return Value.uval; } Index: lib/Object/COFFObjectFile.cpp =================================================================== --- lib/Object/COFFObjectFile.cpp +++ lib/Object/COFFObjectFile.cpp @@ -274,6 +274,10 @@ return Result; } +uint64_t COFFObjectFile::getSectionIndex(DataRefImpl Sec) const { + return (uint64_t)-1; +} + uint64_t COFFObjectFile::getSectionSize(DataRefImpl Ref) const { return getSectionSize(toSec(Ref)); } Index: lib/Object/MachOObjectFile.cpp =================================================================== --- lib/Object/MachOObjectFile.cpp +++ lib/Object/MachOObjectFile.cpp @@ -1450,6 +1450,10 @@ return getSection(Sec).addr; } +uint64_t MachOObjectFile::getSectionIndex(DataRefImpl Sec) const { + return (uint64_t)-1; +} + uint64_t MachOObjectFile::getSectionSize(DataRefImpl Sec) const { // In the case if a malformed Mach-O file where the section offset is past // the end of the file or some part of the section size is past the end of