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