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_StrDwo,
    139   DIDT_StrOffsetsDwo,
    140   DIDT_AppleNames,
    141   DIDT_AppleTypes,
    142   DIDT_AppleNamespaces,
    143   DIDT_AppleObjC,
    144   DIDT_CUIndex,
    145   DIDT_GdbIndex,
    146   DIDT_TUIndex,
    147 };
    148 
    149 class DIContext {
    150 public:
    151   enum DIContextKind {
    152     CK_DWARF,
    153     CK_PDB
    154   };
    155 
    156   DIContext(DIContextKind K) : Kind(K) {}
    157   virtual ~DIContext() = default;
    158 
    159   DIContextKind getKind() const { return Kind; }
    160 
    161   virtual void dump(raw_ostream &OS, DIDumpType DumpType = DIDT_All,
    162                     bool DumpEH = false, bool SummarizeTypes = false) = 0;
    163 
    164   virtual DILineInfo getLineInfoForAddress(uint64_t Address,
    165       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
    166   virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
    167       uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
    168   virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
    169       DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
    170 
    171 private:
    172   const DIContextKind Kind;
    173 };
    174 
    175 /// An inferface for inquiring the load address of a loaded object file
    176 /// to be used by the DIContext implementations when applying relocations
    177 /// on the fly.
    178 class LoadedObjectInfo {
    179 protected:
    180   LoadedObjectInfo() = default;
    181   LoadedObjectInfo(const LoadedObjectInfo &) = default;
    182 
    183 public:
    184   virtual ~LoadedObjectInfo() = default;
    185 
    186   /// Obtain the Load Address of a section by SectionRef.
    187   ///
    188   /// Calculate the address of the given section.
    189   /// The section need not be present in the local address space. The addresses
    190   /// need to be consistent with the addresses used to query the DIContext and
    191   /// the output of this function should be deterministic, i.e. repeated calls with
    192   /// the same Sec should give the same address.
    193   virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const = 0;
    194 
    195   /// If conveniently available, return the content of the given Section.
    196   ///
    197   /// When the section is available in the local address space, in relocated (loaded)
    198   /// form, e.g. because it was relocated by a JIT for execution, this function
    199   /// should provide the contents of said section in `Data`. If the loaded section
    200   /// is not available, or the cost of retrieving it would be prohibitive, this
    201   /// function should return false. In that case, relocations will be read from the
    202   /// local (unrelocated) object file and applied on the fly. Note that this method
    203   /// is used purely for optimzation purposes in the common case of JITting in the
    204   /// local address space, so returning false should always be correct.
    205   virtual bool getLoadedSectionContents(const object::SectionRef &Sec,
    206                                         StringRef &Data) const {
    207     return false;
    208   }
    209 
    210   /// Obtain a copy of this LoadedObjectInfo.
    211   ///
    212   /// The caller is responsible for deallocation once the copy is no longer required.
    213   virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0;
    214 };
    215 
    216 } // end namespace llvm
    217 
    218 #endif // LLVM_DEBUGINFO_DICONTEXT_H
    219