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