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
;
38 } // namespace jitlink
46 class ObjectLinkingLayerJITLinkContext
;
48 /// An ObjectLayer implementation built on JITLink.
50 /// Clients can use this class to add relocatable object files to an
51 /// ExecutionSession, and it typically serves as the base layer (underneath
52 /// a compiling layer like IRCompileLayer) for the rest of the JIT.
53 class ObjectLinkingLayer
: public ObjectLayer
{
54 friend class ObjectLinkingLayerJITLinkContext
;
57 /// Plugin instances can be added to the ObjectLinkingLayer to receive
58 /// callbacks when code is loaded or emitted, and when JITLink is being
63 virtual void modifyPassConfig(MaterializationResponsibility
&MR
,
65 jitlink::PassConfiguration
&Config
) {}
66 virtual void notifyLoaded(MaterializationResponsibility
&MR
) {}
67 virtual Error
notifyEmitted(MaterializationResponsibility
&MR
) {
68 return Error::success();
70 virtual Error
notifyRemovingModule(VModuleKey K
) {
71 return Error::success();
73 virtual Error
notifyRemovingAllModules() { return Error::success(); }
76 using ReturnObjectBufferFunction
=
77 std::function
<void(std::unique_ptr
<MemoryBuffer
>)>;
79 /// Construct an ObjectLinkingLayer with the given NotifyLoaded,
80 /// and NotifyEmitted functors.
81 ObjectLinkingLayer(ExecutionSession
&ES
,
82 jitlink::JITLinkMemoryManager
&MemMgr
);
84 /// Destruct an ObjectLinkingLayer.
85 ~ObjectLinkingLayer();
87 /// Set an object buffer return function. By default object buffers are
88 /// deleted once the JIT has linked them. If a return function is set then
89 /// it will be called to transfer ownership of the buffer instead.
90 void setReturnObjectBuffer(ReturnObjectBufferFunction ReturnObjectBuffer
) {
91 this->ReturnObjectBuffer
= std::move(ReturnObjectBuffer
);
94 /// Add a pass-config modifier.
95 ObjectLinkingLayer
&addPlugin(std::unique_ptr
<Plugin
> P
) {
96 std::lock_guard
<std::mutex
> Lock(LayerMutex
);
97 Plugins
.push_back(std::move(P
));
102 void emit(MaterializationResponsibility R
,
103 std::unique_ptr
<MemoryBuffer
> O
) override
;
105 /// Instructs this ObjectLinkingLayer instance to override the symbol flags
106 /// found in the AtomGraph with the flags supplied by the
107 /// MaterializationResponsibility instance. This is a workaround to support
108 /// symbol visibility in COFF, which does not use the libObject's
109 /// SF_Exported flag. Use only when generating / adding COFF object files.
111 /// FIXME: We should be able to remove this if/when COFF properly tracks
112 /// exported symbols.
114 setOverrideObjectFlagsWithResponsibilityFlags(bool OverrideObjectFlags
) {
115 this->OverrideObjectFlags
= OverrideObjectFlags
;
119 /// If set, this ObjectLinkingLayer instance will claim responsibility
120 /// for any symbols provided by a given object file that were not already in
121 /// the MaterializationResponsibility instance. Setting this flag allows
122 /// higher-level program representations (e.g. LLVM IR) to be added based on
123 /// only a subset of the symbols they provide, without having to write
124 /// intervening layers to scan and add the additional symbols. This trades
125 /// diagnostic quality for convenience however: If all symbols are enumerated
126 /// up-front then clashes can be detected and reported early (and usually
127 /// deterministically). If this option is set, clashes for the additional
128 /// symbols may not be detected until late, and detection may depend on
129 /// the flow of control through JIT'd code. Use with care.
131 setAutoClaimResponsibilityForObjectSymbols(bool AutoClaimObjectSymbols
) {
132 this->AutoClaimObjectSymbols
= AutoClaimObjectSymbols
;
137 using AllocPtr
= std::unique_ptr
<jitlink::JITLinkMemoryManager::Allocation
>;
139 void modifyPassConfig(MaterializationResponsibility
&MR
, const Triple
&TT
,
140 jitlink::PassConfiguration
&PassConfig
);
141 void notifyLoaded(MaterializationResponsibility
&MR
);
142 Error
notifyEmitted(MaterializationResponsibility
&MR
, AllocPtr Alloc
);
144 Error
removeModule(VModuleKey K
);
145 Error
removeAllModules();
147 mutable std::mutex LayerMutex
;
148 jitlink::JITLinkMemoryManager
&MemMgr
;
149 bool OverrideObjectFlags
= false;
150 bool AutoClaimObjectSymbols
= false;
151 ReturnObjectBufferFunction ReturnObjectBuffer
;
152 DenseMap
<VModuleKey
, AllocPtr
> TrackedAllocs
;
153 std::vector
<AllocPtr
> UntrackedAllocs
;
154 std::vector
<std::unique_ptr
<Plugin
>> Plugins
;
157 class EHFrameRegistrationPlugin
: public ObjectLinkingLayer::Plugin
{
159 EHFrameRegistrationPlugin(jitlink::EHFrameRegistrar
&Registrar
);
160 Error
notifyEmitted(MaterializationResponsibility
&MR
) override
;
161 void modifyPassConfig(MaterializationResponsibility
&MR
, const Triple
&TT
,
162 jitlink::PassConfiguration
&PassConfig
) override
;
163 Error
notifyRemovingModule(VModuleKey K
) override
;
164 Error
notifyRemovingAllModules() override
;
168 struct EHFrameRange
{
169 JITTargetAddress Addr
= 0;
173 jitlink::EHFrameRegistrar
&Registrar
;
174 DenseMap
<MaterializationResponsibility
*, EHFrameRange
> InProcessLinks
;
175 DenseMap
<VModuleKey
, EHFrameRange
> TrackedEHFrameRanges
;
176 std::vector
<EHFrameRange
> UntrackedEHFrameRanges
;
179 } // end namespace orc
180 } // end namespace llvm
182 #endif // LLVM_EXECUTIONENGINE_ORC_OBJECTLINKINGLAYER_H