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