<div dir="ltr">Hi Wolfgang,<div><br></div><div>I'm seeing this as losing inline information in the presence of split dwarf. Something in this patch is still NFC - using the llvm-symbolize support.</div><div><br></div><div>I'll see if I can come up with it, but you'll likely need to make this patch smaller to track down changes of this sort.</div><div><br></div><div>Thanks!</div><div><br></div><div>-eric</div></div><br><div class="gmail_quote"><div dir="ltr">On Tue, Oct 30, 2018 at 9:38 AM Ilya Biryukov via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I don't have time to integrate the changes anyway, so leaving this to the US timezone buildcop.</div><br><div class="gmail_quote"><div dir="ltr">On Tue, Oct 30, 2018 at 5:16 PM Ilya Biryukov <<a href="mailto:ibiryukov@google.com" target="_blank">ibiryukov@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">This change seems to break our integrate. I *think* this is not NFC, but I don't have enough context to come up with a minimal repro.<div><a class="gmail_plusreply" id="m_-1947181393579777213m_6544646058458623303plusReplyChip-2" href="mailto:echristo@google.com" target="_blank">+Eric Christopher</a> <a class="gmail_plusreply" id="m_-1947181393579777213m_6544646058458623303plusReplyChip-4" href="mailto:dblaikie@gmail.com" target="_blank">+David Blaikie</a>, could you please try creating a small repro based on our internal test failures?</div><div><br></div><div>Meanwhile, I'll probably have to revert the change, sorry about that.</div></div><br><div class="gmail_quote"><div dir="ltr">On Mon, Oct 29, 2018 at 11:19 PM Wolfgang Pieb via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: wolfgangp<br>
Date: Mon Oct 29 15:16:47 2018<br>
New Revision: 345546<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=345546&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=345546&view=rev</a><br>
Log:<br>
[DWARF][NFC] Refactor range list extraction and dumping<br>
<br>
The purpose of this patch is twofold: <br>
- Fold pre-DWARF v5 functionality into v5 to eliminate the need for 2 different <br>
  versions of range list handling. We get rid of DWARFDebugRangelist{.cpp,.h}.<br>
- Templatize the handling of range list tables so that location list handling<br>
  can take advantage of it as well. Location list and range list tables have the <br>
  same basic layout.<br>
<br>
A non-NFC version of this patch was previously submitted with r342218, but it caused<br>
errors with some TSan tests. This patch has no functional changes. The difference to<br>
the non-NFC patch is that there are no changes to rangelist dumping in this patch.<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D53545" rel="noreferrer" target="_blank">https://reviews.llvm.org/D53545</a><br>
<br>
<br>
Removed:<br>
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h<br>
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp<br>
Modified:<br>
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h<br>
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h<br>
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h<br>
    llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h<br>
    llvm/trunk/lib/DebugInfo/DWARF/CMakeLists.txt<br>
    llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp<br>
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp<br>
    llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp<br>
    llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp<br>
    llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp<br>
    llvm/trunk/tools/dsymutil/DwarfLinker.cpp<br>
    llvm/trunk/tools/dsymutil/DwarfStreamer.cpp<br>
    llvm/trunk/tools/dsymutil/DwarfStreamer.h<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h Mon Oct 29 15:16:47 2018<br>
@@ -231,16 +231,16 @@ public:<br>
   /// Get a DIE given an exact offset.<br>
   DWARFDie getDIEForOffset(uint32_t Offset);<br>
<br>
-  unsigned getMaxVersion() {<br>
+  unsigned getMaxVersion(uint16_t DefaultVersion = 0) {<br>
     // Ensure info units have been parsed to discover MaxVersion<br>
     info_section_units();<br>
-    return MaxVersion;<br>
+    return MaxVersion ? MaxVersion : DefaultVersion;<br>
   }<br>
<br>
-  unsigned getMaxDWOVersion() {<br>
+  unsigned getMaxDWOVersion(uint16_t DefaultVersion = 0) {<br>
     // Ensure DWO info units have been parsed to discover MaxVersion<br>
     dwo_info_section_units();<br>
-    return MaxVersion;<br>
+    return MaxVersion ? MaxVersion : DefaultVersion;<br>
   }<br>
<br>
   void setMaxVersionIfGreater(unsigned Version) {<br>
<br>
Removed: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h?rev=345545&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h?rev=345545&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h (removed)<br>
@@ -1,85 +0,0 @@<br>
-//===- DWARFDebugRangeList.h ------------------------------------*- C++ -*-===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#ifndef LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H<br>
-#define LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H<br>
-<br>
-#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"<br>
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"<br>
-#include <cassert><br>
-#include <cstdint><br>
-#include <vector><br>
-<br>
-namespace llvm {<br>
-<br>
-class raw_ostream;<br>
-<br>
-class DWARFDebugRangeList {<br>
-public:<br>
-  struct RangeListEntry {<br>
-    /// A beginning address offset. This address offset has the size of an<br>
-    /// address and is relative to the applicable base address of the<br>
-    /// compilation unit referencing this range list. It marks the beginning<br>
-    /// of an address range.<br>
-    uint64_t StartAddress;<br>
-    /// An ending address offset. This address offset again has the size of<br>
-    /// an address and is relative to the applicable base address of the<br>
-    /// compilation unit referencing this range list. It marks the first<br>
-    /// address past the end of the address range. The ending address must<br>
-    /// be greater than or equal to the beginning address.<br>
-    uint64_t EndAddress;<br>
-    /// A section index this range belongs to.<br>
-    uint64_t SectionIndex;<br>
-<br>
-    /// The end of any given range list is marked by an end of list entry,<br>
-    /// which consists of a 0 for the beginning address offset<br>
-    /// and a 0 for the ending address offset.<br>
-    bool isEndOfListEntry() const {<br>
-      return (StartAddress == 0) && (EndAddress == 0);<br>
-    }<br>
-<br>
-    /// A base address selection entry consists of:<br>
-    /// 1. The value of the largest representable address offset<br>
-    /// (for example, 0xffffffff when the size of an address is 32 bits).<br>
-    /// 2. An address, which defines the appropriate base address for<br>
-    /// use in interpreting the beginning and ending address offsets of<br>
-    /// subsequent entries of the location list.<br>
-    bool isBaseAddressSelectionEntry(uint8_t AddressSize) const {<br>
-      assert(AddressSize == 4 || AddressSize == 8);<br>
-      if (AddressSize == 4)<br>
-        return StartAddress == -1U;<br>
-      else<br>
-        return StartAddress == -1ULL;<br>
-    }<br>
-  };<br>
-<br>
-private:<br>
-  /// Offset in .debug_ranges section.<br>
-  uint32_t Offset;<br>
-  uint8_t AddressSize;<br>
-  std::vector<RangeListEntry> Entries;<br>
-<br>
-public:<br>
-  DWARFDebugRangeList() { clear(); }<br>
-<br>
-  void clear();<br>
-  void dump(raw_ostream &OS) const;<br>
-  Error extract(const DWARFDataExtractor &data, uint32_t *offset_ptr);<br>
-  const std::vector<RangeListEntry> &getEntries() { return Entries; }<br>
-<br>
-  /// getAbsoluteRanges - Returns absolute address ranges defined by this range<br>
-  /// list. Has to be passed base address of the compile unit referencing this<br>
-  /// range list.<br>
-  DWARFAddressRangesVector<br>
-  getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr) const;<br>
-};<br>
-<br>
-} // end namespace llvm<br>
-<br>
-#endif // LLVM_DEBUGINFO_DWARF_DWARFDEBUGRANGELIST_H<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h Mon Oct 29 15:16:47 2018<br>
@@ -13,8 +13,8 @@<br>
 #include "llvm/ADT/Optional.h"<br>
 #include "llvm/BinaryFormat/Dwarf.h"<br>
 #include "llvm/DebugInfo/DIContext.h"<br>
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"<br>
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFListTable.h"<br>
 #include <cstdint><br>
 #include <map><br>
@@ -22,6 +22,8 @@<br>
<br>
 namespace llvm {<br>
<br>
+struct BaseAddress;<br>
+class DWARFContext;<br>
 class Error;<br>
 class raw_ostream;<br>
 class DWARFUnit;<br>
@@ -35,12 +37,30 @@ struct RangeListEntry : public DWARFList<br>
   uint64_t Value0;<br>
   uint64_t Value1;<br>
<br>
-  Error extract(DWARFDataExtractor Data, uint32_t End, uint32_t *OffsetPtr);<br>
-  void dump(raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,<br>
-            uint64_t &CurrentBase, DIDumpOptions DumpOpts,<br>
+  Error extract(DWARFDataExtractor Data, uint32_t End, uint16_t Version,<br>
+                StringRef SectionName, uint32_t *OffsetPtr, bool isDWO = false);<br>
+  bool isEndOfList() const { return EntryKind == dwarf::DW_RLE_end_of_list; }<br>
+  bool isBaseAddressSelectionEntry() const {<br>
+    return EntryKind == dwarf::DW_RLE_base_address;<br>
+  }<br>
+  uint64_t getStartAddress() const {<br>
+    assert((EntryKind == dwarf::DW_RLE_start_end ||<br>
+            EntryKind == dwarf::DW_RLE_offset_pair ||<br>
+            EntryKind == dwarf::DW_RLE_startx_length) &&<br>
+           "Unexpected range list entry kind");<br>
+    return Value0;<br>
+  }<br>
+  uint64_t getEndAddress() const {<br>
+    assert((EntryKind == dwarf::DW_RLE_start_end ||<br>
+            EntryKind == dwarf::DW_RLE_offset_pair) &&<br>
+           "Unexpected range list entry kind");<br>
+    return Value1;<br>
+  }<br>
+  void dump(raw_ostream &OS, DWARFContext *C, uint8_t AddrSize, <br>
+            uint64_t &CurrentBase, unsigned Indent, uint16_t Version,<br>
+            uint8_t MaxEncodingStringLength, DIDumpOptions DumpOpts,<br>
             llvm::function_ref<Optional<SectionedAddress>(uint32_t)><br>
                 LookupPooledAddress) const;<br>
-  bool isSentinel() const { return EntryKind == dwarf::DW_RLE_end_of_list; }<br>
 };<br>
<br>
 /// A class representing a single rangelist.<br>
@@ -54,10 +74,12 @@ public:<br>
<br>
 class DWARFDebugRnglistTable : public DWARFListTableBase<DWARFDebugRnglist> {<br>
 public:<br>
-  DWARFDebugRnglistTable()<br>
-      : DWARFListTableBase(/* SectionName    = */ ".debug_rnglists",<br>
+  DWARFDebugRnglistTable(DWARFContext *C, StringRef SectionName,<br>
+                         bool isDWO = false)<br>
+      : DWARFListTableBase(C, SectionName, isDWO,<br>
                            /* HeaderString   = */ "ranges:",<br>
-                           /* ListTypeString = */ "range") {}<br>
+                           /* ListTypeString = */ "range",<br>
+                           dwarf::RangeListEncodingString) {}<br>
 };<br>
<br>
 } // end namespace llvm<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFListTable.h Mon Oct 29 15:16:47 2018<br>
@@ -23,6 +23,8 @@<br>
<br>
 namespace llvm {<br>
<br>
+class DWARFContext;<br>
+<br>
 /// A base class for DWARF list entries, such as range or location list<br>
 /// entries.<br>
 struct DWARFListEntryBase {<br>
@@ -37,6 +39,7 @@ struct DWARFListEntryBase {<br>
 /// A base class for lists of entries that are extracted from a particular<br>
 /// section, such as range lists or location lists.<br>
 template <typename ListEntryType> class DWARFListType {<br>
+public:<br>
   using EntryType = ListEntryType;<br>
   using ListEntries = std::vector<EntryType>;<br>
<br>
@@ -45,11 +48,26 @@ protected:<br>
<br>
 public:<br>
   const ListEntries &getEntries() const { return Entries; }<br>
-  bool empty() const { return Entries.empty(); }<br>
+  bool empty() const {<br>
+    return Entries.empty() || Entries.begin()->isEndOfList();<br>
+  }<br>
   void clear() { Entries.clear(); }<br>
+  uint32_t getOffset() const {<br>
+    if (Entries.empty())<br>
+      return 0;<br>
+    return Entries.begin()->Offset;<br>
+  }<br>
+<br>
+  /// Extract a list. The caller must pass the correct DWARF version.<br>
+  /// The end-of-list entry is retained as the last element of the vector of<br>
+  /// entries.<br>
   Error extract(DWARFDataExtractor Data, uint32_t HeaderOffset, uint32_t End,<br>
-                uint32_t *OffsetPtr, StringRef SectionName,<br>
-                StringRef ListStringName);<br>
+                uint16_t Version, uint32_t *OffsetPtr, StringRef SectionName,<br>
+                StringRef ListStringName, bool isDWO = false);<br>
+  void dump(raw_ostream &OS, DWARFContext *C, uint8_t AddressSize,<br>
+            uint64_t BaseAddress, unsigned Indent, uint16_t Version,<br>
+            size_t MaxEncodingStringLength,<br>
+            DIDumpOptions DumpOpts, llvm::function_ref<Optional<SectionedAddress>(uint32_t)> LookupPooledAddress) const;<br>
 };<br>
<br>
 /// A class representing the header of a list table such as the range list<br>
@@ -67,9 +85,9 @@ class DWARFListTableHeader {<br>
     uint8_t AddrSize;<br>
     /// The size in bytes of a segment selector on the target architecture.<br>
     /// If the target system uses a flat address space, this value is 0.<br>
-    uint8_t SegSize;<br>
+    uint8_t SegSize = 0;<br>
     /// The number of offsets that follow the header before the range lists.<br>
-    uint32_t OffsetEntryCount;<br>
+    uint32_t OffsetEntryCount = 0;<br>
   };<br>
<br>
   Header HeaderData;<br>
@@ -78,10 +96,10 @@ class DWARFListTableHeader {<br>
   /// FIXME: Generate the table and use the appropriate forms.<br>
   std::vector<uint32_t> Offsets;<br>
   /// The table's format, either DWARF32 or DWARF64.<br>
-  dwarf::DwarfFormat Format;<br>
+  dwarf::DwarfFormat Format = dwarf::DwarfFormat::DWARF32;<br>
   /// The offset at which the header (and hence the table) is located within<br>
   /// its section.<br>
-  uint32_t HeaderOffset;<br>
+  uint32_t HeaderOffset = 0;<br>
   /// The name of the section the list is located in.<br>
   StringRef SectionName;<br>
   /// A characterization of the list for dumping purposes, e.g. "range" or<br>
@@ -97,9 +115,19 @@ public:<br>
     Offsets.clear();<br>
   }<br>
   uint32_t getHeaderOffset() const { return HeaderOffset; }<br>
+<br>
   uint8_t getAddrSize() const { return HeaderData.AddrSize; }<br>
+  void setAddrSize(uint8_t AddrSize) { HeaderData.AddrSize = AddrSize; }<br>
+<br>
   uint32_t getLength() const { return HeaderData.Length; }<br>
+  void setLength(uint32_t Length) { HeaderData.Length = Length; }<br>
+<br>
   uint16_t getVersion() const { return HeaderData.Version; }<br>
+  void setVersion(uint16_t Version) { HeaderData.Version = Version; }<br>
+<br>
+  uint8_t getSegSize() const { return HeaderData.SegSize; }<br>
+  uint32_t getOffsetEntryCount() const { return HeaderData.OffsetEntryCount; }<br>
+<br>
   StringRef getSectionName() const { return SectionName; }<br>
   StringRef getListTypeString() const { return ListTypeString; }<br>
   dwarf::DwarfFormat getFormat() const { return Format; }<br>
@@ -116,8 +144,10 @@ public:<br>
<br>
   /// Returns the length of the table, including the length field, or 0 if the<br>
   /// length has not been determined (e.g. because the table has not yet been<br>
-  /// parsed, or there was a problem in parsing).<br>
-  uint32_t length() const;<br>
+  /// parsed, or there was a problem in parsing). In fake tables, such as for<br>
+  /// DWARF v4 and earlier, there is no header, so the length simply reflects<br>
+  /// the size of the section.<br>
+  uint32_t getTableLength() const;<br>
 };<br>
<br>
 /// A class representing a table of lists as specified in the DWARF v5<br>
@@ -130,14 +160,22 @@ template <typename DWARFListType> class<br>
   /// A mapping between file offsets and lists. It is used to find a particular<br>
   /// list based on an offset (obtained from DW_AT_ranges, for example).<br>
   std::map<uint32_t, DWARFListType> ListMap;<br>
+  DWARFContext *Ctx;<br>
+  /// True if this list is located in a split-DWARF (dwo or dwp) file.<br>
+  bool isDWO;<br>
   /// This string is displayed as a heading before the list is dumped<br>
   /// (e.g. "ranges:").<br>
   StringRef HeaderString;<br>
+  /// A function returning the encoding string for a given list entry encoding,<br>
+  /// e.g. "DW_RLE_start_end".<br>
+  std::function<StringRef(unsigned)> EncodingString;<br>
<br>
 protected:<br>
-  DWARFListTableBase(StringRef SectionName, StringRef HeaderString,<br>
-                     StringRef ListTypeString)<br>
-      : Header(SectionName, ListTypeString), HeaderString(HeaderString) {}<br>
+  DWARFListTableBase(DWARFContext *C, StringRef SectionName, bool isDWO,<br>
+                     StringRef HeaderString, StringRef ListTypeString,<br>
+                     std::function<StringRef(unsigned)> EncodingString)<br>
+      : Header(SectionName, ListTypeString), Ctx(C), isDWO(isDWO),<br>
+        HeaderString(HeaderString), EncodingString(EncodingString) {}<br>
<br>
 public:<br>
   void clear() {<br>
@@ -148,14 +186,28 @@ public:<br>
   Error extractHeaderAndOffsets(DWARFDataExtractor Data, uint32_t *OffsetPtr) {<br>
     return Header.extract(Data, OffsetPtr);<br>
   }<br>
+<br>
+  /// Initialize the table header to explicit values. This is used for DWARF v4<br>
+  /// and earlier since there is no header that can be extracted from a section.<br>
+  void setHeaderData(uint32_t Length, uint16_t Version, uint8_t AddrSize) {<br>
+    assert(Header.getSegSize() == 0 &&<br>
+           "Unexpected segsize in list table header.");<br>
+    assert(Header.getOffsetEntryCount() == 0 &&<br>
+           "Unexpected offset entry count in list table header.");<br>
+    Header.setLength(Length);<br>
+    Header.setVersion(Version);<br>
+    Header.setAddrSize(AddrSize);<br>
+  }<br>
+<br>
   /// Extract an entire table, including all list entries.<br>
-  Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr);<br>
+  Error extract(DWARFDataExtractor Data, uint16_t Version, uint32_t *OffsetPtr);<br>
   /// Look up a list based on a given offset. Extract it and enter it into the<br>
   /// list map if necessary.<br>
   Expected<DWARFListType> findList(DWARFDataExtractor Data, uint32_t Offset);<br>
<br>
   uint32_t getHeaderOffset() const { return Header.getHeaderOffset(); }<br>
   uint8_t getAddrSize() const { return Header.getAddrSize(); }<br>
+  StringRef getListTypeString() const { return Header.getListTypeString(); }<br>
<br>
   void dump(raw_ostream &OS,<br>
             llvm::function_ref<Optional<SectionedAddress>(uint32_t)><br>
@@ -179,25 +231,35 @@ public:<br>
     llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64");<br>
   }<br>
<br>
-  uint32_t length() { return Header.length(); }<br>
+  uint16_t getVersion() const { return Header.getVersion(); }<br>
+  uint32_t getLength() const { return Header.getTableLength(); }<br>
 };<br>
<br>
 template <typename DWARFListType><br>
 Error DWARFListTableBase<DWARFListType>::extract(DWARFDataExtractor Data,<br>
+                                                 uint16_t Version,<br>
                                                  uint32_t *OffsetPtr) {<br>
+  assert(Version > 0 && "DWARF version required and not given.");<br>
   clear();<br>
-  if (Error E = extractHeaderAndOffsets(Data, OffsetPtr))<br>
+  // For DWARF v4 and earlier, we cannot extract a table header, so we<br>
+  // initialize it explicitly.<br>
+  if (Version < 5)<br>
+    setHeaderData(Data.size(), Version, Data.getAddressSize());<br>
+  else if (Error E = extractHeaderAndOffsets(Data, OffsetPtr))<br>
     return E;<br>
<br>
   Data.setAddressSize(Header.getAddrSize());<br>
-  uint32_t End = getHeaderOffset() + Header.length();<br>
+  uint32_t End = getHeaderOffset() + getLength();<br>
+  // Extract all lists.<br>
   while (*OffsetPtr < End) {<br>
     DWARFListType CurrentList;<br>
     uint32_t Off = *OffsetPtr;<br>
-    if (Error E = CurrentList.extract(Data, getHeaderOffset(), End, OffsetPtr,<br>
-                                      Header.getSectionName(),<br>
-                                      Header.getListTypeString()))<br>
+    if (Error E = CurrentList.extract(<br>
+            Data, getHeaderOffset(), End, Header.getVersion(), OffsetPtr,<br>
+            Header.getSectionName(), Header.getListTypeString(), isDWO)) {<br>
+      *OffsetPtr = End;<br>
       return E;<br>
+    }<br>
     ListMap[Off] = CurrentList;<br>
   }<br>
<br>
@@ -208,22 +270,25 @@ Error DWARFListTableBase<DWARFListType>:<br>
 }<br>
<br>
 template <typename ListEntryType><br>
-Error DWARFListType<ListEntryType>::extract(DWARFDataExtractor Data,<br>
-                                            uint32_t HeaderOffset, uint32_t End,<br>
-                                            uint32_t *OffsetPtr,<br>
-                                            StringRef SectionName,<br>
-                                            StringRef ListTypeString) {<br>
+Error DWARFListType<ListEntryType>::extract(<br>
+    DWARFDataExtractor Data, uint32_t HeaderOffset, uint32_t End,<br>
+    uint16_t Version, uint32_t *OffsetPtr, StringRef SectionName,<br>
+    StringRef ListTypeString, bool isDWO) {<br>
   if (*OffsetPtr < HeaderOffset || *OffsetPtr >= End)<br>
     return createStringError(errc::invalid_argument,<br>
                        "invalid %s list offset 0x%" PRIx32,<br>
                        ListTypeString.data(), *OffsetPtr);<br>
   Entries.clear();<br>
+  uint32_t StartingOffset = *OffsetPtr;<br>
   while (*OffsetPtr < End) {<br>
     ListEntryType Entry;<br>
-    if (Error E = Entry.extract(Data, End, OffsetPtr))<br>
+    if (Error E =<br>
+            Entry.extract(Data, End, Version, SectionName, OffsetPtr, isDWO))<br>
       return E;<br>
+    if (Version < 5)<br>
+      Entry.Offset = StartingOffset;<br>
     Entries.push_back(Entry);<br>
-    if (Entry.isSentinel())<br>
+    if (Entry.isEndOfList())<br>
       return Error::success();<br>
   }<br>
   return createStringError(errc::illegal_byte_sequence,<br>
@@ -232,31 +297,47 @@ Error DWARFListType<ListEntryType>::extr<br>
                      SectionName.data(), HeaderOffset);<br>
 }<br>
<br>
+template <typename ListEntryType><br>
+void DWARFListType<ListEntryType>::dump(raw_ostream &OS, DWARFContext *C,<br>
+                                        uint8_t AddressSize,<br>
+                                        uint64_t BaseAddress, unsigned Indent,<br>
+                                        uint16_t Version,<br>
+                                        size_t MaxEncodingStringLength,<br>
+                                        DIDumpOptions DumpOpts,<br>
+                                        llvm::function_ref<Optional<SectionedAddress>(uint32_t)> LookupPooledAddress) const {<br>
+  uint64_t CurrentBase = BaseAddress;<br>
+  for (const auto &Entry : Entries)<br>
+    Entry.dump(OS, C, AddressSize, CurrentBase, Indent, Version,<br>
+               MaxEncodingStringLength, DumpOpts, LookupPooledAddress);<br>
+}<br>
+<br>
 template <typename DWARFListType><br>
 void DWARFListTableBase<DWARFListType>::dump(<br>
     raw_ostream &OS,<br>
     llvm::function_ref<Optional<SectionedAddress>(uint32_t)><br>
         LookupPooledAddress,<br>
     DIDumpOptions DumpOpts) const {<br>
-  Header.dump(OS, DumpOpts);<br>
-  OS << HeaderString << "\n";<br>
-<br>
   // Determine the length of the longest encoding string we have in the table,<br>
   // so we can align the output properly. We only need this in verbose mode.<br>
   size_t MaxEncodingStringLength = 0;<br>
-  if (DumpOpts.Verbose) {<br>
-    for (const auto &List : ListMap)<br>
-      for (const auto &Entry : List.second.getEntries())<br>
-        MaxEncodingStringLength =<br>
-            std::max(MaxEncodingStringLength,<br>
-                     dwarf::RangeListEncodingString(Entry.EntryKind).size());<br>
+  // Don't dump the fake table header we create for DWARF v4 and earlier.<br>
+  if (Header.getVersion() > 4) {<br>
+    Header.dump(OS, DumpOpts);<br>
+    OS << HeaderString << '\n';<br>
+    // Determine the length of the longest encoding string we have in the table,<br>
+    // so we can align the output properly. We only need this in verbose mode.<br>
+    if (DumpOpts.Verbose)<br>
+      for (const auto &List : ListMap)<br>
+        for (const auto &Entry : List.second.getEntries())<br>
+          MaxEncodingStringLength = std::max(<br>
+              MaxEncodingStringLength, EncodingString(Entry.EntryKind).size());<br>
   }<br>
<br>
   uint64_t CurrentBase = 0;<br>
   for (const auto &List : ListMap)<br>
-    for (const auto &Entry : List.second.getEntries())<br>
-      Entry.dump(OS, getAddrSize(), MaxEncodingStringLength, CurrentBase,<br>
-                 DumpOpts, LookupPooledAddress);<br>
+    List.second.dump(OS, Ctx, getAddrSize(), CurrentBase, 0,<br>
+                     Header.getVersion(), MaxEncodingStringLength, DumpOpts,<br>
+                     LookupPooledAddress);<br>
 }<br>
<br>
 template <typename DWARFListType><br>
@@ -269,11 +350,11 @@ DWARFListTableBase<DWARFListType>::findL<br>
<br>
   // Extract the list from the section and enter it into the list map.<br>
   DWARFListType List;<br>
-  uint32_t End = getHeaderOffset() + Header.length();<br>
+  uint32_t End = getHeaderOffset() + getLength();<br>
   uint32_t StartingOffset = Offset;<br>
-  if (Error E =<br>
-          List.extract(Data, getHeaderOffset(), End, &Offset,<br>
-                       Header.getSectionName(), Header.getListTypeString()))<br>
+  if (Error E = List.extract(Data, getHeaderOffset(), End, Header.getVersion(),<br>
+                             &Offset, Header.getSectionName(),<br>
+                             Header.getListTypeString(), isDWO))<br>
     return std::move(E);<br>
   ListMap[StartingOffset] = List;<br>
   return List;<br>
<br>
Modified: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h (original)<br>
+++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h Mon Oct 29 15:16:47 2018<br>
@@ -17,7 +17,6 @@<br>
 #include "llvm/ADT/iterator_range.h"<br>
 #include "llvm/BinaryFormat/Dwarf.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"<br>
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"<br>
@@ -312,12 +311,6 @@ public:<br>
     return DataExtractor(StringSection, false, 0);<br>
   }<br>
<br>
-  /// Extract the range list referenced by this compile unit from the<br>
-  /// .debug_ranges section. If the extraction is unsuccessful, an error<br>
-  /// is returned. Successful extraction requires that the compile unit<br>
-  /// has already been extracted.<br>
-  Error extractRangeList(uint32_t RangeListOffset,<br>
-                         DWARFDebugRangeList &RangeList) const;<br>
   void clear();<br>
<br>
   const Optional<StrOffsetsContributionDescriptor> &<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/DWARF/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/CMakeLists.txt?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/CMakeLists.txt?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/CMakeLists.txt (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/CMakeLists.txt Mon Oct 29 15:16:47 2018<br>
@@ -15,7 +15,6 @@ add_llvm_library(LLVMDebugInfoDWARF<br>
   DWARFDebugLoc.cpp<br>
   DWARFDebugMacro.cpp<br>
   DWARFDebugPubTable.cpp<br>
-  DWARFDebugRangeList.cpp<br>
   DWARFDebugRnglists.cpp<br>
   DWARFDie.cpp<br>
   DWARFExpression.cpp<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp Mon Oct 29 15:16:47 2018<br>
@@ -25,7 +25,6 @@<br>
 #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"<br>
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"<br>
@@ -268,26 +267,31 @@ static void dumpAddrSection(raw_ostream<br>
   }<br>
 }<br>
<br>
-// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).<br>
+// Dump a section that contains a sequence of tables of lists, such as range<br>
+// or location list tables. In DWARF v5 we expect to find properly formatted<br>
+// tables with headers. In DWARF v4 and earlier we simply expect a sequence of<br>
+// lists, which we treat, mutatis mutandis, like DWARF v5 tables.<br>
+template <typename ListTable><br>
 static void<br>
-dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData,<br>
-                    llvm::function_ref<Optional<SectionedAddress>(uint32_t)><br>
-                        LookupPooledAddress,<br>
-                    DIDumpOptions DumpOpts) {<br>
+dumpListSection(raw_ostream &OS, DWARFContext *C, StringRef SectionName,<br>
+                uint16_t MaxVersion, DWARFDataExtractor &ListData,<br>
+                llvm::function_ref<Optional<SectionedAddress>(uint32_t)><br>
+                    LookupPooledAddress,<br>
+                DIDumpOptions DumpOpts, bool isDWO = false) {<br>
   uint32_t Offset = 0;<br>
-  while (rnglistData.isValidOffset(Offset)) {<br>
-    llvm::DWARFDebugRnglistTable Rnglists;<br>
-    uint32_t TableOffset = Offset;<br>
-    if (Error Err = Rnglists.extract(rnglistData, &Offset)) {<br>
+  while (ListData.isValidOffset(Offset)) {<br>
+    ListTable Table(C, SectionName, isDWO);<br>
+    if (Error Err = Table.extract(ListData, MaxVersion, &Offset)) {<br>
       WithColor::error() << toString(std::move(Err)) << '\n';<br>
-      uint64_t Length = Rnglists.length();<br>
-      // Keep going after an error, if we can, assuming that the length field<br>
-      // could be read. If it couldn't, stop reading the section.<br>
-      if (Length == 0)<br>
+      // If table extraction set Offset to 0, it indicates that we cannot<br>
+      // continue to read the section.<br>
+      if (Offset == 0)<br>
         break;<br>
-      Offset = TableOffset + Length;<br>
+      // In DWARF v4 and earlier, dump as much of the lists as we can.<br>
+      if (MaxVersion < 5)<br>
+        Table.dump(OS, LookupPooledAddress, DumpOpts);<br>
     } else {<br>
-      Rnglists.dump(OS, LookupPooledAddress, DumpOpts);<br>
+      Table.dump(OS, LookupPooledAddress, DumpOpts);<br>
     }<br>
   }<br>
 }<br>
@@ -508,22 +512,6 @@ void DWARFContext::dump(<br>
     dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());<br>
   }<br>
<br>
-  if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,<br>
-                 DObj->getRangeSection().Data)) {<br>
-    uint8_t savedAddressByteSize = getCUAddrSize();<br>
-    DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),<br>
-                                  isLittleEndian(), savedAddressByteSize);<br>
-    uint32_t offset = 0;<br>
-    DWARFDebugRangeList rangeList;<br>
-    while (rangesData.isValidOffset(offset)) {<br>
-      if (Error E = rangeList.extract(rangesData, &offset)) {<br>
-        WithColor::error() << toString(std::move(E)) << '\n';<br>
-        break;<br>
-      }<br>
-      rangeList.dump(OS);<br>
-    }<br>
-  }<br>
-<br>
   auto LookupPooledAddress = [&](uint32_t Index) -> Optional<SectionedAddress> {<br>
     const auto &CUs = compile_units();<br>
     auto I = CUs.begin();<br>
@@ -532,18 +520,32 @@ void DWARFContext::dump(<br>
     return (*I)->getAddrOffsetSectionItem(Index);<br>
   };<br>
<br>
+  if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,<br>
+                 DObj->getRangeSection().Data)) {<br>
+    uint8_t savedAddressByteSize = getCUAddrSize();<br>
+    DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),<br>
+                                  isLittleEndian(), savedAddressByteSize);<br>
+    dumpListSection<DWARFDebugRnglistTable>(OS, this, ".debug_ranges",<br>
+                                            /* MaxVersion = */ 4, rangesData,<br>
+                                            LookupPooledAddress, DumpOpts);<br>
+  }<br>
+<br>
   if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,<br>
                  DObj->getRnglistsSection().Data)) {<br>
     DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),<br>
-                                   isLittleEndian(), 0);<br>
-    dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);<br>
+                                   isLittleEndian(), getCUAddrSize());<br>
+    dumpListSection<DWARFDebugRnglistTable>(OS, this, ".debug_rnglists",<br>
+                                            getMaxVersion(5), RnglistData,<br>
+                                            LookupPooledAddress, DumpOpts);<br>
   }<br>
<br>
   if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,<br>
                  DObj->getRnglistsDWOSection().Data)) {<br>
     DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),<br>
-                                   isLittleEndian(), 0);<br>
-    dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);<br>
+                                   isLittleEndian(), getCUAddrSize());<br>
+    dumpListSection<DWARFDebugRnglistTable>(OS, this, ".debug_rnglists.dwo",<br>
+                                            getMaxVersion(5), RnglistData,<br>
+                                            LookupPooledAddress, DumpOpts);<br>
   }<br>
<br>
   if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,<br>
<br>
Removed: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp?rev=345545&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp?rev=345545&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp (removed)<br>
@@ -1,96 +0,0 @@<br>
-//===- DWARFDebugRangesList.cpp -------------------------------------------===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"<br>
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"<br>
-#include "llvm/Support/Errc.h"<br>
-#include "llvm/Support/Format.h"<br>
-#include "llvm/Support/raw_ostream.h"<br>
-#include <cinttypes><br>
-#include <cstdint><br>
-<br>
-using namespace llvm;<br>
-<br>
-void DWARFDebugRangeList::clear() {<br>
-  Offset = -1U;<br>
-  AddressSize = 0;<br>
-  Entries.clear();<br>
-}<br>
-<br>
-Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,<br>
-                                   uint32_t *offset_ptr) {<br>
-  clear();<br>
-  if (!data.isValidOffset(*offset_ptr))<br>
-    return createStringError(errc::invalid_argument,<br>
-                       "invalid range list offset 0x%" PRIx32, *offset_ptr);<br>
-<br>
-  AddressSize = data.getAddressSize();<br>
-  if (AddressSize != 4 && AddressSize != 8)<br>
-    return createStringError(errc::invalid_argument,<br>
-                       "invalid address size: %" PRIu8, AddressSize);<br>
-  Offset = *offset_ptr;<br>
-  while (true) {<br>
-    RangeListEntry Entry;<br>
-    Entry.SectionIndex = -1ULL;<br>
-<br>
-    uint32_t prev_offset = *offset_ptr;<br>
-    Entry.StartAddress = data.getRelocatedAddress(offset_ptr);<br>
-    Entry.EndAddress =<br>
-        data.getRelocatedAddress(offset_ptr, &Entry.SectionIndex);<br>
-<br>
-    // Check that both values were extracted correctly.<br>
-    if (*offset_ptr != prev_offset + 2 * AddressSize) {<br>
-      clear();<br>
-      return createStringError(errc::invalid_argument,<br>
-                         "invalid range list entry at offset 0x%" PRIx32,<br>
-                         prev_offset);<br>
-    }<br>
-    if (Entry.isEndOfListEntry())<br>
-      break;<br>
-    Entries.push_back(Entry);<br>
-  }<br>
-  return Error::success();<br>
-}<br>
-<br>
-void DWARFDebugRangeList::dump(raw_ostream &OS) const {<br>
-  for (const RangeListEntry &RLE : Entries) {<br>
-    const char *format_str = (AddressSize == 4<br>
-                              ? "%08x %08"  PRIx64 " %08"  PRIx64 "\n"<br>
-                              : "%08x %016" PRIx64 " %016" PRIx64 "\n");<br>
-    OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress);<br>
-  }<br>
-  OS << format("%08x <End of list>\n", Offset);<br>
-}<br>
-<br>
-DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(<br>
-    llvm::Optional<SectionedAddress> BaseAddr) const {<br>
-  DWARFAddressRangesVector Res;<br>
-  for (const RangeListEntry &RLE : Entries) {<br>
-    if (RLE.isBaseAddressSelectionEntry(AddressSize)) {<br>
-      BaseAddr = {RLE.EndAddress, RLE.SectionIndex};<br>
-      continue;<br>
-    }<br>
-<br>
-    DWARFAddressRange E;<br>
-    E.LowPC = RLE.StartAddress;<br>
-    E.HighPC = RLE.EndAddress;<br>
-    E.SectionIndex = RLE.SectionIndex;<br>
-    // Base address of a range list entry is determined by the closest preceding<br>
-    // base address selection entry in the same range list. It defaults to the<br>
-    // base address of the compilation unit if there is no such entry.<br>
-    if (BaseAddr) {<br>
-      E.LowPC += BaseAddr->Address;<br>
-      E.HighPC += BaseAddr->Address;<br>
-      if (E.SectionIndex == -1ULL)<br>
-        E.SectionIndex = BaseAddr->SectionIndex;<br>
-    }<br>
-    Res.push_back(E);<br>
-  }<br>
-  return Res;<br>
-}<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp Mon Oct 29 15:16:47 2018<br>
@@ -13,19 +13,30 @@<br>
 #include "llvm/Support/Errc.h"<br>
 #include "llvm/Support/Error.h"<br>
 #include "llvm/Support/Format.h"<br>
+#include "llvm/Support/MathExtras.h"<br>
 #include "llvm/Support/raw_ostream.h"<br>
<br>
 using namespace llvm;<br>
<br>
 Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,<br>
-                              uint32_t *OffsetPtr) {<br>
+                              uint16_t Version, StringRef /* SectionName */,<br>
+                              uint32_t *OffsetPtr, bool /* isDWO */) {<br>
   Offset = *OffsetPtr;<br>
   SectionIndex = -1ULL;<br>
-  // The caller should guarantee that we have at least 1 byte available, so<br>
-  // we just assert instead of revalidate.<br>
-  assert(*OffsetPtr < End &&<br>
-         "not enough space to extract a rangelist encoding");<br>
-  uint8_t Encoding = Data.getU8(OffsetPtr);<br>
+<br>
+  assert((Data.getAddressSize() == 4 || Data.getAddressSize() == 8) &&<br>
+         "Unsupported address size");<br>
+<br>
+  // We model a DWARF v4 range list entry like DWARF v5 DW_RLE_offset_pair,<br>
+  // since it is subject to base adjustment.<br>
+  uint8_t Encoding = dwarf::DW_RLE_offset_pair;<br>
+  if (Version > 4) {<br>
+    // The caller should guarantee that we have at least 1 byte available, so<br>
+    // we just assert instead of revalidate.<br>
+    assert(*OffsetPtr < End &&<br>
+           "not enough space to extract a rangelist encoding");<br>
+    Encoding = Data.getU8(OffsetPtr);<br>
+  }<br>
<br>
   switch (Encoding) {<br>
   case dwarf::DW_RLE_end_of_list:<br>
@@ -61,6 +72,23 @@ Error RangeListEntry::extract(DWARFDataE<br>
     break;<br>
   }<br>
   case dwarf::DW_RLE_offset_pair: {<br>
+    if (Version < 5) {<br>
+      if ((End - *OffsetPtr) < unsigned(Data.getAddressSize() * 2))<br>
+        return createStringError(<br>
+            errc::illegal_byte_sequence,<br>
+            "invalid range list entry at offset 0x%" PRIx32, *OffsetPtr);<br>
+      Value0 = Data.getRelocatedAddress(OffsetPtr);<br>
+      Value1 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);<br>
+      // Adjust the EntryKind for end-of-list and base_address based on the<br>
+      // contents.<br>
+      if (Value0 == maxUIntN(Data.getAddressSize() * 8)) {<br>
+        Encoding = dwarf::DW_RLE_base_address;<br>
+        Value0 = Value1;<br>
+        Value1 = 0;<br>
+      } else if (Value0 == 0 && Value1 == 0)<br>
+        Encoding = dwarf::DW_RLE_end_of_list;<br>
+      break;<br>
+    }<br>
     uint32_t PreviousOffset = *OffsetPtr - 1;<br>
     Value0 = Data.getULEB128(OffsetPtr);<br>
     Value1 = Data.getULEB128(OffsetPtr);<br>
@@ -71,7 +99,7 @@ Error RangeListEntry::extract(DWARFDataE<br>
                          PreviousOffset);<br>
     break;<br>
   }<br>
-  case dwarf::DW_RLE_base_address: {<br>
+  case dwarf::DW_RLE_base_address:<br>
     if ((End - *OffsetPtr) < Data.getAddressSize())<br>
       return createStringError(errc::invalid_argument,<br>
                          "insufficient space remaining in table for "<br>
@@ -79,18 +107,16 @@ Error RangeListEntry::extract(DWARFDataE<br>
                          *OffsetPtr - 1);<br>
     Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);<br>
     break;<br>
-  }<br>
-  case dwarf::DW_RLE_start_end: {<br>
+  case dwarf::DW_RLE_start_end:<br>
     if ((End - *OffsetPtr) < unsigned(Data.getAddressSize() * 2))<br>
       return createStringError(errc::invalid_argument,<br>
                          "insufficient space remaining in table for "<br>
                          "DW_RLE_start_end encoding "<br>
                          "at offset 0x%" PRIx32,<br>
                          *OffsetPtr - 1);<br>
-    Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);<br>
-    Value1 = Data.getRelocatedAddress(OffsetPtr);<br>
+    Value0 = Data.getRelocatedAddress(OffsetPtr);<br>
+    Value1 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);<br>
     break;<br>
-  }<br>
   case dwarf::DW_RLE_start_length: {<br>
     uint32_t PreviousOffset = *OffsetPtr - 1;<br>
     Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);<br>
@@ -173,8 +199,9 @@ DWARFDebugRnglist::getAbsoluteRanges(llv<br>
 }<br>
<br>
 void RangeListEntry::dump(<br>
-    raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,<br>
-    uint64_t &CurrentBase, DIDumpOptions DumpOpts,<br>
+    raw_ostream &OS, DWARFContext *, uint8_t AddrSize, uint64_t &CurrentBase,<br>
+    unsigned Indent, uint16_t Version, uint8_t MaxEncodingStringLength,<br>
+    DIDumpOptions DumpOpts,<br>
     llvm::function_ref<Optional<SectionedAddress>(uint32_t)><br>
         LookupPooledAddress) const {<br>
   auto PrintRawEntry = [](raw_ostream &OS, const RangeListEntry &Entry,<br>
@@ -187,21 +214,34 @@ void RangeListEntry::dump(<br>
     }<br>
   };<br>
<br>
+  // Output indentations before we print the actual entry. We only print<br>
+  // anything for DW_RLE_base_address when we are in verbose mode.<br>
+  if (Version < 5 || DumpOpts.Verbose || !isBaseAddressSelectionEntry())<br>
+    OS.indent(Indent);<br>
+<br>
+  // Always print the section offset in DWARF v4 and earlier.<br>
+  if (Version < 5) {<br>
+    OS << format("%08x", Offset);<br>
+    DumpOpts.Verbose = false;<br>
+  }<br>
+<br>
   if (DumpOpts.Verbose) {<br>
     // Print the section offset in verbose mode.<br>
     OS << format("0x%8.8" PRIx32 ":", Offset);<br>
-    auto EncodingString = dwarf::RangeListEncodingString(EntryKind);<br>
-    // Unsupported encodings should have been reported during parsing.<br>
-    assert(!EncodingString.empty() && "Unknown range entry encoding");<br>
-    OS << format(" [%s%*c", EncodingString.data(),<br>
-                 MaxEncodingStringLength - EncodingString.size() + 1, ']');<br>
-    if (EntryKind != dwarf::DW_RLE_end_of_list)<br>
-      OS << ": ";<br>
+    if (Version > 4) {<br>
+      auto EncodingString = dwarf::RangeListEncodingString(EntryKind);<br>
+      // Unsupported encodings should have been reported during parsing.<br>
+      assert(!EncodingString.empty() && "Unknown range entry encoding");<br>
+      OS << format(" [%s%*c", EncodingString.data(),<br>
+                   MaxEncodingStringLength - EncodingString.size() + 1, ']');<br>
+      if (!isEndOfList())<br>
+        OS << ": ";<br>
+    }<br>
   }<br>
<br>
   switch (EntryKind) {<br>
   case dwarf::DW_RLE_end_of_list:<br>
-    OS << (DumpOpts.Verbose ? "" : "<End of list>");<br>
+    OS << (DumpOpts.Verbose ? "" : " <End of list>");<br>
     break;<br>
     //  case dwarf::DW_RLE_base_addressx:<br>
   case dwarf::DW_RLE_base_addressx: {<br>
@@ -217,6 +257,13 @@ void RangeListEntry::dump(<br>
   case dwarf::DW_RLE_base_address:<br>
     // In non-verbose mode we do not print anything for this entry.<br>
     CurrentBase = Value0;<br>
+    if (Version < 5) {<br>
+      // Dump the entry in pre-DWARF v5 format, i.e. with a -1 as Value0.<br>
+      uint64_t allOnes = maxUIntN(AddrSize * 8);<br>
+      OS << format(" %*.*" PRIx64, AddrSize * 2, AddrSize * 2, allOnes);<br>
+      OS << format(" %*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value0);<br>
+      break;<br>
+    }<br>
     if (!DumpOpts.Verbose)<br>
       return;<br>
     OS << format(" 0x%*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value0);<br>
@@ -226,6 +273,11 @@ void RangeListEntry::dump(<br>
     DWARFAddressRange(Value0, Value0 + Value1).dump(OS, AddrSize, DumpOpts);<br>
     break;<br>
   case dwarf::DW_RLE_offset_pair:<br>
+    if (Version < 5) {<br>
+      OS << format(" %*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value0);<br>
+      OS << format(" %*.*" PRIx64, AddrSize * 2, AddrSize * 2, Value1);<br>
+      break;<br>
+    }<br>
     PrintRawEntry(OS, *this, AddrSize, DumpOpts);<br>
     DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase)<br>
         .dump(OS, AddrSize, DumpOpts);<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDie.cpp Mon Oct 29 15:16:47 2018<br>
@@ -15,7 +15,6 @@<br>
 #include "llvm/BinaryFormat/Dwarf.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"<br>
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFListTable.cpp Mon Oct 29 15:16:47 2018<br>
@@ -20,30 +20,43 @@ Error DWARFListTableHeader::extract(DWAR<br>
                                     uint32_t *OffsetPtr) {<br>
   HeaderOffset = *OffsetPtr;<br>
   // Read and verify the length field.<br>
-  if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t)))<br>
+  if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t))) {<br>
+    // By setting *OffsetPtr to 0, we indicate to the caller that<br>
+    // we could not detemine the length of the table.<br>
+    *OffsetPtr = 0;<br>
     return createStringError(errc::invalid_argument,<br>
-                       "section is not large enough to contain a "<br>
-                       "%s table length at offset 0x%" PRIx32,<br>
-                       SectionName.data(), *OffsetPtr);<br>
+                             "section is not large enough to contain a "<br>
+                             "%s table length at offset 0x%" PRIx32,<br>
+                             SectionName.data(), HeaderOffset);<br>
+  }<br>
   // TODO: Add support for DWARF64.<br>
   HeaderData.Length = Data.getU32(OffsetPtr);<br>
-  if (HeaderData.Length == 0xffffffffu)<br>
+  if (HeaderData.Length == 0xffffffffu) {<br>
+    *OffsetPtr = 0;<br>
     return createStringError(errc::not_supported,<br>
                        "DWARF64 is not supported in %s at offset 0x%" PRIx32,<br>
                        SectionName.data(), HeaderOffset);<br>
+  }<br>
+<br>
+  uint32_t TableLength = HeaderData.Length + sizeof(uint32_t);<br>
+  uint32_t End = HeaderOffset + TableLength;<br>
   Format = dwarf::DwarfFormat::DWARF32;<br>
-  if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header))<br>
+  if (TableLength < sizeof(Header)) {<br>
+    *OffsetPtr = End;<br>
     return createStringError(errc::invalid_argument,<br>
-                       "%s table at offset 0x%" PRIx32<br>
-                       " has too small length (0x%" PRIx32<br>
-                       ") to contain a complete header",<br>
-                       SectionName.data(), HeaderOffset, length());<br>
-  uint32_t End = HeaderOffset + length();<br>
-  if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset))<br>
-    return createStringError(errc::invalid_argument,<br>
-                       "section is not large enough to contain a %s table "<br>
-                       "of length 0x%" PRIx32 " at offset 0x%" PRIx32,<br>
-                       SectionName.data(), length(), HeaderOffset);<br>
+                             "%s table at offset 0x%" PRIx32<br>
+                             " has too small length (0x%" PRIx32<br>
+                             ") to contain a complete header",<br>
+                             SectionName.data(), HeaderOffset, TableLength);<br>
+  }<br>
+  if (!Data.isValidOffsetForDataOfSize(HeaderOffset, TableLength)) {<br>
+    *OffsetPtr = 0; // No recovery if the length exceeds the section size.<br>
+    return createStringError(<br>
+        errc::invalid_argument,<br>
+        "section is not large enough to contain a %s table "<br>
+        "of length 0x%" PRIx32 " at offset 0x%" PRIx32,<br>
+        SectionName.data(), TableLength, HeaderOffset);<br>
+  }<br>
<br>
   HeaderData.Version = Data.getU16(OffsetPtr);<br>
   HeaderData.AddrSize = Data.getU8(OffsetPtr);<br>
@@ -51,27 +64,36 @@ Error DWARFListTableHeader::extract(DWAR<br>
   HeaderData.OffsetEntryCount = Data.getU32(OffsetPtr);<br>
<br>
   // Perform basic validation of the remaining header fields.<br>
-  if (HeaderData.Version != 5)<br>
+  if (HeaderData.Version != 5) {<br>
+    *OffsetPtr = End;<br>
     return createStringError(errc::invalid_argument,<br>
-                       "unrecognised %s table version %" PRIu16<br>
-                       " in table at offset 0x%" PRIx32,<br>
-                       SectionName.data(), HeaderData.Version, HeaderOffset);<br>
-  if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)<br>
+                             "unrecognised %s table version %" PRIu16<br>
+                             " in table at offset 0x%" PRIx32,<br>
+                             SectionName.data(), HeaderData.Version,<br>
+                             HeaderOffset);<br>
+  }<br>
+  if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8) {<br>
+    *OffsetPtr = End;<br>
     return createStringError(errc::not_supported,<br>
                        "%s table at offset 0x%" PRIx32<br>
                        " has unsupported address size %" PRIu8,<br>
                        SectionName.data(), HeaderOffset, HeaderData.AddrSize);<br>
-  if (HeaderData.SegSize != 0)<br>
+  }<br>
+  if (HeaderData.SegSize != 0) {<br>
+    *OffsetPtr = End;<br>
     return createStringError(errc::not_supported,<br>
                        "%s table at offset 0x%" PRIx32<br>
                        " has unsupported segment selector size %" PRIu8,<br>
                        SectionName.data(), HeaderOffset, HeaderData.SegSize);<br>
+  }<br>
   if (End < HeaderOffset + sizeof(HeaderData) +<br>
-                HeaderData.OffsetEntryCount * sizeof(uint32_t))<br>
+                HeaderData.OffsetEntryCount * sizeof(uint32_t)) {<br>
+    *OffsetPtr = End;<br>
     return createStringError(errc::invalid_argument,<br>
         "%s table at offset 0x%" PRIx32 " has more offset entries (%" PRIu32<br>
         ") than there is space for",<br>
         SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);<br>
+  }<br>
   Data.setAddressSize(HeaderData.AddrSize);<br>
   for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I)<br>
     Offsets.push_back(Data.getU32(OffsetPtr));<br>
@@ -101,9 +123,11 @@ void DWARFListTableHeader::dump(raw_ostr<br>
   }<br>
 }<br>
<br>
-uint32_t DWARFListTableHeader::length() const {<br>
+uint32_t DWARFListTableHeader::getTableLength() const {<br>
   if (HeaderData.Length == 0)<br>
     return 0;<br>
+  assert(HeaderData.Version > 0 &&<br>
+         "No DWARF version in header when using getTableLength()");<br>
   // TODO: DWARF64 support.<br>
-  return HeaderData.Length + sizeof(uint32_t);<br>
+  return HeaderData.Length + (HeaderData.Version > 4) * sizeof(uint32_t);<br>
 }<br>
<br>
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp (original)<br>
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp Mon Oct 29 15:16:47 2018<br>
@@ -296,13 +296,16 @@ bool DWARFUnitHeader::extract(DWARFConte<br>
   return true;<br>
 }<br>
<br>
-// Parse the rangelist table header, including the optional array of offsets<br>
+// Parse a list table header, including the optional array of offsets<br>
 // following it (DWARF v5 and later).<br>
-static Expected<DWARFDebugRnglistTable><br>
-parseRngListTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {<br>
+template <typename DWARFListTable><br>
+static Expected<DWARFListTable><br>
+parseListTableHeader(DWARFDataExtractor DA, DWARFContext *C,<br>
+                     StringRef SectionName, uint32_t Offset, bool isDWO) {<br>
   // TODO: Support DWARF64<br>
   // We are expected to be called with Offset 0 or pointing just past the table<br>
   // header, which is 12 bytes long for DWARF32.<br>
+  DWARFListTable Table(C, SectionName, isDWO);<br>
   if (Offset > 0) {<br>
     if (Offset < 12U)<br>
       return createStringError(errc::invalid_argument, "Did not detect a valid"<br>
@@ -310,20 +313,46 @@ parseRngListTableHeader(DWARFDataExtract<br>
                                Offset);<br>
     Offset -= 12U;<br>
   }<br>
-  llvm::DWARFDebugRnglistTable Table;<br>
   if (Error E = Table.extractHeaderAndOffsets(DA, &Offset))<br>
     return std::move(E);<br>
   return Table;<br>
 }<br>
<br>
-Error DWARFUnit::extractRangeList(uint32_t RangeListOffset,<br>
-                                  DWARFDebugRangeList &RangeList) const {<br>
-  // Require that compile unit is extracted.<br>
-  assert(!DieArray.empty());<br>
-  DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,<br>
-                                isLittleEndian, getAddressByteSize());<br>
-  uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;<br>
-  return RangeList.extract(RangesData, &ActualRangeListOffset);<br>
+// Parse a DWARF v5 list table (e.g. either a rangelist table or a location<br>
+// list table). For DWARF units with version 4 or earlier, we instead create<br>
+// the table artifically by giving it a size that equals the section size.<br>
+template <typename DWARFListTable><br>
+static Optional<DWARFListTable><br>
+setupListTable(DWARFUnit *U, const DWARFSection *Section, StringRef SectionName,<br>
+               uint32_t &Base, bool isDWO, bool isLittleEndian) {<br>
+  if (!Section->Data.size())<br>
+    return None;<br>
+  DWARFContext &Ctx = U->getContext();<br>
+  DWARFListTable Table(&Ctx, SectionName, isDWO);<br>
+  // Parse the list table header. Individual lists are extracted lazily.<br>
+  DWARFDataExtractor DA(Ctx.getDWARFObj(), *Section, isLittleEndian,<br>
+                        U->getAddressByteSize());<br>
+  if (U->getVersion() < 5) {<br>
+    Base = 0;<br>
+    Table.setHeaderData(Section->Data.size(), U->getVersion(),<br>
+                        DA.getAddressSize());<br>
+    return Table;<br>
+  }<br>
+  if (auto TableOrError = parseListTableHeader<DWARFListTable>(<br>
+          DA, &Ctx, SectionName, Base, isDWO))<br>
+    Table = TableOrError.get();<br>
+  else {<br>
+    WithColor::error() << "parsing a " << Table.getListTypeString().data()<br>
+                       << " list table: " << toString(TableOrError.takeError())<br>
+                       << '\n';<br>
+    return None;<br>
+  }<br>
+  // In a split dwarf unit, there are no attributes like DW_AT_rnglists_base or<br>
+  // DW_AT_loclists_base that describe the table base. Adjust Base to point past<br>
+  // the table header which is expected to start at offset 0.<br>
+  if (isDWO)<br>
+    Base = Table.getHeaderSize();<br>
+  return Table;<br>
 }<br>
<br>
 void DWARFUnit::clear() {<br>
@@ -437,35 +466,24 @@ size_t DWARFUnit::extractDIEsIfNeeded(bo<br>
<br>
     // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to<br>
     // describe address ranges.<br>
+    StringRef RangeSectionName = ".debug_ranges";<br>
     if (getVersion() >= 5) {<br>
-      if (IsDWO)<br>
+      if (IsDWO) {<br>
+        RangeSectionName = ".debug_rnglists.dwo";<br>
         setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);<br>
-      else<br>
+      } else {<br>
+        RangeSectionName = ".debug_rnglists";<br>
         setRangesSection(&Context.getDWARFObj().getRnglistsSection(),<br>
                          toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0));<br>
-      if (RangeSection->Data.size()) {<br>
-        // Parse the range list table header. Individual range lists are<br>
-        // extracted lazily.<br>
-        DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,<br>
-                                    isLittleEndian, 0);<br>
-        if (auto TableOrError =<br>
-                parseRngListTableHeader(RangesDA, RangeSectionBase))<br>
-          RngListTable = TableOrError.get();<br>
-        else<br>
-          WithColor::error() << "parsing a range list table: "<br>
-                             << toString(TableOrError.takeError())<br>
-                             << '\n';<br>
-<br>
-        // In a split dwarf unit, there is no DW_AT_rnglists_base attribute.<br>
-        // Adjust RangeSectionBase to point past the table header.<br>
-        if (IsDWO && RngListTable)<br>
-          RangeSectionBase = RngListTable->getHeaderSize();<br>
       }<br>
     }<br>
+    RngListTable = setupListTable<DWARFDebugRnglistTable>(<br>
+        this, RangeSection, RangeSectionName, RangeSectionBase, IsDWO,<br>
+        isLittleEndian);<br>
<br>
     // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for<br>
     // skeleton CU DIE, so that DWARF users not aware of it are not broken.<br>
-    }<br>
+  }<br>
<br>
   return DieArray.size();<br>
 }<br>
@@ -503,16 +521,9 @@ bool DWARFUnit::parseDWO() {<br>
   DWO->setAddrOffsetSection(AddrOffsetSection, AddrOffsetSectionBase);<br>
   if (getVersion() >= 5) {<br>
     DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);<br>
-    DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,<br>
-                                isLittleEndian, 0);<br>
-    if (auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase))<br>
-      DWO->RngListTable = TableOrError.get();<br>
-    else<br>
-      WithColor::error() << "parsing a range list table: "<br>
-                         << toString(TableOrError.takeError())<br>
-                         << '\n';<br>
-    if (DWO->RngListTable)<br>
-      DWO->RangeSectionBase = DWO->RngListTable->getHeaderSize();<br>
+    DWO->RngListTable = setupListTable<DWARFDebugRnglistTable>(<br>
+        DWOCU, DWO->RangeSection, ".debug_rnglists.dwo", DWO->RangeSectionBase,<br>
+        /* isDWO =*/true, isLittleEndian);<br>
   } else {<br>
     auto DWORangesBase = UnitDie.getRangesBaseAttribute();<br>
     DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);<br>
@@ -530,12 +541,6 @@ void DWARFUnit::clearDIEs(bool KeepCUDie<br>
<br>
 Expected<DWARFAddressRangesVector><br>
 DWARFUnit::findRnglistFromOffset(uint32_t Offset) {<br>
-  if (getVersion() <= 4) {<br>
-    DWARFDebugRangeList RangeList;<br>
-    if (Error E = extractRangeList(Offset, RangeList))<br>
-      return std::move(E);<br>
-    return RangeList.getAbsoluteRanges(getBaseAddress());<br>
-  }<br>
   if (RngListTable) {<br>
     DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,<br>
                                   isLittleEndian, RngListTable->getAddrSize());<br>
<br>
Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)<br>
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Mon Oct 29 15:16:47 2018<br>
@@ -43,7 +43,6 @@<br>
 #include "llvm/DebugInfo/DWARF/DWARFContext.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"<br>
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDie.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFSection.h"<br>
@@ -1576,7 +1575,7 @@ DIE *DwarfLinker::DIECloner::cloneDIE(co<br>
 void DwarfLinker::patchRangesForUnit(const CompileUnit &Unit,<br>
                                      DWARFContext &OrigDwarf,<br>
                                      const DebugMapObject &DMO) const {<br>
-  DWARFDebugRangeList RangeList;<br>
+  DWARFDebugRnglist RangeList;<br>
   const auto &FunctionRanges = Unit.getFunctionRanges();<br>
   unsigned AddressSize = Unit.getOrigUnit().getAddressByteSize();<br>
   DWARFDataExtractor RangeExtractor(OrigDwarf.getDWARFObj(),<br>
@@ -1596,28 +1595,30 @@ void DwarfLinker::patchRangesForUnit(con<br>
   for (const auto &RangeAttribute : Unit.getRangesAttributes()) {<br>
     uint32_t Offset = RangeAttribute.get();<br>
     RangeAttribute.set(Streamer->getRangesSectionSize());<br>
-    if (Error E = RangeList.extract(RangeExtractor, &Offset)) {<br>
+    if (Error E = RangeList.extract(RangeExtractor, /* HeaderOffset = */0,<br>
+                                    RangeExtractor.size(),<br>
+                                    Unit.getOrigUnit().getVersion(), &Offset,<br>
+                                    ".debug_ranges", "range")) {<br>
       llvm::consumeError(std::move(E));<br>
       reportWarning("invalid range list ignored.", DMO);<br>
       RangeList.clear();<br>
     }<br>
     const auto &Entries = RangeList.getEntries();<br>
-    if (!Entries.empty()) {<br>
-      const DWARFDebugRangeList::RangeListEntry &First = Entries.front();<br>
-<br>
+    if (!RangeList.empty()) {<br>
+      const auto &First = Entries.front();<br>
       if (CurrRange == InvalidRange ||<br>
-          First.StartAddress + OrigLowPc < CurrRange.start() ||<br>
-          First.StartAddress + OrigLowPc >= CurrRange.stop()) {<br>
-        CurrRange = FunctionRanges.find(First.StartAddress + OrigLowPc);<br>
+          First.getStartAddress() + OrigLowPc < CurrRange.start() ||<br>
+          First.getStartAddress() + OrigLowPc >= CurrRange.stop()) {<br>
+        CurrRange = FunctionRanges.find(First.getStartAddress() + OrigLowPc);<br>
         if (CurrRange == InvalidRange ||<br>
-            CurrRange.start() > First.StartAddress + OrigLowPc) {<br>
+            CurrRange.start() > First.getStartAddress() + OrigLowPc) {<br>
           reportWarning("no mapping for range.", DMO);<br>
           continue;<br>
         }<br>
       }<br>
     }<br>
<br>
-    Streamer->emitRangesEntries(UnitPcOffset, OrigLowPc, CurrRange, Entries,<br>
+    Streamer->emitRangesEntries(UnitPcOffset, OrigLowPc, CurrRange, RangeList,<br>
                                 AddressSize);<br>
   }<br>
 }<br>
<br>
Modified: llvm/trunk/tools/dsymutil/DwarfStreamer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfStreamer.cpp?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfStreamer.cpp?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/DwarfStreamer.cpp (original)<br>
+++ llvm/trunk/tools/dsymutil/DwarfStreamer.cpp Mon Oct 29 15:16:47 2018<br>
@@ -269,28 +269,27 @@ void DwarfStreamer::emitSwiftAST(StringR<br>
 void DwarfStreamer::emitRangesEntries(<br>
     int64_t UnitPcOffset, uint64_t OrigLowPc,<br>
     const FunctionIntervals::const_iterator &FuncRange,<br>
-    const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,<br>
-    unsigned AddressSize) {<br>
+    const DWARFDebugRnglist &RangeList, unsigned AddressSize) {<br>
   MS->SwitchSection(MC->getObjectFileInfo()->getDwarfRangesSection());<br>
<br>
   // Offset each range by the right amount.<br>
-  int64_t PcOffset = Entries.empty() ? 0 : FuncRange.value() + UnitPcOffset;<br>
-  for (const auto &Range : Entries) {<br>
-    if (Range.isBaseAddressSelectionEntry(AddressSize)) {<br>
+  int64_t PcOffset = RangeList.empty() ? 0 : FuncRange.value() + UnitPcOffset;<br>
+  for (const auto &Range : RangeList.getEntries()) {<br>
+    if (Range.isBaseAddressSelectionEntry()) {<br>
       warn("unsupported base address selection operation",<br>
            "emitting debug_ranges");<br>
       break;<br>
     }<br>
     // Do not emit empty ranges.<br>
-    if (Range.StartAddress == Range.EndAddress)<br>
+    if (Range.isEndOfList() || Range.getStartAddress() == Range.getEndAddress())<br>
       continue;<br>
<br>
     // All range entries should lie in the function range.<br>
-    if (!(Range.StartAddress + OrigLowPc >= FuncRange.start() &&<br>
-          Range.EndAddress + OrigLowPc <= FuncRange.stop()))<br>
+    if (!(Range.getStartAddress() + OrigLowPc >= FuncRange.start() &&<br>
+          Range.getEndAddress() + OrigLowPc <= FuncRange.stop()))<br>
       warn("inconsistent range data.", "emitting debug_ranges");<br>
-    MS->EmitIntValue(Range.StartAddress + PcOffset, AddressSize);<br>
-    MS->EmitIntValue(Range.EndAddress + PcOffset, AddressSize);<br>
+    MS->EmitIntValue(Range.getStartAddress() + PcOffset, AddressSize);<br>
+    MS->EmitIntValue(Range.getEndAddress() + PcOffset, AddressSize);<br>
     RangesSectionSize += 2 * AddressSize;<br>
   }<br>
<br>
<br>
Modified: llvm/trunk/tools/dsymutil/DwarfStreamer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfStreamer.h?rev=345546&r1=345545&r2=345546&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfStreamer.h?rev=345546&r1=345545&r2=345546&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/dsymutil/DwarfStreamer.h (original)<br>
+++ llvm/trunk/tools/dsymutil/DwarfStreamer.h Mon Oct 29 15:16:47 2018<br>
@@ -17,7 +17,7 @@<br>
 #include "llvm/CodeGen/AccelTable.h"<br>
 #include "llvm/CodeGen/AsmPrinter.h"<br>
 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"<br>
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"<br>
+#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"<br>
 #include "llvm/MC/MCAsmBackend.h"<br>
 #include "llvm/MC/MCAsmInfo.h"<br>
 #include "llvm/MC/MCCodeEmitter.h"<br>
@@ -83,7 +83,7 @@ public:<br>
   void emitRangesEntries(<br>
       int64_t UnitPcOffset, uint64_t OrigLowPc,<br>
       const FunctionIntervals::const_iterator &FuncRange,<br>
-      const std::vector<DWARFDebugRangeList::RangeListEntry> &Entries,<br>
+      const DWARFDebugRnglist &RangeList,<br>
       unsigned AddressSize);<br>
<br>
   /// Emit debug_aranges entries for \p Unit and if \p DoRangesSection is true,<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="m_-1947181393579777213m_6544646058458623303gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>Regards,</div><div>Ilya Biryukov</div></div></div></div></div>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" class="m_-1947181393579777213gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>Regards,</div><div>Ilya Biryukov</div></div></div></div></div>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>