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