Home | History | Annotate | Download | only in DebugInfo
      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 <cassert>
     21 #include <cstdint>
     22 #include <memory>
     23 #include <string>
     24 #include <tuple>
     25 #include <utility>
     26 
     27 namespace llvm {
     28 
     29 class raw_ostream;
     30 
     31 /// DILineInfo - a format-neutral container for source line information.
     32 struct DILineInfo {
     33   std::string FileName;
     34   std::string FunctionName;
     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   DILineInfo() : FileName("<invalid>"), FunctionName("<invalid>") {}
     43 
     44   bool operator==(const DILineInfo &RHS) const {
     45     return Line == RHS.Line && Column == RHS.Column &&
     46            FileName == RHS.FileName && FunctionName == RHS.FunctionName &&
     47            StartLine == RHS.StartLine && Discriminator == RHS.Discriminator;
     48   }
     49   bool operator!=(const DILineInfo &RHS) const {
     50     return !(*this == RHS);
     51   }
     52   bool operator<(const DILineInfo &RHS) const {
     53     return std::tie(FileName, FunctionName, Line, Column, StartLine,
     54                     Discriminator) <
     55            std::tie(RHS.FileName, RHS.FunctionName, RHS.Line, RHS.Column,
     56                     RHS.StartLine, RHS.Discriminator);
     57   }
     58 };
     59 
     60 typedef SmallVector<std::pair<uint64_t, DILineInfo>, 16> DILineInfoTable;
     61 
     62 /// DIInliningInfo - a format-neutral container for inlined code description.
     63 class DIInliningInfo {
     64   SmallVector<DILineInfo, 4> Frames;
     65 
     66 public:
     67   DIInliningInfo() = default;
     68 
     69   DILineInfo getFrame(unsigned Index) const {
     70     assert(Index < Frames.size());
     71     return Frames[Index];
     72   }
     73 
     74   DILineInfo *getMutableFrame(unsigned Index) {
     75     assert(Index < Frames.size());
     76     return &Frames[Index];
     77   }
     78 
     79   uint32_t getNumberOfFrames() const {
     80     return Frames.size();
     81   }
     82 
     83   void addFrame(const DILineInfo &Frame) {
     84     Frames.push_back(Frame);
     85   }
     86 };
     87 
     88 /// DIGlobal - container for description of a global variable.
     89 struct DIGlobal {
     90   std::string Name;
     91   uint64_t Start = 0;
     92   uint64_t Size = 0;
     93 
     94   DIGlobal() : Name("<invalid>") {}
     95 };
     96 
     97 /// A DINameKind is passed to name search methods to specify a
     98 /// preference regarding the type of name resolution the caller wants.
     99 enum class DINameKind { None, ShortName, LinkageName };
    100 
    101 /// DILineInfoSpecifier - controls which fields of DILineInfo container
    102 /// should be filled with data.
    103 struct DILineInfoSpecifier {
    104   enum class FileLineInfoKind { None, Default, AbsoluteFilePath };
    105   typedef DINameKind FunctionNameKind;
    106 
    107   FileLineInfoKind FLIKind;
    108   FunctionNameKind FNKind;
    109 
    110   DILineInfoSpecifier(FileLineInfoKind FLIKind = FileLineInfoKind::Default,
    111                       FunctionNameKind FNKind = FunctionNameKind::None)
    112       : FLIKind(FLIKind), FNKind(FNKind) {}
    113 };
    114 
    115 /// Selects which debug sections get dumped.
    116 enum DIDumpType {
    117   DIDT_Null,
    118   DIDT_All,
    119   DIDT_Abbrev,
    120   DIDT_AbbrevDwo,
    121   DIDT_Aranges,
    122   DIDT_Frames,
    123   DIDT_Info,
    124   DIDT_InfoDwo,
    125   DIDT_Types,
    126   DIDT_TypesDwo,
    127   DIDT_Line,
    128   DIDT_LineDwo,
    129   DIDT_Loc,
    130   DIDT_LocDwo,
    131   DIDT_Macro,
    132   DIDT_Ranges,
    133   DIDT_Pubnames,
    134   DIDT_Pubtypes,
    135   DIDT_GnuPubnames,
    136   DIDT_GnuPubtypes,
    137   DIDT_Str,
    138   DIDT_StrOffsets,
    139   DIDT_StrDwo,
    140   DIDT_StrOffsetsDwo,
    141   DIDT_AppleNames,
    142   DIDT_AppleTypes,
    143   DIDT_AppleNamespaces,
    144   DIDT_AppleObjC,
    145   DIDT_CUIndex,
    146   DIDT_GdbIndex,
    147   DIDT_TUIndex,
    148 };
    149 
    150 /// Container for dump options that control which debug information will be
    151 /// dumped.
    152 struct DIDumpOptions {
    153     DIDumpType DumpType = DIDT_All;
    154     bool DumpEH = false;
    155     bool SummarizeTypes = false;
    156     bool Brief = false;
    157 };
    158 
    159 class DIContext {
    160 public:
    161   enum DIContextKind {
    162     CK_DWARF,
    163     CK_PDB
    164   };
    165 
    166   DIContext(DIContextKind K) : Kind(K) {}
    167   virtual ~DIContext() = default;
    168 
    169   DIContextKind getKind() const { return Kind; }
    170 
    171   virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
    172 
    173   virtual bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) {
    174     // No verifier? Just say things went well.
    175     return true;
    176   }
    177   virtual DILineInfo getLineInfoForAddress(uint64_t Address,
    178       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
    179   virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
    180       uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
    181   virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
    182       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
    183 
    184 private:
    185   const DIContextKind Kind;
    186 };
    187 
    188 /// An inferface for inquiring the load address of a loaded object file
    189 /// to be used by the DIContext implementations when applying relocations
    190 /// on the fly.
    191 class LoadedObjectInfo {
    192 protected:
    193   LoadedObjectInfo() = default;
    194   LoadedObjectInfo(const LoadedObjectInfo &) = default;
    195 
    196 public:
    197   virtual ~LoadedObjectInfo() = default;
    198 
    199   /// Obtain the Load Address of a section by SectionRef.
    200   ///
    201   /// Calculate the address of the given section.
    202   /// The section need not be present in the local address space. The addresses
    203   /// need to be consistent with the addresses used to query the DIContext and
    204   /// the output of this function should be deterministic, i.e. repeated calls with
    205   /// the same Sec should give the same address.
    206   virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const = 0;
    207 
    208   /// If conveniently available, return the content of the given Section.
    209   ///
    210   /// When the section is available in the local address space, in relocated (loaded)
    211   /// form, e.g. because it was relocated by a JIT for execution, this function
    212   /// should provide the contents of said section in `Data`. If the loaded section
    213   /// is not available, or the cost of retrieving it would be prohibitive, this
    214   /// function should return false. In that case, relocations will be read from the
    215   /// local (unrelocated) object file and applied on the fly. Note that this method
    216   /// is used purely for optimzation purposes in the common case of JITting in the
    217   /// local address space, so returning false should always be correct.
    218   virtual bool getLoadedSectionContents(const object::SectionRef &Sec,
    219                                         StringRef &Data) const {
    220     return false;
    221   }
    222 
    223   /// Obtain a copy of this LoadedObjectInfo.
    224   ///
    225   /// The caller is responsible for deallocation once the copy is no longer required.
    226   virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0;
    227 };
    228 
    229 } // end namespace llvm
    230 
    231 #endif // LLVM_DEBUGINFO_DICONTEXT_H
    232