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_SYMBOLIZE_H
14#define LLVM_SYMBOLIZE_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/MemoryBuffer.h"
21#include <map>
22#include <memory>
23#include <string>
24
25namespace llvm {
26
27typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
28using namespace object;
29
30namespace symbolize {
31
32class ModuleInfo;
33
34class LLVMSymbolizer {
35public:
36  struct Options {
37    bool UseSymbolTable : 1;
38    FunctionNameKind PrintFunctions;
39    bool PrintInlining : 1;
40    bool Demangle : 1;
41    std::string DefaultArch;
42    Options(bool UseSymbolTable = true,
43            FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName,
44            bool PrintInlining = true, bool Demangle = true,
45            std::string DefaultArch = "")
46        : UseSymbolTable(UseSymbolTable), PrintFunctions(PrintFunctions),
47          PrintInlining(PrintInlining), Demangle(Demangle),
48          DefaultArch(DefaultArch) {}
49  };
50
51  LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {}
52  ~LLVMSymbolizer() {
53    flush();
54  }
55
56  // Returns the result of symbolization for module name/offset as
57  // a string (possibly containing newlines).
58  std::string
59  symbolizeCode(const std::string &ModuleName, uint64_t ModuleOffset);
60  std::string
61  symbolizeData(const std::string &ModuleName, uint64_t ModuleOffset);
62  void flush();
63  static std::string DemangleName(const std::string &Name);
64private:
65  typedef std::pair<Binary*, Binary*> BinaryPair;
66
67  ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName);
68  /// \brief Returns pair of pointers to binary and debug binary.
69  BinaryPair getOrCreateBinary(const std::string &Path);
70  /// \brief Returns a parsed object file for a given architecture in a
71  /// universal binary (or the binary itself if it is an object file).
72  ObjectFile *getObjectFileFromBinary(Binary *Bin, const std::string &ArchName);
73
74  std::string printDILineInfo(DILineInfo LineInfo) const;
75
76  // Owns all the parsed binaries and object files.
77  SmallVector<std::unique_ptr<Binary>, 4> ParsedBinariesAndObjects;
78  // Owns module info objects.
79  typedef std::map<std::string, ModuleInfo *> ModuleMapTy;
80  ModuleMapTy Modules;
81  typedef std::map<std::string, BinaryPair> BinaryMapTy;
82  BinaryMapTy BinaryForPath;
83  typedef std::map<std::pair<MachOUniversalBinary *, std::string>, ObjectFile *>
84      ObjectFileForArchMapTy;
85  ObjectFileForArchMapTy ObjectFileForArch;
86
87  Options Opts;
88  static const char kBadString[];
89};
90
91class ModuleInfo {
92public:
93  ModuleInfo(ObjectFile *Obj, DIContext *DICtx);
94
95  DILineInfo symbolizeCode(uint64_t ModuleOffset,
96                           const LLVMSymbolizer::Options &Opts) const;
97  DIInliningInfo symbolizeInlinedCode(
98      uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const;
99  bool symbolizeData(uint64_t ModuleOffset, std::string &Name, uint64_t &Start,
100                     uint64_t &Size) const;
101
102private:
103  bool getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address,
104                              std::string &Name, uint64_t &Addr,
105                              uint64_t &Size) const;
106  void addSymbol(const SymbolRef &Symbol);
107  ObjectFile *Module;
108  std::unique_ptr<DIContext> DebugInfoContext;
109
110  struct SymbolDesc {
111    uint64_t Addr;
112    // If size is 0, assume that symbol occupies the whole memory range up to
113    // the following symbol.
114    uint64_t Size;
115    friend bool operator<(const SymbolDesc &s1, const SymbolDesc &s2) {
116      return s1.Addr < s2.Addr;
117    }
118  };
119  typedef std::map<SymbolDesc, StringRef> SymbolMapTy;
120  SymbolMapTy Functions;
121  SymbolMapTy Objects;
122};
123
124} // namespace symbolize
125} // namespace llvm
126
127#endif // LLVM_SYMBOLIZE_H
128