• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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