LLVM  6.0.0svn
JITSymbol.h
Go to the documentation of this file.
1 //===- JITSymbol.h - JIT symbol abstraction ---------------------*- 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 // Abstraction for target process addresses.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_EXECUTIONENGINE_JITSYMBOL_H
15 #define LLVM_EXECUTIONENGINE_JITSYMBOL_H
16 
17 #include <algorithm>
18 #include <cassert>
19 #include <cstddef>
20 #include <cstdint>
21 #include <functional>
22 #include <string>
23 
24 #include "llvm/Support/Error.h"
25 
26 namespace llvm {
27 
28 class GlobalValue;
29 
30 namespace object {
31 
32 class BasicSymbolRef;
33 
34 } // end namespace object
35 
36 /// @brief Represents an address in the target process's address space.
37 using JITTargetAddress = uint64_t;
38 
39 /// @brief Flags for symbols in the JIT.
41 public:
42  using UnderlyingType = uint8_t;
43  using TargetFlagsType = uint64_t;
44 
46  None = 0,
47  HasError = 1U << 0,
48  Weak = 1U << 1,
49  Common = 1U << 2,
50  Absolute = 1U << 3,
51  Exported = 1U << 4
52  };
53 
54  /// @brief Default-construct a JITSymbolFlags instance.
55  JITSymbolFlags() = default;
56 
57  /// @brief Construct a JITSymbolFlags instance from the given flags.
58  JITSymbolFlags(FlagNames Flags) : Flags(Flags) {}
59 
60  /// @brief Construct a JITSymbolFlags instance from the given flags and target
61  /// flags.
63  : Flags(Flags), TargetFlags(TargetFlags) {}
64 
65  /// @brief Return true if there was an error retrieving this symbol.
66  bool hasError() const {
67  return (Flags & HasError) == HasError;
68  }
69 
70  /// @brief Returns true if the Weak flag is set.
71  bool isWeak() const {
72  return (Flags & Weak) == Weak;
73  }
74 
75  /// @brief Returns true if the Common flag is set.
76  bool isCommon() const {
77  return (Flags & Common) == Common;
78  }
79 
80  /// @brief Returns true if the symbol isn't weak or common.
81  bool isStrongDefinition() const {
82  return !isWeak() && !isCommon();
83  }
84 
85  /// @brief Returns true if the Exported flag is set.
86  bool isExported() const {
87  return (Flags & Exported) == Exported;
88  }
89 
90  /// @brief Implicitly convert to the underlying flags type.
91  operator UnderlyingType&() { return Flags; }
92 
93  /// @brief Implicitly convert to the underlying flags type.
94  operator const UnderlyingType&() const { return Flags; }
95 
96  /// @brief Return a reference to the target-specific flags.
98 
99  /// @brief Return a reference to the target-specific flags.
100  const TargetFlagsType& getTargetFlags() const { return TargetFlags; }
101 
102  /// Construct a JITSymbolFlags value based on the flags of the given global
103  /// value.
104  static JITSymbolFlags fromGlobalValue(const GlobalValue &GV);
105 
106  /// Construct a JITSymbolFlags value based on the flags of the given libobject
107  /// symbol.
108  static JITSymbolFlags fromObjectSymbol(const object::BasicSymbolRef &Symbol);
109 
110 private:
111  UnderlyingType Flags = None;
113 };
114 
115 /// @brief ARM-specific JIT symbol flags.
116 /// FIXME: This should be moved into a target-specific header.
118 public:
119  ARMJITSymbolFlags() = default;
120 
121  enum FlagNames {
122  None = 0,
123  Thumb = 1 << 0
124  };
125 
126  operator JITSymbolFlags::TargetFlagsType&() { return Flags; }
127 
128  static ARMJITSymbolFlags fromObjectSymbol(
130 private:
132 };
133 
134 /// @brief Represents a symbol that has been evaluated to an address already.
136 public:
137  /// @brief Create a 'null' symbol.
138  JITEvaluatedSymbol(std::nullptr_t) {}
139 
140  /// @brief Create a symbol for the given address and flags.
142  : Address(Address), Flags(Flags) {}
143 
144  /// @brief An evaluated symbol converts to 'true' if its address is non-zero.
145  explicit operator bool() const { return Address != 0; }
146 
147  /// @brief Return the address of this symbol.
148  JITTargetAddress getAddress() const { return Address; }
149 
150  /// @brief Return the flags for this symbol.
151  JITSymbolFlags getFlags() const { return Flags; }
152 
153 private:
155  JITSymbolFlags Flags;
156 };
157 
158 /// @brief Represents a symbol in the JIT.
159 class JITSymbol {
160 public:
161  using GetAddressFtor = std::function<Expected<JITTargetAddress>()>;
162 
163  /// @brief Create a 'null' symbol, used to represent a "symbol not found"
164  /// result from a successful (non-erroneous) lookup.
165  JITSymbol(std::nullptr_t)
166  : CachedAddr(0) {}
167 
168  /// @brief Create a JITSymbol representing an error in the symbol lookup
169  /// process (e.g. a network failure during a remote lookup).
171  : Err(std::move(Err)), Flags(JITSymbolFlags::HasError) {}
172 
173  /// @brief Create a symbol for a definition with a known address.
175  : CachedAddr(Addr), Flags(Flags) {}
176 
177  /// @brief Construct a JITSymbol from a JITEvaluatedSymbol.
179  : CachedAddr(Sym.getAddress()), Flags(Sym.getFlags()) {}
180 
181  /// @brief Create a symbol for a definition that doesn't have a known address
182  /// yet.
183  /// @param GetAddress A functor to materialize a definition (fixing the
184  /// address) on demand.
185  ///
186  /// This constructor allows a JIT layer to provide a reference to a symbol
187  /// definition without actually materializing the definition up front. The
188  /// user can materialize the definition at any time by calling the getAddress
189  /// method.
191  : GetAddress(std::move(GetAddress)), CachedAddr(0), Flags(Flags) {}
192 
193  JITSymbol(const JITSymbol&) = delete;
194  JITSymbol& operator=(const JITSymbol&) = delete;
195 
197  : GetAddress(std::move(Other.GetAddress)), Flags(std::move(Other.Flags)) {
198  if (Flags.hasError())
199  Err = std::move(Other.Err);
200  else
201  CachedAddr = std::move(Other.CachedAddr);
202  }
203 
205  GetAddress = std::move(Other.GetAddress);
206  Flags = std::move(Other.Flags);
207  if (Flags.hasError())
208  Err = std::move(Other.Err);
209  else
210  CachedAddr = std::move(Other.CachedAddr);
211  return *this;
212  }
213 
215  if (Flags.hasError())
216  Err.~Error();
217  else
218  CachedAddr.~JITTargetAddress();
219  }
220 
221  /// @brief Returns true if the symbol exists, false otherwise.
222  explicit operator bool() const {
223  return !Flags.hasError() && (CachedAddr || GetAddress);
224  }
225 
226  /// @brief Move the error field value out of this JITSymbol.
228  if (Flags.hasError())
229  return std::move(Err);
230  return Error::success();
231  }
232 
233  /// @brief Get the address of the symbol in the target address space. Returns
234  /// '0' if the symbol does not exist.
236  assert(!Flags.hasError() && "getAddress called on error value");
237  if (GetAddress) {
238  if (auto CachedAddrOrErr = GetAddress()) {
239  GetAddress = nullptr;
240  CachedAddr = *CachedAddrOrErr;
241  assert(CachedAddr && "Symbol could not be materialized.");
242  } else
243  return CachedAddrOrErr.takeError();
244  }
245  return CachedAddr;
246  }
247 
248  JITSymbolFlags getFlags() const { return Flags; }
249 
250 private:
251  GetAddressFtor GetAddress;
252  union {
255  };
256  JITSymbolFlags Flags;
257 };
258 
259 /// \brief Symbol resolution.
261 public:
262  virtual ~JITSymbolResolver() = default;
263 
264  /// This method returns the address of the specified symbol if it exists
265  /// within the logical dynamic library represented by this JITSymbolResolver.
266  /// Unlike findSymbol, queries through this interface should return addresses
267  /// for hidden symbols.
268  ///
269  /// This is of particular importance for the Orc JIT APIs, which support lazy
270  /// compilation by breaking up modules: Each of those broken out modules
271  /// must be able to resolve hidden symbols provided by the others. Clients
272  /// writing memory managers for MCJIT can usually ignore this method.
273  ///
274  /// This method will be queried by RuntimeDyld when checking for previous
275  /// definitions of common symbols.
276  virtual JITSymbol findSymbolInLogicalDylib(const std::string &Name) = 0;
277 
278  /// This method returns the address of the specified function or variable.
279  /// It is used to resolve symbols during module linking.
280  ///
281  /// If the returned symbol's address is equal to ~0ULL then RuntimeDyld will
282  /// skip all relocations for that symbol, and the client will be responsible
283  /// for handling them manually.
284  virtual JITSymbol findSymbol(const std::string &Name) = 0;
285 
286 private:
287  virtual void anchor();
288 };
289 
290 } // end namespace llvm
291 
292 #endif // LLVM_EXECUTIONENGINE_JITSYMBOL_H
const NoneType None
Definition: None.h:24
Represents a symbol in the JIT.
Definition: JITSymbol.h:159
bool isCommon() const
Returns true if the Common flag is set.
Definition: JITSymbol.h:76
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
JITSymbolFlags getFlags() const
Return the flags for this symbol.
Definition: JITSymbol.h:151
JITSymbol & operator=(JITSymbol &&Other)
Definition: JITSymbol.h:204
bool isWeak() const
Returns true if the Weak flag is set.
Definition: JITSymbol.h:71
JITSymbolFlags getFlags() const
Definition: JITSymbol.h:248
Definition: BitVector.h:920
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:736
const TargetFlagsType & getTargetFlags() const
Return a reference to the target-specific flags.
Definition: JITSymbol.h:100
JITSymbolFlags(FlagNames Flags, TargetFlagsType TargetFlags)
Construct a JITSymbolFlags instance from the given flags and target flags.
Definition: JITSymbol.h:62
uint64_t TargetFlagsType
Definition: JITSymbol.h:43
uint64_t JITTargetAddress
Represents an address in the target process&#39;s address space.
Definition: JITSymbol.h:37
JITSymbol(Error Err)
Create a JITSymbol representing an error in the symbol lookup process (e.g.
Definition: JITSymbol.h:170
JITEvaluatedSymbol(std::nullptr_t)
Create a &#39;null&#39; symbol.
Definition: JITSymbol.h:138
JITSymbolFlags(FlagNames Flags)
Construct a JITSymbolFlags instance from the given flags.
Definition: JITSymbol.h:58
Flags for symbols in the JIT.
Definition: JITSymbol.h:40
Symbol resolution.
Definition: JITSymbol.h:260
JITSymbol(JITEvaluatedSymbol Sym)
Construct a JITSymbol from a JITEvaluatedSymbol.
Definition: JITSymbol.h:178
JITEvaluatedSymbol(JITTargetAddress Address, JITSymbolFlags Flags)
Create a symbol for the given address and flags.
Definition: JITSymbol.h:141
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
JITSymbol(JITSymbol &&Other)
Definition: JITSymbol.h:196
Expected< JITTargetAddress > getAddress()
Get the address of the symbol in the target address space.
Definition: JITSymbol.h:235
bool hasError() const
Return true if there was an error retrieving this symbol.
Definition: JITSymbol.h:66
uint8_t UnderlyingType
Definition: JITSymbol.h:42
static bool isWeak(const MCSymbolELF &Sym)
JITSymbol(std::nullptr_t)
Create a &#39;null&#39; symbol, used to represent a "symbol not found" result from a successful (non-erroneou...
Definition: JITSymbol.h:165
Represents a symbol that has been evaluated to an address already.
Definition: JITSymbol.h:135
std::function< Expected< JITTargetAddress >()> GetAddressFtor
Definition: JITSymbol.h:161
bool isExported() const
Returns true if the Exported flag is set.
Definition: JITSymbol.h:86
JITSymbol(JITTargetAddress Addr, JITSymbolFlags Flags)
Create a symbol for a definition with a known address.
Definition: JITSymbol.h:174
This is a value type class that represents a single symbol in the list of symbols in the object file...
Definition: SymbolicFile.h:99
TargetFlagsType & getTargetFlags()
Return a reference to the target-specific flags.
Definition: JITSymbol.h:97
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ARM-specific JIT symbol flags.
Definition: JITSymbol.h:117
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags)
Create a symbol for a definition that doesn&#39;t have a known address yet.
Definition: JITSymbol.h:190
Error takeError()
Move the error field value out of this JITSymbol.
Definition: JITSymbol.h:227
bool isStrongDefinition() const
Returns true if the symbol isn&#39;t weak or common.
Definition: JITSymbol.h:81
JITTargetAddress getAddress() const
Return the address of this symbol.
Definition: JITSymbol.h:148
JITTargetAddress CachedAddr
Definition: JITSymbol.h:253