1 //===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===//
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 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/STLExtras.h"
11 #include "llvm/ExecutionEngine/GenericValue.h"
12 #include "llvm/ExecutionEngine/JITEventListener.h"
13 #include "llvm/ExecutionEngine/MCJIT.h"
14 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
15 #include "llvm/IR/DataLayout.h"
16 #include "llvm/IR/DerivedTypes.h"
17 #include "llvm/IR/Function.h"
18 #include "llvm/IR/LegacyPassManager.h"
19 #include "llvm/IR/Mangler.h"
20 #include "llvm/IR/Module.h"
21 #include "llvm/Object/Archive.h"
22 #include "llvm/Object/ObjectFile.h"
23 #include "llvm/Support/DynamicLibrary.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/MemoryBuffer.h"
32 static struct RegisterJIT
{
33 RegisterJIT() { MCJIT::Register(); }
38 extern "C" void LLVMLinkInMCJIT() {
42 MCJIT::createJIT(std::unique_ptr
<Module
> M
, std::string
*ErrorStr
,
43 std::shared_ptr
<MCJITMemoryManager
> MemMgr
,
44 std::shared_ptr
<LegacyJITSymbolResolver
> Resolver
,
45 std::unique_ptr
<TargetMachine
> TM
) {
46 // Try to register the program as a source of symbols to resolve against.
48 // FIXME: Don't do this here.
49 sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
51 if (!MemMgr
|| !Resolver
) {
52 auto RTDyldMM
= std::make_shared
<SectionMemoryManager
>();
59 return new MCJIT(std::move(M
), std::move(TM
), std::move(MemMgr
),
63 MCJIT::MCJIT(std::unique_ptr
<Module
> M
, std::unique_ptr
<TargetMachine
> TM
,
64 std::shared_ptr
<MCJITMemoryManager
> MemMgr
,
65 std::shared_ptr
<LegacyJITSymbolResolver
> Resolver
)
66 : ExecutionEngine(TM
->createDataLayout(), std::move(M
)), TM(std::move(TM
)),
67 Ctx(nullptr), MemMgr(std::move(MemMgr
)),
68 Resolver(*this, std::move(Resolver
)), Dyld(*this->MemMgr
, this->Resolver
),
70 // FIXME: We are managing our modules, so we do not want the base class
71 // ExecutionEngine to manage them as well. To avoid double destruction
72 // of the first (and only) module added in ExecutionEngine constructor
73 // we remove it from EE and will destruct it ourselves.
75 // It may make sense to move our module manager (based on SmallStPtr) back
76 // into EE if the JIT and Interpreter can live with it.
77 // If so, additional functions: addModule, removeModule, FindFunctionNamed,
78 // runStaticConstructorsDestructors could be moved back to EE as well.
80 std::unique_ptr
<Module
> First
= std::move(Modules
[0]);
83 if (First
->getDataLayout().isDefault())
84 First
->setDataLayout(getDataLayout());
86 OwnedModules
.addModule(std::move(First
));
87 RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
91 std::lock_guard
<sys::Mutex
> locked(lock
);
93 Dyld
.deregisterEHFrames();
95 for (auto &Obj
: LoadedObjects
)
97 notifyFreeingObject(*Obj
);
102 void MCJIT::addModule(std::unique_ptr
<Module
> M
) {
103 std::lock_guard
<sys::Mutex
> locked(lock
);
105 if (M
->getDataLayout().isDefault())
106 M
->setDataLayout(getDataLayout());
108 OwnedModules
.addModule(std::move(M
));
111 bool MCJIT::removeModule(Module
*M
) {
112 std::lock_guard
<sys::Mutex
> locked(lock
);
113 return OwnedModules
.removeModule(M
);
116 void MCJIT::addObjectFile(std::unique_ptr
<object::ObjectFile
> Obj
) {
117 std::unique_ptr
<RuntimeDyld::LoadedObjectInfo
> L
= Dyld
.loadObject(*Obj
);
119 report_fatal_error(Dyld
.getErrorString());
121 notifyObjectLoaded(*Obj
, *L
);
123 LoadedObjects
.push_back(std::move(Obj
));
126 void MCJIT::addObjectFile(object::OwningBinary
<object::ObjectFile
> Obj
) {
127 std::unique_ptr
<object::ObjectFile
> ObjFile
;
128 std::unique_ptr
<MemoryBuffer
> MemBuf
;
129 std::tie(ObjFile
, MemBuf
) = Obj
.takeBinary();
130 addObjectFile(std::move(ObjFile
));
131 Buffers
.push_back(std::move(MemBuf
));
134 void MCJIT::addArchive(object::OwningBinary
<object::Archive
> A
) {
135 Archives
.push_back(std::move(A
));
138 void MCJIT::setObjectCache(ObjectCache
* NewCache
) {
139 std::lock_guard
<sys::Mutex
> locked(lock
);
143 std::unique_ptr
<MemoryBuffer
> MCJIT::emitObject(Module
*M
) {
144 assert(M
&& "Can not emit a null module");
146 std::lock_guard
<sys::Mutex
> locked(lock
);
148 // Materialize all globals in the module if they have not been
149 // materialized already.
150 cantFail(M
->materializeAll());
152 // This must be a module which has already been added but not loaded to this
153 // MCJIT instance, since these conditions are tested by our caller,
154 // generateCodeForModule.
156 legacy::PassManager PM
;
158 // The RuntimeDyld will take ownership of this shortly
159 SmallVector
<char, 4096> ObjBufferSV
;
160 raw_svector_ostream
ObjStream(ObjBufferSV
);
162 // Turn the machine code intermediate representation into bytes in memory
163 // that may be executed.
164 if (TM
->addPassesToEmitMC(PM
, Ctx
, ObjStream
, !getVerifyModules()))
165 report_fatal_error("Target does not support MC emission!");
167 // Initialize passes.
169 // Flush the output buffer to get the generated code into memory
171 std::unique_ptr
<MemoryBuffer
> CompiledObjBuffer(
172 new SmallVectorMemoryBuffer(std::move(ObjBufferSV
)));
174 // If we have an object cache, tell it about the new object.
175 // Note that we're using the compiled image, not the loaded image (as below).
177 // MemoryBuffer is a thin wrapper around the actual memory, so it's OK
178 // to create a temporary object here and delete it after the call.
179 MemoryBufferRef MB
= CompiledObjBuffer
->getMemBufferRef();
180 ObjCache
->notifyObjectCompiled(M
, MB
);
183 return CompiledObjBuffer
;
186 void MCJIT::generateCodeForModule(Module
*M
) {
187 // Get a thread lock to make sure we aren't trying to load multiple times
188 std::lock_guard
<sys::Mutex
> locked(lock
);
190 // This must be a module which has already been added to this MCJIT instance.
191 assert(OwnedModules
.ownsModule(M
) &&
192 "MCJIT::generateCodeForModule: Unknown module.");
194 // Re-compilation is not supported
195 if (OwnedModules
.hasModuleBeenLoaded(M
))
198 std::unique_ptr
<MemoryBuffer
> ObjectToLoad
;
199 // Try to load the pre-compiled object from cache if possible
201 ObjectToLoad
= ObjCache
->getObject(M
);
203 assert(M
->getDataLayout() == getDataLayout() && "DataLayout Mismatch");
205 // If the cache did not contain a suitable object, compile the object
207 ObjectToLoad
= emitObject(M
);
208 assert(ObjectToLoad
&& "Compilation did not produce an object.");
211 // Load the object into the dynamic linker.
212 // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list).
213 Expected
<std::unique_ptr
<object::ObjectFile
>> LoadedObject
=
214 object::ObjectFile::createObjectFile(ObjectToLoad
->getMemBufferRef());
217 raw_string_ostream
OS(Buf
);
218 logAllUnhandledErrors(LoadedObject
.takeError(), OS
);
220 report_fatal_error(Buf
);
222 std::unique_ptr
<RuntimeDyld::LoadedObjectInfo
> L
=
223 Dyld
.loadObject(*LoadedObject
.get());
226 report_fatal_error(Dyld
.getErrorString());
228 notifyObjectLoaded(*LoadedObject
.get(), *L
);
230 Buffers
.push_back(std::move(ObjectToLoad
));
231 LoadedObjects
.push_back(std::move(*LoadedObject
));
233 OwnedModules
.markModuleAsLoaded(M
);
236 void MCJIT::finalizeLoadedModules() {
237 std::lock_guard
<sys::Mutex
> locked(lock
);
239 // Resolve any outstanding relocations.
240 Dyld
.resolveRelocations();
242 OwnedModules
.markAllLoadedModulesAsFinalized();
244 // Register EH frame data for any module we own which has been loaded
245 Dyld
.registerEHFrames();
247 // Set page permissions.
248 MemMgr
->finalizeMemory();
251 // FIXME: Rename this.
252 void MCJIT::finalizeObject() {
253 std::lock_guard
<sys::Mutex
> locked(lock
);
255 // Generate code for module is going to move objects out of the 'added' list,
256 // so we need to copy that out before using it:
257 SmallVector
<Module
*, 16> ModsToAdd
;
258 for (auto M
: OwnedModules
.added())
259 ModsToAdd
.push_back(M
);
261 for (auto M
: ModsToAdd
)
262 generateCodeForModule(M
);
264 finalizeLoadedModules();
267 void MCJIT::finalizeModule(Module
*M
) {
268 std::lock_guard
<sys::Mutex
> locked(lock
);
270 // This must be a module which has already been added to this MCJIT instance.
271 assert(OwnedModules
.ownsModule(M
) && "MCJIT::finalizeModule: Unknown module.");
273 // If the module hasn't been compiled, just do that.
274 if (!OwnedModules
.hasModuleBeenLoaded(M
))
275 generateCodeForModule(M
);
277 finalizeLoadedModules();
280 JITSymbol
MCJIT::findExistingSymbol(const std::string
&Name
) {
281 if (void *Addr
= getPointerToGlobalIfAvailable(Name
))
282 return JITSymbol(static_cast<uint64_t>(
283 reinterpret_cast<uintptr_t>(Addr
)),
284 JITSymbolFlags::Exported
);
286 return Dyld
.getSymbol(Name
);
289 Module
*MCJIT::findModuleForSymbol(const std::string
&Name
,
290 bool CheckFunctionsOnly
) {
291 StringRef DemangledName
= Name
;
292 if (DemangledName
[0] == getDataLayout().getGlobalPrefix())
293 DemangledName
= DemangledName
.substr(1);
295 std::lock_guard
<sys::Mutex
> locked(lock
);
297 // If it hasn't already been generated, see if it's in one of our modules.
298 for (ModulePtrSet::iterator I
= OwnedModules
.begin_added(),
299 E
= OwnedModules
.end_added();
302 Function
*F
= M
->getFunction(DemangledName
);
303 if (F
&& !F
->isDeclaration())
305 if (!CheckFunctionsOnly
) {
306 GlobalVariable
*G
= M
->getGlobalVariable(DemangledName
);
307 if (G
&& !G
->isDeclaration())
309 // FIXME: Do we need to worry about global aliases?
312 // We didn't find the symbol in any of our modules.
316 uint64_t MCJIT::getSymbolAddress(const std::string
&Name
,
317 bool CheckFunctionsOnly
) {
318 std::string MangledName
;
320 raw_string_ostream
MangledNameStream(MangledName
);
321 Mangler::getNameWithPrefix(MangledNameStream
, Name
, getDataLayout());
323 if (auto Sym
= findSymbol(MangledName
, CheckFunctionsOnly
)) {
324 if (auto AddrOrErr
= Sym
.getAddress())
327 report_fatal_error(AddrOrErr
.takeError());
328 } else if (auto Err
= Sym
.takeError())
329 report_fatal_error(Sym
.takeError());
333 JITSymbol
MCJIT::findSymbol(const std::string
&Name
,
334 bool CheckFunctionsOnly
) {
335 std::lock_guard
<sys::Mutex
> locked(lock
);
337 // First, check to see if we already have this symbol.
338 if (auto Sym
= findExistingSymbol(Name
))
341 for (object::OwningBinary
<object::Archive
> &OB
: Archives
) {
342 object::Archive
*A
= OB
.getBinary();
343 // Look for our symbols in each Archive
344 auto OptionalChildOrErr
= A
->findSym(Name
);
345 if (!OptionalChildOrErr
)
346 report_fatal_error(OptionalChildOrErr
.takeError());
347 auto &OptionalChild
= *OptionalChildOrErr
;
349 // FIXME: Support nested archives?
350 Expected
<std::unique_ptr
<object::Binary
>> ChildBinOrErr
=
351 OptionalChild
->getAsBinary();
352 if (!ChildBinOrErr
) {
353 // TODO: Actually report errors helpfully.
354 consumeError(ChildBinOrErr
.takeError());
357 std::unique_ptr
<object::Binary
> &ChildBin
= ChildBinOrErr
.get();
358 if (ChildBin
->isObject()) {
359 std::unique_ptr
<object::ObjectFile
> OF(
360 static_cast<object::ObjectFile
*>(ChildBin
.release()));
361 // This causes the object file to be loaded.
362 addObjectFile(std::move(OF
));
363 // The address should be here now.
364 if (auto Sym
= findExistingSymbol(Name
))
370 // If it hasn't already been generated, see if it's in one of our modules.
371 Module
*M
= findModuleForSymbol(Name
, CheckFunctionsOnly
);
373 generateCodeForModule(M
);
375 // Check the RuntimeDyld table again, it should be there now.
376 return findExistingSymbol(Name
);
379 // If a LazyFunctionCreator is installed, use it to get/create the function.
380 // FIXME: Should we instead have a LazySymbolCreator callback?
381 if (LazyFunctionCreator
) {
382 auto Addr
= static_cast<uint64_t>(
383 reinterpret_cast<uintptr_t>(LazyFunctionCreator(Name
)));
384 return JITSymbol(Addr
, JITSymbolFlags::Exported
);
390 uint64_t MCJIT::getGlobalValueAddress(const std::string
&Name
) {
391 std::lock_guard
<sys::Mutex
> locked(lock
);
392 uint64_t Result
= getSymbolAddress(Name
, false);
394 finalizeLoadedModules();
398 uint64_t MCJIT::getFunctionAddress(const std::string
&Name
) {
399 std::lock_guard
<sys::Mutex
> locked(lock
);
400 uint64_t Result
= getSymbolAddress(Name
, true);
402 finalizeLoadedModules();
406 // Deprecated. Use getFunctionAddress instead.
407 void *MCJIT::getPointerToFunction(Function
*F
) {
408 std::lock_guard
<sys::Mutex
> locked(lock
);
411 SmallString
<128> Name
;
412 TM
->getNameWithPrefix(Name
, F
, Mang
);
414 if (F
->isDeclaration() || F
->hasAvailableExternallyLinkage()) {
415 bool AbortOnFailure
= !F
->hasExternalWeakLinkage();
416 void *Addr
= getPointerToNamedFunction(Name
, AbortOnFailure
);
417 updateGlobalMapping(F
, Addr
);
421 Module
*M
= F
->getParent();
422 bool HasBeenAddedButNotLoaded
= OwnedModules
.hasModuleBeenAddedButNotLoaded(M
);
424 // Make sure the relevant module has been compiled and loaded.
425 if (HasBeenAddedButNotLoaded
)
426 generateCodeForModule(M
);
427 else if (!OwnedModules
.hasModuleBeenLoaded(M
)) {
428 // If this function doesn't belong to one of our modules, we're done.
429 // FIXME: Asking for the pointer to a function that hasn't been registered,
430 // and isn't a declaration (which is handled above) should probably
435 // FIXME: Should the Dyld be retaining module information? Probably not.
437 // This is the accessor for the target address, so make sure to check the
438 // load address of the symbol, not the local address.
439 return (void*)Dyld
.getSymbol(Name
).getAddress();
442 void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
443 bool isDtors
, ModulePtrSet::iterator I
, ModulePtrSet::iterator E
) {
444 for (; I
!= E
; ++I
) {
445 ExecutionEngine::runStaticConstructorsDestructors(**I
, isDtors
);
449 void MCJIT::runStaticConstructorsDestructors(bool isDtors
) {
450 // Execute global ctors/dtors for each module in the program.
451 runStaticConstructorsDestructorsInModulePtrSet(
452 isDtors
, OwnedModules
.begin_added(), OwnedModules
.end_added());
453 runStaticConstructorsDestructorsInModulePtrSet(
454 isDtors
, OwnedModules
.begin_loaded(), OwnedModules
.end_loaded());
455 runStaticConstructorsDestructorsInModulePtrSet(
456 isDtors
, OwnedModules
.begin_finalized(), OwnedModules
.end_finalized());
459 Function
*MCJIT::FindFunctionNamedInModulePtrSet(StringRef FnName
,
460 ModulePtrSet::iterator I
,
461 ModulePtrSet::iterator E
) {
462 for (; I
!= E
; ++I
) {
463 Function
*F
= (*I
)->getFunction(FnName
);
464 if (F
&& !F
->isDeclaration())
470 GlobalVariable
*MCJIT::FindGlobalVariableNamedInModulePtrSet(StringRef Name
,
472 ModulePtrSet::iterator I
,
473 ModulePtrSet::iterator E
) {
474 for (; I
!= E
; ++I
) {
475 GlobalVariable
*GV
= (*I
)->getGlobalVariable(Name
, AllowInternal
);
476 if (GV
&& !GV
->isDeclaration())
483 Function
*MCJIT::FindFunctionNamed(StringRef FnName
) {
484 Function
*F
= FindFunctionNamedInModulePtrSet(
485 FnName
, OwnedModules
.begin_added(), OwnedModules
.end_added());
487 F
= FindFunctionNamedInModulePtrSet(FnName
, OwnedModules
.begin_loaded(),
488 OwnedModules
.end_loaded());
490 F
= FindFunctionNamedInModulePtrSet(FnName
, OwnedModules
.begin_finalized(),
491 OwnedModules
.end_finalized());
495 GlobalVariable
*MCJIT::FindGlobalVariableNamed(StringRef Name
, bool AllowInternal
) {
496 GlobalVariable
*GV
= FindGlobalVariableNamedInModulePtrSet(
497 Name
, AllowInternal
, OwnedModules
.begin_added(), OwnedModules
.end_added());
499 GV
= FindGlobalVariableNamedInModulePtrSet(Name
, AllowInternal
, OwnedModules
.begin_loaded(),
500 OwnedModules
.end_loaded());
502 GV
= FindGlobalVariableNamedInModulePtrSet(Name
, AllowInternal
, OwnedModules
.begin_finalized(),
503 OwnedModules
.end_finalized());
507 GenericValue
MCJIT::runFunction(Function
*F
, ArrayRef
<GenericValue
> ArgValues
) {
508 assert(F
&& "Function *F was null at entry to run()");
510 void *FPtr
= getPointerToFunction(F
);
511 finalizeModule(F
->getParent());
512 assert(FPtr
&& "Pointer to fn's code was null after getPointerToFunction");
513 FunctionType
*FTy
= F
->getFunctionType();
514 Type
*RetTy
= FTy
->getReturnType();
516 assert((FTy
->getNumParams() == ArgValues
.size() ||
517 (FTy
->isVarArg() && FTy
->getNumParams() <= ArgValues
.size())) &&
518 "Wrong number of arguments passed into function!");
519 assert(FTy
->getNumParams() == ArgValues
.size() &&
520 "This doesn't support passing arguments through varargs (yet)!");
522 // Handle some common cases first. These cases correspond to common `main'
524 if (RetTy
->isIntegerTy(32) || RetTy
->isVoidTy()) {
525 switch (ArgValues
.size()) {
527 if (FTy
->getParamType(0)->isIntegerTy(32) &&
528 FTy
->getParamType(1)->isPointerTy() &&
529 FTy
->getParamType(2)->isPointerTy()) {
530 int (*PF
)(int, char **, const char **) =
531 (int(*)(int, char **, const char **))(intptr_t)FPtr
;
533 // Call the function.
535 rv
.IntVal
= APInt(32, PF(ArgValues
[0].IntVal
.getZExtValue(),
536 (char **)GVTOP(ArgValues
[1]),
537 (const char **)GVTOP(ArgValues
[2])));
542 if (FTy
->getParamType(0)->isIntegerTy(32) &&
543 FTy
->getParamType(1)->isPointerTy()) {
544 int (*PF
)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr
;
546 // Call the function.
548 rv
.IntVal
= APInt(32, PF(ArgValues
[0].IntVal
.getZExtValue(),
549 (char **)GVTOP(ArgValues
[1])));
554 if (FTy
->getNumParams() == 1 &&
555 FTy
->getParamType(0)->isIntegerTy(32)) {
557 int (*PF
)(int) = (int(*)(int))(intptr_t)FPtr
;
558 rv
.IntVal
= APInt(32, PF(ArgValues
[0].IntVal
.getZExtValue()));
565 // Handle cases where no arguments are passed first.
566 if (ArgValues
.empty()) {
568 switch (RetTy
->getTypeID()) {
569 default: llvm_unreachable("Unknown return type for function call!");
570 case Type::IntegerTyID
: {
571 unsigned BitWidth
= cast
<IntegerType
>(RetTy
)->getBitWidth();
573 rv
.IntVal
= APInt(BitWidth
, ((bool(*)())(intptr_t)FPtr
)());
574 else if (BitWidth
<= 8)
575 rv
.IntVal
= APInt(BitWidth
, ((char(*)())(intptr_t)FPtr
)());
576 else if (BitWidth
<= 16)
577 rv
.IntVal
= APInt(BitWidth
, ((short(*)())(intptr_t)FPtr
)());
578 else if (BitWidth
<= 32)
579 rv
.IntVal
= APInt(BitWidth
, ((int(*)())(intptr_t)FPtr
)());
580 else if (BitWidth
<= 64)
581 rv
.IntVal
= APInt(BitWidth
, ((int64_t(*)())(intptr_t)FPtr
)());
583 llvm_unreachable("Integer types > 64 bits not supported");
587 rv
.IntVal
= APInt(32, ((int(*)())(intptr_t)FPtr
)());
589 case Type::FloatTyID
:
590 rv
.FloatVal
= ((float(*)())(intptr_t)FPtr
)();
592 case Type::DoubleTyID
:
593 rv
.DoubleVal
= ((double(*)())(intptr_t)FPtr
)();
595 case Type::X86_FP80TyID
:
596 case Type::FP128TyID
:
597 case Type::PPC_FP128TyID
:
598 llvm_unreachable("long double not supported yet");
599 case Type::PointerTyID
:
600 return PTOGV(((void*(*)())(intptr_t)FPtr
)());
604 report_fatal_error("MCJIT::runFunction does not support full-featured "
605 "argument passing. Please use "
606 "ExecutionEngine::getFunctionAddress and cast the result "
607 "to the desired function pointer type.");
610 void *MCJIT::getPointerToNamedFunction(StringRef Name
, bool AbortOnFailure
) {
611 if (!isSymbolSearchingDisabled()) {
612 if (auto Sym
= Resolver
.findSymbol(Name
)) {
613 if (auto AddrOrErr
= Sym
.getAddress())
614 return reinterpret_cast<void*>(
615 static_cast<uintptr_t>(*AddrOrErr
));
616 } else if (auto Err
= Sym
.takeError())
617 report_fatal_error(std::move(Err
));
620 /// If a LazyFunctionCreator is installed, use it to get/create the function.
621 if (LazyFunctionCreator
)
622 if (void *RP
= LazyFunctionCreator(Name
))
625 if (AbortOnFailure
) {
626 report_fatal_error("Program used external function '"+Name
+
627 "' which could not be resolved!");
632 void MCJIT::RegisterJITEventListener(JITEventListener
*L
) {
635 std::lock_guard
<sys::Mutex
> locked(lock
);
636 EventListeners
.push_back(L
);
639 void MCJIT::UnregisterJITEventListener(JITEventListener
*L
) {
642 std::lock_guard
<sys::Mutex
> locked(lock
);
643 auto I
= find(reverse(EventListeners
), L
);
644 if (I
!= EventListeners
.rend()) {
645 std::swap(*I
, EventListeners
.back());
646 EventListeners
.pop_back();
650 void MCJIT::notifyObjectLoaded(const object::ObjectFile
&Obj
,
651 const RuntimeDyld::LoadedObjectInfo
&L
) {
653 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj
.getData().data()));
654 std::lock_guard
<sys::Mutex
> locked(lock
);
655 MemMgr
->notifyObjectLoaded(this, Obj
);
656 for (unsigned I
= 0, S
= EventListeners
.size(); I
< S
; ++I
) {
657 EventListeners
[I
]->notifyObjectLoaded(Key
, Obj
, L
);
661 void MCJIT::notifyFreeingObject(const object::ObjectFile
&Obj
) {
663 static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj
.getData().data()));
664 std::lock_guard
<sys::Mutex
> locked(lock
);
665 for (JITEventListener
*L
: EventListeners
)
666 L
->notifyFreeingObject(Key
);
670 LinkingSymbolResolver::findSymbol(const std::string
&Name
) {
671 auto Result
= ParentEngine
.findSymbol(Name
, false);
674 if (ParentEngine
.isSymbolSearchingDisabled())
676 return ClientResolver
->findSymbol(Name
);
679 void LinkingSymbolResolver::anchor() {}