summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/BinaryFormat/Dwarf.h1
-rw-r--r--llvm/include/llvm/DebugInfo/DIContext.h1
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h4
-rw-r--r--llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h26
-rw-r--r--llvm/lib/BinaryFormat/Dwarf.cpp11
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp9
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp5
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp101
-rw-r--r--llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s2
-rw-r--r--llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists.s115
-rw-r--r--llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s5
11 files changed, 211 insertions, 69 deletions
diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.h b/llvm/include/llvm/BinaryFormat/Dwarf.h
index 3ca71644ada..b21feffe03f 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.h
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.h
@@ -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);
diff --git a/llvm/include/llvm/DebugInfo/DIContext.h b/llvm/include/llvm/DebugInfo/DIContext.h
index 751bbe356f1..f89eb34fdd7 100644
--- a/llvm/include/llvm/DebugInfo/DIContext.h
+++ b/llvm/include/llvm/DebugInfo/DIContext.h
@@ -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() {
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h
index 8fe08e833c3..c7778897ec6 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h
@@ -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,
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
index 19d8dd125fc..7579def070d 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
@@ -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
diff --git a/llvm/lib/BinaryFormat/Dwarf.cpp b/llvm/lib/BinaryFormat/Dwarf.cpp
index bea3df8074e..e345b3acabd 100644
--- a/llvm/lib/BinaryFormat/Dwarf.cpp
+++ b/llvm/lib/BinaryFormat/Dwarf.cpp
@@ -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:
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
index 058d3192b90..86c8d19c02f 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
@@ -14,10 +14,13 @@
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) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 2b1c91ee7b0..3a974dddc4e 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -509,8 +509,9 @@ void DWARFContext::dump(
if (Length == 0)
break;
Offset = TableOffset + Length;
- } else
- Rnglists.dump(OS);
+ } else {
+ Rnglists.dump(OS, DumpOpts);
+ }
}
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index 802fb7ecaea..c2b8b8a5e47 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -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
index 00000000000..0732eda6501
--- /dev/null
+++ b/llvm/test/tools/llvm-dwarfdump/X86/Inputs/debug_rnglists_DWARF64.s
@@ -0,0 +1,2 @@
+.section .debug_rnglists,"",@progbits
+.long 0xffffffff # Unsupported DWARF64 format
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists.s
index 62bb3ce5b2f..399ead81e22 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists.s
@@ -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
@@ -60,11 +89,15 @@
.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
@@ -73,6 +106,12 @@
.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
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s b/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s
index a96f61dfde9..d67f546e8d0 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s
+++ b/llvm/test/tools/llvm-dwarfdump/X86/debug_rnglists_invalid.s
@@ -37,6 +37,11 @@
# 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)
OpenPOWER on IntegriCloud