LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/DWARF - DWARFUnit.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 55 56 98.2 %
Date: 2017-09-14 15:23:50 Functions: 8 10 80.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFUnit.h ----------------------------------------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #ifndef LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
      11             : #define LLVM_DEBUGINFO_DWARF_DWARFUNIT_H
      12             : 
      13             : #include "llvm/ADT/Optional.h"
      14             : #include "llvm/ADT/STLExtras.h"
      15             : #include "llvm/ADT/SmallVector.h"
      16             : #include "llvm/ADT/StringRef.h"
      17             : #include "llvm/ADT/iterator_range.h"
      18             : #include "llvm/BinaryFormat/Dwarf.h"
      19             : #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
      20             : #include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
      21             : #include "llvm/DebugInfo/DWARF/DWARFDie.h"
      22             : #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
      23             : #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
      24             : #include "llvm/DebugInfo/DWARF/DWARFSection.h"
      25             : #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
      26             : #include "llvm/Support/DataExtractor.h"
      27             : #include <algorithm>
      28             : #include <cassert>
      29             : #include <cstddef>
      30             : #include <cstdint>
      31             : #include <map>
      32             : #include <memory>
      33             : #include <utility>
      34             : #include <vector>
      35             : 
      36             : namespace llvm {
      37             : 
      38             : class DWARFAbbreviationDeclarationSet;
      39             : class DWARFContext;
      40             : class DWARFDebugAbbrev;
      41             : class DWARFUnit;
      42             : 
      43             : /// Base class for all DWARFUnitSection classes. This provides the
      44             : /// functionality common to all unit types.
      45             : class DWARFUnitSectionBase {
      46             : public:
      47             :   /// Returns the Unit that contains the given section offset in the
      48             :   /// same section this Unit originated from.
      49             :   virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0;
      50             : 
      51             :   void parse(DWARFContext &C, const DWARFSection &Section);
      52             :   void parseDWO(DWARFContext &C, const DWARFSection &DWOSection,
      53             :                 DWARFUnitIndex *Index = nullptr);
      54             : 
      55             : protected:
      56             :   ~DWARFUnitSectionBase() = default;
      57             : 
      58             :   virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
      59             :                          const DWARFDebugAbbrev *DA, const DWARFSection *RS,
      60             :                          StringRef SS, const DWARFSection &SOS,
      61             :                          const DWARFSection *AOS, const DWARFSection &LS,
      62             :                          bool isLittleEndian, bool isDWO) = 0;
      63             : };
      64             : 
      65             : const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
      66             :                                         DWARFSectionKind Kind);
      67             : 
      68             : /// Concrete instance of DWARFUnitSection, specialized for one Unit type.
      69             : template<typename UnitType>
      70        8296 : class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
      71             :                                public DWARFUnitSectionBase {
      72             :   bool Parsed = false;
      73             : 
      74             : public:
      75             :   using UnitVector = SmallVectorImpl<std::unique_ptr<UnitType>>;
      76             :   using iterator = typename UnitVector::iterator;
      77             :   using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;
      78             : 
      79        2323 :   UnitType *getUnitForOffset(uint32_t Offset) const override {
      80        9292 :     auto *CU = std::upper_bound(
      81             :         this->begin(), this->end(), Offset,
      82             :         [](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) {
      83       12399 :           return LHS < RHS->getNextUnitOffset();
      84             :         });
      85        2323 :     if (CU != this->end())
      86        2248 :       return CU->get();
      87             :     return nullptr;
      88             :   }
      89             : 
      90             : private:
      91        2759 :   void parseImpl(DWARFContext &Context, const DWARFSection &Section,
      92             :                  const DWARFDebugAbbrev *DA, const DWARFSection *RS,
      93             :                  StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
      94             :                  const DWARFSection &LS, bool LE, bool IsDWO) override {
      95        2759 :     if (Parsed)
      96        1715 :       return;
      97        1044 :     const auto &Index = getDWARFUnitIndex(Context, UnitType::Section);
      98        2088 :     DataExtractor Data(Section.Data, LE, 0);
      99        1044 :     uint32_t Offset = 0;
     100       57062 :     while (Data.isValidOffset(Offset)) {
     101       54989 :       auto U = llvm::make_unique<UnitType>(Context, Section, DA, RS, SS, SOS,
     102             :                                            AOS, LS, LE, IsDWO, *this,
     103             :                                            Index.getFromOffset(Offset));
     104       27502 :       if (!U->extract(Data, &Offset))
     105             :         break;
     106       27487 :       this->push_back(std::move(U));
     107      109948 :       Offset = this->back()->getNextUnitOffset();
     108             :     }
     109        1044 :     Parsed = true;
     110             :   }
     111             : };
     112             : 
     113             : /// Represents base address of the CU.
     114             : struct BaseAddress {
     115             :   uint64_t Address;
     116             :   uint64_t SectionIndex;
     117             : };
     118             : 
     119      137776 : class DWARFUnit {
     120             :   DWARFContext &Context;
     121             :   /// Section containing this DWARFUnit.
     122             :   const DWARFSection &InfoSection;
     123             : 
     124             :   const DWARFDebugAbbrev *Abbrev;
     125             :   const DWARFSection *RangeSection;
     126             :   uint32_t RangeSectionBase;
     127             :   const DWARFSection &LineSection;
     128             :   StringRef StringSection;
     129             :   const DWARFSection &StringOffsetSection;
     130             :   uint64_t StringOffsetSectionBase = 0;
     131             :   const DWARFSection *AddrOffsetSection;
     132             :   uint32_t AddrOffsetSectionBase = 0;
     133             :   bool isLittleEndian;
     134             :   bool isDWO;
     135             :   const DWARFUnitSectionBase &UnitSection;
     136             : 
     137             :   // Version, address size, and DWARF format.
     138             :   DWARFFormParams FormParams;
     139             : 
     140             :   uint32_t Offset;
     141             :   uint32_t Length;
     142             :   const DWARFAbbreviationDeclarationSet *Abbrevs;
     143             :   uint8_t UnitType;
     144             :   llvm::Optional<BaseAddress> BaseAddr;
     145             :   /// The compile unit debug information entry items.
     146             :   std::vector<DWARFDebugInfoEntry> DieArray;
     147             : 
     148             :   /// Map from range's start address to end address and corresponding DIE.
     149             :   /// IntervalMap does not support range removal, as a result, we use the
     150             :   /// std::map::upper_bound for address range lookup.
     151             :   std::map<uint64_t, std::pair<uint64_t, DWARFDie>> AddrDieMap;
     152             : 
     153             :   using die_iterator_range =
     154             :       iterator_range<std::vector<DWARFDebugInfoEntry>::iterator>;
     155             : 
     156             :   std::shared_ptr<DWARFUnit> DWO;
     157             : 
     158             :   const DWARFUnitIndex::Entry *IndexEntry;
     159             : 
     160             :   uint32_t getDIEIndex(const DWARFDebugInfoEntry *Die) {
     161    28189982 :     auto First = DieArray.data();
     162             :     assert(Die >= First && Die < First + DieArray.size());
     163    14094991 :     return Die - First;
     164             :   }
     165             : 
     166             : protected:
     167             :   virtual bool extractImpl(DataExtractor debug_info, uint32_t *offset_ptr);
     168             : 
     169             :   /// Size in bytes of the unit header.
     170       29315 :   virtual uint32_t getHeaderSize() const { return getVersion() <= 4 ? 11 : 12; }
     171             : 
     172             : public:
     173             :   DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
     174             :             const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
     175             :             const DWARFSection &SOS, const DWARFSection *AOS,
     176             :             const DWARFSection &LS, bool LE, bool IsDWO,
     177             :             const DWARFUnitSectionBase &UnitSection,
     178             :             const DWARFUnitIndex::Entry *IndexEntry = nullptr);
     179             : 
     180             :   virtual ~DWARFUnit();
     181             : 
     182             :   DWARFContext& getContext() const { return Context; }
     183             : 
     184             :   const DWARFSection &getLineSection() const { return LineSection; }
     185             :   StringRef getStringSection() const { return StringSection; }
     186             :   const DWARFSection &getStringOffsetSection() const {
     187             :     return StringOffsetSection;
     188             :   }
     189             : 
     190             :   void setAddrOffsetSection(const DWARFSection *AOS, uint32_t Base) {
     191          17 :     AddrOffsetSection = AOS;
     192          17 :     AddrOffsetSectionBase = Base;
     193             :   }
     194             : 
     195             :   /// Recursively update address to Die map.
     196             :   void updateAddressDieMap(DWARFDie Die);
     197             : 
     198             :   void setRangesSection(const DWARFSection *RS, uint32_t Base) {
     199          17 :     RangeSection = RS;
     200          17 :     RangeSectionBase = Base;
     201             :   }
     202             : 
     203             :   bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
     204             :   bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
     205             : 
     206             :   DWARFDataExtractor getDebugInfoExtractor() const;
     207             : 
     208             :   DataExtractor getStringExtractor() const {
     209       11419 :     return DataExtractor(StringSection, false, 0);
     210             :   }
     211             : 
     212             : 
     213             :   bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
     214             : 
     215             :   /// extractRangeList - extracts the range list referenced by this compile
     216             :   /// unit from .debug_ranges section. Returns true on success.
     217             :   /// Requires that compile unit is already extracted.
     218             :   bool extractRangeList(uint32_t RangeListOffset,
     219             :                         DWARFDebugRangeList &RangeList) const;
     220             :   void clear();
     221             :   uint32_t getOffset() const { return Offset; }
     222       97278 :   uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
     223             :   uint32_t getLength() const { return Length; }
     224             : 
     225     2552207 :   const DWARFFormParams &getFormParams() const { return FormParams; }
     226             :   uint16_t getVersion() const { return FormParams.Version; }
     227             :   dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
     228             :   uint8_t getAddressByteSize() const { return FormParams.AddrSize; }
     229        1540 :   uint8_t getRefAddrByteSize() const { return FormParams.getRefAddrByteSize(); }
     230             :   uint8_t getDwarfOffsetByteSize() const {
     231     5727339 :     return FormParams.getDwarfOffsetByteSize();
     232             :   }
     233             : 
     234             :   const DWARFAbbreviationDeclarationSet *getAbbreviations() const {
     235             :     return Abbrevs;
     236             :   }
     237             : 
     238             :   uint8_t getUnitType() const { return UnitType; }
     239             : 
     240             :   static bool isValidUnitType(uint8_t UnitType) {
     241             :     return UnitType == dwarf::DW_UT_compile || UnitType == dwarf::DW_UT_type ||
     242             :            UnitType == dwarf::DW_UT_partial ||
     243             :            UnitType == dwarf::DW_UT_skeleton ||
     244           8 :            UnitType == dwarf::DW_UT_split_compile ||
     245           8 :            UnitType == dwarf::DW_UT_split_type;
     246             :   }
     247             : 
     248             :   /// \brief Return the number of bytes for the header of a unit of
     249             :   /// UnitType type.
     250             :   ///
     251             :   /// This function must be called with a valid unit type which in
     252             :   /// DWARF5 is defined as one of the following six types.
     253             :   static uint32_t getDWARF5HeaderSize(uint8_t UnitType) {
     254             :     switch (UnitType) {
     255             :     case dwarf::DW_UT_compile:
     256             :     case dwarf::DW_UT_partial:
     257             :       return 12;
     258             :     case dwarf::DW_UT_skeleton:
     259             :     case dwarf::DW_UT_split_compile:
     260             :       return 20;
     261             :     case dwarf::DW_UT_type:
     262             :     case dwarf::DW_UT_split_type:
     263             :       return 24;
     264             :     }
     265             :     llvm_unreachable("Invalid UnitType.");
     266             :   }
     267             : 
     268      229734 :   llvm::Optional<BaseAddress> getBaseAddress() const { return BaseAddr; }
     269             : 
     270       25909 :   void setBaseAddress(BaseAddress BaseAddr) { this->BaseAddr = BaseAddr; }
     271             : 
     272       26814 :   DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
     273       64818 :     extractDIEsIfNeeded(ExtractUnitDIEOnly);
     274      129636 :     if (DieArray.empty())
     275           0 :       return DWARFDie();
     276       64816 :     return DWARFDie(this, &DieArray[0]);
     277             :   }
     278             : 
     279             :   const char *getCompilationDir();
     280             :   Optional<uint64_t> getDWOId();
     281             : 
     282             :   void collectAddressRanges(DWARFAddressRangesVector &CURanges);
     283             : 
     284             :   /// getInlinedChainForAddress - fetches inlined chain for a given address.
     285             :   /// Returns empty chain if there is no subprogram containing address. The
     286             :   /// chain is valid as long as parsed compile unit DIEs are not cleared.
     287             :   void getInlinedChainForAddress(uint64_t Address,
     288             :                                  SmallVectorImpl<DWARFDie> &InlinedChain);
     289             : 
     290             :   /// getUnitSection - Return the DWARFUnitSection containing this unit.
     291             :   const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; }
     292             : 
     293             :   /// \brief Returns the number of DIEs in the unit. Parses the unit
     294             :   /// if necessary.
     295             :   unsigned getNumDIEs() {
     296        1063 :     extractDIEsIfNeeded(false);
     297        1985 :     return DieArray.size();
     298             :   }
     299             : 
     300             :   /// \brief Return the index of a DIE inside the unit's DIE vector.
     301             :   ///
     302             :   /// It is illegal to call this method with a DIE that hasn't be
     303             :   /// created by this unit. In other word, it's illegal to call this
     304             :   /// method on a DIE that isn't accessible by following
     305             :   /// children/sibling links starting from this unit's getUnitDIE().
     306             :   uint32_t getDIEIndex(const DWARFDie &D) {
     307       11456 :     return getDIEIndex(D.getDebugInfoEntry());
     308             :   }
     309             : 
     310             :   /// \brief Return the DIE object at the given index.
     311             :   DWARFDie getDIEAtIndex(unsigned Index) {
     312             :     assert(Index < DieArray.size());
     313        2428 :     return DWARFDie(this, &DieArray[Index]);
     314             :   }
     315             : 
     316             :   DWARFDie getParent(const DWARFDebugInfoEntry *Die);
     317             :   DWARFDie getSibling(const DWARFDebugInfoEntry *Die);
     318             : 
     319             :   /// \brief Return the DIE object for a given offset inside the
     320             :   /// unit's DIE vector.
     321             :   ///
     322             :   /// The unit needs to have its DIEs extracted for this method to work.
     323        2594 :   DWARFDie getDIEForOffset(uint32_t Offset) {
     324        2594 :     extractDIEsIfNeeded(false);
     325             :     assert(!DieArray.empty());
     326             :     auto it = std::lower_bound(
     327             :         DieArray.begin(), DieArray.end(), Offset,
     328             :         [](const DWARFDebugInfoEntry &LHS, uint32_t Offset) {
     329             :           return LHS.getOffset() < Offset;
     330       10376 :         });
     331        7782 :     if (it != DieArray.end() && it->getOffset() == Offset)
     332        2593 :       return DWARFDie(this, &*it);
     333           1 :     return DWARFDie();
     334             :   }
     335             : 
     336             :   uint32_t getLineTableOffset() const {
     337        3275 :     if (IndexEntry)
     338          10 :       if (const auto *Contrib = IndexEntry->getOffset(DW_SECT_LINE))
     339          10 :         return Contrib->Offset;
     340             :     return 0;
     341             :   }
     342             : 
     343             :   die_iterator_range dies() {
     344           4 :     extractDIEsIfNeeded(false);
     345          16 :     return die_iterator_range(DieArray.begin(), DieArray.end());
     346             :   }
     347             : 
     348             : private:
     349             :   /// Size in bytes of the .debug_info data associated with this compile unit.
     350        1641 :   size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); }
     351             : 
     352             :   /// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
     353             :   /// hasn't already been done. Returns the number of DIEs parsed at this call.
     354             :   size_t extractDIEsIfNeeded(bool CUDieOnly);
     355             : 
     356             :   /// extractDIEsToVector - Appends all parsed DIEs to a vector.
     357             :   void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
     358             :                            std::vector<DWARFDebugInfoEntry> &DIEs) const;
     359             : 
     360             :   /// clearDIEs - Clear parsed DIEs to keep memory usage low.
     361             :   void clearDIEs(bool KeepCUDie);
     362             : 
     363             :   /// parseDWO - Parses .dwo file for current compile unit. Returns true if
     364             :   /// it was actually constructed.
     365             :   bool parseDWO();
     366             : 
     367             :   /// getSubroutineForAddress - Returns subprogram DIE with address range
     368             :   /// encompassing the provided address. The pointer is alive as long as parsed
     369             :   /// compile unit DIEs are not cleared.
     370             :   DWARFDie getSubroutineForAddress(uint64_t Address);
     371             : };
     372             : 
     373             : } // end namespace llvm
     374             : 
     375             : #endif // LLVM_DEBUGINFO_DWARF_DWARFUNIT_H

Generated by: LCOV version 1.13