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