1 //===-- LLVMSymbolize.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 // Header for LLVM symbolization library. 11 // 12 //===----------------------------------------------------------------------===// 13 #ifndef LLVM_TOOLS_LLVM_SYMBOLIZER_LLVMSYMBOLIZE_H 14 #define LLVM_TOOLS_LLVM_SYMBOLIZER_LLVMSYMBOLIZE_H 15 16 #include "llvm/ADT/SmallVector.h" 17 #include "llvm/DebugInfo/DWARF/DIContext.h" 18 #include "llvm/Object/MachOUniversal.h" 19 #include "llvm/Object/ObjectFile.h" 20 #include "llvm/Support/DataExtractor.h" 21 #include "llvm/Support/MemoryBuffer.h" 22 #include <map> 23 #include <memory> 24 #include <string> 25 26 namespace llvm { 27 28 typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; 29 using namespace object; 30 31 namespace symbolize { 32 33 class ModuleInfo; 34 35 class LLVMSymbolizer { 36 public: 37 struct Options { 38 bool UseSymbolTable : 1; 39 FunctionNameKind PrintFunctions; 40 bool PrintInlining : 1; 41 bool Demangle : 1; 42 std::string DefaultArch; 43 std::vector<std::string> DsymHints; 44 Options(bool UseSymbolTable = true, 45 FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName, 46 bool PrintInlining = true, bool Demangle = true, 47 std::string DefaultArch = "") UseSymbolTableOptions48 : UseSymbolTable(UseSymbolTable), 49 PrintFunctions(PrintFunctions), PrintInlining(PrintInlining), 50 Demangle(Demangle), DefaultArch(DefaultArch) {} 51 }; 52 Opts(Opts)53 LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {} ~LLVMSymbolizer()54 ~LLVMSymbolizer() { 55 flush(); 56 } 57 58 // Returns the result of symbolization for module name/offset as 59 // a string (possibly containing newlines). 60 std::string 61 symbolizeCode(const std::string &ModuleName, uint64_t ModuleOffset); 62 std::string 63 symbolizeData(const std::string &ModuleName, uint64_t ModuleOffset); 64 void flush(); 65 static std::string DemangleName(const std::string &Name); 66 private: 67 typedef std::pair<ObjectFile*, ObjectFile*> ObjectPair; 68 69 ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName); 70 ObjectFile *lookUpDsymFile(const std::string &Path, const MachOObjectFile *ExeObj, 71 const std::string &ArchName); 72 73 /// \brief Returns pair of pointers to object and debug object. 74 ObjectPair getOrCreateObjects(const std::string &Path, 75 const std::string &ArchName); 76 /// \brief Returns a parsed object file for a given architecture in a 77 /// universal binary (or the binary itself if it is an object file). 78 ObjectFile *getObjectFileFromBinary(Binary *Bin, const std::string &ArchName); 79 80 std::string printDILineInfo(DILineInfo LineInfo) const; 81 82 // Owns all the parsed binaries and object files. 83 SmallVector<std::unique_ptr<Binary>, 4> ParsedBinariesAndObjects; 84 SmallVector<std::unique_ptr<MemoryBuffer>, 4> MemoryBuffers; addOwningBinary(OwningBinary<Binary> OwningBin)85 void addOwningBinary(OwningBinary<Binary> OwningBin) { 86 std::unique_ptr<Binary> Bin; 87 std::unique_ptr<MemoryBuffer> MemBuf; 88 std::tie(Bin, MemBuf) = OwningBin.takeBinary(); 89 ParsedBinariesAndObjects.push_back(std::move(Bin)); 90 MemoryBuffers.push_back(std::move(MemBuf)); 91 } 92 93 // Owns module info objects. 94 std::map<std::string, ModuleInfo *> Modules; 95 std::map<std::pair<MachOUniversalBinary *, std::string>, ObjectFile *> 96 ObjectFileForArch; 97 std::map<std::pair<std::string, std::string>, ObjectPair> 98 ObjectPairForPathArch; 99 100 Options Opts; 101 static const char kBadString[]; 102 }; 103 104 class ModuleInfo { 105 public: 106 ModuleInfo(ObjectFile *Obj, DIContext *DICtx); 107 108 DILineInfo symbolizeCode(uint64_t ModuleOffset, 109 const LLVMSymbolizer::Options &Opts) const; 110 DIInliningInfo symbolizeInlinedCode( 111 uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const; 112 bool symbolizeData(uint64_t ModuleOffset, std::string &Name, uint64_t &Start, 113 uint64_t &Size) const; 114 115 private: 116 bool getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address, 117 std::string &Name, uint64_t &Addr, 118 uint64_t &Size) const; 119 // For big-endian PowerPC64 ELF, OpdAddress is the address of the .opd 120 // (function descriptor) section and OpdExtractor refers to its contents. 121 void addSymbol(const SymbolRef &Symbol, 122 DataExtractor *OpdExtractor = nullptr, 123 uint64_t OpdAddress = 0); 124 ObjectFile *Module; 125 std::unique_ptr<DIContext> DebugInfoContext; 126 127 struct SymbolDesc { 128 uint64_t Addr; 129 // If size is 0, assume that symbol occupies the whole memory range up to 130 // the following symbol. 131 uint64_t Size; 132 friend bool operator<(const SymbolDesc &s1, const SymbolDesc &s2) { 133 return s1.Addr < s2.Addr; 134 } 135 }; 136 std::map<SymbolDesc, StringRef> Functions; 137 std::map<SymbolDesc, StringRef> Objects; 138 }; 139 140 } // namespace symbolize 141 } // namespace llvm 142 143 #endif 144