Index: include/llvm/BinaryFormat/Dwarf.h =================================================================== --- include/llvm/BinaryFormat/Dwarf.h +++ include/llvm/BinaryFormat/Dwarf.h @@ -475,6 +475,7 @@ StringRef LNExtendedString(unsigned Encoding); StringRef MacinfoString(unsigned Encoding); StringRef RangeListEncodingString(unsigned Encoding); +StringRef LocationListEncodingString(unsigned Entry); StringRef CallFrameString(unsigned Encoding, Triple::ArchType Arch); StringRef ApplePropertyString(unsigned); StringRef UnitTypeString(unsigned); Index: include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h =================================================================== --- include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -11,6 +11,8 @@ #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/iterator.h" +#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include @@ -20,6 +22,11 @@ class MCRegisterInfo; class raw_ostream; +struct DWARFLocation { + DWARFAddressRange Range; + ArrayRef Location; +}; + class DWARFDebugLoc { public: /// A single location within a location list. @@ -81,12 +88,80 @@ SmallVector Loc; }; + class EntryIterator { + public: + using iterator_category = std::input_iterator_tag; + using value_type = Expected; + using difference_type = std::ptrdiff_t; + using pointer = value_type *; + using reference = value_type; + + EntryIterator( + ArrayRef Entries, + llvm::Optional BaseAddr, + std::function(uint32_t)> + AddrOffsetResolver) + : Entries(Entries), BaseAddr(BaseAddr), + AddrOffsetResolver(AddrOffsetResolver) { + processBaseAddressEntries(); + } + + Expected operator*() const; + + EntryIterator &operator++() { + Entries = Entries.drop_front(); + processBaseAddressEntries(); + return *this; + } + + EntryIterator operator++(int) { + EntryIterator Save = *this; + ++*this; + return Save; + } + + friend bool operator==(const EntryIterator &L, const EntryIterator &R) { + return L.Entries.begin() == R.Entries.begin(); + } + + friend bool operator!=(const EntryIterator &L, const EntryIterator &R) { + return !(L == R); + } + + const Entry *position() const { return Entries.begin(); } + + private: + void processBaseAddressEntries(); + + ArrayRef Entries; + llvm::Optional BaseAddr; + std::function(uint32_t)> + AddrOffsetResolver; + }; + struct LocationList { uint64_t Offset; SmallVector Entries; void dump(raw_ostream &OS, uint64_t BaseAddr, bool IsLittleEndian, unsigned AddressSize, const MCRegisterInfo *RegInfo, + DIDumpOptions DumpOpts, + function_ref(uint32_t)> + LookupPooledAddress, DWARFUnit *U, unsigned Indent) const; + + iterator_range getAbsoluteLocations( + Optional BaseAddr, + std::function(uint32_t)> + AddrOffsetResolver) const { + return make_range( + EntryIterator(Entries, BaseAddr, std::move(AddrOffsetResolver)), + EntryIterator(makeArrayRef(Entries.end(), Entries.end()), llvm::None, + {})); + } + + iterator_range + getAbsoluteLocations(Optional BaseAddr, + DWARFUnit &U) const; }; private: @@ -101,7 +176,7 @@ public: void parse(DataExtractor data, unsigned Version); void dump(raw_ostream &OS, uint64_t BaseAddr, const MCRegisterInfo *RegInfo, - Optional Offset) const; + DIDumpOptions DumpOpts, Optional Offset) const; /// Return the location list at the given offset or nullptr. LocationList const *getLocationListAtOffset(uint64_t Offset) const; Index: lib/BinaryFormat/Dwarf.cpp =================================================================== --- lib/BinaryFormat/Dwarf.cpp +++ lib/BinaryFormat/Dwarf.cpp @@ -472,6 +472,31 @@ } } +StringRef llvm::dwarf::LocationListEncodingString(unsigned Entry) { + switch(Entry) { + default: + return StringRef(); + case DW_LLE_end_of_list: + return "DW_LLE_end_of_list"; + case DW_LLE_base_addressx: + return "DW_LLE_base_addressx"; + case DW_LLE_startx_endx: + return "DW_LLE_startx_endx"; + case DW_LLE_startx_length: + return "DW_LLE_startx_length"; + case DW_LLE_offset_pair: + return "DW_LLE_offset_pair"; + case DW_LLE_default_location: + return "DW_LLE_default_location"; + case DW_LLE_base_address: + return "DW_LLE_base_address"; + case DW_LLE_start_end: + return "DW_LLE_start_end"; + case DW_LLE_start_length: + return "DW_LLE_start_length"; + } +} + StringRef llvm::dwarf::CallFrameString(unsigned Encoding, Triple::ArchType Arch) { assert(Arch != llvm::Triple::ArchType::UnknownArch); Index: lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFContext.cpp +++ lib/DebugInfo/DWARF/DWARFContext.cpp @@ -303,7 +303,7 @@ Data.isLittleEndian(), Header.getAddrSize()); Loclists.parse(LocData, Header.getVersion()); - Loclists.dump(OS, 0, MRI, DumpOffset); + Loclists.dump(OS, 0, MRI, DumpOpts, DumpOffset); } void DWARFContext::dump( @@ -390,7 +390,7 @@ if (const auto *Off = shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc, DObj->getLocDWOSection().Data)) { - getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), *Off); + getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), DumpOpts, *Off); } if (const auto *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame, Index: lib/DebugInfo/DWARF/DWARFDebugLoc.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -15,6 +15,8 @@ #include "llvm/DebugInfo/DWARF/DWARFUnit.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Format.h" +#include "llvm/Support/FormatAdapters.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include @@ -22,6 +24,7 @@ #include using namespace llvm; +using object::SectionedAddress; // When directly dumping the .debug_loc without a compile unit, we have to guess // at the DWARF version. This only affects DW_OP_call_ref, which is a rare @@ -135,6 +138,66 @@ } } +Expected DWARFDebugLoclists::EntryIterator::operator*() const { + const Entry &E = Entries.front(); + DWARFLocation Result; + switch (E.Kind) { + case dwarf::DW_LLE_startx_length: { + auto Start = AddrOffsetResolver(E.Value0); + if (!Start) + return createStringError(errc::invalid_argument, + "Failed to read address offset %u", + unsigned(E.Value0)); + Result.Range.LowPC = Start->Address; + Result.Range.HighPC = Start->Address + E.Value1; + Result.Range.SectionIndex = Start->SectionIndex; + break; + } + case dwarf::DW_LLE_start_length: + Result.Range.LowPC = E.Value0; + Result.Range.HighPC = E.Value0 + E.Value1; + // TODO: Store the SectionedAddress in the Entry class + Result.Range.SectionIndex = SectionedAddress::UndefSection; + break; + case dwarf::DW_LLE_offset_pair: + if (!BaseAddr) + return createStringError(errc::invalid_argument, + "Cannot interpret DW_LLE_offset_pair entry due " + "to missing base address"); + + Result.Range.LowPC = BaseAddr->Address + E.Value0; + Result.Range.HighPC = BaseAddr->Address + E.Value1; + Result.Range.SectionIndex = BaseAddr->SectionIndex; + break; + case dwarf::DW_LLE_base_address: + case dwarf::DW_LLE_base_addressx: + llvm_unreachable("Base address selection entries handled elsewhere!"); + default: + // Entries rejected by the parser. + llvm_unreachable("Unsupported location list kind!"); + } + Result.Location = E.Loc; + return Result; +} + +void DWARFDebugLoclists::EntryIterator::processBaseAddressEntries() { + for (; !Entries.empty(); Entries = Entries.drop_front()) { + const Entry &E = Entries.front(); + switch (E.Kind) { + case dwarf::DW_LLE_base_address: + // TODO: Store the SectionedAddress in the Entry class + BaseAddr->Address = E.Value0; + BaseAddr->SectionIndex = SectionedAddress::UndefSection; + break; + case dwarf::DW_LLE_base_addressx: + // Entry rejected by the parser. + llvm_unreachable("Unsupported location list kind!"); + default: + return; + } + } +} + Expected DWARFDebugLoclists::parseOneLocationList(const DataExtractor &Data, uint64_t *Offset, unsigned Version) { @@ -211,50 +274,77 @@ return nullptr; } -void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr, - bool IsLittleEndian, - unsigned AddressSize, - const MCRegisterInfo *MRI, - DWARFUnit *U, - unsigned Indent) const { +iterator_range +DWARFDebugLoclists::LocationList::getAbsoluteLocations( + Optional BaseAddr, DWARFUnit &U) const { + return getAbsoluteLocations(BaseAddr, [&U](uint32_t Index) { + return U.getAddrOffsetSectionItem(Index); + }); +} + +void DWARFDebugLoclists::LocationList::dump( + raw_ostream &OS, uint64_t BaseAddr, bool IsLittleEndian, + unsigned AddressSize, const MCRegisterInfo *MRI, DIDumpOptions DumpOpts, + function_ref(uint32_t)> LookupPooledAddress, + DWARFUnit *U, unsigned Indent) const { + uint8_t MaxEncodingStringLength = 20; + EntryIterator Absolute = + getAbsoluteLocations( + SectionedAddress{BaseAddr, SectionedAddress::UndefSection}, + LookupPooledAddress) + .begin(); for (const Entry &E : Entries) { - switch (E.Kind) { - case dwarf::DW_LLE_startx_length: - OS << '\n'; - OS.indent(Indent); - OS << "Addr idx " << E.Value0 << " (w/ length " << E.Value1 << "): "; - break; - case dwarf::DW_LLE_start_length: - OS << '\n'; - OS.indent(Indent); - OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 "): ", AddressSize * 2, - AddressSize * 2, E.Value0, AddressSize * 2, AddressSize * 2, - E.Value0 + E.Value1); - break; - case dwarf::DW_LLE_offset_pair: - OS << '\n'; - OS.indent(Indent); - OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 "): ", AddressSize * 2, - AddressSize * 2, BaseAddr + E.Value0, AddressSize * 2, - AddressSize * 2, BaseAddr + E.Value1); - break; - case dwarf::DW_LLE_base_address: - BaseAddr = E.Value0; - break; - default: - llvm_unreachable("unreachable locations list kind"); + // We dump the raw encoding if we're in verbose mode, *or* if we failed to + // produce the absolute address range. + const auto &DumpEncoding = [&] { + OS << format("[%-*s]", MaxEncodingStringLength, + dwarf::LocationListEncodingString(E.Kind).data()); + if (E.Kind != dwarf::DW_LLE_end_of_list) + OS << ": "; + switch (E.Kind) { + case dwarf::DW_LLE_end_of_list: + // TODO: Generate these entries. + llvm_unreachable("unreachable locations list kind"); + case dwarf::DW_LLE_base_address: + OS << format_hex(E.Value0, 2 + AddressSize * 2); + break; + case dwarf::DW_LLE_startx_length: + case dwarf::DW_LLE_start_length: + case dwarf::DW_LLE_offset_pair: + OS << format_hex(E.Value0, 2 + AddressSize * 2) << ", " + << format_hex(E.Value1, 2 + AddressSize * 2); + } + }; + OS << "\n"; + OS.indent(Indent); + if (DumpOpts.Verbose) + DumpEncoding(); + if (E.Kind == dwarf::DW_LLE_base_address) + continue; + assert(Absolute.position() == &E); + if (auto ExpectedLocation = *Absolute) { + if (DumpOpts.Verbose) + OS << " => "; + ExpectedLocation->Range.dump(OS, AddressSize); + } else { + DumpEncoding(); + OS << " => "; + OS << formatv("<{0}>", fmt_consume(ExpectedLocation.takeError())); } - + ++Absolute; + OS << " "; dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, U); } } void DWARFDebugLoclists::dump(raw_ostream &OS, uint64_t BaseAddr, - const MCRegisterInfo *MRI, + const MCRegisterInfo *MRI, DIDumpOptions DumpOpts, Optional Offset) const { auto DumpLocationList = [&](const LocationList &L) { OS << format("0x%8.8" PRIx64 ": ", L.Offset); - L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, nullptr, /*Indent=*/12); + L.dump( + OS, BaseAddr, IsLittleEndian, AddressSize, MRI, DumpOpts, + [](uint32_t Index) { return llvm::None; }, nullptr, /*Indent=*/12); OS << "\n\n"; }; Index: lib/DebugInfo/DWARF/DWARFDie.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDie.cpp +++ lib/DebugInfo/DWARF/DWARFDie.cpp @@ -92,27 +92,28 @@ } FormValue.dump(OS, DumpOpts); - const auto &DumpLL = [&](auto ExpectedLL) { - if (ExpectedLL) { - uint64_t BaseAddr = 0; - if (Optional BA = U->getBaseAddress()) - BaseAddr = BA->Address; - ExpectedLL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), - MRI, U, Indent); - } else { + const auto &DumpError = [&](Error E) { OS << '\n'; OS.indent(Indent); OS << formatv("error extracting location list: {0}", - fmt_consume(ExpectedLL.takeError())); - } + fmt_consume(std::move(E))); }; if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) { uint64_t Offset = *FormValue.getAsSectionOffset(); + + uint64_t BaseAddr = 0; + if (Optional BA = U->getBaseAddress()) + BaseAddr = BA->Address; + if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) { DWARFDebugLoc DebugLoc; DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(), Obj.getAddressSize()); - DumpLL(DebugLoc.parseOneLocationList(Data, &Offset)); + if (auto ExpectedLL = DebugLoc.parseOneLocationList(Data, &Offset)) + ExpectedLL->dump(OS, BaseAddr, Ctx.isLittleEndian(), + Obj.getAddressSize(), MRI, U, Indent); + else + DumpError(ExpectedLL.takeError()); return; } @@ -128,8 +129,16 @@ // Modern locations list (.debug_loclists) are used starting from v5. // Ideally we should take the version from the .debug_loclists section // header, but using CU's version for simplicity. - DumpLL(DWARFDebugLoclists::parseOneLocationList( - Data, &Offset, UseLocLists ? U->getVersion() : 4)); + if (auto ExpectedLL = DWARFDebugLoclists::parseOneLocationList( + Data, &Offset, UseLocLists ? U->getVersion() : 4)) + ExpectedLL->dump( + OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, + DumpOpts, + [U](uint32_t Index) { return U->getAddrOffsetSectionItem(Index); }, + U, Indent); + else + DumpError(ExpectedLL.takeError()); + } } } Index: test/CodeGen/X86/debug-loclists.ll =================================================================== --- test/CodeGen/X86/debug-loclists.ll +++ test/CodeGen/X86/debug-loclists.ll @@ -3,8 +3,8 @@ ; CHECK: 0x00000033: DW_TAG_formal_parameter [3] ; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x0000000c -; CHECK-NEXT: [0x0000000000000000, 0x0000000000000004): DW_OP_breg5 RDI+0 -; CHECK-NEXT: [0x0000000000000004, 0x0000000000000012): DW_OP_breg3 RBX+0) +; CHECK-NEXT: [0x0000000000000000, 0x0000000000000004) DW_OP_breg5 RDI+0 +; CHECK-NEXT: [0x0000000000000004, 0x0000000000000012) DW_OP_breg3 RBX+0) ; CHECK-NEXT: DW_AT_name [DW_FORM_strx1] (indexed (0000000e) string = "a") ; CHECK-NEXT: DW_AT_decl_file [DW_FORM_data1] ("/home/folder{{\\|\/}}test.cc") ; CHECK-NEXT: DW_AT_decl_line [DW_FORM_data1] (6) @@ -13,36 +13,8 @@ ; CHECK: .debug_loclists contents: ; CHECK-NEXT: 0x00000000: locations list header: length = 0x00000015, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 ; CHECK-NEXT: 0x00000000: -; CHECK-NEXT: [0x0000000000000000, 0x0000000000000004): DW_OP_breg5 RDI+0 -; CHECK-NEXT: [0x0000000000000004, 0x0000000000000012): DW_OP_breg3 RBX+0 - -; There is no way to use llvm-dwarfdump atm (2018, october) to verify the DW_LLE_* codes emited, -; because dumper is not yet implements that. Use asm code to do this check instead. -; -; RUN: llc -mtriple=x86_64-pc-linux -filetype=asm < %s -o - | FileCheck %s --check-prefix=ASM -; ASM: .section .debug_loclists,"",@progbits -; ASM-NEXT: .long .Ldebug_loclist_table_end0-.Ldebug_loclist_table_start0 # Length -; ASM-NEXT: .Ldebug_loclist_table_start0: -; ASM-NEXT: .short 5 # Version -; ASM-NEXT: .byte 8 # Address size -; ASM-NEXT: .byte 0 # Segment selector size -; ASM-NEXT: .long 0 # Offset entry count -; ASM-NEXT: .Lloclists_table_base0: -; ASM-NEXT: .Ldebug_loc0: -; ASM-NEXT: .byte 4 # DW_LLE_offset_pair -; ASM-NEXT: .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset -; ASM-NEXT: .uleb128 .Ltmp0-.Lfunc_begin0 # ending offset -; ASM-NEXT: .byte 2 # Loc expr size -; ASM-NEXT: .byte 117 # DW_OP_breg5 -; ASM-NEXT: .byte 0 # 0 -; ASM-NEXT: .byte 4 # DW_LLE_offset_pair -; ASM-NEXT: .uleb128 .Ltmp0-.Lfunc_begin0 # starting offset -; ASM-NEXT: .uleb128 .Ltmp1-.Lfunc_begin0 # ending offset -; ASM-NEXT: .byte 2 # Loc expr size -; ASM-NEXT: .byte 115 # DW_OP_breg3 -; ASM-NEXT: .byte 0 # 0 -; ASM-NEXT: .byte 0 # DW_LLE_end_of_list -; ASM-NEXT: .Ldebug_loclist_table_end0: +; CHECK-NEXT: [DW_LLE_offset_pair ]: 0x0000000000000000, 0x0000000000000004 => [0x0000000000000000, 0x0000000000000004) DW_OP_breg5 RDI+0 +; CHECK-NEXT: [DW_LLE_offset_pair ]: 0x0000000000000004, 0x0000000000000012 => [0x0000000000000004, 0x0000000000000012) DW_OP_breg3 RBX+0 ; ModuleID = 'test.cc' source_filename = "test.cc" Index: test/DebugInfo/X86/dwarfdump-debug-loclists-error-cases2.s =================================================================== --- test/DebugInfo/X86/dwarfdump-debug-loclists-error-cases2.s +++ test/DebugInfo/X86/dwarfdump-debug-loclists-error-cases2.s @@ -3,8 +3,8 @@ # CHECK: DW_AT_name ("x0") # CHECK-NEXT: DW_AT_location (0x0000000c -# CHECK-NEXT: [0x0000000000000000, 0x0000000000000002): DW_OP_reg5 RDI -# CHECK-NEXT: [0x0000000000000002, 0x0000000000000003): DW_OP_reg0 RAX) +# CHECK-NEXT: [0x0000000000000000, 0x0000000000000002) DW_OP_reg5 RDI +# CHECK-NEXT: [0x0000000000000002, 0x0000000000000003) DW_OP_reg0 RAX) # CHECK: DW_AT_name ("x1") # CHECK-NEXT: DW_AT_location (0xdeadbeef Index: test/DebugInfo/X86/dwarfdump-debug-loclists.test =================================================================== --- test/DebugInfo/X86/dwarfdump-debug-loclists.test +++ test/DebugInfo/X86/dwarfdump-debug-loclists.test @@ -4,16 +4,19 @@ # CHECK: .debug_info # CHECK: DW_AT_name{{.*}}"stub" # CHECK: DW_AT_location [DW_FORM_sec_offset] (0x0000000c -# CHECK-NEXT: [0x0000000000000010, 0x0000000000000020): DW_OP_breg5 RDI+0 -# CHECK-NEXT: [0x0000000000000530, 0x0000000000000540): DW_OP_breg6 RBP-8, DW_OP_deref -# CHECK-NEXT: [0x0000000000000700, 0x0000000000000710): DW_OP_breg5 RDI+0 +# CHECK-NEXT: [DW_LLE_offset_pair ]: 0x0000000000000000, 0x0000000000000010 => [0x0000000000000010, 0x0000000000000020) DW_OP_breg5 RDI+0 +# CHECK-NEXT: [DW_LLE_base_address ]: 0x0000000000000500 +# +# CHECK-NEXT: [DW_LLE_offset_pair ]: 0x0000000000000030, 0x0000000000000040 => [0x0000000000000530, 0x0000000000000540) DW_OP_breg6 RBP-8, DW_OP_deref +# CHECK-NEXT: [DW_LLE_start_length ]: 0x0000000000000700, 0x0000000000000010 => [0x0000000000000700, 0x0000000000000710) DW_OP_breg5 RDI+0 # CHECK: .debug_loclists contents: # CHECK-NEXT: 0x00000000: locations list header: length = 0x0000002c, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 # CHECK-NEXT: 0x00000000: -# CHECK-NEXT: [0x0000000000000000, 0x0000000000000010): DW_OP_breg5 RDI+0 -# CHECK-NEXT: [0x0000000000000530, 0x0000000000000540): DW_OP_breg6 RBP-8, DW_OP_deref -# CHECK-NEXT: [0x0000000000000700, 0x0000000000000710): DW_OP_breg5 RDI+0 +# CHECK-NEXT: [DW_LLE_offset_pair ]: 0x0000000000000000, 0x0000000000000010 => [0x0000000000000000, 0x0000000000000010) DW_OP_breg5 RDI+0 +# CHECK-NEXT: [DW_LLE_base_address ]: 0x0000000000000500 +# CHECK-NEXT: [DW_LLE_offset_pair ]: 0x0000000000000030, 0x0000000000000040 => [0x0000000000000530, 0x0000000000000540) DW_OP_breg6 RBP-8, DW_OP_deref +# CHECK-NEXT: [DW_LLE_start_length ]: 0x0000000000000700, 0x0000000000000010 => [0x0000000000000700, 0x0000000000000710) DW_OP_breg5 RDI+0 .section .debug_str,"MS",@progbits,1 .asciz "stub" Index: test/DebugInfo/X86/fission-ranges.ll =================================================================== --- test/DebugInfo/X86/fission-ranges.ll +++ test/DebugInfo/X86/fission-ranges.ll @@ -45,18 +45,18 @@ ; if they've changed due to a bugfix, change in register allocation, etc. ; CHECK: [[A]]: -; CHECK-NEXT: Addr idx 2 (w/ length 15): DW_OP_consts +0, DW_OP_stack_value -; CHECK-NEXT: Addr idx 3 (w/ length 15): DW_OP_reg0 RAX -; CHECK-NEXT: Addr idx 4 (w/ length 18): DW_OP_breg7 RSP-8 +; CHECK-NEXT: [DW_LLE_startx_length]: 0x00000002, 0x0000000f => DW_OP_consts +0, DW_OP_stack_value +; CHECK-NEXT: [DW_LLE_startx_length]: 0x00000003, 0x0000000f => DW_OP_reg0 RAX +; CHECK-NEXT: [DW_LLE_startx_length]: 0x00000004, 0x00000012 => DW_OP_breg7 RSP-8 ; CHECK: [[E]]: -; CHECK-NEXT: Addr idx 5 (w/ length 9): DW_OP_reg0 RAX -; CHECK-NEXT: Addr idx 6 (w/ length 98): DW_OP_breg7 RSP-44 +; CHECK-NEXT: [DW_LLE_startx_length]: 0x00000005, 0x00000009 => DW_OP_reg0 RAX +; CHECK-NEXT: [DW_LLE_startx_length]: 0x00000006, 0x00000062 => DW_OP_breg7 RSP-44 ; CHECK: [[B]]: -; CHECK-NEXT: Addr idx 7 (w/ length 15): DW_OP_reg0 RAX -; CHECK-NEXT: Addr idx 8 (w/ length 66): DW_OP_breg7 RSP-32 +; CHECK-NEXT: [DW_LLE_startx_length]: 0x00000007, 0x0000000f => DW_OP_reg0 RAX +; CHECK-NEXT: [DW_LLE_startx_length]: 0x00000008, 0x00000042 => DW_OP_breg7 RSP-32 ; CHECK: [[D]]: -; CHECK-NEXT: Addr idx 9 (w/ length 15): DW_OP_reg0 RAX -; CHECK-NEXT: Addr idx 10 (w/ length 42): DW_OP_breg7 RSP-20 +; CHECK-NEXT: [DW_LLE_startx_length]: 0x00000009, 0x0000000f => DW_OP_reg0 RAX +; CHECK-NEXT: [DW_LLE_startx_length]: 0x0000000a, 0x0000002a => DW_OP_breg7 RSP-20 ; Make sure we don't produce any relocations in any .dwo section (though in particular, debug_info.dwo) ; HDR-NOT: .rela.{{.*}}.dwo Index: test/DebugInfo/X86/loclists-dwp.ll =================================================================== --- test/DebugInfo/X86/loclists-dwp.ll +++ test/DebugInfo/X86/loclists-dwp.ll @@ -19,10 +19,10 @@ ; void b(int i) { asm("" : : : "rdi"); } ; CHECK: DW_AT_location [DW_FORM_sec_offset] (0x00000000 -; CHECK-NEXT: Addr idx 0 (w/ length 6): DW_OP_reg5 RDI) +; CHECK-NEXT: [DW_LLE_startx_length]: 0x0000000000000000, 0x0000000000000006 => DW_OP_reg5 RDI) ; CHECK: DW_AT_location [DW_FORM_sec_offset] (0x00000000 -; CHECK-NEXT: Addr idx 0 (w/ length 0): DW_OP_reg5 RDI) +; CHECK-NEXT: [DW_LLE_startx_length]: 0x0000000000000000, 0x0000000000000000 => DW_OP_reg5 RDI) target triple = "x86_64-unknown-linux-gnu" Index: test/tools/llvm-dwarfdump/X86/debug_loc_dwo.s =================================================================== --- test/tools/llvm-dwarfdump/X86/debug_loc_dwo.s +++ test/tools/llvm-dwarfdump/X86/debug_loc_dwo.s @@ -6,7 +6,7 @@ # CHECK: .debug_loc.dwo contents: # CHECK-NEXT: 0x00000000: -# CHECK-NEXT: Addr idx 1 (w/ length 16): DW_OP_reg5 RDI +# CHECK-NEXT: [DW_LLE_startx_length]: 0x00000001, 0x00000010 => DW_OP_reg5 RDI .section .debug_loc.dwo,"",@progbits # One location list. The pre-DWARF v5 implementation only recognizes Index: test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s =================================================================== --- test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s +++ test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s @@ -8,7 +8,7 @@ # CHECK: .debug_loclists contents: # CHECK-NEXT: 0x00000000: locations list header: length = 0x0000000e, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000 # CHECK-NEXT: 0x00000000: -# CHECK-NEXT: Addr idx 1 (w/ length 16): DW_OP_reg5 RDI +# CHECK-NEXT: [DW_LLE_startx_length]: 0x0000000000000001, 0x0000000000000010[DW_LLE_startx_length]: 0x0000000000000001, 0x0000000000000010 => DW_OP_reg5 RDI .section .debug_loclists,"",@progbits .long .Ldebug_loclist_table_end0-.Ldebug_loclist_table_start0