Index: include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h +++ include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h @@ -18,9 +18,9 @@ class DWARFCompileUnit : public DWARFUnit { public: DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section, - const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, StringRef LS, bool LE, - bool IsDWO, const DWARFUnitSectionBase &UnitSection, + const DWARFDebugAbbrev *DA, const DWARFSection *RS, + StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, + bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *Entry) : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, UnitSection, Entry) {} Index: include/llvm/DebugInfo/DWARF/DWARFContext.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFContext.h +++ include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -216,7 +216,7 @@ virtual StringRef getEHFrameSection() = 0; virtual const DWARFSection &getLineSection() = 0; virtual StringRef getStringSection() = 0; - virtual StringRef getRangeSection() = 0; + virtual const DWARFSection& getRangeSection() = 0; virtual StringRef getMacinfoSection() = 0; virtual StringRef getPubNamesSection() = 0; virtual StringRef getPubTypesSection() = 0; @@ -231,7 +231,7 @@ virtual const DWARFSection &getLocDWOSection() = 0; virtual StringRef getStringDWOSection() = 0; virtual StringRef getStringOffsetDWOSection() = 0; - virtual StringRef getRangeDWOSection() = 0; + virtual const DWARFSection &getRangeDWOSection() = 0; virtual StringRef getAddrSection() = 0; virtual const DWARFSection& getAppleNamesSection() = 0; virtual const DWARFSection& getAppleTypesSection() = 0; @@ -271,7 +271,7 @@ StringRef EHFrameSection; DWARFSection LineSection; StringRef StringSection; - StringRef RangeSection; + DWARFSection RangeSection; StringRef MacinfoSection; StringRef PubNamesSection; StringRef PubTypesSection; @@ -286,7 +286,7 @@ DWARFSection LocDWOSection; StringRef StringDWOSection; StringRef StringOffsetDWOSection; - StringRef RangeDWOSection; + DWARFSection RangeDWOSection; StringRef AddrSection; DWARFSection AppleNamesSection; DWARFSection AppleTypesSection; @@ -319,7 +319,7 @@ StringRef getEHFrameSection() override { return EHFrameSection; } const DWARFSection &getLineSection() override { return LineSection; } StringRef getStringSection() override { return StringSection; } - StringRef getRangeSection() override { return RangeSection; } + const DWARFSection &getRangeSection() override { return RangeSection; } StringRef getMacinfoSection() override { return MacinfoSection; } StringRef getPubNamesSection() override { return PubNamesSection; } StringRef getPubTypesSection() override { return PubTypesSection; } @@ -346,7 +346,7 @@ return StringOffsetDWOSection; } - StringRef getRangeDWOSection() override { return RangeDWOSection; } + const DWARFSection &getRangeDWOSection() override { return RangeDWOSection; } StringRef getAddrSection() override { return AddrSection; Index: include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h @@ -11,6 +11,8 @@ #define LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H #include "llvm/Support/DataExtractor.h" +#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" + #include #include #include @@ -71,7 +73,7 @@ void clear(); void dump(raw_ostream &OS) const; - bool extract(DataExtractor data, uint32_t *offset_ptr); + bool extract(DataExtractor data, uint32_t *offset_ptr, const RelocAddrMap& Relocs); const std::vector &getEntries() { return Entries; } /// getAbsoluteRanges - Returns absolute address ranges defined by this range Index: include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h +++ include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h @@ -30,9 +30,9 @@ public: DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section, - const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO, - const DWARFUnitSectionBase &UnitSection, + const DWARFDebugAbbrev *DA, const DWARFSection *RS, + StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, + bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *Entry) : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, UnitSection, Entry) {} Index: include/llvm/DebugInfo/DWARF/DWARFUnit.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -55,9 +55,9 @@ ~DWARFUnitSectionBase() = default; virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section, - const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, StringRef LS, - bool isLittleEndian, bool isDWO) = 0; + const DWARFDebugAbbrev *DA, const DWARFSection *RS, + StringRef SS, StringRef SOS, StringRef AOS, + StringRef LS, bool isLittleEndian, bool isDWO) = 0; }; const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, @@ -87,9 +87,9 @@ private: void parseImpl(DWARFContext &Context, const DWARFSection &Section, - const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, StringRef LS, bool LE, - bool IsDWO) override { + const DWARFDebugAbbrev *DA, const DWARFSection *RS, + StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, + bool LE, bool IsDWO) override { if (Parsed) return; const auto &Index = getDWARFUnitIndex(Context, UnitType::Section); @@ -114,7 +114,7 @@ const DWARFSection &InfoSection; const DWARFDebugAbbrev *Abbrev; - StringRef RangeSection; + const DWARFSection *RangeSection; uint32_t RangeSectionBase; StringRef LineSection; StringRef StringSection; @@ -165,7 +165,7 @@ public: DWARFUnit(DWARFContext &Context, const DWARFSection &Section, - const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, + const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *IndexEntry = nullptr); @@ -183,7 +183,7 @@ AddrOffsetSectionBase = Base; } - void setRangesSection(StringRef RS, uint32_t Base) { + void setRangesSection(const DWARFSection *RS, uint32_t Base) { RangeSection = RS; RangeSectionBase = Base; } Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -212,11 +212,11 @@ // sizes, but for simplicity we just use the address byte size of the last // compile unit (there is no easy and fast way to associate address range // list and the compile unit it describes). - DataExtractor rangesData(getRangeSection(), isLittleEndian(), + DataExtractor rangesData(getRangeSection().Data, isLittleEndian(), savedAddressByteSize); offset = 0; DWARFDebugRangeList rangeList; - while (rangeList.extract(rangesData, &offset)) + while (rangeList.extract(rangesData, &offset, getRangeSection().Relocs)) rangeList.dump(OS); } @@ -720,7 +720,7 @@ *SectionData = data; if (name == "debug_ranges") { // FIXME: Use the other dwo range section when we emit it. - RangeDWOSection = data; + RangeDWOSection.Data = data; } } else if (name == "debug_types") { // Find debug_types data by section rather than name as there are @@ -761,6 +761,7 @@ .Case("debug_loc", &LocSection.Relocs) .Case("debug_info.dwo", &InfoDWOSection.Relocs) .Case("debug_line", &LineSection.Relocs) + .Case("debug_ranges", &RangeSection.Relocs) .Case("apple_names", &AppleNamesSection.Relocs) .Case("apple_types", &AppleTypesSection.Relocs) .Case("apple_namespaces", &AppleNamespacesSection.Relocs) @@ -843,7 +844,7 @@ .Case("debug_frame", &DebugFrameSection) .Case("eh_frame", &EHFrameSection) .Case("debug_str", &StringSection) - .Case("debug_ranges", &RangeSection) + .Case("debug_ranges", &RangeSection.Data) .Case("debug_macinfo", &MacinfoSection) .Case("debug_pubnames", &PubNamesSection) .Case("debug_pubtypes", &PubTypesSection) Index: lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp +++ lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp @@ -22,7 +22,16 @@ Entries.clear(); } -bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) { +static uint64_t getAddress(DataExtractor &Data, uint32_t *Off, + const RelocAddrMap &Relocs) { + RelocAddrMap::const_iterator AI = Relocs.find(*Off); + if (AI != Relocs.end()) + return Data.getAddress(Off) + AI->second.second; + return Data.getAddress(Off); +} + +bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr, + const RelocAddrMap &Relocs) { clear(); if (!data.isValidOffset(*offset_ptr)) return false; @@ -33,8 +42,8 @@ while (true) { RangeListEntry entry; uint32_t prev_offset = *offset_ptr; - entry.StartAddress = data.getAddress(offset_ptr); - entry.EndAddress = data.getAddress(offset_ptr); + entry.StartAddress = getAddress(data, offset_ptr, Relocs); + entry.EndAddress = getAddress(data, offset_ptr, Relocs); // Check that both values were extracted correctly. if (*offset_ptr != prev_offset + 2 * AddressSize) { clear(); Index: lib/DebugInfo/DWARF/DWARFUnit.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFUnit.cpp +++ lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -32,7 +32,7 @@ using namespace dwarf; void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) { - parseImpl(C, Section, C.getDebugAbbrev(), C.getRangeSection(), + parseImpl(C, Section, C.getDebugAbbrev(), &C.getRangeSection(), C.getStringSection(), StringRef(), C.getAddrSection(), C.getLineSection().Data, C.isLittleEndian(), false); } @@ -40,16 +40,17 @@ void DWARFUnitSectionBase::parseDWO(DWARFContext &C, const DWARFSection &DWOSection, DWARFUnitIndex *Index) { - parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), C.getRangeDWOSection(), + parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &C.getRangeDWOSection(), C.getStringDWOSection(), C.getStringOffsetDWOSection(), C.getAddrSection(), C.getLineDWOSection().Data, C.isLittleEndian(), true); } DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section, - const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, - StringRef SOS, StringRef AOS, StringRef LS, bool LE, - bool IsDWO, const DWARFUnitSectionBase &UnitSection, + const DWARFDebugAbbrev *DA, const DWARFSection *RS, + StringRef SS, StringRef SOS, StringRef AOS, StringRef LS, + bool LE, bool IsDWO, + const DWARFUnitSectionBase &UnitSection, const DWARFUnitIndex::Entry *IndexEntry) : Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS), LineSection(LS), StringSection(SS), StringOffsetSection([&]() { @@ -142,9 +143,10 @@ DWARFDebugRangeList &RangeList) const { // Require that compile unit is extracted. assert(!DieArray.empty()); - DataExtractor RangesData(RangeSection, isLittleEndian, AddrSize); + DataExtractor RangesData(RangeSection->Data, isLittleEndian, AddrSize); uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset; - return RangeList.extract(RangesData, &ActualRangeListOffset); + return RangeList.extract(RangesData, &ActualRangeListOffset, + RangeSection->Relocs); } void DWARFUnit::clear() { Index: test/DebugInfo/dwarfdump-ranges-unrelocated.s =================================================================== --- test/DebugInfo/dwarfdump-ranges-unrelocated.s +++ test/DebugInfo/dwarfdump-ranges-unrelocated.s @@ -0,0 +1,85 @@ +# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t +# RUN: llvm-dwarfdump %t | FileCheck %s + +# CHECK: .debug_ranges contents: +# CHECK: 00000000 0000000000000000 0000000000000001 +# CHECK: 00000000 0000000000000000 0000000000000002 +# CHECK: 00000000 0000000000000000 0000000000000003 +# CHECK: 00000000 + +## Asm code for testcase is a reduced output from next invocation and source: +# clang test.cpp -S -o test.s -g -gsplit-dwarf -ffunction-sections +# test.cpp: +# int foo1() { return 1; } +# int foo2() { return 1; } +# int foo3() { return 1; } + +.section .text._Z4foo1v,"ax",@progbits +_Z4foo1v: +.Lfunc_begin0: + nop +.Lfunc_end0: + +.section .text._Z4foo2v,"ax",@progbits +_Z4foo2v: +.Lfunc_begin1: + nop + nop +.Lfunc_end1: + +.section .text._Z4foo3v,"ax",@progbits +_Z4foo3v: +.Lfunc_begin2: + nop + nop + nop +.Lfunc_end2: + +.section .debug_abbrev,"",@progbits +.byte 1 # Abbreviation Code +.byte 17 # DW_TAG_compile_unit +.byte 0 # DW_CHILDREN_no +.byte 16 # DW_AT_stmt_list +.byte 23 # DW_FORM_sec_offset +.ascii "\260B" # DW_AT_GNU_dwo_name +.byte 14 # DW_FORM_strp +.byte 27 # DW_AT_comp_dir +.byte 14 # DW_FORM_strp +.ascii "\261B" # DW_AT_GNU_dwo_id +.byte 7 # DW_FORM_data8 +.ascii "\263B" # DW_AT_GNU_addr_base +.byte 23 # DW_FORM_sec_offset +.byte 17 # DW_AT_low_pc +.byte 1 # DW_FORM_addr +.byte 85 # DW_AT_ranges +.byte 23 # DW_FORM_sec_offset +.byte 0 # EOM(1) +.byte 0 # EOM(2) +.byte 0 # EOM(3) + +.section .debug_info,"",@progbits +.Lcu_begin0: +.long 44 # Length of Unit +.short 4 # DWARF version number + +.long .debug_abbrev # Offset Into Abbrev. Section +.byte 8 # Address Size (in bytes) +.byte 1 # Abbrev [1] 0xb:0x25 DW_TAG_compile_unit +.long 0 # DW_AT_stmt_list +.long 0 # DW_AT_GNU_dwo_name +.long 0 # DW_AT_comp_dir +.quad 0 # DW_AT_GNU_dwo_id +.long 0 # DW_AT_GNU_addr_base +.quad 0 # DW_AT_low_pc +.long .Ldebug_ranges0 # DW_AT_ranges + +.section .debug_ranges,"",@progbits +.Ldebug_ranges0: +.quad .Lfunc_begin0 +.quad .Lfunc_end0 +.quad .Lfunc_begin1 +.quad .Lfunc_end1 +.quad .Lfunc_begin2 +.quad .Lfunc_end2 +.quad 0 +.quad 0 Index: tools/dsymutil/DwarfLinker.cpp =================================================================== --- tools/dsymutil/DwarfLinker.cpp +++ tools/dsymutil/DwarfLinker.cpp @@ -2859,7 +2859,7 @@ DWARFDebugRangeList RangeList; const auto &FunctionRanges = Unit.getFunctionRanges(); unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize(); - DataExtractor RangeExtractor(OrigDwarf.getRangeSection(), + DataExtractor RangeExtractor(OrigDwarf.getRangeSection().Data, OrigDwarf.isLittleEndian(), AddressSize); auto InvalidRange = FunctionRanges.end(), CurrRange = InvalidRange; DWARFUnit &OrigUnit = Unit.getOrigUnit(); @@ -2874,7 +2874,7 @@ for (const auto &RangeAttribute : Unit.getRangesAttributes()) { uint32_t Offset = RangeAttribute.get(); RangeAttribute.set(Streamer->getRangesSectionSize()); - RangeList.extract(RangeExtractor, &Offset); + RangeList.extract(RangeExtractor, &Offset, OrigDwarf.getRangeSection().Relocs); const auto &Entries = RangeList.getEntries(); if (!Entries.empty()) { const DWARFDebugRangeList::RangeListEntry &First = Entries.front();