summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-symbolizer/LLVMSymbolize.h
blob: a56f1329fd61933364a569d37d36ebacdbf2d3d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
//===-- 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 <map>
#include <memory>
#include <string>

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;
    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<Binary*, Binary*> BinaryPair;

  ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName);
  /// \brief Returns pair of pointers to binary and debug binary.
  BinaryPair getOrCreateBinary(const std::string &Path);
  /// \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<std::unique_ptr<Binary>, 4> ParsedBinariesAndObjects;
  SmallVector<std::unique_ptr<MemoryBuffer>, 4> MemoryBuffers;
  void addOwningBinary(OwningBinary<Binary> Bin) {
    ParsedBinariesAndObjects.push_back(std::move(Bin.getBinary()));
    MemoryBuffers.push_back(std::move(Bin.getBuffer()));
  }

  // Owns module info objects.
  typedef std::map<std::string, ModuleInfo *> ModuleMapTy;
  ModuleMapTy Modules;
  typedef std::map<std::string, BinaryPair> BinaryMapTy;
  BinaryMapTy BinaryForPath;
  typedef std::map<std::pair<MachOUniversalBinary *, std::string>, ObjectFile *>
      ObjectFileForArchMapTy;
  ObjectFileForArchMapTy ObjectFileForArch;

  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<DIContext> 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;
    }
  };
  typedef std::map<SymbolDesc, StringRef> SymbolMapTy;
  SymbolMapTy Functions;
  SymbolMapTy Objects;
};

} // namespace symbolize
} // namespace llvm

#endif
OpenPOWER on IntegriCloud