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 27namespace llvm { 28 29class raw_ostream; 30 31/// DILineInfo - a format-neutral container for source line information. 32struct 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 60typedef SmallVector<std::pair<uint64_t, DILineInfo>, 16> DILineInfoTable; 61 62/// DIInliningInfo - a format-neutral container for inlined code description. 63class DIInliningInfo { 64 SmallVector<DILineInfo, 4> Frames; 65 66public: 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. 89struct 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. 99enum class DINameKind { None, ShortName, LinkageName }; 100 101/// DILineInfoSpecifier - controls which fields of DILineInfo container 102/// should be filled with data. 103struct 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. 116enum 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_StrOffsets, 139 DIDT_StrDwo, 140 DIDT_StrOffsetsDwo, 141 DIDT_AppleNames, 142 DIDT_AppleTypes, 143 DIDT_AppleNamespaces, 144 DIDT_AppleObjC, 145 DIDT_CUIndex, 146 DIDT_GdbIndex, 147 DIDT_TUIndex, 148}; 149 150/// Container for dump options that control which debug information will be 151/// dumped. 152struct DIDumpOptions { 153 DIDumpType DumpType = DIDT_All; 154 bool DumpEH = false; 155 bool SummarizeTypes = false; 156 bool Brief = false; 157}; 158 159class DIContext { 160public: 161 enum DIContextKind { 162 CK_DWARF, 163 CK_PDB 164 }; 165 166 DIContext(DIContextKind K) : Kind(K) {} 167 virtual ~DIContext() = default; 168 169 DIContextKind getKind() const { return Kind; } 170 171 virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0; 172 173 virtual bool verify(raw_ostream &OS, DIDumpType DumpType = DIDT_All) { 174 // No verifier? Just say things went well. 175 return true; 176 } 177 virtual DILineInfo getLineInfoForAddress(uint64_t Address, 178 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; 179 virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address, 180 uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; 181 virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address, 182 DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0; 183 184private: 185 const DIContextKind Kind; 186}; 187 188/// An inferface for inquiring the load address of a loaded object file 189/// to be used by the DIContext implementations when applying relocations 190/// on the fly. 191class LoadedObjectInfo { 192protected: 193 LoadedObjectInfo() = default; 194 LoadedObjectInfo(const LoadedObjectInfo &) = default; 195 196public: 197 virtual ~LoadedObjectInfo() = default; 198 199 /// Obtain the Load Address of a section by SectionRef. 200 /// 201 /// Calculate the address of the given section. 202 /// The section need not be present in the local address space. The addresses 203 /// need to be consistent with the addresses used to query the DIContext and 204 /// the output of this function should be deterministic, i.e. repeated calls with 205 /// the same Sec should give the same address. 206 virtual uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const = 0; 207 208 /// If conveniently available, return the content of the given Section. 209 /// 210 /// When the section is available in the local address space, in relocated (loaded) 211 /// form, e.g. because it was relocated by a JIT for execution, this function 212 /// should provide the contents of said section in `Data`. If the loaded section 213 /// is not available, or the cost of retrieving it would be prohibitive, this 214 /// function should return false. In that case, relocations will be read from the 215 /// local (unrelocated) object file and applied on the fly. Note that this method 216 /// is used purely for optimzation purposes in the common case of JITting in the 217 /// local address space, so returning false should always be correct. 218 virtual bool getLoadedSectionContents(const object::SectionRef &Sec, 219 StringRef &Data) const { 220 return false; 221 } 222 223 /// Obtain a copy of this LoadedObjectInfo. 224 /// 225 /// The caller is responsible for deallocation once the copy is no longer required. 226 virtual std::unique_ptr<LoadedObjectInfo> clone() const = 0; 227}; 228 229} // end namespace llvm 230 231#endif // LLVM_DEBUGINFO_DICONTEXT_H 232