diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h @@ -13,6 +13,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h" +#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h" #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h" #include @@ -21,6 +22,53 @@ class MCRegisterInfo; class raw_ostream; +/// A single location within a location list. Entries are stored in the DWARF5 +/// form even if they originally come from a DWARF<=4 location list. +struct DWARFLocationEntry { + /// The entry kind (DW_LLE_***). + uint8_t Kind; + + /// The first value of the location entry (if applicable). + uint64_t Value0; + + /// The second value of the location entry (if applicable). + uint64_t Value1; + + /// The location expression itself (if applicable). + SmallVector Loc; +}; + +/// An abstract base class for various kinds of location tables (.debug_loc, +/// .debug_loclists, and their dwo variants). +class DWARFLocationTable { +public: + DWARFLocationTable(DWARFDataExtractor Data) : Data(std::move(Data)) {} + virtual ~DWARFLocationTable() = default; + + /// Call the user-provided callback for each entry (including the end-of-list + /// entry) in the location list starting at \p Offset. The callback can return + /// false to terminate the iteration early. Returns an error if it was unable + /// to parse the entire location list correctly. Upon successful termination + /// \p Offset will be updated point past the end of the list. + virtual Error + visitLocationList(uint64_t *Offset, + function_ref F) const = 0; + + /// Dump the location list at the given \p Offset. The function returns true + /// iff it has successfully reched the end of the list. This means that one + /// can attempt to parse another list after the current one (\p Offset will be + /// updated to point past the end of the current list). + bool dumpLocationList(uint64_t *Offset, raw_ostream &OS, uint64_t BaseAddr, + const MCRegisterInfo *MRI, DWARFUnit *U, + DIDumpOptions DumpOpts, unsigned Indent) const; + +protected: + DWARFDataExtractor Data; + + virtual void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS, + unsigned Indent) const = 0; +}; + class DWARFDebugLoc { public: /// A single location within a location list. @@ -74,46 +122,26 @@ parseOneLocationList(const DWARFDataExtractor &Data, uint64_t *Offset); }; -class DWARFDebugLoclists { +class DWARFDebugLoclists final : public DWARFLocationTable { public: - // Unconstructible. - DWARFDebugLoclists() = delete; + DWARFDebugLoclists(DWARFDataExtractor Data, uint16_t Version) + : DWARFLocationTable(std::move(Data)), Version(Version) {} - struct Entry { - uint8_t Kind; - uint64_t Offset; - uint64_t Value0; - uint64_t Value1; - SmallVector Loc; - void dump(raw_ostream &OS, uint64_t &BaseAddr, bool IsLittleEndian, - unsigned AddressSize, const MCRegisterInfo *MRI, DWARFUnit *U, - DIDumpOptions DumpOpts, unsigned Indent, size_t MaxEncodingStringLength) const; - }; + Error visitLocationList( + uint64_t *Offset, + function_ref F) const override; - /// Call the user-provided callback for each entry (including the end-of-list - /// entry) in the location list starting at \p Offset. The callback can return - /// false to terminate the iteration early. Returns an error if it was unable - /// to parse the entire location list correctly. Upon successful termination - /// \p Offset will be updated point past the end of the list. - static Error visitLocationList(const DWARFDataExtractor &Data, - uint64_t *Offset, uint16_t Version, - llvm::function_ref F); + /// Dump all location lists within the given range. + void dumpRange(uint64_t StartOffset, uint64_t Size, raw_ostream &OS, + uint64_t BaseAddr, const MCRegisterInfo *MRI, + DIDumpOptions DumpOpts); - /// Dump the location list at the given \p Offset. The function returns true - /// iff it has successfully reched the end of the list. This means that one - /// can attempt to parse another list after the current one (\p Offset will be - /// updated to point past the end of the current list). - static bool dumpLocationList(const DWARFDataExtractor &Data, uint64_t *Offset, - uint16_t Version, raw_ostream &OS, - uint64_t BaseAddr, const MCRegisterInfo *MRI, - DWARFUnit *U, DIDumpOptions DumpOpts, - unsigned Indent); +protected: + void dumpRawEntry(const DWARFLocationEntry &Entry, raw_ostream &OS, + unsigned Indent) const override; - /// Dump all location lists within the given range. - static void dumpRange(const DWARFDataExtractor &Data, uint64_t StartOffset, - uint64_t Size, uint16_t Version, raw_ostream &OS, - uint64_t BaseAddr, const MCRegisterInfo *MRI, - DIDumpOptions DumpOpts); +private: + uint16_t Version; }; } // end namespace llvm diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFLocationExpression.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFLocationExpression.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFLocationExpression.h @@ -0,0 +1,32 @@ +//===- DWARFLocationExpression.h --------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_DWARF_DWARFLOCATIONEXPRESSION_H +#define LLVM_DEBUGINFO_DWARF_DWARFLOCATIONEXPRESSION_H + +#include "llvm/ADT/Optional.h" +#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h" + +namespace llvm { + +/// Represents a single DWARF expression, whose value is location-dependent. +/// Typically used in DW_AT_location attributes to describe the location of +/// objects. +struct DWARFLocationExpression { + /// The address range in which this expression is valid. None denotes a + /// default entry which is valid in addresses not covered by other location + /// expressions, or everywhere if there are no other expressions. + Optional Range; + + /// The expression itself. + SmallVector Expr; +}; + +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_DWARF_DWARFLOCATIONEXPRESSION_H diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -302,18 +302,18 @@ uint64_t EndOffset = Header.length() + Header.getHeaderOffset(); Data.setAddressSize(Header.getAddrSize()); + DWARFDebugLoclists Loc(Data, Header.getVersion()); if (DumpOffset) { if (DumpOffset >= Offset && DumpOffset < EndOffset) { Offset = *DumpOffset; - DWARFDebugLoclists::dumpLocationList(Data, &Offset, Header.getVersion(), - OS, /*BaseAddr=*/0, MRI, nullptr, - DumpOpts, /*Indent=*/0); + Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/0, MRI, nullptr, + DumpOpts, /*Indent=*/0); OS << "\n"; return; } } else { - DWARFDebugLoclists::dumpRange(Data, Offset, EndOffset - Offset, - Header.getVersion(), OS, 0, MRI, DumpOpts); + Loc.dumpRange(Offset, EndOffset - Offset, OS, /*BaseAddr=*/0, MRI, + DumpOpts); } Offset = EndOffset; } @@ -405,16 +405,16 @@ DObj->getLocDWOSection().Data)) { DWARFDataExtractor Data(*DObj, DObj->getLocDWOSection(), isLittleEndian(), 4); + DWARFDebugLoclists Loc(Data, /*Version=*/4); if (*Off) { uint64_t Offset = **Off; - DWARFDebugLoclists::dumpLocationList(Data, &Offset, /*Version=*/4, OS, - /*BaseAddr=*/0, getRegisterInfo(), - nullptr, DumpOpts, /*Indent=*/0); + Loc.dumpLocationList(&Offset, OS, + /*BaseAddr=*/0, getRegisterInfo(), nullptr, DumpOpts, + /*Indent=*/0); OS << "\n"; } else { - DWARFDebugLoclists::dumpRange(Data, 0, Data.getData().size(), - /*Version=*/4, OS, /*BaseAddr=*/0, - getRegisterInfo(), DumpOpts); + Loc.dumpRange(0, Data.getData().size(), OS, /*BaseAddr=*/0, + getRegisterInfo(), DumpOpts); } } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -22,6 +22,72 @@ #include using namespace llvm; +using object::SectionedAddress; + +namespace { +class DWARFLocationInterpreter { + Optional Base; + std::function(uint32_t)> LookupAddr; + +public: + DWARFLocationInterpreter( + Optional Base, + std::function(uint32_t)> LookupAddr) + : Base(Base), LookupAddr(std::move(LookupAddr)) {} + + Expected> + Interpret(const DWARFLocationEntry &E); +}; +} // namespace + +static Error createResolverError(uint32_t Index, unsigned Kind) { + return createStringError(errc::invalid_argument, + "Unable to resolve indirect address %u for: %s", + Index, dwarf::LocListEncodingString(Kind).data()); +} + +Expected> +DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) { + switch (E.Kind) { + case dwarf::DW_LLE_end_of_list: + return None; + case dwarf::DW_LLE_base_addressx: { + Base = LookupAddr(E.Value0); + if (!Base) + return createResolverError(E.Value0, E.Kind); + return None; + } + case dwarf::DW_LLE_startx_length: { + Optional LowPC = LookupAddr(E.Value0); + if (!LowPC) + return createResolverError(E.Value0, E.Kind); + return DWARFLocationExpression{DWARFAddressRange{LowPC->Address, + LowPC->Address + E.Value1, + LowPC->SectionIndex}, + E.Loc}; + } + case dwarf::DW_LLE_offset_pair: + if (!Base) { + return createStringError( + inconvertibleErrorCode(), + "Unable to resolve DW_LLE_offset_pair: base address unknown"); + } + return DWARFLocationExpression{DWARFAddressRange{Base->Address + E.Value0, + Base->Address + E.Value1, + Base->SectionIndex}, + E.Loc}; + case dwarf::DW_LLE_base_address: + Base = SectionedAddress{E.Value0, SectionedAddress::UndefSection}; + return None; + case dwarf::DW_LLE_start_length: + return DWARFLocationExpression{ + DWARFAddressRange{E.Value0, E.Value0 + E.Value1, + SectionedAddress::UndefSection}, + E.Loc}; + default: + llvm_unreachable("unreachable locations list kind"); + } +} // 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 @@ -35,6 +101,51 @@ DWARFExpression(Extractor, dwarf::DWARF_VERSION, AddressSize).print(OS, MRI, U); } +bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS, + uint64_t BaseAddr, + const MCRegisterInfo *MRI, + DWARFUnit *U, DIDumpOptions DumpOpts, + unsigned Indent) const { + DWARFLocationInterpreter Interp( + SectionedAddress{BaseAddr, SectionedAddress::UndefSection}, + [U](uint32_t Index) -> Optional { + if (U) + return U->getAddrOffsetSectionItem(Index); + return None; + }); + OS << format("0x%8.8" PRIx64 ": ", *Offset); + Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) { + Expected> Loc = Interp.Interpret(E); + if (!Loc || DumpOpts.Verbose) + dumpRawEntry(E, OS, Indent); + if (Loc && *Loc) { + OS << "\n"; + OS.indent(Indent); + if (DumpOpts.Verbose) + OS << " => "; + Loc.get()->Range->dump(OS, Data.getAddressSize(), DumpOpts); + } + if (!Loc) + consumeError(Loc.takeError()); + + if (E.Kind != dwarf::DW_LLE_base_address && + E.Kind != dwarf::DW_LLE_base_addressx && + E.Kind != dwarf::DW_LLE_end_of_list) { + OS << ": "; + dumpExpression(OS, E.Loc, Data.isLittleEndian(), Data.getAddressSize(), + MRI, U); + } + return true; + }); + if (E) { + OS << "\n"; + OS.indent(Indent); + OS << "error: " << toString(std::move(E)); + return false; + } + return true; +} + void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, uint64_t BaseAddress, bool IsLittleEndian, unsigned AddressSize, @@ -140,14 +251,12 @@ } Error DWARFDebugLoclists::visitLocationList( - const DWARFDataExtractor &Data, uint64_t *Offset, uint16_t Version, - llvm::function_ref F) { + uint64_t *Offset, function_ref F) const { DataExtractor::Cursor C(*Offset); bool Continue = true; while (Continue) { - Entry E; - E.Offset = C.tell(); + DWARFLocationEntry E; E.Kind = Data.getU8(C); switch (E.Kind) { case dwarf::DW_LLE_end_of_list: @@ -200,113 +309,41 @@ return Error::success(); } -bool DWARFDebugLoclists::dumpLocationList(const DWARFDataExtractor &Data, - uint64_t *Offset, uint16_t Version, - raw_ostream &OS, uint64_t BaseAddr, - const MCRegisterInfo *MRI, - DWARFUnit *U, DIDumpOptions DumpOpts, - unsigned Indent) { +void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry, + raw_ostream &OS, unsigned Indent) const { size_t MaxEncodingStringLength = 0; - if (DumpOpts.Verbose) { #define HANDLE_DW_LLE(ID, NAME) \ MaxEncodingStringLength = std::max(MaxEncodingStringLength, \ dwarf::LocListEncodingString(ID).size()); #include "llvm/BinaryFormat/Dwarf.def" - } - - OS << format("0x%8.8" PRIx64 ": ", *Offset); - Error E = visitLocationList(Data, Offset, Version, [&](const Entry &E) { - E.dump(OS, BaseAddr, Data.isLittleEndian(), Data.getAddressSize(), MRI, U, - DumpOpts, Indent, MaxEncodingStringLength); - return true; - }); - if (E) { - OS << "\n"; - OS.indent(Indent); - OS << "error: " << toString(std::move(E)); - return false; - } - return true; -} -void DWARFDebugLoclists::Entry::dump(raw_ostream &OS, uint64_t &BaseAddr, - bool IsLittleEndian, unsigned AddressSize, - const MCRegisterInfo *MRI, DWARFUnit *U, - DIDumpOptions DumpOpts, unsigned Indent, - size_t MaxEncodingStringLength) const { - if (DumpOpts.Verbose) { - OS << "\n"; - OS.indent(Indent); - auto EncodingString = dwarf::LocListEncodingString(Kind); - // Unsupported encodings should have been reported during parsing. - assert(!EncodingString.empty() && "Unknown loclist entry encoding"); - OS << format("%s%*c", EncodingString.data(), - MaxEncodingStringLength - EncodingString.size() + 1, '('); - switch (Kind) { - case dwarf::DW_LLE_startx_length: - case dwarf::DW_LLE_start_length: - case dwarf::DW_LLE_offset_pair: - OS << format("0x%*.*" PRIx64 ", 0x%*.*" PRIx64, AddressSize * 2, - AddressSize * 2, Value0, AddressSize * 2, AddressSize * 2, - Value1); - break; - case dwarf::DW_LLE_base_addressx: - case dwarf::DW_LLE_base_address: - OS << format("0x%*.*" PRIx64, AddressSize * 2, AddressSize * 2, - Value0); - break; - case dwarf::DW_LLE_end_of_list: - break; - } - OS << ')'; - } - auto PrintPrefix = [&] { - OS << "\n"; - OS.indent(Indent); - if (DumpOpts.Verbose) - OS << format("%*s", MaxEncodingStringLength, (const char *)"=> "); - }; - switch (Kind) { + OS << "\n"; + OS.indent(Indent); + StringRef EncodingString = dwarf::LocListEncodingString(Entry.Kind); + // Unsupported encodings should have been reported during parsing. + assert(!EncodingString.empty() && "Unknown loclist entry encoding"); + OS << format("%-*s(", MaxEncodingStringLength, EncodingString.data()); + unsigned FieldSize = 2 + 2 * Data.getAddressSize(); + switch (Entry.Kind) { case dwarf::DW_LLE_startx_length: - PrintPrefix(); - OS << "Addr idx " << Value0 << " (w/ length " << Value1 << "): "; - break; case dwarf::DW_LLE_start_length: - PrintPrefix(); - DWARFAddressRange(Value0, Value0 + Value1) - .dump(OS, AddressSize, DumpOpts); - OS << ": "; - break; case dwarf::DW_LLE_offset_pair: - PrintPrefix(); - DWARFAddressRange(BaseAddr + Value0, BaseAddr + Value1) - .dump(OS, AddressSize, DumpOpts); - OS << ": "; + OS << format_hex(Entry.Value0, FieldSize) << ", " + << format_hex(Entry.Value1, FieldSize); break; case dwarf::DW_LLE_base_addressx: - if (!DumpOpts.Verbose) - return; + case dwarf::DW_LLE_base_address: + OS << format_hex(Entry.Value0, FieldSize); break; case dwarf::DW_LLE_end_of_list: - if (!DumpOpts.Verbose) - return; break; - case dwarf::DW_LLE_base_address: - BaseAddr = Value0; - if (!DumpOpts.Verbose) - return; - break; - default: - llvm_unreachable("unreachable locations list kind"); } - - dumpExpression(OS, Loc, IsLittleEndian, AddressSize, MRI, U); + OS << ')'; } -void DWARFDebugLoclists::dumpRange(const DWARFDataExtractor &Data, - uint64_t StartOffset, uint64_t Size, - uint16_t Version, raw_ostream &OS, - uint64_t BaseAddr, const MCRegisterInfo *MRI, +void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size, + raw_ostream &OS, uint64_t BaseAddr, + const MCRegisterInfo *MRI, DIDumpOptions DumpOpts) { if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) { OS << "Invalid dump range\n"; @@ -319,8 +356,8 @@ OS << Separator; Separator = "\n"; - CanContinue = dumpLocationList(Data, &Offset, Version, OS, BaseAddr, MRI, - nullptr, DumpOpts, /*Indent=*/12); + CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, nullptr, + DumpOpts, /*Indent=*/12); OS << '\n'; } } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -133,9 +133,8 @@ // 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. - DWARFDebugLoclists::dumpLocationList( - Data, &Offset, UseLocLists ? U->getVersion() : 4, OS, BaseAddr, MRI, - U, LLDumpOpts, Indent); + DWARFDebugLoclists(Data, UseLocLists ? U->getVersion() : 4) + .dumpLocationList(&Offset, OS, BaseAddr, MRI, U, LLDumpOpts, Indent); } return; } diff --git a/llvm/test/CodeGen/X86/debug-loclists.ll b/llvm/test/CodeGen/X86/debug-loclists.ll --- a/llvm/test/CodeGen/X86/debug-loclists.ll +++ b/llvm/test/CodeGen/X86/debug-loclists.ll @@ -11,7 +11,7 @@ ; CHECK: DW_TAG_variable ; FIXME: Use DW_FORM_loclistx to reduce relocations ; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x0000001d -; CHECK-NEXT: Addr idx 0 (w/ length 3): DW_OP_consts +5, DW_OP_stack_value) +; CHECK-NEXT: [0x0000000000000000, 0x0000000000000003): DW_OP_consts +5, DW_OP_stack_value) ; CHECK-NEXT: DW_AT_name {{.*}} "x" ; CHECK: DW_TAG_variable @@ -29,17 +29,14 @@ ; CHECK-NEXT: 0x0000000c: ; CHECK-NEXT: DW_LLE_base_addressx (0x0000000000000000) -; CHECK-NEXT: DW_LLE_offset_pair (0x0000000000000000, 0x0000000000000003) -; CHECK-NEXT: => [0x0000000000000000, 0x0000000000000003): DW_OP_consts +3, DW_OP_stack_value -; CHECK-NEXT: DW_LLE_offset_pair (0x0000000000000003, 0x0000000000000004) -; CHECK-NEXT: => [0x0000000000000003, 0x0000000000000004): DW_OP_consts +4, DW_OP_stack_value +; CHECK-NEXT: DW_LLE_offset_pair (0x0000000000000000, 0x0000000000000003): DW_OP_consts +3, DW_OP_stack_value +; CHECK-NEXT: DW_LLE_offset_pair (0x0000000000000003, 0x0000000000000004): DW_OP_consts +4, DW_OP_stack_value ; CHECK-NEXT: DW_LLE_end_of_list () ; Show that startx_length can be used when the address range starts at the start of the function. ; CHECK: 0x0000001d: -; CHECK-NEXT: DW_LLE_startx_length (0x0000000000000000, 0x0000000000000003) -; CHECK-NEXT: => Addr idx 0 (w/ length 3): DW_OP_consts +5, DW_OP_stack_value +; CHECK-NEXT: DW_LLE_startx_length (0x0000000000000000, 0x0000000000000003): DW_OP_consts +5, DW_OP_stack_value ; CHECK-NEXT: DW_LLE_end_of_list () ; And use a base address when the range doesn't start at an existing/useful @@ -47,8 +44,7 @@ ; CHECK: 0x00000025: ; CHECK-NEXT: DW_LLE_base_addressx (0x0000000000000000) -; CHECK-NEXT: DW_LLE_offset_pair (0x0000000000000003, 0x0000000000000004) -; CHECK-NEXT: => [0x0000000000000003, 0x0000000000000004): DW_OP_reg0 RAX +; CHECK-NEXT: DW_LLE_offset_pair (0x0000000000000003, 0x0000000000000004): DW_OP_reg0 RAX ; CHECK-NEXT: DW_LLE_end_of_list () ; Built with clang -O3 -ffunction-sections from source: diff --git a/llvm/test/DebugInfo/X86/fission-ranges.ll b/llvm/test/DebugInfo/X86/fission-ranges.ll --- a/llvm/test/DebugInfo/X86/fission-ranges.ll +++ b/llvm/test/DebugInfo/X86/fission-ranges.ll @@ -45,30 +45,21 @@ ; if they've changed due to a bugfix, change in register allocation, etc. ; CHECK: [[A]]: -; CHECK-NEXT: DW_LLE_startx_length (0x00000002, 0x0000000f) -; CHECK-NEXT: => Addr idx 2 (w/ length 15): DW_OP_consts +0, DW_OP_stack_value -; CHECK-NEXT: DW_LLE_startx_length (0x00000003, 0x0000000f) -; CHECK-NEXT: => Addr idx 3 (w/ length 15): DW_OP_reg0 RAX -; CHECK-NEXT: DW_LLE_startx_length (0x00000004, 0x00000012) -; 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-NEXT: DW_LLE_end_of_list () ; CHECK: [[E]]: -; CHECK-NEXT: DW_LLE_startx_length (0x00000005, 0x00000009) -; CHECK-NEXT: => Addr idx 5 (w/ length 9): DW_OP_reg0 RAX -; CHECK-NEXT: DW_LLE_startx_length (0x00000006, 0x00000062) -; 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-NEXT: DW_LLE_end_of_list () ; CHECK: [[B]]: -; CHECK-NEXT: DW_LLE_startx_length (0x00000007, 0x0000000f) -; CHECK-NEXT: => Addr idx 7 (w/ length 15): DW_OP_reg0 RAX -; CHECK-NEXT: DW_LLE_startx_length (0x00000008, 0x00000042) -; 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-NEXT: DW_LLE_end_of_list () ; CHECK: [[D]]: -; CHECK-NEXT: DW_LLE_startx_length (0x00000009, 0x0000000f) -; CHECK-NEXT: => Addr idx 9 (w/ length 15): DW_OP_reg0 RAX -; CHECK-NEXT: DW_LLE_startx_length (0x0000000a, 0x0000002a) -; 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 ; CHECK-NEXT: DW_LLE_end_of_list () ; Make sure we don't produce any relocations in any .dwo section (though in particular, debug_info.dwo) diff --git a/llvm/test/DebugInfo/X86/loclists-dwp.ll b/llvm/test/DebugInfo/X86/loclists-dwp.ll --- a/llvm/test/DebugInfo/X86/loclists-dwp.ll +++ b/llvm/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" diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_loc_dwo.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_loc_dwo.s --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_loc_dwo.s +++ b/llvm/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 diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s @@ -3,11 +3,11 @@ # CHECK: DW_AT_location (0x0000000c -# CHECK-NEXT: Addr idx 0 (w/ length 1): DW_OP_reg0 RAX +# CHECK-NEXT: [0x0000000000000000, 0x0000000000000001): DW_OP_reg0 RAX # CHECK-NEXT: [0x0000000000000001, 0x0000000000000002): DW_OP_reg1 RDX # CHECK-NEXT: [0x0000000000000002, 0x0000000000000003): DW_OP_reg2 RCX # CHECK-NEXT: [0x0000000000000003, 0x0000000000000004): DW_OP_reg3 RBX -# CHECK-NEXT: Addr idx 57005 (w/ length 1): DW_OP_reg4 RSI) +# CHECK-NEXT: DW_LLE_startx_length (0x000000000000dead, 0x0000000000000001): DW_OP_reg4 RSI) .text diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s --- a/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s +++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s @@ -8,8 +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: 0x0000000c: -# CHECK-NEXT: DW_LLE_startx_length (0x0000000000000001, 0x0000000000000010) -# CHECK-NEXT: => Addr idx 1 (w/ length 16): DW_OP_reg5 RDI +# CHECK-NEXT: DW_LLE_startx_length (0x0000000000000001, 0x0000000000000010): DW_OP_reg5 RDI # CHECK-NEXT: DW_LLE_end_of_list () .section .debug_loclists,"",@progbits