1 //===- OrcCBindingsStack.h - Orc JIT stack for C bindings -----*- 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 #ifndef LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
10 #define LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H
12 #include "llvm-c/OrcBindings.h"
13 #include "llvm-c/TargetMachine.h"
14 #include "llvm/ADT/STLExtras.h"
15 #include "llvm/ADT/StringRef.h"
16 #include "llvm/ExecutionEngine/JITSymbol.h"
17 #include "llvm/ExecutionEngine/JITEventListener.h"
18 #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
19 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
20 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
21 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
22 #include "llvm/ExecutionEngine/Orc/LambdaResolver.h"
23 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
24 #include "llvm/ExecutionEngine/RuntimeDyld.h"
25 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
26 #include "llvm/IR/DataLayout.h"
27 #include "llvm/IR/Mangler.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/Support/CBindingWrapping.h"
30 #include "llvm/Support/Error.h"
31 #include "llvm/Support/raw_ostream.h"
32 #include "llvm/Target/TargetMachine.h"
44 class OrcCBindingsStack
;
46 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack
, LLVMOrcJITStackRef
)
47 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine
, LLVMTargetMachineRef
)
51 // FIXME: Kill this off once the Layer concept becomes an interface.
54 virtual ~GenericLayer() = default;
56 virtual JITSymbol
findSymbolIn(orc::VModuleKey K
, const std::string
&Name
,
57 bool ExportedSymbolsOnly
) = 0;
58 virtual Error
removeModule(orc::VModuleKey K
) = 0;
61 template <typename LayerT
> class GenericLayerImpl
: public GenericLayer
{
63 GenericLayerImpl(LayerT
&Layer
) : Layer(Layer
) {}
65 JITSymbol
findSymbolIn(orc::VModuleKey K
, const std::string
&Name
,
66 bool ExportedSymbolsOnly
) override
{
67 return Layer
.findSymbolIn(K
, Name
, ExportedSymbolsOnly
);
70 Error
removeModule(orc::VModuleKey K
) override
{
71 return Layer
.removeModule(K
);
79 class GenericLayerImpl
<orc::LegacyRTDyldObjectLinkingLayer
> : public GenericLayer
{
81 using LayerT
= orc::LegacyRTDyldObjectLinkingLayer
;
83 GenericLayerImpl(LayerT
&Layer
) : Layer(Layer
) {}
85 JITSymbol
findSymbolIn(orc::VModuleKey K
, const std::string
&Name
,
86 bool ExportedSymbolsOnly
) override
{
87 return Layer
.findSymbolIn(K
, Name
, ExportedSymbolsOnly
);
90 Error
removeModule(orc::VModuleKey K
) override
{
91 return Layer
.removeObject(K
);
98 template <typename LayerT
>
99 std::unique_ptr
<GenericLayerImpl
<LayerT
>> createGenericLayer(LayerT
&Layer
) {
100 return std::make_unique
<GenericLayerImpl
<LayerT
>>(Layer
);
103 } // end namespace detail
105 class OrcCBindingsStack
{
108 using CompileCallbackMgr
= orc::JITCompileCallbackManager
;
109 using ObjLayerT
= orc::LegacyRTDyldObjectLinkingLayer
;
110 using CompileLayerT
= orc::LegacyIRCompileLayer
<ObjLayerT
, orc::SimpleCompiler
>;
112 orc::LegacyCompileOnDemandLayer
<CompileLayerT
, CompileCallbackMgr
>;
114 using CallbackManagerBuilder
=
115 std::function
<std::unique_ptr
<CompileCallbackMgr
>()>;
117 using IndirectStubsManagerBuilder
= CODLayerT::IndirectStubsManagerBuilderT
;
121 using OwningObject
= object::OwningBinary
<object::ObjectFile
>;
123 class CBindingsResolver
: public orc::SymbolResolver
{
125 CBindingsResolver(OrcCBindingsStack
&Stack
,
126 LLVMOrcSymbolResolverFn ExternalResolver
,
127 void *ExternalResolverCtx
)
128 : Stack(Stack
), ExternalResolver(std::move(ExternalResolver
)),
129 ExternalResolverCtx(std::move(ExternalResolverCtx
)) {}
132 getResponsibilitySet(const orc::SymbolNameSet
&Symbols
) override
{
133 orc::SymbolNameSet Result
;
135 for (auto &S
: Symbols
) {
136 if (auto Sym
= findSymbol(*S
)) {
137 if (!Sym
.getFlags().isStrong())
139 } else if (auto Err
= Sym
.takeError()) {
140 Stack
.reportError(std::move(Err
));
141 return orc::SymbolNameSet();
149 lookup(std::shared_ptr
<orc::AsynchronousSymbolQuery
> Query
,
150 orc::SymbolNameSet Symbols
) override
{
151 orc::SymbolNameSet UnresolvedSymbols
;
153 for (auto &S
: Symbols
) {
154 if (auto Sym
= findSymbol(*S
)) {
155 if (auto Addr
= Sym
.getAddress()) {
156 Query
->notifySymbolMetRequiredState(
157 S
, JITEvaluatedSymbol(*Addr
, Sym
.getFlags()));
159 Stack
.ES
.legacyFailQuery(*Query
, Addr
.takeError());
160 return orc::SymbolNameSet();
162 } else if (auto Err
= Sym
.takeError()) {
163 Stack
.ES
.legacyFailQuery(*Query
, std::move(Err
));
164 return orc::SymbolNameSet();
166 UnresolvedSymbols
.insert(S
);
169 if (Query
->isComplete())
170 Query
->handleComplete();
172 return UnresolvedSymbols
;
176 JITSymbol
findSymbol(const std::string
&Name
) {
179 // 2. Runtime overrides.
180 // 3. External resolver (if present).
182 if (Stack
.CODLayer
) {
183 if (auto Sym
= Stack
.CODLayer
->findSymbol(Name
, true))
185 else if (auto Err
= Sym
.takeError())
186 return Sym
.takeError();
188 if (auto Sym
= Stack
.CompileLayer
.findSymbol(Name
, true))
190 else if (auto Err
= Sym
.takeError())
191 return Sym
.takeError();
194 if (auto Sym
= Stack
.CXXRuntimeOverrides
.searchOverrides(Name
))
197 if (ExternalResolver
)
198 return JITSymbol(ExternalResolver(Name
.c_str(), ExternalResolverCtx
),
199 JITSymbolFlags::Exported
);
201 return JITSymbol(nullptr);
204 OrcCBindingsStack
&Stack
;
205 LLVMOrcSymbolResolverFn ExternalResolver
;
206 void *ExternalResolverCtx
= nullptr;
210 OrcCBindingsStack(TargetMachine
&TM
,
211 IndirectStubsManagerBuilder IndirectStubsMgrBuilder
)
212 : CCMgr(createCompileCallbackManager(TM
, ES
)), DL(TM
.createDataLayout()),
213 IndirectStubsMgr(IndirectStubsMgrBuilder()),
215 AcknowledgeORCv1Deprecation
, ES
,
216 [this](orc::VModuleKey K
) {
217 auto ResolverI
= Resolvers
.find(K
);
218 assert(ResolverI
!= Resolvers
.end() &&
219 "No resolver for module K");
220 auto Resolver
= std::move(ResolverI
->second
);
221 Resolvers
.erase(ResolverI
);
222 return ObjLayerT::Resources
{
223 std::make_shared
<SectionMemoryManager
>(), Resolver
};
226 [this](orc::VModuleKey K
, const object::ObjectFile
&Obj
,
227 const RuntimeDyld::LoadedObjectInfo
&LoadedObjInfo
) {
228 this->notifyFinalized(K
, Obj
, LoadedObjInfo
);
230 [this](orc::VModuleKey K
, const object::ObjectFile
&Obj
) {
231 this->notifyFreed(K
, Obj
);
233 CompileLayer(AcknowledgeORCv1Deprecation
, ObjectLayer
,
234 orc::SimpleCompiler(TM
)),
235 CODLayer(createCODLayer(ES
, CompileLayer
, CCMgr
.get(),
236 std::move(IndirectStubsMgrBuilder
), Resolvers
)),
238 AcknowledgeORCv1Deprecation
,
239 [this](const std::string
&S
) { return mangle(S
); }) {}
242 // Run any destructors registered with __cxa_atexit.
243 CXXRuntimeOverrides
.runDestructors();
244 // Run any IR destructors.
245 for (auto &DtorRunner
: IRStaticDestructorRunners
)
246 if (auto Err
= DtorRunner
.runViaLayer(*this))
248 return Error::success();
251 std::string
mangle(StringRef Name
) {
252 std::string MangledName
;
254 raw_string_ostream
MangledNameStream(MangledName
);
255 Mangler::getNameWithPrefix(MangledNameStream
, Name
, DL
);
260 template <typename PtrTy
>
261 static PtrTy
fromTargetAddress(JITTargetAddress Addr
) {
262 return reinterpret_cast<PtrTy
>(static_cast<uintptr_t>(Addr
));
265 Expected
<JITTargetAddress
>
266 createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback
,
268 auto WrappedCallback
= [=]() -> JITTargetAddress
{
269 return Callback(wrap(this), CallbackCtx
);
272 return CCMgr
->getCompileCallback(std::move(WrappedCallback
));
275 Error
createIndirectStub(StringRef StubName
, JITTargetAddress Addr
) {
276 return IndirectStubsMgr
->createStub(StubName
, Addr
,
277 JITSymbolFlags::Exported
);
280 Error
setIndirectStubPointer(StringRef Name
, JITTargetAddress Addr
) {
281 return IndirectStubsMgr
->updatePointer(Name
, Addr
);
284 template <typename LayerT
>
285 Expected
<orc::VModuleKey
>
286 addIRModule(LayerT
&Layer
, std::unique_ptr
<Module
> M
,
287 std::unique_ptr
<RuntimeDyld::MemoryManager
> MemMgr
,
288 LLVMOrcSymbolResolverFn ExternalResolver
,
289 void *ExternalResolverCtx
) {
291 // Attach a data-layout if one isn't already present.
292 if (M
->getDataLayout().isDefault())
293 M
->setDataLayout(DL
);
295 // Record the static constructors and destructors. We have to do this before
296 // we hand over ownership of the module to the JIT.
297 std::vector
<std::string
> CtorNames
, DtorNames
;
298 for (auto Ctor
: orc::getConstructors(*M
))
299 CtorNames
.push_back(mangle(Ctor
.Func
->getName()));
300 for (auto Dtor
: orc::getDestructors(*M
))
301 DtorNames
.push_back(mangle(Dtor
.Func
->getName()));
303 // Add the module to the JIT.
304 auto K
= ES
.allocateVModule();
305 Resolvers
[K
] = std::make_shared
<CBindingsResolver
>(*this, ExternalResolver
,
306 ExternalResolverCtx
);
307 if (auto Err
= Layer
.addModule(K
, std::move(M
)))
308 return std::move(Err
);
310 KeyLayers
[K
] = detail::createGenericLayer(Layer
);
312 // Run the static constructors, and save the static destructor runner for
313 // execution when the JIT is torn down.
314 orc::LegacyCtorDtorRunner
<OrcCBindingsStack
> CtorRunner(
315 AcknowledgeORCv1Deprecation
, std::move(CtorNames
), K
);
316 if (auto Err
= CtorRunner
.runViaLayer(*this))
317 return std::move(Err
);
319 IRStaticDestructorRunners
.emplace_back(AcknowledgeORCv1Deprecation
,
320 std::move(DtorNames
), K
);
325 Expected
<orc::VModuleKey
>
326 addIRModuleEager(std::unique_ptr
<Module
> M
,
327 LLVMOrcSymbolResolverFn ExternalResolver
,
328 void *ExternalResolverCtx
) {
329 return addIRModule(CompileLayer
, std::move(M
),
330 std::make_unique
<SectionMemoryManager
>(),
331 std::move(ExternalResolver
), ExternalResolverCtx
);
334 Expected
<orc::VModuleKey
>
335 addIRModuleLazy(std::unique_ptr
<Module
> M
,
336 LLVMOrcSymbolResolverFn ExternalResolver
,
337 void *ExternalResolverCtx
) {
339 return make_error
<StringError
>("Can not add lazy module: No compile "
340 "callback manager available",
341 inconvertibleErrorCode());
343 return addIRModule(*CODLayer
, std::move(M
),
344 std::make_unique
<SectionMemoryManager
>(),
345 std::move(ExternalResolver
), ExternalResolverCtx
);
348 Error
removeModule(orc::VModuleKey K
) {
349 // FIXME: Should error release the module key?
350 if (auto Err
= KeyLayers
[K
]->removeModule(K
))
352 ES
.releaseVModule(K
);
354 return Error::success();
357 Expected
<orc::VModuleKey
> addObject(std::unique_ptr
<MemoryBuffer
> ObjBuffer
,
358 LLVMOrcSymbolResolverFn ExternalResolver
,
359 void *ExternalResolverCtx
) {
360 if (auto Obj
= object::ObjectFile::createObjectFile(
361 ObjBuffer
->getMemBufferRef())) {
363 auto K
= ES
.allocateVModule();
364 Resolvers
[K
] = std::make_shared
<CBindingsResolver
>(
365 *this, ExternalResolver
, ExternalResolverCtx
);
367 if (auto Err
= ObjectLayer
.addObject(K
, std::move(ObjBuffer
)))
368 return std::move(Err
);
370 KeyLayers
[K
] = detail::createGenericLayer(ObjectLayer
);
374 return Obj
.takeError();
377 JITSymbol
findSymbol(const std::string
&Name
,
378 bool ExportedSymbolsOnly
) {
379 if (auto Sym
= IndirectStubsMgr
->findStub(Name
, ExportedSymbolsOnly
))
382 return CODLayer
->findSymbol(mangle(Name
), ExportedSymbolsOnly
);
383 return CompileLayer
.findSymbol(mangle(Name
), ExportedSymbolsOnly
);
386 JITSymbol
findSymbolIn(orc::VModuleKey K
, const std::string
&Name
,
387 bool ExportedSymbolsOnly
) {
388 assert(KeyLayers
.count(K
) && "looking up symbol in unknown module");
389 return KeyLayers
[K
]->findSymbolIn(K
, mangle(Name
), ExportedSymbolsOnly
);
392 Expected
<JITTargetAddress
> findSymbolAddress(const std::string
&Name
,
393 bool ExportedSymbolsOnly
) {
394 if (auto Sym
= findSymbol(Name
, ExportedSymbolsOnly
)) {
395 // Successful lookup, non-null symbol:
396 if (auto AddrOrErr
= Sym
.getAddress())
399 return AddrOrErr
.takeError();
400 } else if (auto Err
= Sym
.takeError()) {
401 // Lookup failure - report error.
402 return std::move(Err
);
405 // No symbol not found. Return 0.
409 Expected
<JITTargetAddress
> findSymbolAddressIn(orc::VModuleKey K
,
410 const std::string
&Name
,
411 bool ExportedSymbolsOnly
) {
412 if (auto Sym
= findSymbolIn(K
, Name
, ExportedSymbolsOnly
)) {
413 // Successful lookup, non-null symbol:
414 if (auto AddrOrErr
= Sym
.getAddress())
417 return AddrOrErr
.takeError();
418 } else if (auto Err
= Sym
.takeError()) {
419 // Lookup failure - report error.
420 return std::move(Err
);
423 // Symbol not found. Return 0.
427 const std::string
&getErrorMessage() const { return ErrMsg
; }
429 void RegisterJITEventListener(JITEventListener
*L
) {
432 EventListeners
.push_back(L
);
435 void UnregisterJITEventListener(JITEventListener
*L
) {
439 auto I
= find(reverse(EventListeners
), L
);
440 if (I
!= EventListeners
.rend()) {
441 std::swap(*I
, EventListeners
.back());
442 EventListeners
.pop_back();
448 std::map
<orc::VModuleKey
, std::shared_ptr
<orc::SymbolResolver
>>;
450 static std::unique_ptr
<CompileCallbackMgr
>
451 createCompileCallbackManager(TargetMachine
&TM
, orc::ExecutionSession
&ES
) {
452 auto CCMgr
= createLocalCompileCallbackManager(TM
.getTargetTriple(), ES
, 0);
454 // FIXME: It would be good if we could report this somewhere, but we do
455 // have an instance yet.
456 logAllUnhandledErrors(CCMgr
.takeError(), errs(), "ORC error: ");
459 return std::move(*CCMgr
);
462 static std::unique_ptr
<CODLayerT
>
463 createCODLayer(orc::ExecutionSession
&ES
, CompileLayerT
&CompileLayer
,
464 CompileCallbackMgr
*CCMgr
,
465 IndirectStubsManagerBuilder IndirectStubsMgrBuilder
,
466 ResolverMap
&Resolvers
) {
467 // If there is no compile callback manager available we can not create a
468 // compile on demand layer.
472 return std::make_unique
<CODLayerT
>(
473 AcknowledgeORCv1Deprecation
, ES
, CompileLayer
,
474 [&Resolvers
](orc::VModuleKey K
) {
475 auto ResolverI
= Resolvers
.find(K
);
476 assert(ResolverI
!= Resolvers
.end() && "No resolver for module K");
477 return ResolverI
->second
;
479 [&Resolvers
](orc::VModuleKey K
,
480 std::shared_ptr
<orc::SymbolResolver
> Resolver
) {
481 assert(!Resolvers
.count(K
) && "Resolver already present");
482 Resolvers
[K
] = std::move(Resolver
);
484 [](Function
&F
) { return std::set
<Function
*>({&F
}); }, *CCMgr
,
485 std::move(IndirectStubsMgrBuilder
), false);
488 void reportError(Error Err
) {
489 // FIXME: Report errors on the execution session.
490 logAllUnhandledErrors(std::move(Err
), errs(), "ORC error: ");
493 void notifyFinalized(orc::VModuleKey K
,
494 const object::ObjectFile
&Obj
,
495 const RuntimeDyld::LoadedObjectInfo
&LoadedObjInfo
) {
496 uint64_t Key
= static_cast<uint64_t>(
497 reinterpret_cast<uintptr_t>(Obj
.getData().data()));
498 for (auto &Listener
: EventListeners
)
499 Listener
->notifyObjectLoaded(Key
, Obj
, LoadedObjInfo
);
502 void notifyFreed(orc::VModuleKey K
, const object::ObjectFile
&Obj
) {
503 uint64_t Key
= static_cast<uint64_t>(
504 reinterpret_cast<uintptr_t>(Obj
.getData().data()));
505 for (auto &Listener
: EventListeners
)
506 Listener
->notifyFreeingObject(Key
);
509 orc::ExecutionSession ES
;
510 std::unique_ptr
<CompileCallbackMgr
> CCMgr
;
512 std::vector
<JITEventListener
*> EventListeners
;
515 SectionMemoryManager CCMgrMemMgr
;
517 std::unique_ptr
<orc::IndirectStubsManager
> IndirectStubsMgr
;
519 ObjLayerT ObjectLayer
;
520 CompileLayerT CompileLayer
;
521 std::unique_ptr
<CODLayerT
> CODLayer
;
523 std::map
<orc::VModuleKey
, std::unique_ptr
<detail::GenericLayer
>> KeyLayers
;
525 orc::LegacyLocalCXXRuntimeOverrides CXXRuntimeOverrides
;
526 std::vector
<orc::LegacyCtorDtorRunner
<OrcCBindingsStack
>> IRStaticDestructorRunners
;
529 ResolverMap Resolvers
;
532 } // end namespace llvm
534 #endif // LLVM_LIB_EXECUTIONENGINE_ORC_ORCCBINDINGSSTACK_H