xref: /freebsd/contrib/llvm-project/llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric 
9*0b57cec5SDimitry Andric #include "MCJIT.h"
10*0b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
11*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/GenericValue.h"
12*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/JITEventListener.h"
13*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/MCJIT.h"
14*0b57cec5SDimitry Andric #include "llvm/ExecutionEngine/SectionMemoryManager.h"
15*0b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
16*0b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h"
17*0b57cec5SDimitry Andric #include "llvm/IR/Function.h"
18*0b57cec5SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
19*0b57cec5SDimitry Andric #include "llvm/IR/Mangler.h"
20*0b57cec5SDimitry Andric #include "llvm/IR/Module.h"
21*0b57cec5SDimitry Andric #include "llvm/Object/Archive.h"
22*0b57cec5SDimitry Andric #include "llvm/Object/ObjectFile.h"
23*0b57cec5SDimitry Andric #include "llvm/Support/DynamicLibrary.h"
24*0b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
25*0b57cec5SDimitry Andric #include "llvm/Support/MemoryBuffer.h"
26*0b57cec5SDimitry Andric #include "llvm/Support/MutexGuard.h"
27*0b57cec5SDimitry Andric 
28*0b57cec5SDimitry Andric using namespace llvm;
29*0b57cec5SDimitry Andric 
30*0b57cec5SDimitry Andric namespace {
31*0b57cec5SDimitry Andric 
32*0b57cec5SDimitry Andric static struct RegisterJIT {
33*0b57cec5SDimitry Andric   RegisterJIT() { MCJIT::Register(); }
34*0b57cec5SDimitry Andric } JITRegistrator;
35*0b57cec5SDimitry Andric 
36*0b57cec5SDimitry Andric }
37*0b57cec5SDimitry Andric 
38*0b57cec5SDimitry Andric extern "C" void LLVMLinkInMCJIT() {
39*0b57cec5SDimitry Andric }
40*0b57cec5SDimitry Andric 
41*0b57cec5SDimitry Andric ExecutionEngine *
42*0b57cec5SDimitry Andric MCJIT::createJIT(std::unique_ptr<Module> M, std::string *ErrorStr,
43*0b57cec5SDimitry Andric                  std::shared_ptr<MCJITMemoryManager> MemMgr,
44*0b57cec5SDimitry Andric                  std::shared_ptr<LegacyJITSymbolResolver> Resolver,
45*0b57cec5SDimitry Andric                  std::unique_ptr<TargetMachine> TM) {
46*0b57cec5SDimitry Andric   // Try to register the program as a source of symbols to resolve against.
47*0b57cec5SDimitry Andric   //
48*0b57cec5SDimitry Andric   // FIXME: Don't do this here.
49*0b57cec5SDimitry Andric   sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
50*0b57cec5SDimitry Andric 
51*0b57cec5SDimitry Andric   if (!MemMgr || !Resolver) {
52*0b57cec5SDimitry Andric     auto RTDyldMM = std::make_shared<SectionMemoryManager>();
53*0b57cec5SDimitry Andric     if (!MemMgr)
54*0b57cec5SDimitry Andric       MemMgr = RTDyldMM;
55*0b57cec5SDimitry Andric     if (!Resolver)
56*0b57cec5SDimitry Andric       Resolver = RTDyldMM;
57*0b57cec5SDimitry Andric   }
58*0b57cec5SDimitry Andric 
59*0b57cec5SDimitry Andric   return new MCJIT(std::move(M), std::move(TM), std::move(MemMgr),
60*0b57cec5SDimitry Andric                    std::move(Resolver));
61*0b57cec5SDimitry Andric }
62*0b57cec5SDimitry Andric 
63*0b57cec5SDimitry Andric MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> TM,
64*0b57cec5SDimitry Andric              std::shared_ptr<MCJITMemoryManager> MemMgr,
65*0b57cec5SDimitry Andric              std::shared_ptr<LegacyJITSymbolResolver> Resolver)
66*0b57cec5SDimitry Andric     : ExecutionEngine(TM->createDataLayout(), std::move(M)), TM(std::move(TM)),
67*0b57cec5SDimitry Andric       Ctx(nullptr), MemMgr(std::move(MemMgr)),
68*0b57cec5SDimitry Andric       Resolver(*this, std::move(Resolver)), Dyld(*this->MemMgr, this->Resolver),
69*0b57cec5SDimitry Andric       ObjCache(nullptr) {
70*0b57cec5SDimitry Andric   // FIXME: We are managing our modules, so we do not want the base class
71*0b57cec5SDimitry Andric   // ExecutionEngine to manage them as well. To avoid double destruction
72*0b57cec5SDimitry Andric   // of the first (and only) module added in ExecutionEngine constructor
73*0b57cec5SDimitry Andric   // we remove it from EE and will destruct it ourselves.
74*0b57cec5SDimitry Andric   //
75*0b57cec5SDimitry Andric   // It may make sense to move our module manager (based on SmallStPtr) back
76*0b57cec5SDimitry Andric   // into EE if the JIT and Interpreter can live with it.
77*0b57cec5SDimitry Andric   // If so, additional functions: addModule, removeModule, FindFunctionNamed,
78*0b57cec5SDimitry Andric   // runStaticConstructorsDestructors could be moved back to EE as well.
79*0b57cec5SDimitry Andric   //
80*0b57cec5SDimitry Andric   std::unique_ptr<Module> First = std::move(Modules[0]);
81*0b57cec5SDimitry Andric   Modules.clear();
82*0b57cec5SDimitry Andric 
83*0b57cec5SDimitry Andric   if (First->getDataLayout().isDefault())
84*0b57cec5SDimitry Andric     First->setDataLayout(getDataLayout());
85*0b57cec5SDimitry Andric 
86*0b57cec5SDimitry Andric   OwnedModules.addModule(std::move(First));
87*0b57cec5SDimitry Andric   RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
88*0b57cec5SDimitry Andric }
89*0b57cec5SDimitry Andric 
90*0b57cec5SDimitry Andric MCJIT::~MCJIT() {
91*0b57cec5SDimitry Andric   MutexGuard locked(lock);
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric   Dyld.deregisterEHFrames();
94*0b57cec5SDimitry Andric 
95*0b57cec5SDimitry Andric   for (auto &Obj : LoadedObjects)
96*0b57cec5SDimitry Andric     if (Obj)
97*0b57cec5SDimitry Andric       notifyFreeingObject(*Obj);
98*0b57cec5SDimitry Andric 
99*0b57cec5SDimitry Andric   Archives.clear();
100*0b57cec5SDimitry Andric }
101*0b57cec5SDimitry Andric 
102*0b57cec5SDimitry Andric void MCJIT::addModule(std::unique_ptr<Module> M) {
103*0b57cec5SDimitry Andric   MutexGuard locked(lock);
104*0b57cec5SDimitry Andric 
105*0b57cec5SDimitry Andric   if (M->getDataLayout().isDefault())
106*0b57cec5SDimitry Andric     M->setDataLayout(getDataLayout());
107*0b57cec5SDimitry Andric 
108*0b57cec5SDimitry Andric   OwnedModules.addModule(std::move(M));
109*0b57cec5SDimitry Andric }
110*0b57cec5SDimitry Andric 
111*0b57cec5SDimitry Andric bool MCJIT::removeModule(Module *M) {
112*0b57cec5SDimitry Andric   MutexGuard locked(lock);
113*0b57cec5SDimitry Andric   return OwnedModules.removeModule(M);
114*0b57cec5SDimitry Andric }
115*0b57cec5SDimitry Andric 
116*0b57cec5SDimitry Andric void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) {
117*0b57cec5SDimitry Andric   std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L = Dyld.loadObject(*Obj);
118*0b57cec5SDimitry Andric   if (Dyld.hasError())
119*0b57cec5SDimitry Andric     report_fatal_error(Dyld.getErrorString());
120*0b57cec5SDimitry Andric 
121*0b57cec5SDimitry Andric   notifyObjectLoaded(*Obj, *L);
122*0b57cec5SDimitry Andric 
123*0b57cec5SDimitry Andric   LoadedObjects.push_back(std::move(Obj));
124*0b57cec5SDimitry Andric }
125*0b57cec5SDimitry Andric 
126*0b57cec5SDimitry Andric void MCJIT::addObjectFile(object::OwningBinary<object::ObjectFile> Obj) {
127*0b57cec5SDimitry Andric   std::unique_ptr<object::ObjectFile> ObjFile;
128*0b57cec5SDimitry Andric   std::unique_ptr<MemoryBuffer> MemBuf;
129*0b57cec5SDimitry Andric   std::tie(ObjFile, MemBuf) = Obj.takeBinary();
130*0b57cec5SDimitry Andric   addObjectFile(std::move(ObjFile));
131*0b57cec5SDimitry Andric   Buffers.push_back(std::move(MemBuf));
132*0b57cec5SDimitry Andric }
133*0b57cec5SDimitry Andric 
134*0b57cec5SDimitry Andric void MCJIT::addArchive(object::OwningBinary<object::Archive> A) {
135*0b57cec5SDimitry Andric   Archives.push_back(std::move(A));
136*0b57cec5SDimitry Andric }
137*0b57cec5SDimitry Andric 
138*0b57cec5SDimitry Andric void MCJIT::setObjectCache(ObjectCache* NewCache) {
139*0b57cec5SDimitry Andric   MutexGuard locked(lock);
140*0b57cec5SDimitry Andric   ObjCache = NewCache;
141*0b57cec5SDimitry Andric }
142*0b57cec5SDimitry Andric 
143*0b57cec5SDimitry Andric std::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
144*0b57cec5SDimitry Andric   assert(M && "Can not emit a null module");
145*0b57cec5SDimitry Andric 
146*0b57cec5SDimitry Andric   MutexGuard locked(lock);
147*0b57cec5SDimitry Andric 
148*0b57cec5SDimitry Andric   // Materialize all globals in the module if they have not been
149*0b57cec5SDimitry Andric   // materialized already.
150*0b57cec5SDimitry Andric   cantFail(M->materializeAll());
151*0b57cec5SDimitry Andric 
152*0b57cec5SDimitry Andric   // This must be a module which has already been added but not loaded to this
153*0b57cec5SDimitry Andric   // MCJIT instance, since these conditions are tested by our caller,
154*0b57cec5SDimitry Andric   // generateCodeForModule.
155*0b57cec5SDimitry Andric 
156*0b57cec5SDimitry Andric   legacy::PassManager PM;
157*0b57cec5SDimitry Andric 
158*0b57cec5SDimitry Andric   // The RuntimeDyld will take ownership of this shortly
159*0b57cec5SDimitry Andric   SmallVector<char, 4096> ObjBufferSV;
160*0b57cec5SDimitry Andric   raw_svector_ostream ObjStream(ObjBufferSV);
161*0b57cec5SDimitry Andric 
162*0b57cec5SDimitry Andric   // Turn the machine code intermediate representation into bytes in memory
163*0b57cec5SDimitry Andric   // that may be executed.
164*0b57cec5SDimitry Andric   if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !getVerifyModules()))
165*0b57cec5SDimitry Andric     report_fatal_error("Target does not support MC emission!");
166*0b57cec5SDimitry Andric 
167*0b57cec5SDimitry Andric   // Initialize passes.
168*0b57cec5SDimitry Andric   PM.run(*M);
169*0b57cec5SDimitry Andric   // Flush the output buffer to get the generated code into memory
170*0b57cec5SDimitry Andric 
171*0b57cec5SDimitry Andric   std::unique_ptr<MemoryBuffer> CompiledObjBuffer(
172*0b57cec5SDimitry Andric       new SmallVectorMemoryBuffer(std::move(ObjBufferSV)));
173*0b57cec5SDimitry Andric 
174*0b57cec5SDimitry Andric   // If we have an object cache, tell it about the new object.
175*0b57cec5SDimitry Andric   // Note that we're using the compiled image, not the loaded image (as below).
176*0b57cec5SDimitry Andric   if (ObjCache) {
177*0b57cec5SDimitry Andric     // MemoryBuffer is a thin wrapper around the actual memory, so it's OK
178*0b57cec5SDimitry Andric     // to create a temporary object here and delete it after the call.
179*0b57cec5SDimitry Andric     MemoryBufferRef MB = CompiledObjBuffer->getMemBufferRef();
180*0b57cec5SDimitry Andric     ObjCache->notifyObjectCompiled(M, MB);
181*0b57cec5SDimitry Andric   }
182*0b57cec5SDimitry Andric 
183*0b57cec5SDimitry Andric   return CompiledObjBuffer;
184*0b57cec5SDimitry Andric }
185*0b57cec5SDimitry Andric 
186*0b57cec5SDimitry Andric void MCJIT::generateCodeForModule(Module *M) {
187*0b57cec5SDimitry Andric   // Get a thread lock to make sure we aren't trying to load multiple times
188*0b57cec5SDimitry Andric   MutexGuard locked(lock);
189*0b57cec5SDimitry Andric 
190*0b57cec5SDimitry Andric   // This must be a module which has already been added to this MCJIT instance.
191*0b57cec5SDimitry Andric   assert(OwnedModules.ownsModule(M) &&
192*0b57cec5SDimitry Andric          "MCJIT::generateCodeForModule: Unknown module.");
193*0b57cec5SDimitry Andric 
194*0b57cec5SDimitry Andric   // Re-compilation is not supported
195*0b57cec5SDimitry Andric   if (OwnedModules.hasModuleBeenLoaded(M))
196*0b57cec5SDimitry Andric     return;
197*0b57cec5SDimitry Andric 
198*0b57cec5SDimitry Andric   std::unique_ptr<MemoryBuffer> ObjectToLoad;
199*0b57cec5SDimitry Andric   // Try to load the pre-compiled object from cache if possible
200*0b57cec5SDimitry Andric   if (ObjCache)
201*0b57cec5SDimitry Andric     ObjectToLoad = ObjCache->getObject(M);
202*0b57cec5SDimitry Andric 
203*0b57cec5SDimitry Andric   assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch");
204*0b57cec5SDimitry Andric 
205*0b57cec5SDimitry Andric   // If the cache did not contain a suitable object, compile the object
206*0b57cec5SDimitry Andric   if (!ObjectToLoad) {
207*0b57cec5SDimitry Andric     ObjectToLoad = emitObject(M);
208*0b57cec5SDimitry Andric     assert(ObjectToLoad && "Compilation did not produce an object.");
209*0b57cec5SDimitry Andric   }
210*0b57cec5SDimitry Andric 
211*0b57cec5SDimitry Andric   // Load the object into the dynamic linker.
212*0b57cec5SDimitry Andric   // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list).
213*0b57cec5SDimitry Andric   Expected<std::unique_ptr<object::ObjectFile>> LoadedObject =
214*0b57cec5SDimitry Andric     object::ObjectFile::createObjectFile(ObjectToLoad->getMemBufferRef());
215*0b57cec5SDimitry Andric   if (!LoadedObject) {
216*0b57cec5SDimitry Andric     std::string Buf;
217*0b57cec5SDimitry Andric     raw_string_ostream OS(Buf);
218*0b57cec5SDimitry Andric     logAllUnhandledErrors(LoadedObject.takeError(), OS);
219*0b57cec5SDimitry Andric     OS.flush();
220*0b57cec5SDimitry Andric     report_fatal_error(Buf);
221*0b57cec5SDimitry Andric   }
222*0b57cec5SDimitry Andric   std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L =
223*0b57cec5SDimitry Andric     Dyld.loadObject(*LoadedObject.get());
224*0b57cec5SDimitry Andric 
225*0b57cec5SDimitry Andric   if (Dyld.hasError())
226*0b57cec5SDimitry Andric     report_fatal_error(Dyld.getErrorString());
227*0b57cec5SDimitry Andric 
228*0b57cec5SDimitry Andric   notifyObjectLoaded(*LoadedObject.get(), *L);
229*0b57cec5SDimitry Andric 
230*0b57cec5SDimitry Andric   Buffers.push_back(std::move(ObjectToLoad));
231*0b57cec5SDimitry Andric   LoadedObjects.push_back(std::move(*LoadedObject));
232*0b57cec5SDimitry Andric 
233*0b57cec5SDimitry Andric   OwnedModules.markModuleAsLoaded(M);
234*0b57cec5SDimitry Andric }
235*0b57cec5SDimitry Andric 
236*0b57cec5SDimitry Andric void MCJIT::finalizeLoadedModules() {
237*0b57cec5SDimitry Andric   MutexGuard locked(lock);
238*0b57cec5SDimitry Andric 
239*0b57cec5SDimitry Andric   // Resolve any outstanding relocations.
240*0b57cec5SDimitry Andric   Dyld.resolveRelocations();
241*0b57cec5SDimitry Andric 
242*0b57cec5SDimitry Andric   OwnedModules.markAllLoadedModulesAsFinalized();
243*0b57cec5SDimitry Andric 
244*0b57cec5SDimitry Andric   // Register EH frame data for any module we own which has been loaded
245*0b57cec5SDimitry Andric   Dyld.registerEHFrames();
246*0b57cec5SDimitry Andric 
247*0b57cec5SDimitry Andric   // Set page permissions.
248*0b57cec5SDimitry Andric   MemMgr->finalizeMemory();
249*0b57cec5SDimitry Andric }
250*0b57cec5SDimitry Andric 
251*0b57cec5SDimitry Andric // FIXME: Rename this.
252*0b57cec5SDimitry Andric void MCJIT::finalizeObject() {
253*0b57cec5SDimitry Andric   MutexGuard locked(lock);
254*0b57cec5SDimitry Andric 
255*0b57cec5SDimitry Andric   // Generate code for module is going to move objects out of the 'added' list,
256*0b57cec5SDimitry Andric   // so we need to copy that out before using it:
257*0b57cec5SDimitry Andric   SmallVector<Module*, 16> ModsToAdd;
258*0b57cec5SDimitry Andric   for (auto M : OwnedModules.added())
259*0b57cec5SDimitry Andric     ModsToAdd.push_back(M);
260*0b57cec5SDimitry Andric 
261*0b57cec5SDimitry Andric   for (auto M : ModsToAdd)
262*0b57cec5SDimitry Andric     generateCodeForModule(M);
263*0b57cec5SDimitry Andric 
264*0b57cec5SDimitry Andric   finalizeLoadedModules();
265*0b57cec5SDimitry Andric }
266*0b57cec5SDimitry Andric 
267*0b57cec5SDimitry Andric void MCJIT::finalizeModule(Module *M) {
268*0b57cec5SDimitry Andric   MutexGuard locked(lock);
269*0b57cec5SDimitry Andric 
270*0b57cec5SDimitry Andric   // This must be a module which has already been added to this MCJIT instance.
271*0b57cec5SDimitry Andric   assert(OwnedModules.ownsModule(M) && "MCJIT::finalizeModule: Unknown module.");
272*0b57cec5SDimitry Andric 
273*0b57cec5SDimitry Andric   // If the module hasn't been compiled, just do that.
274*0b57cec5SDimitry Andric   if (!OwnedModules.hasModuleBeenLoaded(M))
275*0b57cec5SDimitry Andric     generateCodeForModule(M);
276*0b57cec5SDimitry Andric 
277*0b57cec5SDimitry Andric   finalizeLoadedModules();
278*0b57cec5SDimitry Andric }
279*0b57cec5SDimitry Andric 
280*0b57cec5SDimitry Andric JITSymbol MCJIT::findExistingSymbol(const std::string &Name) {
281*0b57cec5SDimitry Andric   if (void *Addr = getPointerToGlobalIfAvailable(Name))
282*0b57cec5SDimitry Andric     return JITSymbol(static_cast<uint64_t>(
283*0b57cec5SDimitry Andric                          reinterpret_cast<uintptr_t>(Addr)),
284*0b57cec5SDimitry Andric                      JITSymbolFlags::Exported);
285*0b57cec5SDimitry Andric 
286*0b57cec5SDimitry Andric   return Dyld.getSymbol(Name);
287*0b57cec5SDimitry Andric }
288*0b57cec5SDimitry Andric 
289*0b57cec5SDimitry Andric Module *MCJIT::findModuleForSymbol(const std::string &Name,
290*0b57cec5SDimitry Andric                                    bool CheckFunctionsOnly) {
291*0b57cec5SDimitry Andric   StringRef DemangledName = Name;
292*0b57cec5SDimitry Andric   if (DemangledName[0] == getDataLayout().getGlobalPrefix())
293*0b57cec5SDimitry Andric     DemangledName = DemangledName.substr(1);
294*0b57cec5SDimitry Andric 
295*0b57cec5SDimitry Andric   MutexGuard locked(lock);
296*0b57cec5SDimitry Andric 
297*0b57cec5SDimitry Andric   // If it hasn't already been generated, see if it's in one of our modules.
298*0b57cec5SDimitry Andric   for (ModulePtrSet::iterator I = OwnedModules.begin_added(),
299*0b57cec5SDimitry Andric                               E = OwnedModules.end_added();
300*0b57cec5SDimitry Andric        I != E; ++I) {
301*0b57cec5SDimitry Andric     Module *M = *I;
302*0b57cec5SDimitry Andric     Function *F = M->getFunction(DemangledName);
303*0b57cec5SDimitry Andric     if (F && !F->isDeclaration())
304*0b57cec5SDimitry Andric       return M;
305*0b57cec5SDimitry Andric     if (!CheckFunctionsOnly) {
306*0b57cec5SDimitry Andric       GlobalVariable *G = M->getGlobalVariable(DemangledName);
307*0b57cec5SDimitry Andric       if (G && !G->isDeclaration())
308*0b57cec5SDimitry Andric         return M;
309*0b57cec5SDimitry Andric       // FIXME: Do we need to worry about global aliases?
310*0b57cec5SDimitry Andric     }
311*0b57cec5SDimitry Andric   }
312*0b57cec5SDimitry Andric   // We didn't find the symbol in any of our modules.
313*0b57cec5SDimitry Andric   return nullptr;
314*0b57cec5SDimitry Andric }
315*0b57cec5SDimitry Andric 
316*0b57cec5SDimitry Andric uint64_t MCJIT::getSymbolAddress(const std::string &Name,
317*0b57cec5SDimitry Andric                                  bool CheckFunctionsOnly) {
318*0b57cec5SDimitry Andric   std::string MangledName;
319*0b57cec5SDimitry Andric   {
320*0b57cec5SDimitry Andric     raw_string_ostream MangledNameStream(MangledName);
321*0b57cec5SDimitry Andric     Mangler::getNameWithPrefix(MangledNameStream, Name, getDataLayout());
322*0b57cec5SDimitry Andric   }
323*0b57cec5SDimitry Andric   if (auto Sym = findSymbol(MangledName, CheckFunctionsOnly)) {
324*0b57cec5SDimitry Andric     if (auto AddrOrErr = Sym.getAddress())
325*0b57cec5SDimitry Andric       return *AddrOrErr;
326*0b57cec5SDimitry Andric     else
327*0b57cec5SDimitry Andric       report_fatal_error(AddrOrErr.takeError());
328*0b57cec5SDimitry Andric   } else if (auto Err = Sym.takeError())
329*0b57cec5SDimitry Andric     report_fatal_error(Sym.takeError());
330*0b57cec5SDimitry Andric   return 0;
331*0b57cec5SDimitry Andric }
332*0b57cec5SDimitry Andric 
333*0b57cec5SDimitry Andric JITSymbol MCJIT::findSymbol(const std::string &Name,
334*0b57cec5SDimitry Andric                             bool CheckFunctionsOnly) {
335*0b57cec5SDimitry Andric   MutexGuard locked(lock);
336*0b57cec5SDimitry Andric 
337*0b57cec5SDimitry Andric   // First, check to see if we already have this symbol.
338*0b57cec5SDimitry Andric   if (auto Sym = findExistingSymbol(Name))
339*0b57cec5SDimitry Andric     return Sym;
340*0b57cec5SDimitry Andric 
341*0b57cec5SDimitry Andric   for (object::OwningBinary<object::Archive> &OB : Archives) {
342*0b57cec5SDimitry Andric     object::Archive *A = OB.getBinary();
343*0b57cec5SDimitry Andric     // Look for our symbols in each Archive
344*0b57cec5SDimitry Andric     auto OptionalChildOrErr = A->findSym(Name);
345*0b57cec5SDimitry Andric     if (!OptionalChildOrErr)
346*0b57cec5SDimitry Andric       report_fatal_error(OptionalChildOrErr.takeError());
347*0b57cec5SDimitry Andric     auto &OptionalChild = *OptionalChildOrErr;
348*0b57cec5SDimitry Andric     if (OptionalChild) {
349*0b57cec5SDimitry Andric       // FIXME: Support nested archives?
350*0b57cec5SDimitry Andric       Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
351*0b57cec5SDimitry Andric           OptionalChild->getAsBinary();
352*0b57cec5SDimitry Andric       if (!ChildBinOrErr) {
353*0b57cec5SDimitry Andric         // TODO: Actually report errors helpfully.
354*0b57cec5SDimitry Andric         consumeError(ChildBinOrErr.takeError());
355*0b57cec5SDimitry Andric         continue;
356*0b57cec5SDimitry Andric       }
357*0b57cec5SDimitry Andric       std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
358*0b57cec5SDimitry Andric       if (ChildBin->isObject()) {
359*0b57cec5SDimitry Andric         std::unique_ptr<object::ObjectFile> OF(
360*0b57cec5SDimitry Andric             static_cast<object::ObjectFile *>(ChildBin.release()));
361*0b57cec5SDimitry Andric         // This causes the object file to be loaded.
362*0b57cec5SDimitry Andric         addObjectFile(std::move(OF));
363*0b57cec5SDimitry Andric         // The address should be here now.
364*0b57cec5SDimitry Andric         if (auto Sym = findExistingSymbol(Name))
365*0b57cec5SDimitry Andric           return Sym;
366*0b57cec5SDimitry Andric       }
367*0b57cec5SDimitry Andric     }
368*0b57cec5SDimitry Andric   }
369*0b57cec5SDimitry Andric 
370*0b57cec5SDimitry Andric   // If it hasn't already been generated, see if it's in one of our modules.
371*0b57cec5SDimitry Andric   Module *M = findModuleForSymbol(Name, CheckFunctionsOnly);
372*0b57cec5SDimitry Andric   if (M) {
373*0b57cec5SDimitry Andric     generateCodeForModule(M);
374*0b57cec5SDimitry Andric 
375*0b57cec5SDimitry Andric     // Check the RuntimeDyld table again, it should be there now.
376*0b57cec5SDimitry Andric     return findExistingSymbol(Name);
377*0b57cec5SDimitry Andric   }
378*0b57cec5SDimitry Andric 
379*0b57cec5SDimitry Andric   // If a LazyFunctionCreator is installed, use it to get/create the function.
380*0b57cec5SDimitry Andric   // FIXME: Should we instead have a LazySymbolCreator callback?
381*0b57cec5SDimitry Andric   if (LazyFunctionCreator) {
382*0b57cec5SDimitry Andric     auto Addr = static_cast<uint64_t>(
383*0b57cec5SDimitry Andric                   reinterpret_cast<uintptr_t>(LazyFunctionCreator(Name)));
384*0b57cec5SDimitry Andric     return JITSymbol(Addr, JITSymbolFlags::Exported);
385*0b57cec5SDimitry Andric   }
386*0b57cec5SDimitry Andric 
387*0b57cec5SDimitry Andric   return nullptr;
388*0b57cec5SDimitry Andric }
389*0b57cec5SDimitry Andric 
390*0b57cec5SDimitry Andric uint64_t MCJIT::getGlobalValueAddress(const std::string &Name) {
391*0b57cec5SDimitry Andric   MutexGuard locked(lock);
392*0b57cec5SDimitry Andric   uint64_t Result = getSymbolAddress(Name, false);
393*0b57cec5SDimitry Andric   if (Result != 0)
394*0b57cec5SDimitry Andric     finalizeLoadedModules();
395*0b57cec5SDimitry Andric   return Result;
396*0b57cec5SDimitry Andric }
397*0b57cec5SDimitry Andric 
398*0b57cec5SDimitry Andric uint64_t MCJIT::getFunctionAddress(const std::string &Name) {
399*0b57cec5SDimitry Andric   MutexGuard locked(lock);
400*0b57cec5SDimitry Andric   uint64_t Result = getSymbolAddress(Name, true);
401*0b57cec5SDimitry Andric   if (Result != 0)
402*0b57cec5SDimitry Andric     finalizeLoadedModules();
403*0b57cec5SDimitry Andric   return Result;
404*0b57cec5SDimitry Andric }
405*0b57cec5SDimitry Andric 
406*0b57cec5SDimitry Andric // Deprecated.  Use getFunctionAddress instead.
407*0b57cec5SDimitry Andric void *MCJIT::getPointerToFunction(Function *F) {
408*0b57cec5SDimitry Andric   MutexGuard locked(lock);
409*0b57cec5SDimitry Andric 
410*0b57cec5SDimitry Andric   Mangler Mang;
411*0b57cec5SDimitry Andric   SmallString<128> Name;
412*0b57cec5SDimitry Andric   TM->getNameWithPrefix(Name, F, Mang);
413*0b57cec5SDimitry Andric 
414*0b57cec5SDimitry Andric   if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
415*0b57cec5SDimitry Andric     bool AbortOnFailure = !F->hasExternalWeakLinkage();
416*0b57cec5SDimitry Andric     void *Addr = getPointerToNamedFunction(Name, AbortOnFailure);
417*0b57cec5SDimitry Andric     updateGlobalMapping(F, Addr);
418*0b57cec5SDimitry Andric     return Addr;
419*0b57cec5SDimitry Andric   }
420*0b57cec5SDimitry Andric 
421*0b57cec5SDimitry Andric   Module *M = F->getParent();
422*0b57cec5SDimitry Andric   bool HasBeenAddedButNotLoaded = OwnedModules.hasModuleBeenAddedButNotLoaded(M);
423*0b57cec5SDimitry Andric 
424*0b57cec5SDimitry Andric   // Make sure the relevant module has been compiled and loaded.
425*0b57cec5SDimitry Andric   if (HasBeenAddedButNotLoaded)
426*0b57cec5SDimitry Andric     generateCodeForModule(M);
427*0b57cec5SDimitry Andric   else if (!OwnedModules.hasModuleBeenLoaded(M)) {
428*0b57cec5SDimitry Andric     // If this function doesn't belong to one of our modules, we're done.
429*0b57cec5SDimitry Andric     // FIXME: Asking for the pointer to a function that hasn't been registered,
430*0b57cec5SDimitry Andric     //        and isn't a declaration (which is handled above) should probably
431*0b57cec5SDimitry Andric     //        be an assertion.
432*0b57cec5SDimitry Andric     return nullptr;
433*0b57cec5SDimitry Andric   }
434*0b57cec5SDimitry Andric 
435*0b57cec5SDimitry Andric   // FIXME: Should the Dyld be retaining module information? Probably not.
436*0b57cec5SDimitry Andric   //
437*0b57cec5SDimitry Andric   // This is the accessor for the target address, so make sure to check the
438*0b57cec5SDimitry Andric   // load address of the symbol, not the local address.
439*0b57cec5SDimitry Andric   return (void*)Dyld.getSymbol(Name).getAddress();
440*0b57cec5SDimitry Andric }
441*0b57cec5SDimitry Andric 
442*0b57cec5SDimitry Andric void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
443*0b57cec5SDimitry Andric     bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) {
444*0b57cec5SDimitry Andric   for (; I != E; ++I) {
445*0b57cec5SDimitry Andric     ExecutionEngine::runStaticConstructorsDestructors(**I, isDtors);
446*0b57cec5SDimitry Andric   }
447*0b57cec5SDimitry Andric }
448*0b57cec5SDimitry Andric 
449*0b57cec5SDimitry Andric void MCJIT::runStaticConstructorsDestructors(bool isDtors) {
450*0b57cec5SDimitry Andric   // Execute global ctors/dtors for each module in the program.
451*0b57cec5SDimitry Andric   runStaticConstructorsDestructorsInModulePtrSet(
452*0b57cec5SDimitry Andric       isDtors, OwnedModules.begin_added(), OwnedModules.end_added());
453*0b57cec5SDimitry Andric   runStaticConstructorsDestructorsInModulePtrSet(
454*0b57cec5SDimitry Andric       isDtors, OwnedModules.begin_loaded(), OwnedModules.end_loaded());
455*0b57cec5SDimitry Andric   runStaticConstructorsDestructorsInModulePtrSet(
456*0b57cec5SDimitry Andric       isDtors, OwnedModules.begin_finalized(), OwnedModules.end_finalized());
457*0b57cec5SDimitry Andric }
458*0b57cec5SDimitry Andric 
459*0b57cec5SDimitry Andric Function *MCJIT::FindFunctionNamedInModulePtrSet(StringRef FnName,
460*0b57cec5SDimitry Andric                                                  ModulePtrSet::iterator I,
461*0b57cec5SDimitry Andric                                                  ModulePtrSet::iterator E) {
462*0b57cec5SDimitry Andric   for (; I != E; ++I) {
463*0b57cec5SDimitry Andric     Function *F = (*I)->getFunction(FnName);
464*0b57cec5SDimitry Andric     if (F && !F->isDeclaration())
465*0b57cec5SDimitry Andric       return F;
466*0b57cec5SDimitry Andric   }
467*0b57cec5SDimitry Andric   return nullptr;
468*0b57cec5SDimitry Andric }
469*0b57cec5SDimitry Andric 
470*0b57cec5SDimitry Andric GlobalVariable *MCJIT::FindGlobalVariableNamedInModulePtrSet(StringRef Name,
471*0b57cec5SDimitry Andric                                                              bool AllowInternal,
472*0b57cec5SDimitry Andric                                                              ModulePtrSet::iterator I,
473*0b57cec5SDimitry Andric                                                              ModulePtrSet::iterator E) {
474*0b57cec5SDimitry Andric   for (; I != E; ++I) {
475*0b57cec5SDimitry Andric     GlobalVariable *GV = (*I)->getGlobalVariable(Name, AllowInternal);
476*0b57cec5SDimitry Andric     if (GV && !GV->isDeclaration())
477*0b57cec5SDimitry Andric       return GV;
478*0b57cec5SDimitry Andric   }
479*0b57cec5SDimitry Andric   return nullptr;
480*0b57cec5SDimitry Andric }
481*0b57cec5SDimitry Andric 
482*0b57cec5SDimitry Andric 
483*0b57cec5SDimitry Andric Function *MCJIT::FindFunctionNamed(StringRef FnName) {
484*0b57cec5SDimitry Andric   Function *F = FindFunctionNamedInModulePtrSet(
485*0b57cec5SDimitry Andric       FnName, OwnedModules.begin_added(), OwnedModules.end_added());
486*0b57cec5SDimitry Andric   if (!F)
487*0b57cec5SDimitry Andric     F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_loaded(),
488*0b57cec5SDimitry Andric                                         OwnedModules.end_loaded());
489*0b57cec5SDimitry Andric   if (!F)
490*0b57cec5SDimitry Andric     F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_finalized(),
491*0b57cec5SDimitry Andric                                         OwnedModules.end_finalized());
492*0b57cec5SDimitry Andric   return F;
493*0b57cec5SDimitry Andric }
494*0b57cec5SDimitry Andric 
495*0b57cec5SDimitry Andric GlobalVariable *MCJIT::FindGlobalVariableNamed(StringRef Name, bool AllowInternal) {
496*0b57cec5SDimitry Andric   GlobalVariable *GV = FindGlobalVariableNamedInModulePtrSet(
497*0b57cec5SDimitry Andric       Name, AllowInternal, OwnedModules.begin_added(), OwnedModules.end_added());
498*0b57cec5SDimitry Andric   if (!GV)
499*0b57cec5SDimitry Andric     GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_loaded(),
500*0b57cec5SDimitry Andric                                         OwnedModules.end_loaded());
501*0b57cec5SDimitry Andric   if (!GV)
502*0b57cec5SDimitry Andric     GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_finalized(),
503*0b57cec5SDimitry Andric                                         OwnedModules.end_finalized());
504*0b57cec5SDimitry Andric   return GV;
505*0b57cec5SDimitry Andric }
506*0b57cec5SDimitry Andric 
507*0b57cec5SDimitry Andric GenericValue MCJIT::runFunction(Function *F, ArrayRef<GenericValue> ArgValues) {
508*0b57cec5SDimitry Andric   assert(F && "Function *F was null at entry to run()");
509*0b57cec5SDimitry Andric 
510*0b57cec5SDimitry Andric   void *FPtr = getPointerToFunction(F);
511*0b57cec5SDimitry Andric   finalizeModule(F->getParent());
512*0b57cec5SDimitry Andric   assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
513*0b57cec5SDimitry Andric   FunctionType *FTy = F->getFunctionType();
514*0b57cec5SDimitry Andric   Type *RetTy = FTy->getReturnType();
515*0b57cec5SDimitry Andric 
516*0b57cec5SDimitry Andric   assert((FTy->getNumParams() == ArgValues.size() ||
517*0b57cec5SDimitry Andric           (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
518*0b57cec5SDimitry Andric          "Wrong number of arguments passed into function!");
519*0b57cec5SDimitry Andric   assert(FTy->getNumParams() == ArgValues.size() &&
520*0b57cec5SDimitry Andric          "This doesn't support passing arguments through varargs (yet)!");
521*0b57cec5SDimitry Andric 
522*0b57cec5SDimitry Andric   // Handle some common cases first.  These cases correspond to common `main'
523*0b57cec5SDimitry Andric   // prototypes.
524*0b57cec5SDimitry Andric   if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
525*0b57cec5SDimitry Andric     switch (ArgValues.size()) {
526*0b57cec5SDimitry Andric     case 3:
527*0b57cec5SDimitry Andric       if (FTy->getParamType(0)->isIntegerTy(32) &&
528*0b57cec5SDimitry Andric           FTy->getParamType(1)->isPointerTy() &&
529*0b57cec5SDimitry Andric           FTy->getParamType(2)->isPointerTy()) {
530*0b57cec5SDimitry Andric         int (*PF)(int, char **, const char **) =
531*0b57cec5SDimitry Andric           (int(*)(int, char **, const char **))(intptr_t)FPtr;
532*0b57cec5SDimitry Andric 
533*0b57cec5SDimitry Andric         // Call the function.
534*0b57cec5SDimitry Andric         GenericValue rv;
535*0b57cec5SDimitry Andric         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
536*0b57cec5SDimitry Andric                                  (char **)GVTOP(ArgValues[1]),
537*0b57cec5SDimitry Andric                                  (const char **)GVTOP(ArgValues[2])));
538*0b57cec5SDimitry Andric         return rv;
539*0b57cec5SDimitry Andric       }
540*0b57cec5SDimitry Andric       break;
541*0b57cec5SDimitry Andric     case 2:
542*0b57cec5SDimitry Andric       if (FTy->getParamType(0)->isIntegerTy(32) &&
543*0b57cec5SDimitry Andric           FTy->getParamType(1)->isPointerTy()) {
544*0b57cec5SDimitry Andric         int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
545*0b57cec5SDimitry Andric 
546*0b57cec5SDimitry Andric         // Call the function.
547*0b57cec5SDimitry Andric         GenericValue rv;
548*0b57cec5SDimitry Andric         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
549*0b57cec5SDimitry Andric                                  (char **)GVTOP(ArgValues[1])));
550*0b57cec5SDimitry Andric         return rv;
551*0b57cec5SDimitry Andric       }
552*0b57cec5SDimitry Andric       break;
553*0b57cec5SDimitry Andric     case 1:
554*0b57cec5SDimitry Andric       if (FTy->getNumParams() == 1 &&
555*0b57cec5SDimitry Andric           FTy->getParamType(0)->isIntegerTy(32)) {
556*0b57cec5SDimitry Andric         GenericValue rv;
557*0b57cec5SDimitry Andric         int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
558*0b57cec5SDimitry Andric         rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
559*0b57cec5SDimitry Andric         return rv;
560*0b57cec5SDimitry Andric       }
561*0b57cec5SDimitry Andric       break;
562*0b57cec5SDimitry Andric     }
563*0b57cec5SDimitry Andric   }
564*0b57cec5SDimitry Andric 
565*0b57cec5SDimitry Andric   // Handle cases where no arguments are passed first.
566*0b57cec5SDimitry Andric   if (ArgValues.empty()) {
567*0b57cec5SDimitry Andric     GenericValue rv;
568*0b57cec5SDimitry Andric     switch (RetTy->getTypeID()) {
569*0b57cec5SDimitry Andric     default: llvm_unreachable("Unknown return type for function call!");
570*0b57cec5SDimitry Andric     case Type::IntegerTyID: {
571*0b57cec5SDimitry Andric       unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
572*0b57cec5SDimitry Andric       if (BitWidth == 1)
573*0b57cec5SDimitry Andric         rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)());
574*0b57cec5SDimitry Andric       else if (BitWidth <= 8)
575*0b57cec5SDimitry Andric         rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)());
576*0b57cec5SDimitry Andric       else if (BitWidth <= 16)
577*0b57cec5SDimitry Andric         rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)());
578*0b57cec5SDimitry Andric       else if (BitWidth <= 32)
579*0b57cec5SDimitry Andric         rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)());
580*0b57cec5SDimitry Andric       else if (BitWidth <= 64)
581*0b57cec5SDimitry Andric         rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)());
582*0b57cec5SDimitry Andric       else
583*0b57cec5SDimitry Andric         llvm_unreachable("Integer types > 64 bits not supported");
584*0b57cec5SDimitry Andric       return rv;
585*0b57cec5SDimitry Andric     }
586*0b57cec5SDimitry Andric     case Type::VoidTyID:
587*0b57cec5SDimitry Andric       rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
588*0b57cec5SDimitry Andric       return rv;
589*0b57cec5SDimitry Andric     case Type::FloatTyID:
590*0b57cec5SDimitry Andric       rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
591*0b57cec5SDimitry Andric       return rv;
592*0b57cec5SDimitry Andric     case Type::DoubleTyID:
593*0b57cec5SDimitry Andric       rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
594*0b57cec5SDimitry Andric       return rv;
595*0b57cec5SDimitry Andric     case Type::X86_FP80TyID:
596*0b57cec5SDimitry Andric     case Type::FP128TyID:
597*0b57cec5SDimitry Andric     case Type::PPC_FP128TyID:
598*0b57cec5SDimitry Andric       llvm_unreachable("long double not supported yet");
599*0b57cec5SDimitry Andric     case Type::PointerTyID:
600*0b57cec5SDimitry Andric       return PTOGV(((void*(*)())(intptr_t)FPtr)());
601*0b57cec5SDimitry Andric     }
602*0b57cec5SDimitry Andric   }
603*0b57cec5SDimitry Andric 
604*0b57cec5SDimitry Andric   report_fatal_error("MCJIT::runFunction does not support full-featured "
605*0b57cec5SDimitry Andric                      "argument passing. Please use "
606*0b57cec5SDimitry Andric                      "ExecutionEngine::getFunctionAddress and cast the result "
607*0b57cec5SDimitry Andric                      "to the desired function pointer type.");
608*0b57cec5SDimitry Andric }
609*0b57cec5SDimitry Andric 
610*0b57cec5SDimitry Andric void *MCJIT::getPointerToNamedFunction(StringRef Name, bool AbortOnFailure) {
611*0b57cec5SDimitry Andric   if (!isSymbolSearchingDisabled()) {
612*0b57cec5SDimitry Andric     if (auto Sym = Resolver.findSymbol(Name)) {
613*0b57cec5SDimitry Andric       if (auto AddrOrErr = Sym.getAddress())
614*0b57cec5SDimitry Andric         return reinterpret_cast<void*>(
615*0b57cec5SDimitry Andric                  static_cast<uintptr_t>(*AddrOrErr));
616*0b57cec5SDimitry Andric     } else if (auto Err = Sym.takeError())
617*0b57cec5SDimitry Andric       report_fatal_error(std::move(Err));
618*0b57cec5SDimitry Andric   }
619*0b57cec5SDimitry Andric 
620*0b57cec5SDimitry Andric   /// If a LazyFunctionCreator is installed, use it to get/create the function.
621*0b57cec5SDimitry Andric   if (LazyFunctionCreator)
622*0b57cec5SDimitry Andric     if (void *RP = LazyFunctionCreator(Name))
623*0b57cec5SDimitry Andric       return RP;
624*0b57cec5SDimitry Andric 
625*0b57cec5SDimitry Andric   if (AbortOnFailure) {
626*0b57cec5SDimitry Andric     report_fatal_error("Program used external function '"+Name+
627*0b57cec5SDimitry Andric                        "' which could not be resolved!");
628*0b57cec5SDimitry Andric   }
629*0b57cec5SDimitry Andric   return nullptr;
630*0b57cec5SDimitry Andric }
631*0b57cec5SDimitry Andric 
632*0b57cec5SDimitry Andric void MCJIT::RegisterJITEventListener(JITEventListener *L) {
633*0b57cec5SDimitry Andric   if (!L)
634*0b57cec5SDimitry Andric     return;
635*0b57cec5SDimitry Andric   MutexGuard locked(lock);
636*0b57cec5SDimitry Andric   EventListeners.push_back(L);
637*0b57cec5SDimitry Andric }
638*0b57cec5SDimitry Andric 
639*0b57cec5SDimitry Andric void MCJIT::UnregisterJITEventListener(JITEventListener *L) {
640*0b57cec5SDimitry Andric   if (!L)
641*0b57cec5SDimitry Andric     return;
642*0b57cec5SDimitry Andric   MutexGuard locked(lock);
643*0b57cec5SDimitry Andric   auto I = find(reverse(EventListeners), L);
644*0b57cec5SDimitry Andric   if (I != EventListeners.rend()) {
645*0b57cec5SDimitry Andric     std::swap(*I, EventListeners.back());
646*0b57cec5SDimitry Andric     EventListeners.pop_back();
647*0b57cec5SDimitry Andric   }
648*0b57cec5SDimitry Andric }
649*0b57cec5SDimitry Andric 
650*0b57cec5SDimitry Andric void MCJIT::notifyObjectLoaded(const object::ObjectFile &Obj,
651*0b57cec5SDimitry Andric                                const RuntimeDyld::LoadedObjectInfo &L) {
652*0b57cec5SDimitry Andric   uint64_t Key =
653*0b57cec5SDimitry Andric       static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.getData().data()));
654*0b57cec5SDimitry Andric   MutexGuard locked(lock);
655*0b57cec5SDimitry Andric   MemMgr->notifyObjectLoaded(this, Obj);
656*0b57cec5SDimitry Andric   for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
657*0b57cec5SDimitry Andric     EventListeners[I]->notifyObjectLoaded(Key, Obj, L);
658*0b57cec5SDimitry Andric   }
659*0b57cec5SDimitry Andric }
660*0b57cec5SDimitry Andric 
661*0b57cec5SDimitry Andric void MCJIT::notifyFreeingObject(const object::ObjectFile &Obj) {
662*0b57cec5SDimitry Andric   uint64_t Key =
663*0b57cec5SDimitry Andric       static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.getData().data()));
664*0b57cec5SDimitry Andric   MutexGuard locked(lock);
665*0b57cec5SDimitry Andric   for (JITEventListener *L : EventListeners)
666*0b57cec5SDimitry Andric     L->notifyFreeingObject(Key);
667*0b57cec5SDimitry Andric }
668*0b57cec5SDimitry Andric 
669*0b57cec5SDimitry Andric JITSymbol
670*0b57cec5SDimitry Andric LinkingSymbolResolver::findSymbol(const std::string &Name) {
671*0b57cec5SDimitry Andric   auto Result = ParentEngine.findSymbol(Name, false);
672*0b57cec5SDimitry Andric   if (Result)
673*0b57cec5SDimitry Andric     return Result;
674*0b57cec5SDimitry Andric   if (ParentEngine.isSymbolSearchingDisabled())
675*0b57cec5SDimitry Andric     return nullptr;
676*0b57cec5SDimitry Andric   return ClientResolver->findSymbol(Name);
677*0b57cec5SDimitry Andric }
678*0b57cec5SDimitry Andric 
679*0b57cec5SDimitry Andric void LinkingSymbolResolver::anchor() {}
680