[DWARF v5] Support for verbose dumping of .debug_rnglist entries
authorWolfgang Pieb <Wolfgang.Pieb@sony.com>
Thu, 8 Mar 2018 20:52:35 +0000 (20:52 +0000)
committerWolfgang Pieb <Wolfgang.Pieb@sony.com>
Thu, 8 Mar 2018 20:52:35 +0000 (20:52 +0000)
Adding verbose dumping to the recent implementation of dumping of v5 range list entries.
We're capturing the entries as is as they come in during extraction, including their file offset,
so we can dump them in more detail.
The offset table entries which are table-relative are shown as is (as in non-verbose mode)
and with the actual file offset they map to.

Reviewers: dblaikie, aprantl, jdevlieghere, jhenderson

Subscribers: llvm-commits

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

llvm-svn: 327059

llvm/include/llvm/BinaryFormat/Dwarf.h
llvm/include/llvm/DebugInfo/DIContext.h
llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h
llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
llvm/lib/BinaryFormat/Dwarf.cpp
llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s [new file with mode: 0644]
llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists.s
llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s

index 3ca7164..b21feff 100644 (file)
@@ -423,6 +423,7 @@ StringRef ArrayOrderString(unsigned Order);
 StringRef LNStandardString(unsigned Standard);
 StringRef LNExtendedString(unsigned Encoding);
 StringRef MacinfoString(unsigned Encoding);
+StringRef RangeListEncodingString(unsigned Encoding);
 StringRef CallFrameString(unsigned Encoding);
 StringRef ApplePropertyString(unsigned);
 StringRef UnitTypeString(unsigned);
index 751bbe3..f89eb34 100644 (file)
@@ -160,6 +160,7 @@ struct DIDumpOptions {
   bool ShowForm = false;
   bool SummarizeTypes = false;
   bool Verbose = false;
+  bool DisplayRawContents = false;
 
   /// Return default option set for printing a single DIE without children.
   static DIDumpOptions getForSingleDIE() {
index 8fe08e8..c777889 100644 (file)
@@ -10,6 +10,7 @@
 #ifndef LLVM_DEBUGINFO_DWARF_DWARFADDRESSRANGE_H
 #define LLVM_DEBUGINFO_DWARF_DWARFADDRESSRANGE_H
 
+#include "llvm/DebugInfo/DIContext.h"
 #include <cstdint>
 #include <tuple>
 #include <vector>
@@ -48,7 +49,8 @@ struct DWARFAddressRange {
     return false;
   }
 
-  void dump(raw_ostream &OS, uint32_t AddressSize) const;
+  void dump(raw_ostream &OS, uint32_t AddressSize,
+            DIDumpOptions DumpOpts = {}) const;
 };
 
 static inline bool operator<(const DWARFAddressRange &LHS,
index 19d8dd1..7579def 100644 (file)
@@ -10,6 +10,7 @@
 #ifndef LLVM_DEBUGINFO_DWARFDEBUGRNGLISTS_H
 #define LLVM_DEBUGINFO_DWARFDEBUGRNGLISTS_H
 
+#include "llvm/DebugInfo/DIContext.h"
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
 #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
 #include <cstdint>
@@ -39,14 +40,35 @@ private:
     uint32_t OffsetEntryCount;
   };
 
+public:
+  struct RangeListEntry {
+    /// The offset at which the entry is located in the section.
+    const uint32_t Offset;
+    /// The DWARF encoding (DW_RLE_*).
+    const uint8_t EntryKind;
+    /// The values making up the range list entry. Most represent a range with
+    /// a start and end address or a start address and a length. Others are
+    /// single value base addresses or end-of-list with no values. The unneeded
+    /// values are semantically undefined, but initialized to 0.
+    const uint64_t Value0;
+    const uint64_t Value1;
+  };
+
+  using DWARFRangeList = std::vector<RangeListEntry>;
+
+private:
+  uint32_t HeaderOffset;
   Header HeaderData;
   std::vector<uint32_t> Offsets;
-  std::vector<DWARFAddressRangesVector> Ranges;
+  std::vector<DWARFRangeList> Ranges;
+  // The length of the longest encoding string we encountered during parsing.
+  uint8_t MaxEncodingStringLength = 0;
 
 public:
   void clear();
   Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr);
-  void dump(raw_ostream &OS) const;
+  uint32_t getHeaderOffset() const { return HeaderOffset; }
+  void dump(raw_ostream &OS, DIDumpOptions DumpOpts) const;
 
   /// Returns the length of this table, including the length field, or 0 if the
   /// length has not been determined (e.g. because the table has not yet been
index bea3df8..e345b3a 100644 (file)
@@ -444,6 +444,17 @@ unsigned llvm::dwarf::getMacinfo(StringRef MacinfoString) {
       .Default(DW_MACINFO_invalid);
 }
 
+StringRef llvm::dwarf::RangeListEncodingString(unsigned Encoding) {
+  switch (Encoding) {
+  default:
+    return StringRef();
+#define HANDLE_DW_RLE(ID, NAME)                                                \
+  case DW_RLE_##NAME:                                                          \
+    return "DW_RLE_" #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+  }
+}
+
 StringRef llvm::dwarf::CallFrameString(unsigned Encoding) {
   switch (Encoding) {
   default:
index 058d319..86c8d19 100644 (file)
 
 using namespace llvm;
 
-void DWARFAddressRange::dump(raw_ostream &OS, uint32_t AddressSize) const {
+void DWARFAddressRange::dump(raw_ostream &OS, uint32_t AddressSize,
+                             DIDumpOptions DumpOpts) const {
 
-  OS << format("[0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2, LowPC)
-     << format(" 0x%*.*" PRIx64 ")", AddressSize * 2, AddressSize * 2, HighPC);
+  OS << (DumpOpts.DisplayRawContents ? " " : "[");
+  OS << format("0x%*.*" PRIx64 ", ", AddressSize * 2, AddressSize * 2, LowPC)
+     << format("0x%*.*" PRIx64, AddressSize * 2, AddressSize * 2, HighPC);
+  OS << (DumpOpts.DisplayRawContents ? "" : ")");
 }
 
 raw_ostream &llvm::operator<<(raw_ostream &OS, const DWARFAddressRange &R) {
index 2b1c91e..3a974dd 100644 (file)
@@ -509,8 +509,9 @@ void DWARFContext::dump(
         if (Length == 0)
           break;
         Offset = TableOffset + Length;
-      } else
-        Rnglists.dump(OS);
+      } else {
+        Rnglists.dump(OS, DumpOpts);
+      }
     }
   }
 
index 802fb7e..c2b8b8a 100644 (file)
@@ -33,7 +33,7 @@ static Error createError(char const *Fmt, const Ts &... Vals) {
 Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
                                   uint32_t *OffsetPtr) {
   clear();
-  uint32_t TableOffset = *OffsetPtr;
+  HeaderOffset = *OffsetPtr;
 
   // Read and verify the length field.
   if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t)))
@@ -42,17 +42,21 @@ Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
                        *OffsetPtr);
   // TODO: Add support for DWARF64.
   HeaderData.Length = Data.getU32(OffsetPtr);
+  if (HeaderData.Length == 0xffffffffu)
+    return createError(
+        "DWARF64 is not supported in .debug_rnglists at offset 0x%" PRIx32,
+        HeaderOffset);
   if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header))
     return createError(".debug_rnglists table at offset 0x%" PRIx32
                        " has too small length (0x%" PRIx32
                        ") to contain a complete header",
-                       TableOffset, length());
-  uint32_t End = TableOffset + length();
-  if (!Data.isValidOffsetForDataOfSize(TableOffset, End - TableOffset))
+                       HeaderOffset, length());
+  uint32_t End = HeaderOffset + length();
+  if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset))
     return createError(
         "section is not large enough to contain a .debug_rnglists table "
         "of length 0x%" PRIx32 " at offset 0x%" PRIx32,
-        length(), TableOffset);
+        length(), HeaderOffset);
 
   HeaderData.Version = Data.getU16(OffsetPtr);
   HeaderData.AddrSize = Data.getU8(OffsetPtr);
@@ -63,32 +67,37 @@ Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
   if (HeaderData.Version != 5)
     return createError("unrecognised .debug_rnglists table version %" PRIu16
                        " in table at offset 0x%" PRIx32,
-                       HeaderData.Version, TableOffset);
+                       HeaderData.Version, HeaderOffset);
   if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
     return createError(".debug_rnglists table at offset 0x%" PRIx32
                        " has unsupported address size %hhu",
-                       TableOffset, HeaderData.AddrSize);
+                       HeaderOffset, HeaderData.AddrSize);
   if (HeaderData.SegSize != 0)
     return createError(".debug_rnglists table at offset 0x%" PRIx32
                        " has unsupported segment selector size %" PRIu8,
-                       TableOffset, HeaderData.SegSize);
-  if (End < TableOffset + sizeof(HeaderData) +
+                       HeaderOffset, HeaderData.SegSize);
+  if (End < HeaderOffset + sizeof(HeaderData) +
                 HeaderData.OffsetEntryCount * sizeof(uint32_t))
     return createError(".debug_rnglists table at offset 0x%" PRIx32
                        " has more offset entries (%" PRIu32
                        ") than there is space for",
-                       TableOffset, HeaderData.OffsetEntryCount);
+                       HeaderOffset, HeaderData.OffsetEntryCount);
 
   Data.setAddressSize(HeaderData.AddrSize);
 
   for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I)
     Offsets.push_back(Data.getU32(OffsetPtr));
 
-  DWARFAddressRangesVector CurrentRanges;
+  DWARFRangeList CurrentRanges;
   while (*OffsetPtr < End) {
+    uint32_t EntryOffset = *OffsetPtr;
     uint8_t Encoding = Data.getU8(OffsetPtr);
+    MaxEncodingStringLength =
+        std::max(MaxEncodingStringLength,
+                 (uint8_t)dwarf::RangeListEncodingString(Encoding).size());
     switch (Encoding) {
     case dwarf::DW_RLE_end_of_list:
+      CurrentRanges.push_back(RangeListEntry{EntryOffset, Encoding});
       Ranges.insert(Ranges.end(), CurrentRanges);
       CurrentRanges.clear();
       break;
@@ -121,7 +130,8 @@ Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
                            *OffsetPtr - 1);
       uint64_t Start = Data.getAddress(OffsetPtr);
       uint64_t End = Data.getAddress(OffsetPtr);
-      CurrentRanges.emplace_back(Start, End);
+      CurrentRanges.push_back(
+          RangeListEntry{EntryOffset, Encoding, Start, End});
       break;
     }
     case dwarf::DW_RLE_start_length: {
@@ -132,7 +142,8 @@ Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
         return createError("read past end of table when reading "
                            "DW_RLE_start_length encoding at offset 0x%" PRIx32,
                            PreviousOffset);
-      CurrentRanges.emplace_back(Start, Start + Length);
+      CurrentRanges.push_back(
+          RangeListEntry{EntryOffset, Encoding, Start, Length});
       break;
     }
     default:
@@ -155,12 +166,55 @@ Error DWARFDebugRnglists::extract(DWARFDataExtractor Data,
     return createError(
         "no end of list marker detected at end of .debug_rnglists table "
         "starting at offset 0x%" PRIx32,
-        TableOffset);
+        HeaderOffset);
   return Error::success();
 }
 
-void DWARFDebugRnglists::dump(raw_ostream &OS) const {
-  // TODO: Add verbose printing of the raw encodings.
+static void dumpRangeEntry(raw_ostream &OS,
+                           DWARFDebugRnglists::RangeListEntry Entry,
+                           uint8_t AddrSize, uint8_t MaxEncodingStringLength,
+                           DIDumpOptions DumpOpts) {
+  if (DumpOpts.Verbose) {
+    // Print the section offset in verbose mode.
+    OS << format("0x%8.8" PRIx32 ":", Entry.Offset);
+    auto EncodingString = dwarf::RangeListEncodingString(Entry.EntryKind);
+    // Unsupported encodings should have been reported during parsing.
+    assert(!EncodingString.empty() && "Unknown range entry encoding");
+    OS << format(" [%s%*c", EncodingString.data(),
+                 MaxEncodingStringLength - EncodingString.size() + 1, ']');
+    if (Entry.EntryKind != dwarf::DW_RLE_end_of_list)
+      OS << ": ";
+  }
+
+  switch (Entry.EntryKind) {
+  case dwarf::DW_RLE_end_of_list:
+    OS << (DumpOpts.Verbose ? "" : "<End of list>");
+    break;
+  case dwarf::DW_RLE_start_length:
+    if (DumpOpts.Verbose) {
+      // Make the address range display its contents in raw form rather than
+      // as an interval (i.e. without brackets).
+      DumpOpts.DisplayRawContents = true;
+      DWARFAddressRange(Entry.Value0, Entry.Value1)
+          .dump(OS, AddrSize, DumpOpts);
+      OS << " => ";
+    }
+    DumpOpts.DisplayRawContents = false;
+    DWARFAddressRange(Entry.Value0, Entry.Value0 + Entry.Value1)
+        .dump(OS, AddrSize, DumpOpts);
+    break;
+  case dwarf::DW_RLE_start_end:
+    DWARFAddressRange(Entry.Value0, Entry.Value1).dump(OS, AddrSize, DumpOpts);
+    break;
+  default:
+    llvm_unreachable("Unsupported range list encoding");
+  }
+  OS << "\n";
+}
+
+void DWARFDebugRnglists::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
+  if (DumpOpts.Verbose)
+    OS << format("0x%8.8" PRIx32 ": ", HeaderOffset);
   OS << format("Range List Header: length = 0x%8.8" PRIx32
                ", version = 0x%4.4" PRIx16 ", "
                "addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8
@@ -171,19 +225,20 @@ void DWARFDebugRnglists::dump(raw_ostream &OS) const {
 
   if (HeaderData.OffsetEntryCount > 0) {
     OS << "Offsets: [";
-    for (const auto &Off : Offsets)
+    for (const auto &Off : Offsets) {
       OS << format("\n0x%8.8" PRIx32, Off);
+      if (DumpOpts.Verbose)
+        OS << format(" => 0x%8.8" PRIx32,
+                     Off + HeaderOffset + sizeof(HeaderData));
+    }
     OS << "\n]\n";
   }
   OS << "Ranges:\n";
 
-  const uint32_t HexWidth = HeaderData.AddrSize * 2;
-  for (const auto &List : Ranges) {
+  for (const auto &List : Ranges)
     for (const auto &Entry : List)
-      OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 ")\n", HexWidth, HexWidth,
-                   Entry.LowPC, HexWidth, HexWidth, Entry.HighPC);
-    OS << "<End of list>\n";
-  }
+      dumpRangeEntry(OS, Entry, HeaderData.AddrSize, MaxEncodingStringLength,
+                     DumpOpts);
 }
 
 uint32_t DWARFDebugRnglists::length() const {
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s
new file mode 100644 (file)
index 0000000..0732eda
--- /dev/null
@@ -0,0 +1,2 @@
+.section .debug_rnglists,"",@progbits
+.long 0xffffffff  # Unsupported DWARF64 format
index 62bb3ce..399ead8 100644 (file)
@@ -1,50 +1,79 @@
-# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o - | \
-# RUN: llvm-dwarfdump --debug-rnglists - 2> %t.err | FileCheck %s
+# RUN: llvm-mc %s -filetype obj -triple x86_64-pc-linux -o %t.o
+# RUN: llvm-dwarfdump --debug-rnglists %t.o 2> %t.err | FileCheck %s --check-prefixes=TERSE,BOTH
 # RUN: FileCheck %s --input-file %t.err --check-prefix=ERR
-
-# CHECK: .debug_rnglists contents:
-# CHECK-NEXT: Range List Header: length = 0x0000003f, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000002
-# CHECK-NEXT: Offsets: [
-# CHECK-NEXT:    0x00000008
-# CHECK-NEXT:    0x0000002b
-# CHECK-NEXT: ]
-# CHECK-NEXT: Ranges:
-# CHECK-NEXT: [0x0000000000000010, 0x0000000000000020)
-# CHECK-NEXT: [0x0000000000000025, 0x00000000000000a5)
-# CHECK-NEXT: <End of list>
-# CHECK-NEXT: [0x0000000000000100, 0x0000000000000200)
-# CHECK-NEXT: <End of list>
-# CHECK-NEXT: Range List Header: length = 0x0000001b, version = 0x0005, addr_size = 0x04, seg_size = 0x00, offset_entry_count = 0x00000000
-# CHECK-NEXT: Ranges:
-# CHECK-NEXT: [0x00000000, 0x00000000)
-# CHECK-NEXT: [0x00000002, 0x00000006)
-# CHECK-NEXT: <End of list>
-# CHECK-NEXT: Range List Header: length = 0x00000008, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
-# CHECK-NOT: Offsets:
-# CHECK: Ranges:
-# CHECK-NOT: [
-# CHECK-NOT: Range List Header:
+# RUN: llvm-dwarfdump -v --debug-rnglists %t.o 2> %t.err | FileCheck %s --check-prefixes=VERBOSE,BOTH
+
+# BOTH:         .debug_rnglists contents:
+# TERSE-NEXT:     Range List Header: length = 0x00000037, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+
+# VERBOSE-NEXT: 0x{{[0-9a-f]*}}:
+# VERBOSE-SAME: Range List Header: length = 0x00000037, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+
+# BOTH-NEXT:    Ranges:
+# TERSE-NEXT:   [0x0000000000000010, 0x0000000000000020)
+# TERSE-NEXT:   [0x0000000000000025, 0x00000000000000a5)
+# TERSE-NEXT:   <End of list>
+# TERSE-NEXT:   [0x0000000000000100, 0x0000000000000200)
+# TERSE-NEXT:   <End of list>
+
+# VERBOSE-NEXT: 0x0000000c: [DW_RLE_start_end   ]: [0x0000000000000010, 0x0000000000000020)
+# VERBOSE-NEXT: 0x0000001d: [DW_RLE_start_length]:  0x0000000000000025, 0x0000000000000080
+# VERBOSE-SAME: => [0x0000000000000025, 0x00000000000000a5)
+# VERBOSE-NEXT: 0x00000028: [DW_RLE_end_of_list ]
+# VERBOSE-NEXT: 0x00000029: [DW_RLE_start_end   ]: [0x0000000000000100, 0x0000000000000200)
+# VERBOSE-NEXT: 0x0000003a: [DW_RLE_end_of_list ]
+
+# TERSE-NEXT:   Range List Header: length = 0x0000002b, version = 0x0005, addr_size = 0x04, seg_size = 0x00, offset_entry_count = 0x00000002
+
+# VERBOSE-NEXT: 0x{{[0-9a-f]*}}:
+# VERBOSE-SAME: Range List Header: length = 0x0000002b, version = 0x0005, addr_size = 0x04, seg_size = 0x00, offset_entry_count = 0x00000002
+
+# BOTH-NEXT:    Offsets: [
+# BOTH-NEXT:      0x00000008
+# VERBOSE-SAME:   => 0x0000004f
+# BOTH-NEXT:      0x0000001b
+# VERBOSE-SAME:   => 0x00000062
+# BOTH-NEXT:    ]
+# BOTH-NEXT:    Ranges:
+
+# TERSE-NEXT:   [0x00000000, 0x00000000)
+# TERSE-NEXT:   [0x00000002, 0x00000006)
+# TERSE-NEXT:   <End of list>
+# TERSE-NEXT:   [0x00000036, 0x00000136)
+# TERSE-NEXT:   <End of list>
+
+# VERBOSE-NEXT: 0x0000004f: [DW_RLE_start_end   ]: [0x00000000, 0x00000000)
+# VERBOSE-NEXT: 0x00000058: [DW_RLE_start_end   ]: [0x00000002, 0x00000006)
+# VERBOSE-NEXT: 0x00000061: [DW_RLE_end_of_list ]
+# VERBOSE-NEXT: 0x00000062: [DW_RLE_start_length]:  0x00000036, 0x00000100 => [0x00000036, 0x00000136)
+# VERBOSE-NEXT: 0x00000069: [DW_RLE_end_of_list ]
+
+# TERSE-NEXT:   Range List Header: length = 0x00000008, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+
+# VERBOSE-NEXT: 0x{{[0-9a-f]*}}:
+# VERBOSE-SAME: Range List Header: length = 0x00000008, version = 0x0005, addr_size = 0x08, seg_size = 0x00, offset_entry_count = 0x00000000
+
+# BOTH-NOT:     Offsets:
+# BOTH:         Ranges:
+# BOTH-NOT:     [
+# BOTH-NOT:     Range List Header:
 
 # ERR-NOT:  error:
-# ERR:      error: unsupported rnglists encoding DW_RLE_base_addressx at offset 0x7a
-# ERR-NEXT: error: unsupported rnglists encoding DW_RLE_startx_endx at offset 0x89
-# ERR-NEXT: error: unsupported rnglists encoding DW_RLE_startx_length at offset 0x99
-# ERR-NEXT: error: unsupported rnglists encoding DW_RLE_offset_pair at offset 0xa9
-# ERR-NEXT: error: unsupported rnglists encoding DW_RLE_base_address at offset 0xb9
+# ERR:      error: unsupported rnglists encoding DW_RLE_base_addressx at offset 0x82
+# ERR-NEXT: error: unsupported rnglists encoding DW_RLE_startx_endx at offset 0x91
+# ERR-NEXT: error: unsupported rnglists encoding DW_RLE_startx_length at offset 0xa1
+# ERR-NEXT: error: unsupported rnglists encoding DW_RLE_offset_pair at offset 0xb1
+# ERR-NEXT: error: unsupported rnglists encoding DW_RLE_base_address at offset 0xc
 # ERR-NOT:  error:
 
 .section .debug_rnglists,"",@progbits
 
 # First table (tests DW_RLE_end_of_list, start_end, and start_length encodings)
-.long 63 # Table length
+.long 55 # Table length
 .short 5 # Version
 .byte 8  # Address size
 .byte 0  # Segment selector size
-.long 2  # Offset entry count
-
-# Offset array
-.long 8  # Offset Entry 0
-.long 43 # Offset Entry 1
+.long 0  # Offset entry count
 
 # First range list
 .byte 6          # DW_RLE_start_end
 .byte 0          # DW_RLE_end_of_list
 
 # Second table (shows support for size 4 addresses)
-.long 27 # Table length
+.long 43 # Table length
 .short 5 # Version
 .byte 4  # Address size
 .byte 0  # Segment selector size
-.long 0  # Offset entry count
+.long 2  # Offset entry count
+
+# Offset array
+.long 8  # Offset Entry 0
+.long 27 # Offset Entry 1
 
 # First range list
 .byte 6          # DW_RLE_start_end
 .long 0x2, 0x6     # Start, end address
 .byte 0          # DW_RLE_end_of_list
 
+# Second range list
+.byte 7          # DW_RLE_start_length
+.long 0x36         # Start address
+.byte 0x80, 0x02   # Length
+.byte 0          # DW_RLE_end_of_list
+
 # Third (empty) table
 .long 8  # Table length
 .short 5 # Version
index a96f61d..d67f546 100644 (file)
 # CHECK-NEXT: error: section is not large enough to contain a .debug_rnglists table of length 0x1f at offset 0xe5
 # CHECK-NOT: error:
 
+# RUN: llvm-mc %S/Inputs/debug_rnglists_DWARF64.s -filetype obj -triple x86_64-pc-linux -o - | \
+# RUN: llvm-dwarfdump --debug-rnglists - 2>&1 | FileCheck %s --check-prefix=DWARF64
+
+# DWARF64: DWARF64 is not supported in .debug_rnglists at offset 0x0
+
 .section .debug_rnglists,"",@progbits
 
 # Table 1 (good)