]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/include/llvm/ExecutionEngine/JITSymbol.h
MFV r317581: less v491.
[FreeBSD/FreeBSD.git] / contrib / llvm / include / llvm / ExecutionEngine / JITSymbol.h
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 namespace llvm {
25
26 class GlobalValue;
27
28 namespace object {
29   class BasicSymbolRef;
30 } // end namespace object
31
32 /// @brief Represents an address in the target process's address space.
33 typedef uint64_t JITTargetAddress;
34
35 /// @brief Flags for symbols in the JIT.
36 class JITSymbolFlags {
37 public:
38   typedef uint8_t UnderlyingType;
39
40   enum FlagNames : UnderlyingType {
41     None = 0,
42     Weak = 1U << 0,
43     Common = 1U << 1,
44     Absolute = 1U << 2,
45     Exported = 1U << 3
46   };
47
48   /// @brief Default-construct a JITSymbolFlags instance.
49   JITSymbolFlags() : Flags(None) {}
50
51   /// @brief Construct a JITSymbolFlags instance from the given flags.
52   JITSymbolFlags(FlagNames Flags) : Flags(Flags) {}
53
54   /// @brief Returns true is the Weak flag is set.
55   bool isWeak() const {
56     return (Flags & Weak) == Weak;
57   }
58
59   /// @brief Returns true is the Weak flag is set.
60   bool isCommon() const {
61     return (Flags & Common) == Common;
62   }
63
64   bool isStrongDefinition() const {
65     return !isWeak() && !isCommon();
66   }
67
68   /// @brief Returns true is the Weak flag is set.
69   bool isExported() const {
70     return (Flags & Exported) == Exported;
71   }
72
73   operator UnderlyingType&() { return Flags; }
74
75   /// Construct a JITSymbolFlags value based on the flags of the given global
76   /// value.
77   static JITSymbolFlags fromGlobalValue(const GlobalValue &GV);
78
79   /// Construct a JITSymbolFlags value based on the flags of the given libobject
80   /// symbol.
81   static JITSymbolFlags fromObjectSymbol(const object::BasicSymbolRef &Symbol);
82
83 private:
84   UnderlyingType Flags;
85 };
86
87 /// @brief Represents a symbol that has been evaluated to an address already.
88 class JITEvaluatedSymbol {
89 public:
90   /// @brief Create a 'null' symbol.
91   JITEvaluatedSymbol(std::nullptr_t)
92       : Address(0) {}
93
94   /// @brief Create a symbol for the given address and flags.
95   JITEvaluatedSymbol(JITTargetAddress Address, JITSymbolFlags Flags)
96       : Address(Address), Flags(Flags) {}
97
98   /// @brief An evaluated symbol converts to 'true' if its address is non-zero.
99   explicit operator bool() const { return Address != 0; }
100
101   /// @brief Return the address of this symbol.
102   JITTargetAddress getAddress() const { return Address; }
103
104   /// @brief Return the flags for this symbol.
105   JITSymbolFlags getFlags() const { return Flags; }
106
107 private:
108   JITTargetAddress Address;
109   JITSymbolFlags Flags;
110 };
111
112 /// @brief Represents a symbol in the JIT.
113 class JITSymbol {
114 public:
115   typedef std::function<JITTargetAddress()> GetAddressFtor;
116
117   /// @brief Create a 'null' symbol that represents failure to find a symbol
118   ///        definition.
119   JITSymbol(std::nullptr_t)
120       : CachedAddr(0) {}
121
122   /// @brief Create a symbol for a definition with a known address.
123   JITSymbol(JITTargetAddress Addr, JITSymbolFlags Flags)
124       : CachedAddr(Addr), Flags(Flags) {}
125
126   /// @brief Construct a JITSymbol from a JITEvaluatedSymbol.
127   JITSymbol(JITEvaluatedSymbol Sym)
128       : CachedAddr(Sym.getAddress()), Flags(Sym.getFlags()) {}
129
130   /// @brief Create a symbol for a definition that doesn't have a known address
131   ///        yet.
132   /// @param GetAddress A functor to materialize a definition (fixing the
133   ///        address) on demand.
134   ///
135   ///   This constructor allows a JIT layer to provide a reference to a symbol
136   /// definition without actually materializing the definition up front. The
137   /// user can materialize the definition at any time by calling the getAddress
138   /// method.
139   JITSymbol(GetAddressFtor GetAddress, JITSymbolFlags Flags)
140       : GetAddress(std::move(GetAddress)), CachedAddr(0), Flags(Flags) {}
141
142   /// @brief Returns true if the symbol exists, false otherwise.
143   explicit operator bool() const { return CachedAddr || GetAddress; }
144
145   /// @brief Get the address of the symbol in the target address space. Returns
146   ///        '0' if the symbol does not exist.
147   JITTargetAddress getAddress() {
148     if (GetAddress) {
149       CachedAddr = GetAddress();
150       assert(CachedAddr && "Symbol could not be materialized.");
151       GetAddress = nullptr;
152     }
153     return CachedAddr;
154   }
155
156   JITSymbolFlags getFlags() const { return Flags; }
157
158 private:
159   GetAddressFtor GetAddress;
160   JITTargetAddress CachedAddr;
161   JITSymbolFlags Flags;
162 };
163
164 /// \brief Symbol resolution.
165 class JITSymbolResolver {
166 public:
167   virtual ~JITSymbolResolver() = default;
168
169   /// This method returns the address of the specified symbol if it exists
170   /// within the logical dynamic library represented by this JITSymbolResolver.
171   /// Unlike findSymbol, queries through this interface should return addresses
172   /// for hidden symbols.
173   ///
174   /// This is of particular importance for the Orc JIT APIs, which support lazy
175   /// compilation by breaking up modules: Each of those broken out modules
176   /// must be able to resolve hidden symbols provided by the others. Clients
177   /// writing memory managers for MCJIT can usually ignore this method.
178   ///
179   /// This method will be queried by RuntimeDyld when checking for previous
180   /// definitions of common symbols.
181   virtual JITSymbol findSymbolInLogicalDylib(const std::string &Name) = 0;
182
183   /// This method returns the address of the specified function or variable.
184   /// It is used to resolve symbols during module linking.
185   ///
186   /// If the returned symbol's address is equal to ~0ULL then RuntimeDyld will
187   /// skip all relocations for that symbol, and the client will be responsible
188   /// for handling them manually.
189   virtual JITSymbol findSymbol(const std::string &Name) = 0;
190
191 private:
192   virtual void anchor();
193 };
194
195 } // end namespace llvm
196
197 #endif // LLVM_EXECUTIONENGINE_JITSYMBOL_H