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