LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo - DIContext.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 34 48 70.8 %
Date: 2018-10-20 13:21:21 Functions: 9 19 47.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DIContext.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             : // This file defines DIContext, an abstract data structure that holds
      11             : // debug information data.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #ifndef LLVM_DEBUGINFO_DICONTEXT_H
      16             : #define LLVM_DEBUGINFO_DICONTEXT_H
      17             : 
      18             : #include "llvm/ADT/SmallVector.h"
      19             : #include "llvm/Object/ObjectFile.h"
      20             : #include "llvm/Support/raw_ostream.h"
      21             : #include <cassert>
      22             : #include <cstdint>
      23             : #include <memory>
      24             : #include <string>
      25             : #include <tuple>
      26             : #include <utility>
      27             : 
      28             : namespace llvm {
      29             : 
      30             : /// A format-neutral container for source line information.
      31             : struct DILineInfo {
      32             :   std::string FileName;
      33             :   std::string FunctionName;
      34             :   Optional<StringRef> Source;
      35             :   uint32_t Line = 0;
      36             :   uint32_t Column = 0;
      37             :   uint32_t StartLine = 0;
      38             : 
      39             :   // DWARF-specific.
      40             :   uint32_t Discriminator = 0;
      41             : 
      42        6311 :   DILineInfo() : FileName("<invalid>"), FunctionName("<invalid>") {}
      43             : 
      44           3 :   bool operator==(const DILineInfo &RHS) const {
      45           3 :     return Line == RHS.Line && Column == RHS.Column &&
      46           0 :            FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
      47           3 :            StartLine == RHS.StartLine && Discriminator == RHS.Discriminator;
      48             :   }
      49             : 
      50             :   bool operator!=(const DILineInfo &RHS) const {
      51           3 :     return !(*this == RHS);
      52             :   }
      53             : 
      54         200 :   bool operator<(const DILineInfo &RHS) const {
      55         400 :     return std::tie(FileName, FunctionName, Line, Column, StartLine,
      56         200 :                     Discriminator) <
      57         400 :            std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column,
      58         400 :                     RHS.StartLine, RHS.Discriminator);
      59             :   }
      60             : 
      61           3 :   explicit operator bool() const { return *this != DILineInfo(); }
      62             : 
      63           3 :   void dump(raw_ostream &OS) {
      64           3 :     OS << "Line info: ";
      65           3 :     if (FileName != "<invalid>")
      66           6 :       OS << "file '" << FileName << "', ";
      67           3 :     if (FunctionName != "<invalid>")
      68           0 :       OS << "function '" << FunctionName << "', ";
      69           3 :     OS << "line " << Line << ", ";
      70           3 :     OS << "column " << Column << ", ";
      71           3 :     OS << "start line " << StartLine << '\n';
      72           3 :   }
      73             : };
      74             : 
      75             : using DILineInfoTable = SmallVector<std::pair<uint64_t, DILineInfo>, 16>;
      76             : 
      77             : /// A format-neutral container for inlined code description.
      78        2497 : class DIInliningInfo {
      79             :   SmallVector<DILineInfo, 4> Frames;
      80             : 
      81             : public:
      82             :   DIInliningInfo() = default;
      83             : 
      84             :   DILineInfo getFrame(unsigned Index) const {
      85             :     assert(Index < Frames.size());
      86        1453 :     return Frames[Index];
      87             :   }
      88             : 
      89             :   DILineInfo *getMutableFrame(unsigned Index) {
      90             :     assert(Index < Frames.size());
      91        1233 :     return &Frames[Index];
      92             :   }
      93             : 
      94             :   uint32_t getNumberOfFrames() const {
      95        2741 :     return Frames.size();
      96             :   }
      97             : 
      98             :   void addFrame(const DILineInfo &Frame) {
      99         722 :     Frames.push_back(Frame);
     100             :   }
     101             : };
     102             : 
     103             : /// Container for description of a global variable.
     104           0 : struct DIGlobal {
     105             :   std::string Name;
     106             :   uint64_t Start = 0;
     107             :   uint64_t Size = 0;
     108             : 
     109           0 :   DIGlobal() : Name("<invalid>") {}
     110             : };
     111             : 
     112             : /// A DINameKind is passed to name search methods to specify a
     113             : /// preference regarding the type of name resolution the caller wants.
     114             : enum class DINameKind { None, ShortName, LinkageName };
     115             : 
     116             : /// Controls which fields of DILineInfo container should be filled
     117             : /// with data.
     118             : struct DILineInfoSpecifier {
     119             :   enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
     120             :   using FunctionNameKind = DINameKind;
     121             : 
     122             :   FileLineInfoKind FLIKind;
     123             :   FunctionNameKind FNKind;
     124             : 
     125             :   DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::Default,
     126             :                       FunctionNameKind FNKind = FunctionNameKind::None)
     127          26 :       : FLIKind(FLIKind), FNKind(FNKind) {}
     128             : };
     129             : 
     130             : /// This is just a helper to programmatically construct DIDumpType.
     131             : enum DIDumpTypeCounter {
     132             : #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \
     133             :   DIDT_ID_##ENUM_NAME,
     134             : #include "llvm/BinaryFormat/Dwarf.def"
     135             : #undef HANDLE_DWARF_SECTION
     136             :   DIDT_ID_UUID,
     137             :   DIDT_ID_Count
     138             : };
     139             : static_assert(DIDT_ID_Count <= 32, "section types overflow storage");
     140             : 
     141             : /// Selects which debug sections get dumped.
     142             : enum DIDumpType : unsigned {
     143             :   DIDT_Null,
     144             :   DIDT_All             = ~0U,
     145             : #define HANDLE_DWARF_SECTION(ENUM_NAME, ELF_NAME, CMDLINE_NAME) \
     146             :   DIDT_##ENUM_NAME = 1U << DIDT_ID_##ENUM_NAME,
     147             : #include "llvm/BinaryFormat/Dwarf.def"
     148             : #undef HANDLE_DWARF_SECTION
     149             :   DIDT_UUID = 1 << DIDT_ID_UUID,
     150             : };
     151             : 
     152             : /// Container for dump options that control which debug information will be
     153             : /// dumped.
     154        2002 : struct DIDumpOptions {
     155             :   unsigned DumpType = DIDT_All;
     156             :   unsigned RecurseDepth = -1U;
     157             :   uint16_t Version = 0; // DWARF version to assume when extracting.
     158             :   uint8_t AddrSize = 4; // Address byte size to assume when extracting.
     159             :   bool ShowAddresses = true;
     160             :   bool ShowChildren = false;
     161             :   bool ShowParents = false;
     162             :   bool ShowForm = false;
     163             :   bool SummarizeTypes = false;
     164             :   bool Verbose = false;
     165             :   bool DisplayRawContents = false;
     166             : 
     167             :   /// Return default option set for printing a single DIE without children.
     168             :   static DIDumpOptions getForSingleDIE() {
     169             :     DIDumpOptions Opts;
     170             :     Opts.RecurseDepth = 0;
     171             :     return Opts;
     172             :   }
     173             : 
     174             :   /// Return the options with RecurseDepth set to 0 unless explicitly required.
     175             :   DIDumpOptions noImplicitRecursion() const {
     176          57 :     DIDumpOptions Opts = *this;
     177          47 :     if (RecurseDepth == -1U && !ShowChildren)
     178          57 :       Opts.RecurseDepth = 0;
     179             :     return Opts;
     180             :   }
     181             : };
     182             : 
     183             : class DIContext {
     184             : public:
     185             :   enum DIContextKind {
     186             :     CK_DWARF,
     187             :     CK_PDB
     188             :   };
     189             : 
     190        1544 :   DIContext(DIContextKind K) : Kind(K) {}
     191           0 :   virtual ~DIContext() = default;
     192             : 
     193           0 :   DIContextKind getKind() const { return Kind; }
     194             : 
     195             :   virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
     196             : 
     197           0 :   virtual bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) {
     198             :     // No verifier? Just say things went well.
     199           0 :     return true;
     200             :   }
     201             : 
     202             :   virtual DILineInfo getLineInfoForAddress(uint64_t Address,
     203             :       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
     204             :   virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
     205             :       uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
     206             :   virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
     207             :       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
     208             : 
     209             : private:
     210             :   const DIContextKind Kind;
     211             : };
     212             : 
     213             : /// An inferface for inquiring the load address of a loaded object file
     214             : /// to be used by the DIContext implementations when applying relocations
     215             : /// on the fly.
     216             : class LoadedObjectInfo {
     217             : protected:
     218             :   LoadedObjectInfo() = default;
     219           0 :   LoadedObjectInfo(const LoadedObjectInfo &) = default;
     220             : 
     221             : public:
     222           0 :   virtual ~LoadedObjectInfo() = default;
     223             : 
     224             :   /// Obtain the Load Address of a section by SectionRef.
     225             :   ///
     226             :   /// Calculate the address of the given section.
     227             :   /// The section need not be present in the local address space. The addresses
     228             :   /// need to be consistent with the addresses used to query the DIContext and
     229             :   /// the output of this function should be deterministic, i.e. repeated calls
     230             :   /// with the same Sec should give the same address.
     231           0 :   virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const {
     232           0 :     return 0;
     233             :   }
     234             : 
     235             :   /// If conveniently available, return the content of the given Section.
     236             :   ///
     237             :   /// When the section is available in the local address space, in relocated
     238             :   /// (loaded) form, e.g. because it was relocated by a JIT for execution, this
     239             :   /// function should provide the contents of said section in `Data`. If the
     240             :   /// loaded section is not available, or the cost of retrieving it would be
     241             :   /// prohibitive, this function should return false. In that case, relocations
     242             :   /// will be read from the local (unrelocated) object file and applied on the
     243             :   /// fly. Note that this method is used purely for optimzation purposes in the
     244             :   /// common case of JITting in the local address space, so returning false
     245             :   /// should always be correct.
     246         134 :   virtual bool getLoadedSectionContents(const object::SectionRef &Sec,
     247             :                                         StringRef &Data) const {
     248         134 :     return false;
     249             :   }
     250             : 
     251             :   // FIXME: This is untested and unused anywhere in the LLVM project, it's
     252             :   // used/needed by Julia (an external project). It should have some coverage
     253             :   // (at least tests, but ideally example functionality).
     254             :   /// Obtain a copy of this LoadedObjectInfo.
     255             :   virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0;
     256             : };
     257             : 
     258             : template <typename Derived, typename Base = LoadedObjectInfo>
     259             : struct LoadedObjectInfoHelper : Base {
     260             : protected:
     261             :   LoadedObjectInfoHelper(const LoadedObjectInfoHelper &) = default;
     262             :   LoadedObjectInfoHelper() = default;
     263             : 
     264             : public:
     265             :   template <typename... Ts>
     266         350 :   LoadedObjectInfoHelper(Ts &&... Args) : Base(std::forward<Ts>(Args)...) {}
     267             : 
     268           0 :   std::unique_ptr<llvm::LoadedObjectInfo> clone() const override {
     269           0 :     return llvm::make_unique<Derived>(static_cast<const Derived &>(*this));
     270             :   }
     271             : };
     272             : 
     273             : } // end namespace llvm
     274             : 
     275             : #endif // LLVM_DEBUGINFO_DICONTEXT_H

Generated by: LCOV version 1.13