1 //===-- ObjectLinkingLayer.h - JITLink-based jit linking layer --*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Contains the definition for an JITLink-based, in-process object linking
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
15 #define LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H
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"
37 class EHFrameRegistrar;
39 } // namespace jitlink
47 class ObjectLinkingLayerJITLinkContext;
49 /// An ObjectLayer implementation built on JITLink.
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, private ResourceManager {
55 friend class ObjectLinkingLayerJITLinkContext;
58 /// Plugin instances can be added to the ObjectLinkingLayer to receive
59 /// callbacks when code is loaded or emitted, and when JITLink is being
63 using JITLinkSymbolVector = std::vector<const jitlink::Symbol *>;
64 using LocalDependenciesMap = DenseMap<SymbolStringPtr, JITLinkSymbolVector>;
67 virtual void modifyPassConfig(MaterializationResponsibility &MR,
69 jitlink::PassConfiguration &Config) {}
71 virtual void notifyLoaded(MaterializationResponsibility &MR) {}
72 virtual Error notifyEmitted(MaterializationResponsibility &MR) {
73 return Error::success();
75 virtual Error notifyFailed(MaterializationResponsibility &MR) = 0;
76 virtual Error notifyRemovingResources(ResourceKey K) = 0;
77 virtual void notifyTransferringResources(ResourceKey DstKey,
78 ResourceKey SrcKey) = 0;
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
84 virtual LocalDependenciesMap
85 getSyntheticSymbolLocalDependencies(MaterializationResponsibility &MR) {
86 return LocalDependenciesMap();
90 using ReturnObjectBufferFunction =
91 std::function<void(std::unique_ptr<MemoryBuffer>)>;
93 /// Construct an ObjectLinkingLayer.
94 ObjectLinkingLayer(ExecutionSession &ES,
95 jitlink::JITLinkMemoryManager &MemMgr);
97 /// Construct an ObjectLinkingLayer. Takes ownership of the given
98 /// JITLinkMemoryManager. This method is a temporary hack to simplify
99 /// co-existence with RTDyldObjectLinkingLayer (which also owns its
101 ObjectLinkingLayer(ExecutionSession &ES,
102 std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgr);
104 /// Destruct an ObjectLinkingLayer.
105 ~ObjectLinkingLayer();
107 /// Set an object buffer return function. By default object buffers are
108 /// deleted once the JIT has linked them. If a return function is set then
109 /// it will be called to transfer ownership of the buffer instead.
110 void setReturnObjectBuffer(ReturnObjectBufferFunction ReturnObjectBuffer) {
111 this->ReturnObjectBuffer = std::move(ReturnObjectBuffer);
114 /// Add a pass-config modifier.
115 ObjectLinkingLayer &addPlugin(std::unique_ptr<Plugin> P) {
116 std::lock_guard<std::mutex> Lock(LayerMutex);
117 Plugins.push_back(std::move(P));
122 void emit(std::unique_ptr<MaterializationResponsibility> R,
123 std::unique_ptr<MemoryBuffer> O) override;
125 /// Instructs this ObjectLinkingLayer instance to override the symbol flags
126 /// found in the AtomGraph with the flags supplied by the
127 /// MaterializationResponsibility instance. This is a workaround to support
128 /// symbol visibility in COFF, which does not use the libObject's
129 /// SF_Exported flag. Use only when generating / adding COFF object files.
131 /// FIXME: We should be able to remove this if/when COFF properly tracks
132 /// exported symbols.
134 setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags) {
135 this->OverrideObjectFlags = OverrideObjectFlags;
139 /// If set, this ObjectLinkingLayer instance will claim responsibility
140 /// for any symbols provided by a given object file that were not already in
141 /// the MaterializationResponsibility instance. Setting this flag allows
142 /// higher-level program representations (e.g. LLVM IR) to be added based on
143 /// only a subset of the symbols they provide, without having to write
144 /// intervening layers to scan and add the additional symbols. This trades
145 /// diagnostic quality for convenience however: If all symbols are enumerated
146 /// up-front then clashes can be detected and reported early (and usually
147 /// deterministically). If this option is set, clashes for the additional
148 /// symbols may not be detected until late, and detection may depend on
149 /// the flow of control through JIT'd code. Use with care.
151 setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols) {
152 this->AutoClaimObjectSymbols = AutoClaimObjectSymbols;
157 using AllocPtr = std::unique_ptr<jitlink::JITLinkMemoryManager::Allocation>;
159 void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
160 jitlink::PassConfiguration &PassConfig);
161 void notifyLoaded(MaterializationResponsibility &MR);
162 Error notifyEmitted(MaterializationResponsibility &MR, AllocPtr Alloc);
164 Error handleRemoveResources(ResourceKey K) override;
165 void handleTransferResources(ResourceKey DstKey, ResourceKey SrcKey) override;
167 mutable std::mutex LayerMutex;
168 jitlink::JITLinkMemoryManager &MemMgr;
169 std::unique_ptr<jitlink::JITLinkMemoryManager> MemMgrOwnership;
170 bool OverrideObjectFlags = false;
171 bool AutoClaimObjectSymbols = false;
172 ReturnObjectBufferFunction ReturnObjectBuffer;
173 DenseMap<ResourceKey, std::vector<AllocPtr>> Allocs;
174 std::vector<std::unique_ptr<Plugin>> Plugins;
177 class EHFrameRegistrationPlugin : public ObjectLinkingLayer::Plugin {
179 EHFrameRegistrationPlugin(
180 ExecutionSession &ES,
181 std::unique_ptr<jitlink::EHFrameRegistrar> Registrar);
182 void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
183 jitlink::PassConfiguration &PassConfig) override;
184 Error notifyEmitted(MaterializationResponsibility &MR) override;
185 Error notifyFailed(MaterializationResponsibility &MR) override;
186 Error notifyRemovingResources(ResourceKey K) override;
187 void notifyTransferringResources(ResourceKey DstKey,
188 ResourceKey SrcKey) override;
192 struct EHFrameRange {
193 JITTargetAddress Addr = 0;
197 std::mutex EHFramePluginMutex;
198 ExecutionSession &ES;
199 std::unique_ptr<jitlink::EHFrameRegistrar> Registrar;
200 DenseMap<MaterializationResponsibility *, EHFrameRange> InProcessLinks;
201 DenseMap<ResourceKey, std::vector<EHFrameRange>> EHFrameRanges;
204 } // end namespace orc
205 } // end namespace llvm
207 #endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H