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