1221345Sdim//===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim 10218885Sdim#include "MCJIT.h" 11218885Sdim#include "llvm/ExecutionEngine/GenericValue.h" 12245431Sdim#include "llvm/ExecutionEngine/JITEventListener.h" 13245431Sdim#include "llvm/ExecutionEngine/JITMemoryManager.h" 14218885Sdim#include "llvm/ExecutionEngine/MCJIT.h" 15245431Sdim#include "llvm/ExecutionEngine/ObjectBuffer.h" 16245431Sdim#include "llvm/ExecutionEngine/ObjectImage.h" 17263509Sdim#include "llvm/PassManager.h" 18252723Sdim#include "llvm/ExecutionEngine/SectionMemoryManager.h" 19252723Sdim#include "llvm/IR/DataLayout.h" 20252723Sdim#include "llvm/IR/DerivedTypes.h" 21252723Sdim#include "llvm/IR/Function.h" 22263509Sdim#include "llvm/IR/Module.h" 23221345Sdim#include "llvm/MC/MCAsmInfo.h" 24252723Sdim#include "llvm/Support/DynamicLibrary.h" 25218885Sdim#include "llvm/Support/ErrorHandling.h" 26221345Sdim#include "llvm/Support/MemoryBuffer.h" 27245431Sdim#include "llvm/Support/MutexGuard.h" 28218885Sdim 29218885Sdimusing namespace llvm; 30218885Sdim 31218885Sdimnamespace { 32218885Sdim 33218885Sdimstatic struct RegisterJIT { 34218885Sdim RegisterJIT() { MCJIT::Register(); } 35218885Sdim} JITRegistrator; 36218885Sdim 37218885Sdim} 38218885Sdim 39218885Sdimextern "C" void LLVMLinkInMCJIT() { 40218885Sdim} 41218885Sdim 42218885SdimExecutionEngine *MCJIT::createJIT(Module *M, 43218885Sdim std::string *ErrorStr, 44263509Sdim RTDyldMemoryManager *MemMgr, 45218885Sdim bool GVsWithCode, 46223017Sdim TargetMachine *TM) { 47218885Sdim // Try to register the program as a source of symbols to resolve against. 48218885Sdim // 49218885Sdim // FIXME: Don't do this here. 50218885Sdim sys::DynamicLibrary::LoadLibraryPermanently(0, NULL); 51218885Sdim 52263509Sdim return new MCJIT(M, TM, MemMgr ? MemMgr : new SectionMemoryManager(), 53263509Sdim GVsWithCode); 54245431Sdim} 55218885Sdim 56245431SdimMCJIT::MCJIT(Module *m, TargetMachine *tm, RTDyldMemoryManager *MM, 57245431Sdim bool AllocateGVsWithCode) 58263509Sdim : ExecutionEngine(m), TM(tm), Ctx(0), MemMgr(this, MM), Dyld(&MemMgr), 59263509Sdim ObjCache(0) { 60245431Sdim 61263509Sdim OwnedModules.addModule(m); 62245431Sdim setDataLayout(TM->getDataLayout()); 63218885Sdim} 64218885Sdim 65245431SdimMCJIT::~MCJIT() { 66263509Sdim MutexGuard locked(lock); 67263509Sdim // FIXME: We are managing our modules, so we do not want the base class 68263509Sdim // ExecutionEngine to manage them as well. To avoid double destruction 69263509Sdim // of the first (and only) module added in ExecutionEngine constructor 70263509Sdim // we remove it from EE and will destruct it ourselves. 71263509Sdim // 72263509Sdim // It may make sense to move our module manager (based on SmallStPtr) back 73263509Sdim // into EE if the JIT and Interpreter can live with it. 74263509Sdim // If so, additional functions: addModule, removeModule, FindFunctionNamed, 75263509Sdim // runStaticConstructorsDestructors could be moved back to EE as well. 76263509Sdim // 77263509Sdim Modules.clear(); 78263509Sdim Dyld.deregisterEHFrames(); 79263509Sdim 80263509Sdim LoadedObjectMap::iterator it, end = LoadedObjects.end(); 81263509Sdim for (it = LoadedObjects.begin(); it != end; ++it) { 82263509Sdim ObjectImage *Obj = it->second; 83263509Sdim if (Obj) { 84263509Sdim NotifyFreeingObject(*Obj); 85263509Sdim delete Obj; 86263509Sdim } 87263509Sdim } 88263509Sdim LoadedObjects.clear(); 89245431Sdim delete TM; 90245431Sdim} 91221345Sdim 92263509Sdimvoid MCJIT::addModule(Module *M) { 93263509Sdim MutexGuard locked(lock); 94263509Sdim OwnedModules.addModule(M); 95263509Sdim} 96263509Sdim 97263509Sdimbool MCJIT::removeModule(Module *M) { 98263509Sdim MutexGuard locked(lock); 99263509Sdim return OwnedModules.removeModule(M); 100263509Sdim} 101263509Sdim 102263509Sdim 103263509Sdim 104252723Sdimvoid MCJIT::setObjectCache(ObjectCache* NewCache) { 105263509Sdim MutexGuard locked(lock); 106252723Sdim ObjCache = NewCache; 107252723Sdim} 108252723Sdim 109263509SdimObjectBufferStream* MCJIT::emitObject(Module *M) { 110245431Sdim MutexGuard locked(lock); 111245431Sdim 112263509Sdim // This must be a module which has already been added but not loaded to this 113263509Sdim // MCJIT instance, since these conditions are tested by our caller, 114263509Sdim // generateCodeForModule. 115245431Sdim 116245431Sdim PassManager PM; 117245431Sdim 118245431Sdim PM.add(new DataLayout(*TM->getDataLayout())); 119245431Sdim 120245431Sdim // The RuntimeDyld will take ownership of this shortly 121252723Sdim OwningPtr<ObjectBufferStream> CompiledObject(new ObjectBufferStream()); 122245431Sdim 123221345Sdim // Turn the machine code intermediate representation into bytes in memory 124221345Sdim // that may be executed. 125252723Sdim if (TM->addPassesToEmitMC(PM, Ctx, CompiledObject->getOStream(), false)) { 126221345Sdim report_fatal_error("Target does not support MC emission!"); 127221345Sdim } 128221345Sdim 129221345Sdim // Initialize passes. 130263509Sdim PM.run(*M); 131245431Sdim // Flush the output buffer to get the generated code into memory 132252723Sdim CompiledObject->flush(); 133221345Sdim 134252723Sdim // If we have an object cache, tell it about the new object. 135252723Sdim // Note that we're using the compiled image, not the loaded image (as below). 136252723Sdim if (ObjCache) { 137252723Sdim // MemoryBuffer is a thin wrapper around the actual memory, so it's OK 138252723Sdim // to create a temporary object here and delete it after the call. 139252723Sdim OwningPtr<MemoryBuffer> MB(CompiledObject->getMemBuffer()); 140263509Sdim ObjCache->notifyObjectCompiled(M, MB.get()); 141252723Sdim } 142252723Sdim 143252723Sdim return CompiledObject.take(); 144252723Sdim} 145252723Sdim 146263509Sdimvoid MCJIT::generateCodeForModule(Module *M) { 147252723Sdim // Get a thread lock to make sure we aren't trying to load multiple times 148252723Sdim MutexGuard locked(lock); 149252723Sdim 150263509Sdim // This must be a module which has already been added to this MCJIT instance. 151263509Sdim assert(OwnedModules.ownsModule(M) && 152263509Sdim "MCJIT::generateCodeForModule: Unknown module."); 153263509Sdim 154252723Sdim // Re-compilation is not supported 155263509Sdim if (OwnedModules.hasModuleBeenLoaded(M)) 156252723Sdim return; 157252723Sdim 158252723Sdim OwningPtr<ObjectBuffer> ObjectToLoad; 159252723Sdim // Try to load the pre-compiled object from cache if possible 160252723Sdim if (0 != ObjCache) { 161263509Sdim OwningPtr<MemoryBuffer> PreCompiledObject(ObjCache->getObject(M)); 162252723Sdim if (0 != PreCompiledObject.get()) 163252723Sdim ObjectToLoad.reset(new ObjectBuffer(PreCompiledObject.take())); 164252723Sdim } 165252723Sdim 166252723Sdim // If the cache did not contain a suitable object, compile the object 167252723Sdim if (!ObjectToLoad) { 168252723Sdim ObjectToLoad.reset(emitObject(M)); 169252723Sdim assert(ObjectToLoad.get() && "Compilation did not produce an object."); 170252723Sdim } 171252723Sdim 172221345Sdim // Load the object into the dynamic linker. 173263509Sdim // MCJIT now owns the ObjectImage pointer (via its LoadedObjects map). 174263509Sdim ObjectImage *LoadedObject = Dyld.loadObject(ObjectToLoad.take()); 175263509Sdim LoadedObjects[M] = LoadedObject; 176245431Sdim if (!LoadedObject) 177221345Sdim report_fatal_error(Dyld.getErrorString()); 178245431Sdim 179245431Sdim // FIXME: Make this optional, maybe even move it to a JIT event listener 180245431Sdim LoadedObject->registerWithDebugger(); 181245431Sdim 182245431Sdim NotifyObjectEmitted(*LoadedObject); 183245431Sdim 184263509Sdim OwnedModules.markModuleAsLoaded(M); 185218885Sdim} 186218885Sdim 187263509Sdimvoid MCJIT::finalizeLoadedModules() { 188263509Sdim MutexGuard locked(lock); 189263509Sdim 190263509Sdim // Resolve any outstanding relocations. 191263509Sdim Dyld.resolveRelocations(); 192263509Sdim 193263509Sdim OwnedModules.markAllLoadedModulesAsFinalized(); 194263509Sdim 195263509Sdim // Register EH frame data for any module we own which has been loaded 196263509Sdim Dyld.registerEHFrames(); 197263509Sdim 198263509Sdim // Set page permissions. 199263509Sdim MemMgr.finalizeMemory(); 200263509Sdim} 201263509Sdim 202263509Sdim// FIXME: Rename this. 203245431Sdimvoid MCJIT::finalizeObject() { 204263509Sdim MutexGuard locked(lock); 205263509Sdim 206263509Sdim for (ModulePtrSet::iterator I = OwnedModules.begin_added(), 207263509Sdim E = OwnedModules.end_added(); 208263509Sdim I != E; ++I) { 209263509Sdim Module *M = *I; 210263509Sdim generateCodeForModule(M); 211245431Sdim } 212245431Sdim 213263509Sdim finalizeLoadedModules(); 214263509Sdim} 215252723Sdim 216263509Sdimvoid MCJIT::finalizeModule(Module *M) { 217263509Sdim MutexGuard locked(lock); 218263509Sdim 219263509Sdim // This must be a module which has already been added to this MCJIT instance. 220263509Sdim assert(OwnedModules.ownsModule(M) && "MCJIT::finalizeModule: Unknown module."); 221263509Sdim 222263509Sdim // If the module hasn't been compiled, just do that. 223263509Sdim if (!OwnedModules.hasModuleBeenLoaded(M)) 224263509Sdim generateCodeForModule(M); 225263509Sdim 226263509Sdim finalizeLoadedModules(); 227218885Sdim} 228218885Sdim 229218885Sdimvoid *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { 230218885Sdim report_fatal_error("not yet implemented"); 231218885Sdim} 232218885Sdim 233263509Sdimuint64_t MCJIT::getExistingSymbolAddress(const std::string &Name) { 234263509Sdim // Check with the RuntimeDyld to see if we already have this symbol. 235263509Sdim if (Name[0] == '\1') 236263509Sdim return Dyld.getSymbolLoadAddress(Name.substr(1)); 237263509Sdim return Dyld.getSymbolLoadAddress((TM->getMCAsmInfo()->getGlobalPrefix() 238263509Sdim + Name)); 239263509Sdim} 240263509Sdim 241263509SdimModule *MCJIT::findModuleForSymbol(const std::string &Name, 242263509Sdim bool CheckFunctionsOnly) { 243263509Sdim MutexGuard locked(lock); 244263509Sdim 245263509Sdim // If it hasn't already been generated, see if it's in one of our modules. 246263509Sdim for (ModulePtrSet::iterator I = OwnedModules.begin_added(), 247263509Sdim E = OwnedModules.end_added(); 248263509Sdim I != E; ++I) { 249263509Sdim Module *M = *I; 250263509Sdim Function *F = M->getFunction(Name); 251263509Sdim if (F && !F->isDeclaration()) 252263509Sdim return M; 253263509Sdim if (!CheckFunctionsOnly) { 254263509Sdim GlobalVariable *G = M->getGlobalVariable(Name); 255263509Sdim if (G && !G->isDeclaration()) 256263509Sdim return M; 257263509Sdim // FIXME: Do we need to worry about global aliases? 258263509Sdim } 259263509Sdim } 260263509Sdim // We didn't find the symbol in any of our modules. 261263509Sdim return NULL; 262263509Sdim} 263263509Sdim 264263509Sdimuint64_t MCJIT::getSymbolAddress(const std::string &Name, 265263509Sdim bool CheckFunctionsOnly) 266263509Sdim{ 267263509Sdim MutexGuard locked(lock); 268263509Sdim 269263509Sdim // First, check to see if we already have this symbol. 270263509Sdim uint64_t Addr = getExistingSymbolAddress(Name); 271263509Sdim if (Addr) 272263509Sdim return Addr; 273263509Sdim 274263509Sdim // If it hasn't already been generated, see if it's in one of our modules. 275263509Sdim Module *M = findModuleForSymbol(Name, CheckFunctionsOnly); 276263509Sdim if (!M) 277263509Sdim return 0; 278263509Sdim 279263509Sdim generateCodeForModule(M); 280263509Sdim 281263509Sdim // Check the RuntimeDyld table again, it should be there now. 282263509Sdim return getExistingSymbolAddress(Name); 283263509Sdim} 284263509Sdim 285263509Sdimuint64_t MCJIT::getGlobalValueAddress(const std::string &Name) { 286263509Sdim MutexGuard locked(lock); 287263509Sdim uint64_t Result = getSymbolAddress(Name, false); 288263509Sdim if (Result != 0) 289263509Sdim finalizeLoadedModules(); 290263509Sdim return Result; 291263509Sdim} 292263509Sdim 293263509Sdimuint64_t MCJIT::getFunctionAddress(const std::string &Name) { 294263509Sdim MutexGuard locked(lock); 295263509Sdim uint64_t Result = getSymbolAddress(Name, true); 296263509Sdim if (Result != 0) 297263509Sdim finalizeLoadedModules(); 298263509Sdim return Result; 299263509Sdim} 300263509Sdim 301263509Sdim// Deprecated. Use getFunctionAddress instead. 302218885Sdimvoid *MCJIT::getPointerToFunction(Function *F) { 303263509Sdim MutexGuard locked(lock); 304245431Sdim 305221345Sdim if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) { 306221345Sdim bool AbortOnFailure = !F->hasExternalWeakLinkage(); 307221345Sdim void *Addr = getPointerToNamedFunction(F->getName(), AbortOnFailure); 308221345Sdim addGlobalMapping(F, Addr); 309221345Sdim return Addr; 310221345Sdim } 311221345Sdim 312263509Sdim Module *M = F->getParent(); 313263509Sdim bool HasBeenAddedButNotLoaded = OwnedModules.hasModuleBeenAddedButNotLoaded(M); 314263509Sdim 315263509Sdim // Make sure the relevant module has been compiled and loaded. 316263509Sdim if (HasBeenAddedButNotLoaded) 317263509Sdim generateCodeForModule(M); 318263509Sdim else if (!OwnedModules.hasModuleBeenLoaded(M)) 319263509Sdim // If this function doesn't belong to one of our modules, we're done. 320263509Sdim return NULL; 321263509Sdim 322245431Sdim // FIXME: Should the Dyld be retaining module information? Probably not. 323223017Sdim // FIXME: Should we be using the mangler for this? Probably. 324245431Sdim // 325245431Sdim // This is the accessor for the target address, so make sure to check the 326245431Sdim // load address of the symbol, not the local address. 327223017Sdim StringRef BaseName = F->getName(); 328223017Sdim if (BaseName[0] == '\1') 329245431Sdim return (void*)Dyld.getSymbolLoadAddress(BaseName.substr(1)); 330245431Sdim return (void*)Dyld.getSymbolLoadAddress((TM->getMCAsmInfo()->getGlobalPrefix() 331223017Sdim + BaseName).str()); 332218885Sdim} 333218885Sdim 334218885Sdimvoid *MCJIT::recompileAndRelinkFunction(Function *F) { 335218885Sdim report_fatal_error("not yet implemented"); 336218885Sdim} 337218885Sdim 338218885Sdimvoid MCJIT::freeMachineCodeForFunction(Function *F) { 339218885Sdim report_fatal_error("not yet implemented"); 340218885Sdim} 341218885Sdim 342263509Sdimvoid MCJIT::runStaticConstructorsDestructorsInModulePtrSet( 343263509Sdim bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) { 344263509Sdim for (; I != E; ++I) { 345263509Sdim ExecutionEngine::runStaticConstructorsDestructors(*I, isDtors); 346263509Sdim } 347263509Sdim} 348263509Sdim 349263509Sdimvoid MCJIT::runStaticConstructorsDestructors(bool isDtors) { 350263509Sdim // Execute global ctors/dtors for each module in the program. 351263509Sdim runStaticConstructorsDestructorsInModulePtrSet( 352263509Sdim isDtors, OwnedModules.begin_added(), OwnedModules.end_added()); 353263509Sdim runStaticConstructorsDestructorsInModulePtrSet( 354263509Sdim isDtors, OwnedModules.begin_loaded(), OwnedModules.end_loaded()); 355263509Sdim runStaticConstructorsDestructorsInModulePtrSet( 356263509Sdim isDtors, OwnedModules.begin_finalized(), OwnedModules.end_finalized()); 357263509Sdim} 358263509Sdim 359263509SdimFunction *MCJIT::FindFunctionNamedInModulePtrSet(const char *FnName, 360263509Sdim ModulePtrSet::iterator I, 361263509Sdim ModulePtrSet::iterator E) { 362263509Sdim for (; I != E; ++I) { 363263509Sdim if (Function *F = (*I)->getFunction(FnName)) 364263509Sdim return F; 365263509Sdim } 366263509Sdim return 0; 367263509Sdim} 368263509Sdim 369263509SdimFunction *MCJIT::FindFunctionNamed(const char *FnName) { 370263509Sdim Function *F = FindFunctionNamedInModulePtrSet( 371263509Sdim FnName, OwnedModules.begin_added(), OwnedModules.end_added()); 372263509Sdim if (!F) 373263509Sdim F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_loaded(), 374263509Sdim OwnedModules.end_loaded()); 375263509Sdim if (!F) 376263509Sdim F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_finalized(), 377263509Sdim OwnedModules.end_finalized()); 378263509Sdim return F; 379263509Sdim} 380263509Sdim 381218885SdimGenericValue MCJIT::runFunction(Function *F, 382218885Sdim const std::vector<GenericValue> &ArgValues) { 383221345Sdim assert(F && "Function *F was null at entry to run()"); 384221345Sdim 385221345Sdim void *FPtr = getPointerToFunction(F); 386221345Sdim assert(FPtr && "Pointer to fn's code was null after getPointerToFunction"); 387226890Sdim FunctionType *FTy = F->getFunctionType(); 388226890Sdim Type *RetTy = FTy->getReturnType(); 389221345Sdim 390221345Sdim assert((FTy->getNumParams() == ArgValues.size() || 391221345Sdim (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) && 392221345Sdim "Wrong number of arguments passed into function!"); 393221345Sdim assert(FTy->getNumParams() == ArgValues.size() && 394221345Sdim "This doesn't support passing arguments through varargs (yet)!"); 395221345Sdim 396221345Sdim // Handle some common cases first. These cases correspond to common `main' 397221345Sdim // prototypes. 398221345Sdim if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) { 399221345Sdim switch (ArgValues.size()) { 400221345Sdim case 3: 401221345Sdim if (FTy->getParamType(0)->isIntegerTy(32) && 402221345Sdim FTy->getParamType(1)->isPointerTy() && 403221345Sdim FTy->getParamType(2)->isPointerTy()) { 404221345Sdim int (*PF)(int, char **, const char **) = 405221345Sdim (int(*)(int, char **, const char **))(intptr_t)FPtr; 406221345Sdim 407221345Sdim // Call the function. 408221345Sdim GenericValue rv; 409221345Sdim rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), 410221345Sdim (char **)GVTOP(ArgValues[1]), 411221345Sdim (const char **)GVTOP(ArgValues[2]))); 412221345Sdim return rv; 413221345Sdim } 414221345Sdim break; 415221345Sdim case 2: 416221345Sdim if (FTy->getParamType(0)->isIntegerTy(32) && 417221345Sdim FTy->getParamType(1)->isPointerTy()) { 418221345Sdim int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr; 419221345Sdim 420221345Sdim // Call the function. 421221345Sdim GenericValue rv; 422221345Sdim rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(), 423221345Sdim (char **)GVTOP(ArgValues[1]))); 424221345Sdim return rv; 425221345Sdim } 426221345Sdim break; 427221345Sdim case 1: 428221345Sdim if (FTy->getNumParams() == 1 && 429221345Sdim FTy->getParamType(0)->isIntegerTy(32)) { 430221345Sdim GenericValue rv; 431221345Sdim int (*PF)(int) = (int(*)(int))(intptr_t)FPtr; 432221345Sdim rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue())); 433221345Sdim return rv; 434221345Sdim } 435221345Sdim break; 436221345Sdim } 437221345Sdim } 438221345Sdim 439221345Sdim // Handle cases where no arguments are passed first. 440221345Sdim if (ArgValues.empty()) { 441221345Sdim GenericValue rv; 442221345Sdim switch (RetTy->getTypeID()) { 443221345Sdim default: llvm_unreachable("Unknown return type for function call!"); 444221345Sdim case Type::IntegerTyID: { 445221345Sdim unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth(); 446221345Sdim if (BitWidth == 1) 447221345Sdim rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)()); 448221345Sdim else if (BitWidth <= 8) 449221345Sdim rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)()); 450221345Sdim else if (BitWidth <= 16) 451221345Sdim rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)()); 452221345Sdim else if (BitWidth <= 32) 453221345Sdim rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)()); 454221345Sdim else if (BitWidth <= 64) 455221345Sdim rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)()); 456221345Sdim else 457221345Sdim llvm_unreachable("Integer types > 64 bits not supported"); 458221345Sdim return rv; 459221345Sdim } 460221345Sdim case Type::VoidTyID: 461221345Sdim rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)()); 462221345Sdim return rv; 463221345Sdim case Type::FloatTyID: 464221345Sdim rv.FloatVal = ((float(*)())(intptr_t)FPtr)(); 465221345Sdim return rv; 466221345Sdim case Type::DoubleTyID: 467221345Sdim rv.DoubleVal = ((double(*)())(intptr_t)FPtr)(); 468221345Sdim return rv; 469221345Sdim case Type::X86_FP80TyID: 470221345Sdim case Type::FP128TyID: 471221345Sdim case Type::PPC_FP128TyID: 472221345Sdim llvm_unreachable("long double not supported yet"); 473221345Sdim case Type::PointerTyID: 474221345Sdim return PTOGV(((void*(*)())(intptr_t)FPtr)()); 475221345Sdim } 476221345Sdim } 477221345Sdim 478235633Sdim llvm_unreachable("Full-featured argument passing not supported yet!"); 479218885Sdim} 480235633Sdim 481235633Sdimvoid *MCJIT::getPointerToNamedFunction(const std::string &Name, 482245431Sdim bool AbortOnFailure) { 483263509Sdim if (!isSymbolSearchingDisabled()) { 484263509Sdim void *ptr = MemMgr.getPointerToNamedFunction(Name, false); 485235633Sdim if (ptr) 486235633Sdim return ptr; 487235633Sdim } 488235633Sdim 489235633Sdim /// If a LazyFunctionCreator is installed, use it to get/create the function. 490235633Sdim if (LazyFunctionCreator) 491235633Sdim if (void *RP = LazyFunctionCreator(Name)) 492235633Sdim return RP; 493235633Sdim 494235633Sdim if (AbortOnFailure) { 495235633Sdim report_fatal_error("Program used external function '"+Name+ 496245431Sdim "' which could not be resolved!"); 497235633Sdim } 498235633Sdim return 0; 499235633Sdim} 500245431Sdim 501245431Sdimvoid MCJIT::RegisterJITEventListener(JITEventListener *L) { 502245431Sdim if (L == NULL) 503245431Sdim return; 504245431Sdim MutexGuard locked(lock); 505245431Sdim EventListeners.push_back(L); 506245431Sdim} 507245431Sdimvoid MCJIT::UnregisterJITEventListener(JITEventListener *L) { 508245431Sdim if (L == NULL) 509245431Sdim return; 510245431Sdim MutexGuard locked(lock); 511245431Sdim SmallVector<JITEventListener*, 2>::reverse_iterator I= 512245431Sdim std::find(EventListeners.rbegin(), EventListeners.rend(), L); 513245431Sdim if (I != EventListeners.rend()) { 514245431Sdim std::swap(*I, EventListeners.back()); 515245431Sdim EventListeners.pop_back(); 516245431Sdim } 517245431Sdim} 518245431Sdimvoid MCJIT::NotifyObjectEmitted(const ObjectImage& Obj) { 519245431Sdim MutexGuard locked(lock); 520263509Sdim MemMgr.notifyObjectLoaded(this, &Obj); 521245431Sdim for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { 522245431Sdim EventListeners[I]->NotifyObjectEmitted(Obj); 523245431Sdim } 524245431Sdim} 525245431Sdimvoid MCJIT::NotifyFreeingObject(const ObjectImage& Obj) { 526245431Sdim MutexGuard locked(lock); 527245431Sdim for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) { 528245431Sdim EventListeners[I]->NotifyFreeingObject(Obj); 529245431Sdim } 530245431Sdim} 531263509Sdim 532263509Sdimuint64_t LinkingMemoryManager::getSymbolAddress(const std::string &Name) { 533263509Sdim uint64_t Result = ParentEngine->getSymbolAddress(Name, false); 534263509Sdim // If the symbols wasn't found and it begins with an underscore, try again 535263509Sdim // without the underscore. 536263509Sdim if (!Result && Name[0] == '_') 537263509Sdim Result = ParentEngine->getSymbolAddress(Name.substr(1), false); 538263509Sdim if (Result) 539263509Sdim return Result; 540263509Sdim return ClientMM->getSymbolAddress(Name); 541263509Sdim} 542