X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FDebugInfo%2FDWARFUnit.h;h=786f00f5e8eecb52755928cf1d1b5b7c464fe2db;hb=7435fa333d1b646690021bfaa9350355017d0bdf;hp=4d93de9e100a7669060cdd44e64ade352893e26a;hpb=cd7c4980d4ee2d22d92a4907f2d029e67b52d732;p=oota-llvm.git diff --git a/lib/DebugInfo/DWARFUnit.h b/lib/DebugInfo/DWARFUnit.h index 4d93de9e100..786f00f5e8e 100644 --- a/lib/DebugInfo/DWARFUnit.h +++ b/lib/DebugInfo/DWARFUnit.h @@ -7,14 +7,14 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_DEBUGINFO_DWARFUNIT_H -#define LLVM_DEBUGINFO_DWARFUNIT_H +#ifndef LLVM_LIB_DEBUGINFO_DWARFUNIT_H +#define LLVM_LIB_DEBUGINFO_DWARFUNIT_H -#include "llvm/ADT/OwningPtr.h" #include "DWARFDebugAbbrev.h" #include "DWARFDebugInfoEntry.h" #include "DWARFDebugRangeList.h" #include "DWARFRelocMap.h" +#include "DWARFSection.h" #include namespace llvm { @@ -23,22 +23,96 @@ namespace object { class ObjectFile; } +class DWARFContext; class DWARFDebugAbbrev; +class DWARFUnit; class StringRef; class raw_ostream; +/// Base class for all DWARFUnitSection classes. This provides the +/// functionality common to all unit types. +class DWARFUnitSectionBase { +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; + + void parse(DWARFContext &C, const DWARFSection &Section); + void parseDWO(DWARFContext &C, const DWARFSection &DWOSection); + +protected: + virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section, + const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, + StringRef SOS, StringRef AOS, bool isLittleEndian) = 0; + + ~DWARFUnitSectionBase() {} +}; + +/// Concrete instance of DWARFUnitSection, specialized for one Unit type. +template +class DWARFUnitSection final : public SmallVector, 1>, + public DWARFUnitSectionBase { + + struct UnitOffsetComparator { + bool operator()(uint32_t LHS, + const std::unique_ptr &RHS) const { + return LHS < RHS->getNextUnitOffset(); + } + }; + + bool Parsed; + +public: + DWARFUnitSection() : Parsed(false) {} + DWARFUnitSection(DWARFUnitSection &&DUS) : + SmallVector, 1>(std::move(DUS)), Parsed(DUS.Parsed) {} + + typedef llvm::SmallVectorImpl> UnitVector; + typedef typename UnitVector::iterator iterator; + typedef llvm::iterator_range iterator_range; + + UnitType *getUnitForOffset(uint32_t Offset) const override { + auto *CU = std::upper_bound(this->begin(), this->end(), Offset, + UnitOffsetComparator()); + if (CU != this->end()) + return CU->get(); + return nullptr; + } + +private: + void parseImpl(DWARFContext &Context, const DWARFSection &Section, + const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, + StringRef SOS, StringRef AOS, bool LE) override { + if (Parsed) + return; + DataExtractor Data(Section.Data, LE, 0); + uint32_t Offset = 0; + while (Data.isValidOffset(Offset)) { + auto U = llvm::make_unique(Context, Section, DA, RS, SS, SOS, + AOS, LE, *this); + if (!U->extract(Data, &Offset)) + break; + this->push_back(std::move(U)); + Offset = this->back()->getNextUnitOffset(); + } + Parsed = true; + } +}; + class DWARFUnit { + DWARFContext &Context; + // Section containing this DWARFUnit. + const DWARFSection &InfoSection; + const DWARFDebugAbbrev *Abbrev; - StringRef InfoSection; - StringRef AbbrevSection; StringRef RangeSection; uint32_t RangeSectionBase; StringRef StringSection; StringRef StringOffsetSection; StringRef AddrOffsetSection; uint32_t AddrOffsetSectionBase; - const RelocAddrMap *RelocMap; bool isLittleEndian; + const DWARFUnitSectionBase &UnitSection; uint32_t Offset; uint32_t Length; @@ -50,26 +124,30 @@ class DWARFUnit { std::vector DieArray; class DWOHolder { - OwningPtr DWOFile; - OwningPtr DWOContext; + object::OwningBinary DWOFile; + std::unique_ptr DWOContext; DWARFUnit *DWOU; public: - DWOHolder(object::ObjectFile *DWOFile); + DWOHolder(StringRef DWOPath); DWARFUnit *getUnit() const { return DWOU; } }; - OwningPtr DWO; + std::unique_ptr DWO; protected: virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr); + /// Size in bytes of the unit header. + virtual uint32_t getHeaderSize() const { return 11; } public: - - DWARFUnit(const DWARFDebugAbbrev *DA, StringRef IS, StringRef AS, - StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, - const RelocAddrMap *M, bool LE); + DWARFUnit(DWARFContext &Context, const DWARFSection &Section, + const DWARFDebugAbbrev *DA, StringRef RS, StringRef SS, + StringRef SOS, StringRef AOS, bool LE, + const DWARFUnitSectionBase &UnitSection); virtual ~DWARFUnit(); + DWARFContext& getContext() const { return Context; } + StringRef getStringSection() const { return StringSection; } StringRef getStringOffsetSection() const { return StringOffsetSection; } void setAddrOffsetSection(StringRef AOS, uint32_t Base) { @@ -86,21 +164,16 @@ public: bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const; DataExtractor getDebugInfoExtractor() const { - return DataExtractor(InfoSection, isLittleEndian, AddrSize); + return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize); } DataExtractor getStringExtractor() const { return DataExtractor(StringSection, false, 0); } - const RelocAddrMap *getRelocMap() const { return RelocMap; } + const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; } bool extract(DataExtractor debug_info, uint32_t* offset_ptr); - uint32_t extract(uint32_t offset, DataExtractor debug_info_data, - const DWARFAbbreviationDeclarationSet *abbrevs); - /// 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. - size_t extractDIEsIfNeeded(bool CUDieOnly); /// 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. @@ -108,16 +181,7 @@ public: DWARFDebugRangeList &RangeList) const; void clear(); uint32_t getOffset() const { return Offset; } - /// Size in bytes of the compile unit header. - virtual uint32_t getSize() const { return 11; } - bool containsDIEOffset(uint32_t die_offset) const { - return die_offset >= getFirstDIEOffset() && - die_offset < getNextUnitOffset(); - } - uint32_t getFirstDIEOffset() const { return Offset + getSize(); } uint32_t getNextUnitOffset() const { return Offset + Length + 4; } - /// Size in bytes of the .debug_info data associated with this compile unit. - size_t getDebugInfoSize() const { return Length + 4 - getSize(); } uint32_t getLength() const { return Length; } uint16_t getVersion() const { return Version; } const DWARFAbbreviationDeclarationSet *getAbbreviations() const { @@ -133,30 +197,36 @@ public: const DWARFDebugInfoEntryMinimal * getCompileUnitDIE(bool extract_cu_die_only = true) { extractDIEsIfNeeded(extract_cu_die_only); - return DieArray.empty() ? NULL : &DieArray[0]; + return DieArray.empty() ? nullptr : &DieArray[0]; } const char *getCompilationDir(); uint64_t getDWOId(); - /// setDIERelations - We read in all of the DIE entries into our flat list - /// of DIE entries and now we need to go back through all of them and set the - /// parent, sibling and child pointers for quick DIE navigation. - void setDIERelations(); - - void buildAddressRangeTable(DWARFDebugAranges *debug_aranges, - bool clear_dies_if_already_not_parsed, - uint32_t CUOffsetInAranges); + void collectAddressRanges(DWARFAddressRangesVector &CURanges); /// getInlinedChainForAddress - fetches inlined chain for a given address. /// Returns empty chain if there is no subprogram containing address. The /// chain is valid as long as parsed compile unit DIEs are not cleared. DWARFDebugInfoEntryInlinedChain getInlinedChainForAddress(uint64_t Address); + /// getUnitSection - Return the DWARFUnitSection containing this unit. + const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; } + private: + /// Size in bytes of the .debug_info data associated with this compile unit. + size_t getDebugInfoSize() const { return Length + 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. + size_t extractDIEsIfNeeded(bool CUDieOnly); /// extractDIEsToVector - Appends all parsed DIEs to a vector. void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs, std::vector &DIEs) const; + /// setDIERelations - We read in all of the DIE entries into our flat list + /// of DIE entries and now we need to go back through all of them and set the + /// parent, sibling and child pointers for quick DIE navigation. + void setDIERelations(); /// clearDIEs - Clear parsed DIEs to keep memory usage low. void clearDIEs(bool KeepCUDie);