[llvm] ebe2f56 - DWARFDebugLoclists: add location list "interpretation" logic

Pavel Labath via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 12 01:41:13 PST 2019


Author: Pavel Labath
Date: 2019-11-12T10:40:13+01:00
New Revision: ebe2f56030458e7a4c2375c6d92a48f0ed01eb5b

URL: https://github.com/llvm/llvm-project/commit/ebe2f56030458e7a4c2375c6d92a48f0ed01eb5b
DIFF: https://github.com/llvm/llvm-project/commit/ebe2f56030458e7a4c2375c6d92a48f0ed01eb5b.diff

LOG: DWARFDebugLoclists: add location list "interpretation" logic

Summary:
This patch extracts the logic for computing the "absolute" locations,
which was partially present in the debug_loclists dumper, completes it,
and moves it into a separate function. This makes it possible to later
reuse the same logic for uses other than dumping.

The dumper is changed to reuse the location list interpreter, and its
format is changed somewhat. In "verbose" mode it prints the "raw" value
of a location list, the interpreted location (if available) and the
expression itself. In non-verbose mode it prints only one of the
location forms: it prefers the interpreted form, but falls back to the
"raw" format if interpretation is not possible (for instance, because we
were not given a base address, or the resolution of indirect addresses
failed).

This patch also undos some of the changes made in D69672, namely the
part about making all functions static. The main reason for this is that
I learned that the original approach (dumping only fully resolved
locations) meant that it was impossible to rewrite one of the existing
tests. To make that possible (and make the "inline location" dump work
in more cases), I now reuse the same dumping mechanism as is used for
section-based dumping. As this required having more objects know about
the various location lists classes, it seemed like a good idea to create
an interface abstracting the difference between them.

Therefore, I now create a DWARFLocationTable class, which will serve as
a base class for the location list classes. DWARFDebugLoclists is made
to inherit from that. DWARFDebugLoc will follow.

Another positive effect of this change is that section-based dumping
code will not need to use templates (as originally) envisioned, and that
the argument lists of the dumping functions become shorter.

Reviewers: dblaikie, probinson, JDevlieghere, aprantl, SouraVX

Subscribers: hiraditya, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D70081

Added: 
    llvm/include/llvm/DebugInfo/DWARF/DWARFLocationExpression.h

Modified: 
    llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
    llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
    llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
    llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
    llvm/test/CodeGen/X86/debug-loclists.ll
    llvm/test/DebugInfo/X86/fission-ranges.ll
    llvm/test/DebugInfo/X86/loclists-dwp.ll
    llvm/test/tools/llvm-dwarfdump/X86/debug_loc_dwo.s
    llvm/test/tools/llvm-dwarfdump/X86/debug_loclists.s
    llvm/test/tools/llvm-dwarfdump/X86/debug_loclists_startx_length.s

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
index 25b771317749..356757b5724d 100644
--- 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 <cstdint>
 
@@ -21,6 +22,53 @@ class DWARFUnit;
 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<uint8_t, 4> 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<bool(const DWARFLocationEntry &)> 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 @@ class DWARFDebugLoc {
   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<uint8_t, 4> 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<bool(const DWARFLocationEntry &)> 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<bool(const Entry &)> 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
index 000000000000..7bde33d394fd
--- /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<DWARFAddressRange> Range;
+
+  /// The expression itself.
+  SmallVector<uint8_t, 4> 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
index e13b3836b133..7ca319baa8e4 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -302,18 +302,18 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
 
     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 @@ void DWARFContext::dump(
                      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
index e0faaed035d0..8bb9fc5837d3 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -22,6 +22,72 @@
 #include <cstdint>
 
 using namespace llvm;
+using object::SectionedAddress;
+
+namespace {
+class DWARFLocationInterpreter {
+  Optional<object::SectionedAddress> Base;
+  std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr;
+
+public:
+  DWARFLocationInterpreter(
+      Optional<object::SectionedAddress> Base,
+      std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr)
+      : Base(Base), LookupAddr(std::move(LookupAddr)) {}
+
+  Expected<Optional<DWARFLocationExpression>>
+  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<Optional<DWARFLocationExpression>>
+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<SectionedAddress> 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 @@ static void dumpExpression(raw_ostream &OS, ArrayRef<uint8_t> Data,
   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<SectionedAddress> {
+        if (U)
+          return U->getAddrOffsetSectionItem(Index);
+        return None;
+      });
+  OS << format("0x%8.8" PRIx64 ": ", *Offset);
+  Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
+    Expected<Optional<DWARFLocationExpression>> 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 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
 }
 
 Error DWARFDebugLoclists::visitLocationList(
-    const DWARFDataExtractor &Data, uint64_t *Offset, uint16_t Version,
-    llvm::function_ref<bool(const Entry &)> F) {
+    uint64_t *Offset, function_ref<bool(const DWARFLocationEntry &)> 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 @@ Error DWARFDebugLoclists::visitLocationList(
   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 @@ void DWARFDebugLoclists::dumpRange(const DWARFDataExtractor &Data,
     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
index ebc8cc565f34..22ae8ebb6494 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -133,9 +133,8 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
       // 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
index 7746826f30f6..ba6eb6a988cf 100644
--- 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
index 8f72ee116f55..1c5d2e9479f5 100644
--- 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
index cba81a8a952a..91f838876338 100644
--- 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
index b1555df02ad6..3de9c5cdf344 100644
--- 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,"", at 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
index a44080eb9946..59c0a967013a 100644
--- 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
index 25e883381c19..4203c382ee7f 100644
--- 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,"", at progbits


        


More information about the llvm-commits mailing list