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