[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:58:22 PDT 2018
It would be appreciated, yes.
-eric
On Tue, Oct 30, 2018 at 4:57 PM <wolfgang.pieb at sony.com> wrote:
> Thanks, do you want me to revert it for now?
>
> -wolfgang
>
>
>
> *From:* Eric Christopher <echristo at gmail.com>
> *Sent:* Tuesday, October 30, 2018 4:51 PM
> *To:* Ilya Biryukov <ibiryukov at google.com>
> *Cc:* Pieb, Wolfgang <wolfgang.pieb at sony.com>; David Blaikie <
> dblaikie at gmail.com>; Eric Christopher <echristo at google.com>; llvm-commits
> <llvm-commits at lists.llvm.org>
> *Subject:* Re: [llvm] r345546 - [DWARF][NFC] Refactor range list
> extraction and dumping
>
>
>
> 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
> <http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfStreamer.cpp?rev=345546&r1=345545&r2=345546&view=diff>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20181030/d6a52274/attachment.html>
More information about the llvm-commits
mailing list