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 @@ -50,6 +50,11 @@ // entire size of the debug info sections. typedef DenseMap> RelocAddrMap; +// Reads a value from data extractor and applies relocation to result if +// relocation is exist for given offset. +uint64_t getRelocatedValue(const DataExtractor &Data, uint32_t Size, + uint32_t *Off, const RelocAddrMap *Relocs); + /// DWARFContext /// This data structure is the top level entity that deals with dwarf debug /// information parsing. The actual data is supplied through pure virtual @@ -216,7 +221,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 +236,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 +276,7 @@ StringRef EHFrameSection; DWARFSection LineSection; StringRef StringSection; - StringRef RangeSection; + DWARFSection RangeSection; StringRef MacinfoSection; StringRef PubNamesSection; StringRef PubTypesSection; @@ -286,7 +291,7 @@ DWARFSection LocDWOSection; StringRef StringDWOSection; StringRef StringOffsetDWOSection; - StringRef RangeDWOSection; + DWARFSection RangeDWOSection; StringRef AddrSection; DWARFSection AppleNamesSection; DWARFSection AppleTypesSection; @@ -319,7 +324,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 +351,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 @@ -41,8 +43,16 @@ // The end of any given range list is marked by an end of list entry, // which consists of a 0 for the beginning address offset // and a 0 for the ending address offset. - bool isEndOfListEntry() const { - return (StartAddress == 0) && (EndAddress == 0); + // For unrelocated object case we should also check if relocations + // present for start and end address offset. If them are, it is not + // an end of list marker. + bool isEndOfListEntry(const RelocAddrMap &Relocs, uint32_t Offset, + int8_t AddressSize) const { + if (StartAddress || EndAddress) + return false; + if (Relocs.find(Offset) != Relocs.end()) + return false; + return Relocs.find(Offset + AddressSize) == Relocs.end(); } // A base address selection entry consists of: @@ -71,7 +81,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 @@ -56,6 +56,16 @@ typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind; typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; +uint64_t llvm::getRelocatedValue(const DataExtractor &Data, uint32_t Size, + uint32_t *Off, const RelocAddrMap *Relocs) { + if (Relocs) { + RelocAddrMap::const_iterator AI = Relocs->find(*Off); + if (AI != Relocs->end()) + return Data.getUnsigned(Off, Size) + AI->second.second; + } + return Data.getUnsigned(Off, Size); +} + static void dumpAccelSection(raw_ostream &OS, StringRef Name, const DWARFSection& Section, StringRef StringSection, bool LittleEndian) { @@ -212,11 +222,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 +730,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 +771,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 +854,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/DWARFDebugLine.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/SmallString.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/Support/Dwarf.h" @@ -302,16 +303,9 @@ // relocatable address. All of the other statement program opcodes // that affect the address register add a delta to it. This instruction // stores a relocatable value into it instead. - { - // 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; - State.Row.Address = - debug_line_data.getAddress(offset_ptr) + R.second; - } else - State.Row.Address = debug_line_data.getAddress(offset_ptr); - } + State.Row.Address = + getRelocatedValue(debug_line_data, debug_line_data.getAddressSize(), + offset_ptr, RMap); break; case DW_LNE_define_file: Index: lib/DebugInfo/DWARF/DWARFDebugLoc.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/StringRef.h" +#include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include "llvm/Support/Dwarf.h" @@ -48,18 +49,10 @@ // 2.6.2 Location Lists // A location list entry consists of: while (true) { + // A beginning and ending address offsets. Entry E; - RelocAddrMap::const_iterator AI = RelocMap.find(Offset); - // 1. A beginning address offset. ... - E.Begin = data.getUnsigned(&Offset, AddressSize); - if (AI != RelocMap.end()) - E.Begin += AI->second.second; - - 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.Begin = getRelocatedValue(data, AddressSize, &Offset, &RelocMap); + E.End = getRelocatedValue(data, AddressSize, &Offset, &RelocMap); // 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 @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h" #include "llvm/Support/Format.h" #include "llvm/Support/raw_ostream.h" @@ -22,7 +23,8 @@ Entries.clear(); } -bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr) { +bool DWARFDebugRangeList::extract(DataExtractor data, uint32_t *offset_ptr, + const RelocAddrMap &Relocs) { clear(); if (!data.isValidOffset(*offset_ptr)) return false; @@ -33,14 +35,17 @@ while (true) { RangeListEntry entry; uint32_t prev_offset = *offset_ptr; - entry.StartAddress = data.getAddress(offset_ptr); - entry.EndAddress = data.getAddress(offset_ptr); + entry.StartAddress = + getRelocatedValue(data, AddressSize, offset_ptr, &Relocs); + entry.EndAddress = + getRelocatedValue(data, AddressSize, offset_ptr, &Relocs); + // Check that both values were extracted correctly. if (*offset_ptr != prev_offset + 2 * AddressSize) { clear(); return false; } - if (entry.isEndOfListEntry()) + if (entry.isEndOfListEntry(Relocs, prev_offset, AddressSize)) break; Entries.push_back(entry); } Index: lib/DebugInfo/DWARF/DWARFFormValue.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -334,11 +334,8 @@ (Form == DW_FORM_addr) ? U->getAddressByteSize() : U->getRefAddrByteSize(); - RelocAddrMap::const_iterator AI = U->getRelocMap()->find(*offset_ptr); - if (AI != U->getRelocMap()->end()) { - Value.uval = data.getUnsigned(offset_ptr, AddrSize) + AI->second.second; - } else - Value.uval = data.getUnsigned(offset_ptr, AddrSize); + Value.uval = + getRelocatedValue(data, AddrSize, offset_ptr, U->getRelocMap()); break; } case DW_FORM_exprloc: @@ -376,12 +373,8 @@ case DW_FORM_ref_sup4: case DW_FORM_strx4: case DW_FORM_addrx4: { - Value.uval = data.getU32(offset_ptr); - if (!U) - break; - RelocAddrMap::const_iterator AI = U->getRelocMap()->find(*offset_ptr-4); - if (AI != U->getRelocMap()->end()) - Value.uval += AI->second.second; + const RelocAddrMap* RelocMap = U ? U->getRelocMap() : nullptr; + Value.uval = getRelocatedValue(data, 4, offset_ptr, RelocMap); break; } case DW_FORM_data8: @@ -411,11 +404,8 @@ case DW_FORM_strp_sup: { if (!U) return false; - RelocAddrMap::const_iterator AI = U->getRelocMap()->find(*offset_ptr); - uint8_t Size = U->getDwarfOffsetByteSize(); - Value.uval = data.getUnsigned(offset_ptr, Size); - if (AI != U->getRelocMap()->end()) - Value.uval += AI->second.second; + Value.uval = getRelocatedValue(data, U->getDwarfOffsetByteSize(), + offset_ptr, U->getRelocMap()); break; } case DW_FORM_flag_present: 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,69 @@ +# 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 0000000000000000 +# CHECK: 00000000 0000000000000000 0000000000000001 +# 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: +# void foo1() { } +# void foo2() { } + +.section .text.foo1,"ax",@progbits +.Lfunc_begin0: +.Lfunc_end0: + +.section .text.foo2,"ax",@progbits +.Lfunc_begin1: + nop +.Lfunc_end1: + +.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 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();