//===-- LLVMSymbolize.h ----------------------------------------- C++ -----===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // Header for LLVM symbolization library. // //===----------------------------------------------------------------------===// #ifndef LLVM_TOOLS_LLVM_SYMBOLIZER_LLVMSYMBOLIZE_H #define LLVM_TOOLS_LLVM_SYMBOLIZER_LLVMSYMBOLIZE_H #include "llvm/ADT/SmallVector.h" #include "llvm/DebugInfo/DIContext.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/MemoryBuffer.h" #include #include #include namespace llvm { typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind; using namespace object; namespace symbolize { class ModuleInfo; class LLVMSymbolizer { public: struct Options { bool UseSymbolTable : 1; FunctionNameKind PrintFunctions; bool PrintInlining : 1; bool Demangle : 1; std::string DefaultArch; std::vector DsymHints; Options(bool UseSymbolTable = true, FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName, bool PrintInlining = true, bool Demangle = true, std::string DefaultArch = "") : UseSymbolTable(UseSymbolTable), PrintFunctions(PrintFunctions), PrintInlining(PrintInlining), Demangle(Demangle), DefaultArch(DefaultArch) {} }; LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {} ~LLVMSymbolizer() { flush(); } // Returns the result of symbolization for module name/offset as // a string (possibly containing newlines). std::string symbolizeCode(const std::string &ModuleName, uint64_t ModuleOffset); std::string symbolizeData(const std::string &ModuleName, uint64_t ModuleOffset); void flush(); static std::string DemangleName(const std::string &Name); private: typedef std::pair ObjectPair; ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName); ObjectFile *lookUpDsymFile(const std::string &Path, const MachOObjectFile *ExeObj, const std::string &ArchName); /// \brief Returns pair of pointers to object and debug object. ObjectPair getOrCreateObjects(const std::string &Path, const std::string &ArchName); /// \brief Returns a parsed object file for a given architecture in a /// universal binary (or the binary itself if it is an object file). ObjectFile *getObjectFileFromBinary(Binary *Bin, const std::string &ArchName); std::string printDILineInfo(DILineInfo LineInfo) const; // Owns all the parsed binaries and object files. SmallVector, 4> ParsedBinariesAndObjects; SmallVector, 4> MemoryBuffers; void addOwningBinary(OwningBinary Bin) { ParsedBinariesAndObjects.push_back(std::move(Bin.getBinary())); MemoryBuffers.push_back(std::move(Bin.getBuffer())); } // Owns module info objects. std::map Modules; std::map, ObjectFile *> ObjectFileForArch; std::map, ObjectPair> ObjectPairForPathArch; Options Opts; static const char kBadString[]; }; class ModuleInfo { public: ModuleInfo(ObjectFile *Obj, DIContext *DICtx); DILineInfo symbolizeCode(uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const; DIInliningInfo symbolizeInlinedCode( uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const; bool symbolizeData(uint64_t ModuleOffset, std::string &Name, uint64_t &Start, uint64_t &Size) const; private: bool getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address, std::string &Name, uint64_t &Addr, uint64_t &Size) const; void addSymbol(const SymbolRef &Symbol); ObjectFile *Module; std::unique_ptr DebugInfoContext; struct SymbolDesc { uint64_t Addr; // If size is 0, assume that symbol occupies the whole memory range up to // the following symbol. uint64_t Size; friend bool operator<(const SymbolDesc &s1, const SymbolDesc &s2) { return s1.Addr < s2.Addr; } }; std::map Functions; std::map Objects; }; } // namespace symbolize } // namespace llvm #endif