LLVM  15.0.0git
Symbolize.h
Go to the documentation of this file.
1 //===- Symbolize.h ----------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Header for LLVM symbolization library.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H
14 #define LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H
15 
16 #include "llvm/ADT/StringMap.h"
17 #include "llvm/ADT/ilist_node.h"
18 #include "llvm/ADT/simple_ilist.h"
21 #include "llvm/Object/Binary.h"
22 #include "llvm/Support/Error.h"
23 #include <algorithm>
24 #include <cstdint>
25 #include <map>
26 #include <memory>
27 #include <string>
28 #include <utility>
29 #include <vector>
30 
31 namespace llvm {
32 namespace object {
33 class ELFObjectFileBase;
34 class MachOObjectFile;
35 class ObjectFile;
36 struct SectionedAddress;
37 } // namespace object
38 
39 namespace symbolize {
40 
41 class SymbolizableModule;
42 
43 using namespace object;
44 
47 
48 class CachedBinary;
49 
51 public:
52  struct Options {
55  bool UseSymbolTable = true;
56  bool Demangle = true;
57  bool RelativeAddresses = false;
58  bool UntagAddresses = false;
59  bool UseDIA = false;
60  std::string DefaultArch;
61  std::vector<std::string> DsymHints;
62  std::string FallbackDebugPath;
63  std::string DWPName;
64  std::vector<std::string> DebugFileDirectory;
65  size_t MaxCacheSize =
66  sizeof(size_t) == 4
67  ? 512 * 1024 * 1024 /* 512 MiB */
68  : static_cast<size_t>(4ULL * 1024 * 1024 * 1024) /* 4 GiB */;
69  };
70 
72  LLVMSymbolizer(const Options &Opts);
73 
74  ~LLVMSymbolizer();
75 
76  // Overloads accepting ObjectFile does not support COFF currently
77  Expected<DILineInfo> symbolizeCode(const ObjectFile &Obj,
78  object::SectionedAddress ModuleOffset);
79  Expected<DILineInfo> symbolizeCode(const std::string &ModuleName,
80  object::SectionedAddress ModuleOffset);
82  object::SectionedAddress ModuleOffset);
84  symbolizeInlinedCode(const ObjectFile &Obj,
85  object::SectionedAddress ModuleOffset);
87  symbolizeInlinedCode(const std::string &ModuleName,
88  object::SectionedAddress ModuleOffset);
90  symbolizeInlinedCode(ArrayRef<uint8_t> BuildID,
91  object::SectionedAddress ModuleOffset);
92 
93  Expected<DIGlobal> symbolizeData(const ObjectFile &Obj,
94  object::SectionedAddress ModuleOffset);
95  Expected<DIGlobal> symbolizeData(const std::string &ModuleName,
96  object::SectionedAddress ModuleOffset);
98  object::SectionedAddress ModuleOffset);
100  symbolizeFrame(const ObjectFile &Obj, object::SectionedAddress ModuleOffset);
102  symbolizeFrame(const std::string &ModuleName,
103  object::SectionedAddress ModuleOffset);
105  symbolizeFrame(ArrayRef<uint8_t> BuildID,
106  object::SectionedAddress ModuleOffset);
107  void flush();
108 
109  // Evict entries from the binary cache until it is under the maximum size
110  // given in the options. Calling this invalidates references in the DI...
111  // objects returned by the methods above.
112  void pruneCache();
113 
114  static std::string
115  DemangleName(const std::string &Name,
116  const SymbolizableModule *DbiModuleDescriptor);
117 
118  void addDIFetcher(std::unique_ptr<DIFetcher> Fetcher) {
119  DIFetchers.push_back(std::move(Fetcher));
120  }
121 
122 private:
123  // Bundles together object file with code/data and object file with
124  // corresponding debug info. These objects can be the same.
125  using ObjectPair = std::pair<const ObjectFile *, const ObjectFile *>;
126 
127  template <typename T>
129  symbolizeCodeCommon(const T &ModuleSpecifier,
130  object::SectionedAddress ModuleOffset);
131  template <typename T>
133  symbolizeInlinedCodeCommon(const T &ModuleSpecifier,
134  object::SectionedAddress ModuleOffset);
135  template <typename T>
136  Expected<DIGlobal> symbolizeDataCommon(const T &ModuleSpecifier,
137  object::SectionedAddress ModuleOffset);
138  template <typename T>
140  symbolizeFrameCommon(const T &ModuleSpecifier,
141  object::SectionedAddress ModuleOffset);
142 
143  /// Returns a SymbolizableModule or an error if loading debug info failed.
144  /// Only one attempt is made to load a module, and errors during loading are
145  /// only reported once. Subsequent calls to get module info for a module that
146  /// failed to load will return nullptr.
148  getOrCreateModuleInfo(const std::string &ModuleName);
149  Expected<SymbolizableModule *> getOrCreateModuleInfo(const ObjectFile &Obj);
150 
151  /// Returns a SymbolizableModule or an error if loading debug info failed.
152  /// Unlike the above, errors are reported each time, since they are more
153  /// likely to be transient.
155  getOrCreateModuleInfo(ArrayRef<uint8_t> BuildID);
156 
158  createModuleInfo(const ObjectFile *Obj, std::unique_ptr<DIContext> Context,
160 
161  ObjectFile *lookUpDsymFile(const std::string &Path,
162  const MachOObjectFile *ExeObj,
163  const std::string &ArchName);
164  ObjectFile *lookUpDebuglinkObject(const std::string &Path,
165  const ObjectFile *Obj,
166  const std::string &ArchName);
167  ObjectFile *lookUpBuildIDObject(const std::string &Path,
168  const ELFObjectFileBase *Obj,
169  const std::string &ArchName);
170 
171  bool findDebugBinary(const std::string &OrigPath,
172  const std::string &DebuglinkName, uint32_t CRCHash,
173  std::string &Result);
174 
175  bool getOrFindDebugBinary(const ArrayRef<uint8_t> BuildID,
176  std::string &Result);
177 
178  /// Returns pair of pointers to object and debug object.
179  Expected<ObjectPair> getOrCreateObjectPair(const std::string &Path,
180  const std::string &ArchName);
181 
182  /// Return a pointer to object file at specified path, for a specified
183  /// architecture (e.g. if path refers to a Mach-O universal binary, only one
184  /// object file from it will be returned).
185  Expected<ObjectFile *> getOrCreateObject(const std::string &Path,
186  const std::string &ArchName);
187 
188  /// Update the LRU cache order when a binary is accessed.
189  void recordAccess(CachedBinary &Bin);
190 
191  std::map<std::string, std::unique_ptr<SymbolizableModule>, std::less<>>
192  Modules;
193  StringMap<std::string> BuildIDPaths;
194 
195  /// Contains cached results of getOrCreateObjectPair().
196  std::map<std::pair<std::string, std::string>, ObjectPair>
197  ObjectPairForPathArch;
198 
199  /// Contains parsed binary for each path, or parsing error.
200  std::map<std::string, CachedBinary> BinaryForPath;
201 
202  /// A list of cached binaries in LRU order.
203  simple_ilist<CachedBinary> LRUBinaries;
204  /// Sum of the sizes of the cached binaries.
205  size_t CacheSize = 0;
206 
207  /// Parsed object file for path/architecture pair, where "path" refers
208  /// to Mach-O universal binary.
209  std::map<std::pair<std::string, std::string>, std::unique_ptr<ObjectFile>>
210  ObjectForUBPathAndArch;
211 
212  Options Opts;
213 
215 };
216 
217 // A binary intrusively linked into a LRU cache list. If the binary is empty,
218 // then the entry marks that an error occurred, and it is not part of the LRU
219 // list.
220 class CachedBinary : public ilist_node<CachedBinary> {
221 public:
222  CachedBinary() = default;
224 
227 
228  // Add an action to be performed when the binary is evicted, before all
229  // previously registered evictors.
230  void pushEvictor(std::function<void()> Evictor);
231 
232  // Run all registered evictors in the reverse of the order in which they were
233  // added.
234  void evict() {
235  if (Evictor)
236  Evictor();
237  }
238 
239  size_t size() { return Bin.getBinary()->getData().size(); }
240 
241 private:
243  std::function<void()> Evictor;
244 };
245 
246 } // end namespace symbolize
247 } // end namespace llvm
248 
249 #endif // LLVM_DEBUGINFO_SYMBOLIZE_SYMBOLIZE_H
llvm::symbolize::CachedBinary::operator->
OwningBinary< Binary > * operator->()
Definition: Symbolize.h:226
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::symbolize::CachedBinary::size
size_t size()
Definition: Symbolize.h:239
llvm::symbolize::LLVMSymbolizer::addDIFetcher
void addDIFetcher(std::unique_ptr< DIFetcher > Fetcher)
Definition: Symbolize.h:118
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::symbolize::CachedBinary::evict
void evict()
Definition: Symbolize.h:234
Error.h
llvm::symbolize::LLVMSymbolizer::Options::DebugFileDirectory
std::vector< std::string > DebugFileDirectory
Definition: Symbolize.h:64
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
llvm::DINameKind::LinkageName
@ LinkageName
llvm::symbolize::CachedBinary
Definition: Symbolize.h:220
llvm::symbolize::LLVMSymbolizer::Options::DsymHints
std::vector< std::string > DsymHints
Definition: Symbolize.h:61
llvm::SubDirectoryType::Bin
@ Bin
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::object::ELFObjectFileBase
Definition: ELFObjectFile.h:51
llvm::symbolize::LLVMSymbolizer::Options::DefaultArch
std::string DefaultArch
Definition: Symbolize.h:60
llvm::DINameKind
DINameKind
A DINameKind is passed to name search methods to specify a preference regarding the type of name reso...
Definition: DIContext.h:135
Options
const char LLVMTargetMachineRef LLVMPassBuilderOptionsRef Options
Definition: PassBuilderBindings.cpp:48
StringMap.h
llvm::StringMap< std::string >
llvm::object::MachOObjectFile
Definition: MachO.h:381
object
bar al al movzbl eax ret Missed when stored in a memory object
Definition: README.txt:1411
llvm::symbolize::CachedBinary::CachedBinary
CachedBinary(OwningBinary< Binary > Bin)
Definition: Symbolize.h:223
llvm::symbolize::SymbolizableModule
Definition: SymbolizableModule.h:23
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
DIFetcher.h
llvm::DILineInfoSpecifier::FileLineInfoKind
FileLineInfoKind
Definition: DIContext.h:140
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1675
llvm::symbolize::CachedBinary::operator*
OwningBinary< Binary > & operator*()
Definition: Symbolize.h:225
ModuleName
Definition: ItaniumDemangle.h:989
function
print Print MemDeps of function
Definition: MemDepPrinter.cpp:82
llvm::codeview::CodeViewContainer::ObjectFile
@ ObjectFile
llvm::symbolize::LLVMSymbolizer
Definition: Symbolize.h:50
llvm::ArrayRef< uint8_t >
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::object::ObjectFile
This class is the base class for all object file types.
Definition: ObjectFile.h:228
uint32_t
llvm::symbolize::LLVMSymbolizer::Options::FallbackDebugPath
std::string FallbackDebugPath
Definition: Symbolize.h:62
llvm::DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath
@ AbsoluteFilePath
llvm::ilist_node
Definition: ilist_node.h:149
DIContext.h
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
std
Definition: BitVector.h:851
llvm::object::OwningBinary
Definition: RuntimeDyld.h:36
Binary.h
llvm::DILineInfoSpecifier::FunctionNameKind
DINameKind FunctionNameKind
Definition: DIContext.h:150
llvm::symbolize::LLVMSymbolizer::Options::DWPName
std::string DWPName
Definition: Symbolize.h:63
llvm::object::SectionedAddress
Definition: ObjectFile.h:144
simple_ilist.h
llvm::simple_ilist
A simple intrusive list implementation.
Definition: simple_ilist.h:78
ilist_node.h
llvm::pruneCache
bool pruneCache(StringRef Path, CachePruningPolicy Policy)
Peform pruning using the supplied policy, returns true if pruning occurred, i.e.
Definition: CachePruning.cpp:144
llvm::symbolize::LLVMSymbolizer::Options
Definition: Symbolize.h:52
FunctionNameKind
DILineInfoSpecifier::FunctionNameKind FunctionNameKind
Definition: DWARFContext.cpp:71