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