]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h
zfs: merge openzfs/zfs@aee26af27 (zfs-2.1-release) into stable/13
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / ExecutionEngine / Orc / ObjectLinkingLayer.h
1 //===-- ObjectLinkingLayer.h - JITLink-based jit linking layer --*- 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 // Contains the definition for an JITLink-based, in-process object linking
10 // layer.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
15 #define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
16
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ExecutionEngine/JITLink/JITLink.h"
21 #include "llvm/ExecutionEngine/JITSymbol.h"
22 #include "llvm/ExecutionEngine/Orc/Core.h"
23 #include "llvm/ExecutionEngine/Orc/Layer.h"
24 #include "llvm/Support/Error.h"
25 #include <algorithm>
26 #include <cassert>
27 #include <functional>
28 #include <list>
29 #include <memory>
30 #include <string>
31 #include <utility>
32 #include <vector>
33
34 namespace llvm {
35
36 namespace jitlink {
37 class EHFrameRegistrar;
38 class Symbol;
39 } // namespace jitlink
40
41 namespace object {
42 class ObjectFile;
43 } // namespace object
44
45 namespace orc {
46
47 class ObjectLinkingLayerJITLinkContext;
48
49 /// An ObjectLayer implementation built on JITLink.
50 ///
51 /// Clients can use this class to add relocatable object files to an
52 /// ExecutionSession, and it typically serves as the base layer (underneath
53 /// a compiling layer like IRCompileLayer) for the rest of the JIT.
54 class ObjectLinkingLayer : public ObjectLayer {
55   friend class ObjectLinkingLayerJITLinkContext;
56
57 public:
58   /// Plugin instances can be added to the ObjectLinkingLayer to receive
59   /// callbacks when code is loaded or emitted, and when JITLink is being
60   /// configured.
61   class Plugin {
62   public:
63     using JITLinkSymbolVector = std::vector<const jitlink::Symbol *>;
64     using LocalDependenciesMap = DenseMap<SymbolStringPtr, JITLinkSymbolVector>;
65
66     virtual ~Plugin();
67     virtual void modifyPassConfig(MaterializationResponsibility &MR,
68                                   const Triple &TT,
69                                   jitlink::PassConfiguration &Config) {}
70
71     virtual void notifyLoaded(MaterializationResponsibility &MR) {}
72     virtual Error notifyEmitted(MaterializationResponsibility &MR) {
73       return Error::success();
74     }
75     virtual Error notifyRemovingModule(VModuleKey K) {
76       return Error::success();
77     }
78     virtual Error notifyRemovingAllModules() { return Error::success(); }
79
80     /// Return any dependencies that synthetic symbols (e.g. init symbols)
81     /// have on locally scoped jitlink::Symbols. This is used by the
82     /// ObjectLinkingLayer to update the dependencies for the synthetic
83     /// symbols.
84     virtual LocalDependenciesMap
85     getSyntheticSymbolLocalDependencies(MaterializationResponsibility &MR) {
86       return LocalDependenciesMap();
87     }
88   };
89
90   using ReturnObjectBufferFunction =
91       std::function<void(std::unique_ptr<MemoryBuffer>)>;
92
93   /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
94   /// and NotifyEmitted functors.
95   ObjectLinkingLayer(ExecutionSession &ES,
96                      std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
97
98   /// Destruct an ObjectLinkingLayer.
99   ~ObjectLinkingLayer();
100
101   /// Set an object buffer return function. By default object buffers are
102   /// deleted once the JIT has linked them. If a return function is set then
103   /// it will be called to transfer ownership of the buffer instead.
104   void setReturnObjectBuffer(ReturnObjectBufferFunction ReturnObjectBuffer) {
105     this->ReturnObjectBuffer = std::move(ReturnObjectBuffer);
106   }
107
108   /// Add a pass-config modifier.
109   ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) {
110     std::lock_guard<std::mutex> Lock(LayerMutex);
111     Plugins.push_back(std::move(P));
112     return *this;
113   }
114
115   /// Emit the object.
116   void emit(MaterializationResponsibility R,
117             std::unique_ptr<MemoryBuffer> O) override;
118
119   /// Instructs this ObjectLinkingLayer instance to override the symbol flags
120   /// found in the AtomGraph with the flags supplied by the
121   /// MaterializationResponsibility instance. This is a workaround to support
122   /// symbol visibility in COFF, which does not use the libObject's
123   /// SF_Exported flag. Use only when generating / adding COFF object files.
124   ///
125   /// FIXME: We should be able to remove this if/when COFF properly tracks
126   /// exported symbols.
127   ObjectLinkingLayer &
128   setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) {
129     this->OverrideObjectFlags = OverrideObjectFlags;
130     return *this;
131   }
132
133   /// If set, this ObjectLinkingLayer instance will claim responsibility
134   /// for any symbols provided by a given object file that were not already in
135   /// the MaterializationResponsibility instance. Setting this flag allows
136   /// higher-level program representations (e.g. LLVM IR) to be added based on
137   /// only a subset of the symbols they provide, without having to write
138   /// intervening layers to scan and add the additional symbols. This trades
139   /// diagnostic quality for convenience however: If all symbols are enumerated
140   /// up-front then clashes can be detected and reported early (and usually
141   /// deterministically). If this option is set, clashes for the additional
142   /// symbols may not be detected until late, and detection may depend on
143   /// the flow of control through JIT'd code. Use with care.
144   ObjectLinkingLayer &
145   setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) {
146     this->AutoClaimObjectSymbols = AutoClaimObjectSymbols;
147     return *this;
148   }
149
150 private:
151   using AllocPtr = std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>;
152
153   void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
154                         jitlink::PassConfiguration &PassConfig);
155   void notifyLoaded(MaterializationResponsibility &MR);
156   Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc);
157
158   Error removeModule(VModuleKey K);
159   Error removeAllModules();
160
161   mutable std::mutex LayerMutex;
162   std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr;
163   bool OverrideObjectFlags = false;
164   bool AutoClaimObjectSymbols = false;
165   ReturnObjectBufferFunction ReturnObjectBuffer;
166   DenseMap<VModuleKey, AllocPtr> TrackedAllocs;
167   std::vector<AllocPtr> UntrackedAllocs;
168   std::vector<std::unique_ptr<Plugin>> Plugins;
169 };
170
171 class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
172 public:
173   EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar &Registrar);
174   Error notifyEmitted(MaterializationResponsibility &MR) override;
175   void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
176                         jitlink::PassConfiguration &PassConfig) override;
177   Error notifyRemovingModule(VModuleKey K) override;
178   Error notifyRemovingAllModules() override;
179
180 private:
181
182   struct EHFrameRange {
183     JITTargetAddress Addr = 0;
184     size_t Size;
185   };
186
187   std::mutex EHFramePluginMutex;
188   jitlink::EHFrameRegistrar &Registrar;
189   DenseMap<MaterializationResponsibility *, EHFrameRange> InProcessLinks;
190   DenseMap<VModuleKey, EHFrameRange> TrackedEHFrameRanges;
191   std::vector<EHFrameRange> UntrackedEHFrameRanges;
192 };
193
194 } // end namespace orc
195 } // end namespace llvm
196
197 #endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H