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 DILineInfoDILineInfo35 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: DIInliningInfo()53 DIInliningInfo() {} getFrame(unsigned Index)54 DILineInfo getFrame(unsigned Index) const { 55 assert(Index < Frames.size()); 56 return Frames[Index]; 57 } getMutableFrame(unsigned Index)58 DILineInfo *getMutableFrame(unsigned Index) { 59 assert(Index < Frames.size()); 60 return &Frames[Index]; 61 } getNumberOfFrames()62 uint32_t getNumberOfFrames() const { 63 return Frames.size(); 64 } addFrame(const DILineInfo & Frame)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 DIGlobalDIGlobal76 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) FLIKindDILineInfoSpecifier94 : 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 }; getKind()136 DIContextKind getKind() const { return Kind; } 137 DIContext(DIContextKind K)138 DIContext(DIContextKind K) : Kind(K) {} ~DIContext()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. getLoadedSectionContents(const object::SectionRef & Sec,StringRef & Data)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