[llvm] r345546 - [DWARF][NFC] Refactor range list extraction and dumping

Eric Christopher via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 30 16:50:51 PDT 2018


Hi Wolfgang,

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.

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.

Thanks!

-eric

On Tue, Oct 30, 2018 at 9:38 AM Ilya Biryukov via llvm-commits <
llvm-commits at lists.llvm.org> wrote:

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


More information about the llvm-commits mailing list