Update clang to r339409.
Change-Id: I800772d2d838223be1f6b40d490c4591b937fca2
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index fe3f573..0908504 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -18,6 +18,7 @@
#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"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
@@ -40,124 +41,116 @@
class DWARFDebugAbbrev;
class DWARFUnit;
-/// Base class for all DWARFUnitSection classes. This provides the
-/// functionality common to all unit types.
-class DWARFUnitSectionBase {
+/// Base class describing the header of any kind of "unit." Some information
+/// is specific to certain unit types. We separate this class out so we can
+/// parse the header before deciding what specific kind of unit to construct.
+class DWARFUnitHeader {
+ // Offset within section.
+ uint32_t Offset = 0;
+ // Version, address size, and DWARF format.
+ dwarf::FormParams FormParams;
+ uint32_t Length = 0;
+ uint64_t AbbrOffset = 0;
+
+ // For DWO units only.
+ const DWARFUnitIndex::Entry *IndexEntry = nullptr;
+
+ // For type units only.
+ uint64_t TypeHash = 0;
+ uint32_t TypeOffset = 0;
+
+ // For v5 split or skeleton compile units only.
+ Optional<uint64_t> DWOId;
+
+ // Unit type as parsed, or derived from the section kind.
+ uint8_t UnitType = 0;
+
+ // Size as parsed. uint8_t for compactness.
+ uint8_t Size = 0;
+
public:
- /// Returns the Unit that contains the given section offset in the
- /// same section this Unit originated from.
- virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0;
- virtual DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) = 0;
-
- void parse(DWARFContext &C, const DWARFSection &Section);
- void parseDWO(DWARFContext &C, const DWARFSection &DWOSection,
- bool Lazy = false);
-
-protected:
- ~DWARFUnitSectionBase() = default;
-
- virtual void parseImpl(DWARFContext &Context, const DWARFObject &Obj,
- const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, const DWARFSection *RS,
- StringRef SS, const DWARFSection &SOS,
- const DWARFSection *AOS, const DWARFSection &LS,
- bool isLittleEndian, bool isDWO, bool Lazy) = 0;
+ /// Parse a unit header from \p debug_info starting at \p offset_ptr.
+ bool extract(DWARFContext &Context, const DWARFDataExtractor &debug_info,
+ uint32_t *offset_ptr, DWARFSectionKind Kind = DW_SECT_INFO,
+ const DWARFUnitIndex *Index = nullptr);
+ uint32_t getOffset() const { return Offset; }
+ const dwarf::FormParams &getFormParams() const { return FormParams; }
+ uint16_t getVersion() const { return FormParams.Version; }
+ dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
+ uint8_t getAddressByteSize() const { return FormParams.AddrSize; }
+ uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); }
+ uint8_t getDwarfOffsetByteSize() const {
+ return FormParams.getDwarfOffsetByteSize();
+ }
+ uint32_t getLength() const { return Length; }
+ uint64_t getAbbrOffset() const { return AbbrOffset; }
+ Optional<uint64_t> getDWOId() const { return DWOId; }
+ void setDWOId(uint64_t Id) {
+ assert((!DWOId || *DWOId == Id) && "setting DWOId to a different value");
+ DWOId = Id;
+ }
+ const DWARFUnitIndex::Entry *getIndexEntry() const { return IndexEntry; }
+ uint64_t getTypeHash() const { return TypeHash; }
+ uint32_t getTypeOffset() const { return TypeOffset; }
+ uint8_t getUnitType() const { return UnitType; }
+ bool isTypeUnit() const {
+ return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type;
+ }
+ uint8_t getSize() const { return Size; }
+ // FIXME: Support DWARF64.
+ uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
};
const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
DWARFSectionKind Kind);
-/// Concrete instance of DWARFUnitSection, specialized for one Unit type.
-template<typename UnitType>
-class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
- public DWARFUnitSectionBase {
- bool Parsed = false;
- std::function<std::unique_ptr<UnitType>(uint32_t)> Parser;
+/// Describe a collection of units. Intended to hold all units either from
+/// .debug_info and .debug_types, or from .debug_info.dwo and .debug_types.dwo.
+class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
+ std::function<std::unique_ptr<DWARFUnit>(uint32_t, DWARFSectionKind,
+ const DWARFSection *)>
+ Parser;
+ unsigned NumInfoUnits = 0;
public:
- using UnitVector = SmallVectorImpl<std::unique_ptr<UnitType>>;
+ using UnitVector = SmallVectorImpl<std::unique_ptr<DWARFUnit>>;
using iterator = typename UnitVector::iterator;
using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;
- UnitType *getUnitForOffset(uint32_t Offset) const override {
- auto *CU = std::upper_bound(
- this->begin(), this->end(), Offset,
- [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) {
- return LHS < RHS->getNextUnitOffset();
- });
- if (CU != this->end() && (*CU)->getOffset() <= Offset)
- return CU->get();
- return nullptr;
- }
- UnitType *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) override {
- const auto *CUOff = E.getOffset(DW_SECT_INFO);
- if (!CUOff)
- return nullptr;
+ DWARFUnit *getUnitForOffset(uint32_t Offset) const;
+ DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
- auto Offset = CUOff->Offset;
+ /// Read units from a .debug_info or .debug_types section. Calls made
+ /// before finishedInfoUnits() are assumed to be for .debug_info sections,
+ /// calls after finishedInfoUnits() are for .debug_types sections. Caller
+ /// must not mix calls to addUnitsForSection and addUnitsForDWOSection.
+ void addUnitsForSection(DWARFContext &C, const DWARFSection &Section,
+ DWARFSectionKind SectionKind);
+ /// Read units from a .debug_info.dwo or .debug_types.dwo section. Calls
+ /// made before finishedInfoUnits() are assumed to be for .debug_info.dwo
+ /// sections, calls after finishedInfoUnits() are for .debug_types.dwo
+ /// sections. Caller must not mix calls to addUnitsForSection and
+ /// addUnitsForDWOSection.
+ void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection,
+ DWARFSectionKind SectionKind, bool Lazy = false);
- auto *CU = std::upper_bound(
- this->begin(), this->end(), CUOff->Offset,
- [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) {
- return LHS < RHS->getNextUnitOffset();
- });
- if (CU != this->end() && (*CU)->getOffset() <= Offset)
- return CU->get();
-
- if (!Parser)
- return nullptr;
-
- auto U = Parser(Offset);
- if (!U)
- U = nullptr;
-
- auto *NewCU = U.get();
- this->insert(CU, std::move(U));
- return NewCU;
- }
+ /// Returns number of all units held by this instance.
+ unsigned getNumUnits() { return size(); }
+ /// Returns number of units from all .debug_info[.dwo] sections.
+ unsigned getNumInfoUnits() { return NumInfoUnits; }
+ /// Returns number of units from all .debug_types[.dwo] sections.
+ unsigned getNumTypesUnits() { return size() - NumInfoUnits; }
+ /// Indicate that parsing .debug_info[.dwo] is done, and remaining units
+ /// will be from .debug_types[.dwo].
+ void finishedInfoUnits() { NumInfoUnits = size(); }
private:
- void parseImpl(DWARFContext &Context, const DWARFObject &Obj,
- const DWARFSection &Section, const DWARFDebugAbbrev *DA,
- const DWARFSection *RS, StringRef SS, const DWARFSection &SOS,
- const DWARFSection *AOS, const DWARFSection &LS, bool LE,
- bool IsDWO, bool Lazy) override {
- if (Parsed)
- return;
- DWARFDataExtractor Data(Obj, Section, LE, 0);
- if (!Parser) {
- const DWARFUnitIndex *Index = nullptr;
- if (IsDWO)
- Index = &getDWARFUnitIndex(Context, UnitType::Section);
- Parser = [=, &Context, &Section, &SOS,
- &LS](uint32_t Offset) -> std::unique_ptr<UnitType> {
- if (!Data.isValidOffset(Offset))
- return nullptr;
- auto U = llvm::make_unique<UnitType>(
- Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, *this,
- Index ? Index->getFromOffset(Offset) : nullptr);
- if (!U->extract(Data, &Offset))
- return nullptr;
- return U;
- };
- }
- if (Lazy)
- return;
- auto I = this->begin();
- uint32_t Offset = 0;
- while (Data.isValidOffset(Offset)) {
- if (I != this->end() && (*I)->getOffset() == Offset) {
- ++I;
- continue;
- }
- auto U = Parser(Offset);
- if (!U)
- break;
- Offset = U->getNextUnitOffset();
- I = std::next(this->insert(I, std::move(U)));
- }
- Parsed = true;
- }
+ void addUnitsImpl(DWARFContext &Context, const DWARFObject &Obj,
+ const DWARFSection &Section, const DWARFDebugAbbrev *DA,
+ const DWARFSection *RS, StringRef SS,
+ const DWARFSection &SOS, const DWARFSection *AOS,
+ const DWARFSection &LS, bool LE, bool IsDWO, bool Lazy,
+ DWARFSectionKind SectionKind);
};
/// Represents base address of the CU.
@@ -169,6 +162,7 @@
/// Represents a unit's contribution to the string offsets table.
struct StrOffsetsContributionDescriptor {
uint64_t Base = 0;
+ /// The contribution size not including the header.
uint64_t Size = 0;
/// Format and version.
dwarf::FormParams FormParams = {0, 0, dwarf::DwarfFormat::DWARF32};
@@ -194,6 +188,7 @@
/// Section containing this DWARFUnit.
const DWARFSection &InfoSection;
+ DWARFUnitHeader Header;
const DWARFDebugAbbrev *Abbrev;
const DWARFSection *RangeSection;
uint32_t RangeSectionBase;
@@ -204,19 +199,16 @@
uint32_t AddrOffsetSectionBase = 0;
bool isLittleEndian;
bool isDWO;
- const DWARFUnitSectionBase &UnitSection;
+ const DWARFUnitVector &UnitVector;
- // Version, address size, and DWARF format.
- dwarf::FormParams FormParams;
/// Start, length, and DWARF format of the unit's contribution to the string
/// offsets table (DWARF v5).
Optional<StrOffsetsContributionDescriptor> StringOffsetsTableContribution;
- uint32_t Offset;
- uint32_t Length;
+ /// A table of range lists (DWARF v5 and later).
+ Optional<DWARFDebugRnglistTable> RngListTable;
+
mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
- uint64_t AbbrOffset;
- uint8_t UnitType;
llvm::Optional<BaseAddress> BaseAddr;
/// The compile unit debug information entry items.
std::vector<DWARFDebugInfoEntry> DieArray;
@@ -231,8 +223,6 @@
std::shared_ptr<DWARFUnit> DWO;
- const DWARFUnitIndex::Entry *IndexEntry;
-
uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) {
auto First = DieArray.data();
assert(Die >= First && Die < First + DieArray.size());
@@ -240,11 +230,10 @@
}
protected:
- virtual bool extractImpl(const DWARFDataExtractor &debug_info,
- uint32_t *offset_ptr);
+ const DWARFUnitHeader &getHeader() const { return Header; }
- /// Size in bytes of the unit header.
- virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; }
+ /// Size in bytes of the parsed unit header.
+ uint32_t getHeaderSize() const { return Header.getSize(); }
/// Find the unit's contribution to the string offsets table and determine its
/// length and form. The given offset is expected to be derived from the unit
@@ -263,16 +252,30 @@
public:
DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
+ const DWARFUnitHeader &Header,
const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
const DWARFSection &SOS, const DWARFSection *AOS,
const DWARFSection &LS, bool LE, bool IsDWO,
- const DWARFUnitSectionBase &UnitSection,
- const DWARFUnitIndex::Entry *IndexEntry = nullptr);
+ const DWARFUnitVector &UnitVector);
virtual ~DWARFUnit();
DWARFContext& getContext() const { return Context; }
-
+ const DWARFSection &getInfoSection() const { return InfoSection; }
+ uint32_t getOffset() const { return Header.getOffset(); }
+ const dwarf::FormParams &getFormParams() const {
+ return Header.getFormParams();
+ }
+ uint16_t getVersion() const { return Header.getVersion(); }
+ uint8_t getAddressByteSize() const { return Header.getAddressByteSize(); }
+ uint8_t getRefAddrByteSize() const { return Header.getRefAddrByteSize(); }
+ uint8_t getDwarfOffsetByteSize() const {
+ return Header.getDwarfOffsetByteSize();
+ }
+ uint32_t getLength() const { return Header.getLength(); }
+ uint8_t getUnitType() const { return Header.getUnitType(); }
+ bool isTypeUnit() const { return Header.isTypeUnit(); }
+ uint32_t getNextUnitOffset() const { return Header.getNextUnitOffset(); }
const DWARFSection &getLineSection() const { return LineSection; }
StringRef getStringSection() const { return StringSection; }
const DWARFSection &getStringOffsetSection() const {
@@ -301,30 +304,18 @@
return DataExtractor(StringSection, false, 0);
}
- bool extract(const DWARFDataExtractor &debug_info, uint32_t *offset_ptr);
-
- /// extractRangeList - extracts the range list referenced by this compile
- /// unit from .debug_ranges section. Returns true on success.
- /// Requires that compile unit is already extracted.
- bool extractRangeList(uint32_t RangeListOffset,
- DWARFDebugRangeList &RangeList) const;
+ /// 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();
- uint32_t getOffset() const { return Offset; }
- uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
- uint32_t getLength() const { return Length; }
const Optional<StrOffsetsContributionDescriptor> &
getStringOffsetsTableContribution() const {
return StringOffsetsTableContribution;
}
- const dwarf::FormParams &getFormParams() const { return FormParams; }
- uint16_t getVersion() const { return FormParams.Version; }
- dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
- uint8_t getAddressByteSize() const { return FormParams.AddrSize; }
- uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); }
- uint8_t getDwarfOffsetByteSize() const {
- return FormParams.getDwarfOffsetByteSize();
- }
uint8_t getDwarfStringOffsetsByteSize() const {
assert(StringOffsetsTableContribution);
@@ -338,8 +329,6 @@
const DWARFAbbreviationDeclarationSet *getAbbreviations() const;
- uint8_t getUnitType() const { return UnitType; }
-
static bool isMatchingUnitTypeAndTag(uint8_t UnitType, dwarf::Tag Tag) {
switch (UnitType) {
case dwarf::DW_UT_compile:
@@ -357,7 +346,7 @@
return false;
}
- /// \brief Return the number of bytes for the header of a unit of
+ /// Return the number of bytes for the header of a unit of
/// UnitType type.
///
/// This function must be called with a valid unit type which in
@@ -377,9 +366,7 @@
llvm_unreachable("Invalid UnitType.");
}
- llvm::Optional<BaseAddress> getBaseAddress() const { return BaseAddr; }
-
- void setBaseAddress(BaseAddress BaseAddr) { this->BaseAddr = BaseAddr; }
+ llvm::Optional<BaseAddress> getBaseAddress();
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
extractDIEsIfNeeded(ExtractUnitDIEOnly);
@@ -389,7 +376,29 @@
}
const char *getCompilationDir();
- Optional<uint64_t> getDWOId();
+ Optional<uint64_t> getDWOId() {
+ extractDIEsIfNeeded(/*CUDieOnly*/ true);
+ return getHeader().getDWOId();
+ }
+ void setDWOId(uint64_t NewID) { Header.setDWOId(NewID); }
+
+ /// Return a vector of address ranges resulting from a (possibly encoded)
+ /// range list starting at a given offset in the appropriate ranges section.
+ Expected<DWARFAddressRangesVector> findRnglistFromOffset(uint32_t Offset);
+
+ /// Return a vector of address ranges retrieved from an encoded range
+ /// list whose offset is found via a table lookup given an index (DWARF v5
+ /// and later).
+ Expected<DWARFAddressRangesVector> findRnglistFromIndex(uint32_t Index);
+
+ /// Return a rangelist's offset based on an index. The index designates
+ /// an entry in the rangelist table's offset array and is supplied by
+ /// DW_FORM_rnglistx.
+ Optional<uint32_t> getRnglistOffset(uint32_t Index) {
+ if (RngListTable)
+ return RngListTable->getOffsetEntry(Index);
+ return None;
+ }
void collectAddressRanges(DWARFAddressRangesVector &CURanges);
@@ -404,17 +413,17 @@
void getInlinedChainForAddress(uint64_t Address,
SmallVectorImpl<DWARFDie> &InlinedChain);
- /// getUnitSection - Return the DWARFUnitSection containing this unit.
- const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; }
+ /// Return the DWARFUnitVector containing this unit.
+ const DWARFUnitVector &getUnitVector() const { return UnitVector; }
- /// \brief Returns the number of DIEs in the unit. Parses the unit
+ /// Returns the number of DIEs in the unit. Parses the unit
/// if necessary.
unsigned getNumDIEs() {
extractDIEsIfNeeded(false);
return DieArray.size();
}
- /// \brief Return the index of a DIE inside the unit's DIE vector.
+ /// Return the index of a DIE inside the unit's DIE vector.
///
/// It is illegal to call this method with a DIE that hasn't be
/// created by this unit. In other word, it's illegal to call this
@@ -424,7 +433,7 @@
return getDIEIndex(D.getDebugInfoEntry());
}
- /// \brief Return the DIE object at the given index.
+ /// Return the DIE object at the given index.
DWARFDie getDIEAtIndex(unsigned Index) {
assert(Index < DieArray.size());
return DWARFDie(this, &DieArray[Index]);
@@ -432,9 +441,11 @@
DWARFDie getParent(const DWARFDebugInfoEntry *Die);
DWARFDie getSibling(const DWARFDebugInfoEntry *Die);
+ DWARFDie getPreviousSibling(const DWARFDebugInfoEntry *Die);
DWARFDie getFirstChild(const DWARFDebugInfoEntry *Die);
+ DWARFDie getLastChild(const DWARFDebugInfoEntry *Die);
- /// \brief Return the DIE object for a given offset inside the
+ /// Return the DIE object for a given offset inside the
/// unit's DIE vector.
///
/// The unit needs to have its DIEs extracted for this method to work.
@@ -452,7 +463,7 @@
}
uint32_t getLineTableOffset() const {
- if (IndexEntry)
+ if (auto IndexEntry = Header.getIndexEntry())
if (const auto *Contrib = IndexEntry->getOffset(DW_SECT_LINE))
return Contrib->Offset;
return 0;
@@ -463,9 +474,12 @@
return die_iterator_range(DieArray.begin(), DieArray.end());
}
+ virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
private:
/// Size in bytes of the .debug_info data associated with this compile unit.
- size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }
+ size_t getDebugInfoSize() const {
+ return Header.getLength() + 4 - getHeaderSize();
+ }
/// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
/// hasn't already been done. Returns the number of DIEs parsed at this call.