LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/DWARF - DWARFContext.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 39 42 92.9 %
Date: 2018-10-20 13:21:21 Functions: 6 8 75.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFContext.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_DWARFCONTEXT_H
      11             : #define LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H
      12             : 
      13             : #include "llvm/ADT/MapVector.h"
      14             : #include "llvm/ADT/SmallString.h"
      15             : #include "llvm/ADT/SmallVector.h"
      16             : #include "llvm/ADT/StringMap.h"
      17             : #include "llvm/ADT/StringRef.h"
      18             : #include "llvm/ADT/iterator_range.h"
      19             : #include "llvm/DebugInfo/DIContext.h"
      20             : #include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
      21             : #include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
      22             : #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
      23             : #include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
      24             : #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
      25             : #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
      26             : #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
      27             : #include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
      28             : #include "llvm/DebugInfo/DWARF/DWARFDie.h"
      29             : #include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
      30             : #include "llvm/DebugInfo/DWARF/DWARFObject.h"
      31             : #include "llvm/DebugInfo/DWARF/DWARFSection.h"
      32             : #include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
      33             : #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
      34             : #include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
      35             : #include "llvm/Object/Binary.h"
      36             : #include "llvm/Object/ObjectFile.h"
      37             : #include "llvm/Support/DataExtractor.h"
      38             : #include "llvm/Support/Error.h"
      39             : #include "llvm/Support/Host.h"
      40             : #include <cstdint>
      41             : #include <deque>
      42             : #include <map>
      43             : #include <memory>
      44             : 
      45             : namespace llvm {
      46             : 
      47             : class MCRegisterInfo;
      48             : class MemoryBuffer;
      49             : class raw_ostream;
      50             : 
      51             : /// Used as a return value for a error callback passed to DWARF context.
      52             : /// Callback should return Halt if client application wants to stop
      53             : /// object parsing, or should return Continue otherwise.
      54             : enum class ErrorPolicy { Halt, Continue };
      55             : 
      56             : /// DWARFContext
      57             : /// This data structure is the top level entity that deals with dwarf debug
      58             : /// information parsing. The actual data is supplied through DWARFObj.
      59       10790 : class DWARFContext : public DIContext {
      60             :   DWARFUnitVector NormalUnits;
      61             :   std::unique_ptr<DWARFUnitIndex> CUIndex;
      62             :   std::unique_ptr<DWARFGdbIndex> GdbIndex;
      63             :   std::unique_ptr<DWARFUnitIndex> TUIndex;
      64             :   std::unique_ptr<DWARFDebugAbbrev> Abbrev;
      65             :   std::unique_ptr<DWARFDebugLoc> Loc;
      66             :   std::unique_ptr<DWARFDebugAranges> Aranges;
      67             :   std::unique_ptr<DWARFDebugLine> Line;
      68             :   std::unique_ptr<DWARFDebugFrame> DebugFrame;
      69             :   std::unique_ptr<DWARFDebugFrame> EHFrame;
      70             :   std::unique_ptr<DWARFDebugMacro> Macro;
      71             :   std::unique_ptr<DWARFDebugNames> Names;
      72             :   std::unique_ptr<AppleAcceleratorTable> AppleNames;
      73             :   std::unique_ptr<AppleAcceleratorTable> AppleTypes;
      74             :   std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
      75             :   std::unique_ptr<AppleAcceleratorTable> AppleObjC;
      76             : 
      77             :   DWARFUnitVector DWOUnits;
      78             :   std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
      79             :   std::unique_ptr<DWARFDebugLocDWO> LocDWO;
      80             : 
      81             :   /// The maximum DWARF version of all units.
      82             :   unsigned MaxVersion = 0;
      83             : 
      84             :   struct DWOFile {
      85             :     object::OwningBinary<object::ObjectFile> File;
      86             :     std::unique_ptr<DWARFContext> Context;
      87             :   };
      88             :   StringMap<std::weak_ptr<DWOFile>> DWOFiles;
      89             :   std::weak_ptr<DWOFile> DWP;
      90             :   bool CheckedForDWP = false;
      91             :   std::string DWPName;
      92             : 
      93             :   std::unique_ptr<MCRegisterInfo> RegInfo;
      94             : 
      95             :   /// Read compile units from the debug_info section (if necessary)
      96             :   /// and type units from the debug_types sections (if necessary)
      97             :   /// and store them in NormalUnits.
      98             :   void parseNormalUnits();
      99             : 
     100             :   /// Read compile units from the debug_info.dwo section (if necessary)
     101             :   /// and type units from the debug_types.dwo section (if necessary)
     102             :   /// and store them in DWOUnits.
     103             :   /// If \p Lazy is true, set up to parse but don't actually parse them.
     104             :   enum { EagerParse = false, LazyParse = true };
     105             :   void parseDWOUnits(bool Lazy = false);
     106             : 
     107             :   std::unique_ptr<const DWARFObject> DObj;
     108             : 
     109             : public:
     110             :   DWARFContext(std::unique_ptr<const DWARFObject> DObj,
     111             :                std::string DWPName = "");
     112             :   ~DWARFContext();
     113             : 
     114             :   DWARFContext(DWARFContext &) = delete;
     115             :   DWARFContext &operator=(DWARFContext &) = delete;
     116             : 
     117             :   const DWARFObject &getDWARFObj() const { return *DObj; }
     118             : 
     119             :   static bool classof(const DIContext *DICtx) {
     120         954 :     return DICtx->getKind() == CK_DWARF;
     121             :   }
     122             : 
     123             :   /// Dump a textual representation to \p OS. If any \p DumpOffsets are present,
     124             :   /// dump only the record at the specified offset.
     125             :   void dump(raw_ostream &OS, DIDumpOptions DumpOpts,
     126             :             std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets);
     127             : 
     128          10 :   void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override {
     129             :     std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets;
     130          10 :     dump(OS, DumpOpts, DumpOffsets);
     131          10 :   }
     132             : 
     133             :   bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
     134             : 
     135             :   using unit_iterator_range = DWARFUnitVector::iterator_range;
     136             : 
     137             :   /// Get units from .debug_info in this context.
     138             :   unit_iterator_range info_section_units() {
     139        1651 :     parseNormalUnits();
     140        1541 :     return unit_iterator_range(NormalUnits.begin(),
     141        1601 :                                NormalUnits.begin() +
     142        1601 :                                    NormalUnits.getNumInfoUnits());
     143             :   }
     144             : 
     145             :   /// Get units from .debug_types in this context.
     146         241 :   unit_iterator_range types_section_units() {
     147         241 :     parseNormalUnits();
     148         241 :     return unit_iterator_range(
     149         482 :         NormalUnits.begin() + NormalUnits.getNumInfoUnits(), NormalUnits.end());
     150             :   }
     151             : 
     152             :   /// Get compile units in this context.
     153             :   unit_iterator_range compile_units() { return info_section_units(); }
     154             : 
     155             :   /// Get type units in this context.
     156         223 :   unit_iterator_range type_units() { return types_section_units(); }
     157             : 
     158             :   /// Get all normal compile/type units in this context.
     159             :   unit_iterator_range normal_units() {
     160          22 :     parseNormalUnits();
     161             :     return unit_iterator_range(NormalUnits.begin(), NormalUnits.end());
     162             :   }
     163             : 
     164             :   /// Get units from .debug_info..dwo in the DWO context.
     165         131 :   unit_iterator_range dwo_info_section_units() {
     166         131 :     parseDWOUnits();
     167         131 :     return unit_iterator_range(DWOUnits.begin(),
     168         262 :                                DWOUnits.begin() + DWOUnits.getNumInfoUnits());
     169             :   }
     170             : 
     171             :   /// Get units from .debug_types.dwo in the DWO context.
     172          32 :   unit_iterator_range dwo_types_section_units() {
     173          32 :     parseDWOUnits();
     174          32 :     return unit_iterator_range(DWOUnits.begin() + DWOUnits.getNumInfoUnits(),
     175          32 :                                DWOUnits.end());
     176             :   }
     177             : 
     178             :   /// Get compile units in the DWO context.
     179          61 :   unit_iterator_range dwo_compile_units() { return dwo_info_section_units(); }
     180             : 
     181             :   /// Get type units in the DWO context.
     182          18 :   unit_iterator_range dwo_type_units() { return dwo_types_section_units(); }
     183             : 
     184             :   /// Get all units in the DWO context.
     185             :   unit_iterator_range dwo_units() {
     186          28 :     parseDWOUnits();
     187             :     return unit_iterator_range(DWOUnits.begin(), DWOUnits.end());
     188             :   }
     189             : 
     190             :   /// Get the number of compile units in this context.
     191             :   unsigned getNumCompileUnits() {
     192         287 :     parseNormalUnits();
     193             :     return NormalUnits.getNumInfoUnits();
     194             :   }
     195             : 
     196             :   /// Get the number of type units in this context.
     197             :   unsigned getNumTypeUnits() {
     198         204 :     parseNormalUnits();
     199             :     return NormalUnits.getNumTypesUnits();
     200             :   }
     201             : 
     202             :   /// Get the number of compile units in the DWO context.
     203             :   unsigned getNumDWOCompileUnits() {
     204             :     parseDWOUnits();
     205             :     return DWOUnits.getNumInfoUnits();
     206             :   }
     207             : 
     208             :   /// Get the number of type units in the DWO context.
     209             :   unsigned getNumDWOTypeUnits() {
     210         210 :     parseDWOUnits();
     211             :     return DWOUnits.getNumTypesUnits();
     212             :   }
     213             : 
     214             :   /// Get the unit at the specified index.
     215             :   DWARFUnit *getUnitAtIndex(unsigned index) {
     216          90 :     parseNormalUnits();
     217             :     return NormalUnits[index].get();
     218             :   }
     219             : 
     220             :   /// Get the unit at the specified index for the DWO units.
     221             :   DWARFUnit *getDWOUnitAtIndex(unsigned index) {
     222             :     parseDWOUnits();
     223             :     return DWOUnits[index].get();
     224             :   }
     225             : 
     226             :   DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
     227             : 
     228             :   /// Return the compile unit that includes an offset (relative to .debug_info).
     229             :   DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
     230             : 
     231             :   /// Get a DIE given an exact offset.
     232             :   DWARFDie getDIEForOffset(uint32_t Offset);
     233             : 
     234             :   unsigned getMaxVersion() {
     235             :     // Ensure info units have been parsed to discover MaxVersion
     236             :     info_section_units();
     237          50 :     return MaxVersion;
     238             :   }
     239             : 
     240             :   unsigned getMaxDWOVersion() {
     241             :     // Ensure DWO info units have been parsed to discover MaxVersion
     242          28 :     dwo_info_section_units();
     243          28 :     return MaxVersion;
     244             :   }
     245             : 
     246           0 :   void setMaxVersionIfGreater(unsigned Version) {
     247        4937 :     if (Version > MaxVersion)
     248        1128 :       MaxVersion = Version;
     249           0 :   }
     250             : 
     251             :   const DWARFUnitIndex &getCUIndex();
     252             :   DWARFGdbIndex &getGdbIndex();
     253             :   const DWARFUnitIndex &getTUIndex();
     254             : 
     255             :   /// Get a pointer to the parsed DebugAbbrev object.
     256             :   const DWARFDebugAbbrev *getDebugAbbrev();
     257             : 
     258             :   /// Get a pointer to the parsed DebugLoc object.
     259             :   const DWARFDebugLoc *getDebugLoc();
     260             : 
     261             :   /// Get a pointer to the parsed dwo abbreviations object.
     262             :   const DWARFDebugAbbrev *getDebugAbbrevDWO();
     263             : 
     264             :   /// Get a pointer to the parsed DebugLoc object.
     265             :   const DWARFDebugLocDWO *getDebugLocDWO();
     266             : 
     267             :   /// Get a pointer to the parsed DebugAranges object.
     268             :   const DWARFDebugAranges *getDebugAranges();
     269             : 
     270             :   /// Get a pointer to the parsed frame information object.
     271             :   const DWARFDebugFrame *getDebugFrame();
     272             : 
     273             :   /// Get a pointer to the parsed eh frame information object.
     274             :   const DWARFDebugFrame *getEHFrame();
     275             : 
     276             :   /// Get a pointer to the parsed DebugMacro object.
     277             :   const DWARFDebugMacro *getDebugMacro();
     278             : 
     279             :   /// Get a reference to the parsed accelerator table object.
     280             :   const DWARFDebugNames &getDebugNames();
     281             : 
     282             :   /// Get a reference to the parsed accelerator table object.
     283             :   const AppleAcceleratorTable &getAppleNames();
     284             : 
     285             :   /// Get a reference to the parsed accelerator table object.
     286             :   const AppleAcceleratorTable &getAppleTypes();
     287             : 
     288             :   /// Get a reference to the parsed accelerator table object.
     289             :   const AppleAcceleratorTable &getAppleNamespaces();
     290             : 
     291             :   /// Get a reference to the parsed accelerator table object.
     292             :   const AppleAcceleratorTable &getAppleObjC();
     293             : 
     294             :   /// Get a pointer to a parsed line table corresponding to a compile unit.
     295             :   /// Report any parsing issues as warnings on stderr.
     296             :   const DWARFDebugLine::LineTable *getLineTableForUnit(DWARFUnit *U);
     297             : 
     298             :   /// Get a pointer to a parsed line table corresponding to a compile unit.
     299             :   /// Report any recoverable parsing problems using the callback.
     300             :   Expected<const DWARFDebugLine::LineTable *>
     301             :   getLineTableForUnit(DWARFUnit *U,
     302             :                       std::function<void(Error)> RecoverableErrorCallback);
     303             : 
     304             :   DataExtractor getStringExtractor() const {
     305           2 :     return DataExtractor(DObj->getStringSection(), false, 0);
     306             :   }
     307             :   DataExtractor getLineStringExtractor() const {
     308         220 :     return DataExtractor(DObj->getLineStringSection(), false, 0);
     309             :   }
     310             : 
     311             :   /// Wraps the returned DIEs for a given address.
     312             :   struct DIEsForAddress {
     313             :     DWARFCompileUnit *CompileUnit = nullptr;
     314             :     DWARFDie FunctionDIE;
     315             :     DWARFDie BlockDIE;
     316           0 :     explicit operator bool() const { return CompileUnit != nullptr; }
     317             :   };
     318             : 
     319             :   /// Get the compilation unit, the function DIE and lexical block DIE for the
     320             :   /// given address where applicable.
     321             :   DIEsForAddress getDIEsForAddress(uint64_t Address);
     322             : 
     323             :   DILineInfo getLineInfoForAddress(uint64_t Address,
     324             :       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
     325             :   DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
     326             :       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
     327             :   DIInliningInfo getInliningInfoForAddress(uint64_t Address,
     328             :       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
     329             : 
     330        7867 :   bool isLittleEndian() const { return DObj->isLittleEndian(); }
     331             :   static bool isSupportedVersion(unsigned version) {
     332        5069 :     return version == 2 || version == 3 || version == 4 || version == 5;
     333             :   }
     334             : 
     335             :   std::shared_ptr<DWARFContext> getDWOContext(StringRef AbsolutePath);
     336             : 
     337             :   const MCRegisterInfo *getRegisterInfo() const { return RegInfo.get(); }
     338             : 
     339             :   /// Function used to handle default error reporting policy. Prints a error
     340             :   /// message and returns Continue, so DWARF context ignores the error.
     341             :   static ErrorPolicy defaultErrorHandler(Error E);
     342             :   static std::unique_ptr<DWARFContext>
     343             :   create(const object::ObjectFile &Obj, const LoadedObjectInfo *L = nullptr,
     344             :          function_ref<ErrorPolicy(Error)> HandleError = defaultErrorHandler,
     345             :          std::string DWPName = "");
     346             : 
     347             :   static std::unique_ptr<DWARFContext>
     348             :   create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
     349             :          uint8_t AddrSize, bool isLittleEndian = sys::IsLittleEndianHost);
     350             : 
     351             :   /// Loads register info for the architecture of the provided object file.
     352             :   /// Improves readability of dumped DWARF expressions. Requires the caller to
     353             :   /// have initialized the relevant target descriptions.
     354             :   Error loadRegisterInfo(const object::ObjectFile &Obj);
     355             : 
     356             :   /// Get address size from CUs.
     357             :   /// TODO: refactor compile_units() to make this const.
     358             :   uint8_t getCUAddrSize();
     359             : 
     360             :   /// Dump Error as warning message to stderr.
     361             :   static void dumpWarning(Error Warning);
     362             : 
     363             : private:
     364             :   /// Return the compile unit which contains instruction with provided
     365             :   /// address.
     366             :   DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
     367             : };
     368             : 
     369             : } // end namespace llvm
     370             : 
     371             : #endif // LLVM_DEBUGINFO_DWARF_DWARFCONTEXT_H

Generated by: LCOV version 1.13