[llvm] r345546 - [DWARF][NFC] Refactor range list extraction and dumping
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 2 15:22:44 PDT 2018
Well, I've got /something/ at least.
Build Clang with compiler_rt (& libcxx and libcxxabi), then run:
CLANG=... ZLIB_SRC=...
path/to/src/projects/compiler-rt/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh
lib/clang/8.0.0/lib/linux
Then compile the following file:
extern "C" void __sanitizer_print_stack_trace(void);
int main() { __sanitizer_print_stack_trace(); }
$ clang++ -fsanitize=thread symbolizer_test.cc -g
& run the resulting binary:
./a.out
ThreadSanitizer:DEADLYSIGNAL
==91375==ERROR: ThreadSanitizer: SEGV on unknown address 0x000000000000
(pc 0x0000005615fd bp 0x7fa81c703830 sp 0x7fff330149d0 T91375)
==91375==The signal is caused by a READ memory access.
==91375==Hint: address points to the zero page.
whereas it should print:
#0 __sanitizer_print_stack_trace
.../projects/compiler-rt/lib/tsan/rtl/tsan_rtl_report.cc:753:25
(a.out+0x4a9d09)
#1 main .../dev/scratch/symbolizer_test.cc:2:14 (a.out+0x4affa5)
#2 __libc_start_main <null> (libc.so.6+0x202b0)
#3 _start <null> (a.out+0x41f2d9)
Though I don't know much about this integrated symbolizer... - I'm poking
around more, but this at least gets you a reproduction/you can debug it
maybe about as easily as I can :/
As Eric said - smaller patches might help (& would generally be good
regardless) - but wouldn't be sure it'd make it super obvious.
On Tue, Oct 30, 2018 at 5:23 PM Eric Christopher <echristo at gmail.com> wrote:
> On Tue, Oct 30, 2018 at 5:16 PM David Blaikie <dblaikie at gmail.com> wrote:
>
>> 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.
>>
>>
>
> Agreed. Breaking it into smaller pieces will help this, but someone should
> work on getting a test case here. I'm out of town the rest of the week so
> I'm going to leave it up to David, Richard, and Ilya here to try to reduce
> down something.
>
> Thanks.
>
> -eric
>
>
>>
>>> 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/20181102/662e843f/attachment-0001.html>
More information about the llvm-commits
mailing list