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