[llvm] r345546 - [DWARF][NFC] Refactor range list extraction and dumping
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 30 17:16:36 PDT 2018
On Tue, Oct 30, 2018 at 4:51 PM Eric Christopher <echristo at gmail.com> wrote:
> 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.
>
There are test cases in tree that run llvm-symbolizer with split DWARF
inputs - so I expect it's something more nuanced than that & it seems
reasonable to expect/provide a test case to allow Wolfgang to make progress
here.
>
> 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/c331ae89/attachment-0001.html>
More information about the llvm-commits
mailing list