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