123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684 |
- //===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "MCJIT.h"
- #include "llvm/ADT/STLExtras.h"
- #include "llvm/ExecutionEngine/GenericValue.h"
- #include "llvm/ExecutionEngine/JITEventListener.h"
- #include "llvm/ExecutionEngine/MCJIT.h"
- #include "llvm/ExecutionEngine/ObjectCache.h"
- #include "llvm/ExecutionEngine/SectionMemoryManager.h"
- #include "llvm/IR/DataLayout.h"
- #include "llvm/IR/DerivedTypes.h"
- #include "llvm/IR/Function.h"
- #include "llvm/IR/LegacyPassManager.h"
- #include "llvm/IR/Mangler.h"
- #include "llvm/IR/Module.h"
- #include "llvm/MC/MCContext.h"
- #include "llvm/Object/Archive.h"
- #include "llvm/Object/ObjectFile.h"
- #include "llvm/Support/DynamicLibrary.h"
- #include "llvm/Support/ErrorHandling.h"
- #include "llvm/Support/MemoryBuffer.h"
- #include "llvm/Support/SmallVectorMemoryBuffer.h"
- #include <mutex>
- using namespace llvm;
- namespace {
- static struct RegisterJIT {
- RegisterJIT() { MCJIT::Register(); }
- } JITRegistrator;
- }
- extern "C" void LLVMLinkInMCJIT() {
- }
- ExecutionEngine *
- MCJIT::createJIT(std::unique_ptr<Module> M, std::string *ErrorStr,
- std::shared_ptr<MCJITMemoryManager> MemMgr,
- std::shared_ptr<LegacyJITSymbolResolver> Resolver,
- std::unique_ptr<TargetMachine> TM) {
- // Try to register the program as a source of symbols to resolve against.
- //
- // FIXME: Don't do this here.
- sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
- if (!MemMgr || !Resolver) {
- auto RTDyldMM = std::make_shared<SectionMemoryManager>();
- if (!MemMgr)
- MemMgr = RTDyldMM;
- if (!Resolver)
- Resolver = RTDyldMM;
- }
- return new MCJIT(std::move(M), std::move(TM), std::move(MemMgr),
- std::move(Resolver));
- }
- MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> TM,
- std::shared_ptr<MCJITMemoryManager> MemMgr,
- std::shared_ptr<LegacyJITSymbolResolver> Resolver)
- : ExecutionEngine(TM->createDataLayout(), std::move(M)), TM(std::move(TM)),
- Ctx(nullptr), MemMgr(std::move(MemMgr)),
- Resolver(*this, std::move(Resolver)), Dyld(*this->MemMgr, this->Resolver),
- ObjCache(nullptr) {
- // FIXME: We are managing our modules, so we do not want the base class
- // ExecutionEngine to manage them as well. To avoid double destruction
- // of the first (and only) module added in ExecutionEngine constructor
- // we remove it from EE and will destruct it ourselves.
- //
- // It may make sense to move our module manager (based on SmallStPtr) back
- // into EE if the JIT and Interpreter can live with it.
- // If so, additional functions: addModule, removeModule, FindFunctionNamed,
- // runStaticConstructorsDestructors could be moved back to EE as well.
- //
- std::unique_ptr<Module> First = std::move(Modules[0]);
- Modules.clear();
- if (First->getDataLayout().isDefault())
- First->setDataLayout(getDataLayout());
- OwnedModules.addModule(std::move(First));
- RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
- }
- MCJIT::~MCJIT() {
- std::lock_guard<sys::Mutex> locked(lock);
- Dyld.deregisterEHFrames();
- for (auto &Obj : LoadedObjects)
- if (Obj)
- notifyFreeingObject(*Obj);
- Archives.clear();
- }
- void MCJIT::addModule(std::unique_ptr<Module> M) {
- std::lock_guard<sys::Mutex> locked(lock);
- if (M->getDataLayout().isDefault())
- M->setDataLayout(getDataLayout());
- OwnedModules.addModule(std::move(M));
- }
- bool MCJIT::removeModule(Module *M) {
- std::lock_guard<sys::Mutex> locked(lock);
- return OwnedModules.removeModule(M);
- }
- void MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) {
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L = Dyld.loadObject(*Obj);
- if (Dyld.hasError())
- report_fatal_error(Dyld.getErrorString());
- notifyObjectLoaded(*Obj, *L);
- LoadedObjects.push_back(std::move(Obj));
- }
- void MCJIT::addObjectFile(object::OwningBinary<object::ObjectFile> Obj) {
- std::unique_ptr<object::ObjectFile> ObjFile;
- std::unique_ptr<MemoryBuffer> MemBuf;
- std::tie(ObjFile, MemBuf) = Obj.takeBinary();
- addObjectFile(std::move(ObjFile));
- Buffers.push_back(std::move(MemBuf));
- }
- void MCJIT::addArchive(object::OwningBinary<object::Archive> A) {
- Archives.push_back(std::move(A));
- }
- void MCJIT::setObjectCache(ObjectCache* NewCache) {
- std::lock_guard<sys::Mutex> locked(lock);
- ObjCache = NewCache;
- }
- std::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
- assert(M && "Can not emit a null module");
- std::lock_guard<sys::Mutex> locked(lock);
- // Materialize all globals in the module if they have not been
- // materialized already.
- cantFail(M->materializeAll());
- // This must be a module which has already been added but not loaded to this
- // MCJIT instance, since these conditions are tested by our caller,
- // generateCodeForModule.
- legacy::PassManager PM;
- // The RuntimeDyld will take ownership of this shortly
- SmallVector<char, 4096> ObjBufferSV;
- raw_svector_ostream ObjStream(ObjBufferSV);
- // Turn the machine code intermediate representation into bytes in memory
- // that may be executed.
- if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !getVerifyModules()))
- report_fatal_error("Target does not support MC emission!");
- // Initialize passes.
- PM.run(*M);
- // Flush the output buffer to get the generated code into memory
- auto CompiledObjBuffer = std::make_unique<SmallVectorMemoryBuffer>(
- std::move(ObjBufferSV), /*RequiresNullTerminator=*/false);
- // If we have an object cache, tell it about the new object.
- // Note that we're using the compiled image, not the loaded image (as below).
- if (ObjCache) {
- // MemoryBuffer is a thin wrapper around the actual memory, so it's OK
- // to create a temporary object here and delete it after the call.
- MemoryBufferRef MB = CompiledObjBuffer->getMemBufferRef();
- ObjCache->notifyObjectCompiled(M, MB);
- }
- return CompiledObjBuffer;
- }
- void MCJIT::generateCodeForModule(Module *M) {
- // Get a thread lock to make sure we aren't trying to load multiple times
- std::lock_guard<sys::Mutex> locked(lock);
- // This must be a module which has already been added to this MCJIT instance.
- assert(OwnedModules.ownsModule(M) &&
- "MCJIT::generateCodeForModule: Unknown module.");
- // Re-compilation is not supported
- if (OwnedModules.hasModuleBeenLoaded(M))
- return;
- std::unique_ptr<MemoryBuffer> ObjectToLoad;
- // Try to load the pre-compiled object from cache if possible
- if (ObjCache)
- ObjectToLoad = ObjCache->getObject(M);
- assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch");
- // If the cache did not contain a suitable object, compile the object
- if (!ObjectToLoad) {
- ObjectToLoad = emitObject(M);
- assert(ObjectToLoad && "Compilation did not produce an object.");
- }
- // Load the object into the dynamic linker.
- // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list).
- Expected<std::unique_ptr<object::ObjectFile>> LoadedObject =
- object::ObjectFile::createObjectFile(ObjectToLoad->getMemBufferRef());
- if (!LoadedObject) {
- std::string Buf;
- raw_string_ostream OS(Buf);
- logAllUnhandledErrors(LoadedObject.takeError(), OS);
- report_fatal_error(Twine(OS.str()));
- }
- std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L =
- Dyld.loadObject(*LoadedObject.get());
- if (Dyld.hasError())
- report_fatal_error(Dyld.getErrorString());
- notifyObjectLoaded(*LoadedObject.get(), *L);
- Buffers.push_back(std::move(ObjectToLoad));
- LoadedObjects.push_back(std::move(*LoadedObject));
- OwnedModules.markModuleAsLoaded(M);
- }
- void MCJIT::finalizeLoadedModules() {
- std::lock_guard<sys::Mutex> locked(lock);
- // Resolve any outstanding relocations.
- Dyld.resolveRelocations();
- // Check for Dyld error.
- if (Dyld.hasError())
- ErrMsg = Dyld.getErrorString().str();
- OwnedModules.markAllLoadedModulesAsFinalized();
- // Register EH frame data for any module we own which has been loaded
- Dyld.registerEHFrames();
- // Set page permissions.
- MemMgr->finalizeMemory();
- }
- // FIXME: Rename this.
- void MCJIT::finalizeObject() {
- std::lock_guard<sys::Mutex> locked(lock);
- // Generate code for module is going to move objects out of the 'added' list,
- // so we need to copy that out before using it:
- SmallVector<Module*, 16> ModsToAdd;
- for (auto *M : OwnedModules.added())
- ModsToAdd.push_back(M);
- for (auto *M : ModsToAdd)
- generateCodeForModule(M);
- finalizeLoadedModules();
- }
- void MCJIT::finalizeModule(Module *M) {
- std::lock_guard<sys::Mutex> locked(lock);
- // This must be a module which has already been added to this MCJIT instance.
- assert(OwnedModules.ownsModule(M) && "MCJIT::finalizeModule: Unknown module.");
- // If the module hasn't been compiled, just do that.
- if (!OwnedModules.hasModuleBeenLoaded(M))
- generateCodeForModule(M);
- finalizeLoadedModules();
- }
- JITSymbol MCJIT::findExistingSymbol(const std::string &Name) {
- if (void *Addr = getPointerToGlobalIfAvailable(Name))
- return JITSymbol(static_cast<uint64_t>(
- reinterpret_cast<uintptr_t>(Addr)),
- JITSymbolFlags::Exported);
- return Dyld.getSymbol(Name);
- }
- Module *MCJIT::findModuleForSymbol(const std::string &Name,
- bool CheckFunctionsOnly) {
- StringRef DemangledName = Name;
- if (DemangledName[0] == getDataLayout().getGlobalPrefix())
- DemangledName = DemangledName.substr(1);
- std::lock_guard<sys::Mutex> locked(lock);
- // If it hasn't already been generated, see if it's in one of our modules.
- for (ModulePtrSet::iterator I = OwnedModules.begin_added(),
- E = OwnedModules.end_added();
- I != E; ++I) {
- Module *M = *I;
- Function *F = M->getFunction(DemangledName);
- if (F && !F->isDeclaration())
- return M;
- if (!CheckFunctionsOnly) {
- GlobalVariable *G = M->getGlobalVariable(DemangledName);
- if (G && !G->isDeclaration())
- return M;
- // FIXME: Do we need to worry about global aliases?
- }
- }
- // We didn't find the symbol in any of our modules.
- return nullptr;
- }
- uint64_t MCJIT::getSymbolAddress(const std::string &Name,
- bool CheckFunctionsOnly) {
- std::string MangledName;
- {
- raw_string_ostream MangledNameStream(MangledName);
- Mangler::getNameWithPrefix(MangledNameStream, Name, getDataLayout());
- }
- if (auto Sym = findSymbol(MangledName, CheckFunctionsOnly)) {
- if (auto AddrOrErr = Sym.getAddress())
- return *AddrOrErr;
- else
- report_fatal_error(AddrOrErr.takeError());
- } else if (auto Err = Sym.takeError())
- report_fatal_error(Sym.takeError());
- return 0;
- }
- JITSymbol MCJIT::findSymbol(const std::string &Name,
- bool CheckFunctionsOnly) {
- std::lock_guard<sys::Mutex> locked(lock);
- // First, check to see if we already have this symbol.
- if (auto Sym = findExistingSymbol(Name))
- return Sym;
- for (object::OwningBinary<object::Archive> &OB : Archives) {
- object::Archive *A = OB.getBinary();
- // Look for our symbols in each Archive
- auto OptionalChildOrErr = A->findSym(Name);
- if (!OptionalChildOrErr)
- report_fatal_error(OptionalChildOrErr.takeError());
- auto &OptionalChild = *OptionalChildOrErr;
- if (OptionalChild) {
- // FIXME: Support nested archives?
- Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
- OptionalChild->getAsBinary();
- if (!ChildBinOrErr) {
- // TODO: Actually report errors helpfully.
- consumeError(ChildBinOrErr.takeError());
- continue;
- }
- std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
- if (ChildBin->isObject()) {
- std::unique_ptr<object::ObjectFile> OF(
- static_cast<object::ObjectFile *>(ChildBin.release()));
- // This causes the object file to be loaded.
- addObjectFile(std::move(OF));
- // The address should be here now.
- if (auto Sym = findExistingSymbol(Name))
- return Sym;
- }
- }
- }
- // If it hasn't already been generated, see if it's in one of our modules.
- Module *M = findModuleForSymbol(Name, CheckFunctionsOnly);
- if (M) {
- generateCodeForModule(M);
- // Check the RuntimeDyld table again, it should be there now.
- return findExistingSymbol(Name);
- }
- // If a LazyFunctionCreator is installed, use it to get/create the function.
- // FIXME: Should we instead have a LazySymbolCreator callback?
- if (LazyFunctionCreator) {
- auto Addr = static_cast<uint64_t>(
- reinterpret_cast<uintptr_t>(LazyFunctionCreator(Name)));
- return JITSymbol(Addr, JITSymbolFlags::Exported);
- }
- return nullptr;
- }
- uint64_t MCJIT::getGlobalValueAddress(const std::string &Name) {
- std::lock_guard<sys::Mutex> locked(lock);
- uint64_t Result = getSymbolAddress(Name, false);
- if (Result != 0)
- finalizeLoadedModules();
- return Result;
- }
- uint64_t MCJIT::getFunctionAddress(const std::string &Name) {
- std::lock_guard<sys::Mutex> locked(lock);
- uint64_t Result = getSymbolAddress(Name, true);
- if (Result != 0)
- finalizeLoadedModules();
- return Result;
- }
- // Deprecated. Use getFunctionAddress instead.
- void *MCJIT::getPointerToFunction(Function *F) {
- std::lock_guard<sys::Mutex> locked(lock);
- Mangler Mang;
- SmallString<128> Name;
- TM->getNameWithPrefix(Name, F, Mang);
- if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
- bool AbortOnFailure = !F->hasExternalWeakLinkage();
- void *Addr = getPointerToNamedFunction(Name, AbortOnFailure);
- updateGlobalMapping(F, Addr);
- return Addr;
- }
- Module *M = F->getParent();
- bool HasBeenAddedButNotLoaded = OwnedModules.hasModuleBeenAddedButNotLoaded(M);
- // Make sure the relevant module has been compiled and loaded.
- if (HasBeenAddedButNotLoaded)
- generateCodeForModule(M);
- else if (!OwnedModules.hasModuleBeenLoaded(M)) {
- // If this function doesn't belong to one of our modules, we're done.
- // FIXME: Asking for the pointer to a function that hasn't been registered,
- // and isn't a declaration (which is handled above) should probably
- // be an assertion.
- return nullptr;
- }
- // FIXME: Should the Dyld be retaining module information? Probably not.
- //
- // This is the accessor for the target address, so make sure to check the
- // load address of the symbol, not the local address.
- return (void*)Dyld.getSymbol(Name).getAddress();
- }
- void MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
- bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) {
- for (; I != E; ++I) {
- ExecutionEngine::runStaticConstructorsDestructors(**I, isDtors);
- }
- }
- void MCJIT::runStaticConstructorsDestructors(bool isDtors) {
- // Execute global ctors/dtors for each module in the program.
- runStaticConstructorsDestructorsInModulePtrSet(
- isDtors, OwnedModules.begin_added(), OwnedModules.end_added());
- runStaticConstructorsDestructorsInModulePtrSet(
- isDtors, OwnedModules.begin_loaded(), OwnedModules.end_loaded());
- runStaticConstructorsDestructorsInModulePtrSet(
- isDtors, OwnedModules.begin_finalized(), OwnedModules.end_finalized());
- }
- Function *MCJIT::FindFunctionNamedInModulePtrSet(StringRef FnName,
- ModulePtrSet::iterator I,
- ModulePtrSet::iterator E) {
- for (; I != E; ++I) {
- Function *F = (*I)->getFunction(FnName);
- if (F && !F->isDeclaration())
- return F;
- }
- return nullptr;
- }
- GlobalVariable *MCJIT::FindGlobalVariableNamedInModulePtrSet(StringRef Name,
- bool AllowInternal,
- ModulePtrSet::iterator I,
- ModulePtrSet::iterator E) {
- for (; I != E; ++I) {
- GlobalVariable *GV = (*I)->getGlobalVariable(Name, AllowInternal);
- if (GV && !GV->isDeclaration())
- return GV;
- }
- return nullptr;
- }
- Function *MCJIT::FindFunctionNamed(StringRef FnName) {
- Function *F = FindFunctionNamedInModulePtrSet(
- FnName, OwnedModules.begin_added(), OwnedModules.end_added());
- if (!F)
- F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_loaded(),
- OwnedModules.end_loaded());
- if (!F)
- F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_finalized(),
- OwnedModules.end_finalized());
- return F;
- }
- GlobalVariable *MCJIT::FindGlobalVariableNamed(StringRef Name, bool AllowInternal) {
- GlobalVariable *GV = FindGlobalVariableNamedInModulePtrSet(
- Name, AllowInternal, OwnedModules.begin_added(), OwnedModules.end_added());
- if (!GV)
- GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_loaded(),
- OwnedModules.end_loaded());
- if (!GV)
- GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_finalized(),
- OwnedModules.end_finalized());
- return GV;
- }
- GenericValue MCJIT::runFunction(Function *F, ArrayRef<GenericValue> ArgValues) {
- assert(F && "Function *F was null at entry to run()");
- void *FPtr = getPointerToFunction(F);
- finalizeModule(F->getParent());
- assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
- FunctionType *FTy = F->getFunctionType();
- Type *RetTy = FTy->getReturnType();
- assert((FTy->getNumParams() == ArgValues.size() ||
- (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
- "Wrong number of arguments passed into function!");
- assert(FTy->getNumParams() == ArgValues.size() &&
- "This doesn't support passing arguments through varargs (yet)!");
- // Handle some common cases first. These cases correspond to common `main'
- // prototypes.
- if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
- switch (ArgValues.size()) {
- case 3:
- if (FTy->getParamType(0)->isIntegerTy(32) &&
- FTy->getParamType(1)->isPointerTy() &&
- FTy->getParamType(2)->isPointerTy()) {
- int (*PF)(int, char **, const char **) =
- (int(*)(int, char **, const char **))(intptr_t)FPtr;
- // Call the function.
- GenericValue rv;
- rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
- (char **)GVTOP(ArgValues[1]),
- (const char **)GVTOP(ArgValues[2])));
- return rv;
- }
- break;
- case 2:
- if (FTy->getParamType(0)->isIntegerTy(32) &&
- FTy->getParamType(1)->isPointerTy()) {
- int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
- // Call the function.
- GenericValue rv;
- rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
- (char **)GVTOP(ArgValues[1])));
- return rv;
- }
- break;
- case 1:
- if (FTy->getNumParams() == 1 &&
- FTy->getParamType(0)->isIntegerTy(32)) {
- GenericValue rv;
- int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
- rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
- return rv;
- }
- break;
- }
- }
- // Handle cases where no arguments are passed first.
- if (ArgValues.empty()) {
- GenericValue rv;
- switch (RetTy->getTypeID()) {
- default: llvm_unreachable("Unknown return type for function call!");
- case Type::IntegerTyID: {
- unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
- if (BitWidth == 1)
- rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)());
- else if (BitWidth <= 8)
- rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)());
- else if (BitWidth <= 16)
- rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)());
- else if (BitWidth <= 32)
- rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)());
- else if (BitWidth <= 64)
- rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)());
- else
- llvm_unreachable("Integer types > 64 bits not supported");
- return rv;
- }
- case Type::VoidTyID:
- rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
- return rv;
- case Type::FloatTyID:
- rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
- return rv;
- case Type::DoubleTyID:
- rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
- return rv;
- case Type::X86_FP80TyID:
- case Type::FP128TyID:
- case Type::PPC_FP128TyID:
- llvm_unreachable("long double not supported yet");
- case Type::PointerTyID:
- return PTOGV(((void*(*)())(intptr_t)FPtr)());
- }
- }
- report_fatal_error("MCJIT::runFunction does not support full-featured "
- "argument passing. Please use "
- "ExecutionEngine::getFunctionAddress and cast the result "
- "to the desired function pointer type.");
- }
- void *MCJIT::getPointerToNamedFunction(StringRef Name, bool AbortOnFailure) {
- if (!isSymbolSearchingDisabled()) {
- if (auto Sym = Resolver.findSymbol(std::string(Name))) {
- if (auto AddrOrErr = Sym.getAddress())
- return reinterpret_cast<void*>(
- static_cast<uintptr_t>(*AddrOrErr));
- } else if (auto Err = Sym.takeError())
- report_fatal_error(std::move(Err));
- }
- /// If a LazyFunctionCreator is installed, use it to get/create the function.
- if (LazyFunctionCreator)
- if (void *RP = LazyFunctionCreator(std::string(Name)))
- return RP;
- if (AbortOnFailure) {
- report_fatal_error("Program used external function '"+Name+
- "' which could not be resolved!");
- }
- return nullptr;
- }
- void MCJIT::RegisterJITEventListener(JITEventListener *L) {
- if (!L)
- return;
- std::lock_guard<sys::Mutex> locked(lock);
- EventListeners.push_back(L);
- }
- void MCJIT::UnregisterJITEventListener(JITEventListener *L) {
- if (!L)
- return;
- std::lock_guard<sys::Mutex> locked(lock);
- auto I = find(reverse(EventListeners), L);
- if (I != EventListeners.rend()) {
- std::swap(*I, EventListeners.back());
- EventListeners.pop_back();
- }
- }
- void MCJIT::notifyObjectLoaded(const object::ObjectFile &Obj,
- const RuntimeDyld::LoadedObjectInfo &L) {
- uint64_t Key =
- static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.getData().data()));
- std::lock_guard<sys::Mutex> locked(lock);
- MemMgr->notifyObjectLoaded(this, Obj);
- for (JITEventListener *EL : EventListeners)
- EL->notifyObjectLoaded(Key, Obj, L);
- }
- void MCJIT::notifyFreeingObject(const object::ObjectFile &Obj) {
- uint64_t Key =
- static_cast<uint64_t>(reinterpret_cast<uintptr_t>(Obj.getData().data()));
- std::lock_guard<sys::Mutex> locked(lock);
- for (JITEventListener *L : EventListeners)
- L->notifyFreeingObject(Key);
- }
- JITSymbol
- LinkingSymbolResolver::findSymbol(const std::string &Name) {
- auto Result = ParentEngine.findSymbol(Name, false);
- if (Result)
- return Result;
- if (ParentEngine.isSymbolSearchingDisabled())
- return nullptr;
- return ClientResolver->findSymbol(Name);
- }
- void LinkingSymbolResolver::anchor() {}
|