1bb498ca5c2acb7567d8d4d84b00229bed6f501b1Eric Christopher//===-- MCJIT.cpp - MC-based Just-in-Time Compiler ------------------------===//
26aec29848676494867e26307698155bc2c5a4033Daniel Dunbar//
36aec29848676494867e26307698155bc2c5a4033Daniel Dunbar//                     The LLVM Compiler Infrastructure
46aec29848676494867e26307698155bc2c5a4033Daniel Dunbar//
56aec29848676494867e26307698155bc2c5a4033Daniel Dunbar// This file is distributed under the University of Illinois Open Source
66aec29848676494867e26307698155bc2c5a4033Daniel Dunbar// License. See LICENSE.TXT for details.
76aec29848676494867e26307698155bc2c5a4033Daniel Dunbar//
86aec29848676494867e26307698155bc2c5a4033Daniel Dunbar//===----------------------------------------------------------------------===//
96aec29848676494867e26307698155bc2c5a4033Daniel Dunbar
106aec29848676494867e26307698155bc2c5a4033Daniel Dunbar#include "MCJIT.h"
110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar#include "llvm/ADT/STLExtras.h"
126aec29848676494867e26307698155bc2c5a4033Daniel Dunbar#include "llvm/ExecutionEngine/GenericValue.h"
13776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor#include "llvm/ExecutionEngine/JITEventListener.h"
143f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor#include "llvm/ExecutionEngine/MCJIT.h"
15d2755af8bda2e0fd80efb46556485c4cdbe8704aAndrew Kaylor#include "llvm/ExecutionEngine/SectionMemoryManager.h"
160b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h"
170b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h"
180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h"
19ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/IR/LegacyPassManager.h"
2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/Mangler.h"
218e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor#include "llvm/IR/Module.h"
22f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach#include "llvm/MC/MCAsmInfo.h"
2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Object/Archive.h"
24ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Object/ObjectFile.h"
251f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/DynamicLibrary.h"
26d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ErrorHandling.h"
27f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach#include "llvm/Support/MemoryBuffer.h"
28ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor#include "llvm/Support/MutexGuard.h"
296aec29848676494867e26307698155bc2c5a4033Daniel Dunbar
306aec29848676494867e26307698155bc2c5a4033Daniel Dunbarusing namespace llvm;
316aec29848676494867e26307698155bc2c5a4033Daniel Dunbar
32ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid ObjectCache::anchor() {}
33ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
346aec29848676494867e26307698155bc2c5a4033Daniel Dunbarnamespace {
356aec29848676494867e26307698155bc2c5a4033Daniel Dunbar
366aec29848676494867e26307698155bc2c5a4033Daniel Dunbarstatic struct RegisterJIT {
376aec29848676494867e26307698155bc2c5a4033Daniel Dunbar  RegisterJIT() { MCJIT::Register(); }
386aec29848676494867e26307698155bc2c5a4033Daniel Dunbar} JITRegistrator;
396aec29848676494867e26307698155bc2c5a4033Daniel Dunbar
406aec29848676494867e26307698155bc2c5a4033Daniel Dunbar}
416aec29848676494867e26307698155bc2c5a4033Daniel Dunbar
426aec29848676494867e26307698155bc2c5a4033Daniel Dunbarextern "C" void LLVMLinkInMCJIT() {
436aec29848676494867e26307698155bc2c5a4033Daniel Dunbar}
446aec29848676494867e26307698155bc2c5a4033Daniel Dunbar
450c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga NainarExecutionEngine*
460c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga NainarMCJIT::createJIT(std::unique_ptr<Module> M,
470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                 std::string *ErrorStr,
480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                 std::shared_ptr<MCJITMemoryManager> MemMgr,
490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                 std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver,
500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                 std::unique_ptr<TargetMachine> TM) {
516aec29848676494867e26307698155bc2c5a4033Daniel Dunbar  // Try to register the program as a source of symbols to resolve against.
526aec29848676494867e26307698155bc2c5a4033Daniel Dunbar  //
536aec29848676494867e26307698155bc2c5a4033Daniel Dunbar  // FIXME: Don't do this here.
54dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  sys::DynamicLibrary::LoadLibraryPermanently(nullptr, nullptr);
556aec29848676494867e26307698155bc2c5a4033Daniel Dunbar
560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (!MemMgr || !Resolver) {
570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    auto RTDyldMM = std::make_shared<SectionMemoryManager>();
580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (!MemMgr)
590c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      MemMgr = RTDyldMM;
600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    if (!Resolver)
610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      Resolver = RTDyldMM;
620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
640c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return new MCJIT(std::move(M), std::move(TM), std::move(MemMgr),
650c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                   std::move(Resolver));
666aec29848676494867e26307698155bc2c5a4033Daniel Dunbar}
676aec29848676494867e26307698155bc2c5a4033Daniel Dunbar
68f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarMCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> TM,
690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar             std::shared_ptr<MCJITMemoryManager> MemMgr,
700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar             std::shared_ptr<RuntimeDyld::SymbolResolver> Resolver)
71f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    : ExecutionEngine(TM->createDataLayout(), std::move(M)), TM(std::move(TM)),
72f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Ctx(nullptr), MemMgr(std::move(MemMgr)),
73f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Resolver(*this, std::move(Resolver)), Dyld(*this->MemMgr, this->Resolver),
74f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ObjCache(nullptr) {
752ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // FIXME: We are managing our modules, so we do not want the base class
762ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // ExecutionEngine to manage them as well. To avoid double destruction
772ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // of the first (and only) module added in ExecutionEngine constructor
782ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // we remove it from EE and will destruct it ourselves.
792ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  //
802ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // It may make sense to move our module manager (based on SmallStPtr) back
812ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // into EE if the JIT and Interpreter can live with it.
822ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // If so, additional functions: addModule, removeModule, FindFunctionNamed,
832ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // runStaticConstructorsDestructors could be moved back to EE as well.
842ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  //
8537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<Module> First = std::move(Modules[0]);
862ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  Modules.clear();
8737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
88de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (First->getDataLayout().isDefault())
89de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    First->setDataLayout(getDataLayout());
90de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  OwnedModules.addModule(std::move(First));
92ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  RegisterJITEventListener(JITEventListener::createGDBRegistrationListener());
9337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
9437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMCJIT::~MCJIT() {
9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MutexGuard locked(lock);
9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
9843507d026bef31100cb0c35614bcf419029a265bAndrew Kaylor  Dyld.deregisterEHFrames();
99817987350442e9349dbcf3416abaadc1796036a4Chandler Carruth
10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (auto &Obj : LoadedObjects)
10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Obj)
102817987350442e9349dbcf3416abaadc1796036a4Chandler Carruth      NotifyFreeingObject(*Obj);
10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Archives.clear();
105ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor}
106ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor
10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid MCJIT::addModule(std::unique_ptr<Module> M) {
1086169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
109de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
110de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (M->getDataLayout().isDefault())
111de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    M->setDataLayout(getDataLayout());
112de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  OwnedModules.addModule(std::move(M));
1142ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor}
1152ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor
1162ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylorbool MCJIT::removeModule(Module *M) {
1172ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  MutexGuard locked(lock);
1182ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  return OwnedModules.removeModule(M);
1198e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor}
1208e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid MCJIT::addObjectFile(std::unique_ptr<object::ObjectFile> Obj) {
122ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L = Dyld.loadObject(*Obj);
123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Dyld.hasError())
12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    report_fatal_error(Dyld.getErrorString());
12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  NotifyObjectEmitted(*Obj, *L);
12737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  LoadedObjects.push_back(std::move(Obj));
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid MCJIT::addObjectFile(object::OwningBinary<object::ObjectFile> Obj) {
13237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<object::ObjectFile> ObjFile;
13337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::unique_ptr<MemoryBuffer> MemBuf;
13437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  std::tie(ObjFile, MemBuf) = Obj.takeBinary();
13537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  addObjectFile(std::move(ObjFile));
13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Buffers.push_back(std::move(MemBuf));
13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
13937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid MCJIT::addArchive(object::OwningBinary<object::Archive> A) {
14037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Archives.push_back(std::move(A));
14137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1431c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylorvoid MCJIT::setObjectCache(ObjectCache* NewCache) {
1446169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
1451c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor  ObjCache = NewCache;
1461c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor}
1471c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor
148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstd::unique_ptr<MemoryBuffer> MCJIT::emitObject(Module *M) {
1496169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
1506169453ba37ac353655f2475f336e66f31276752Andrew Kaylor
1512ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // This must be a module which has already been added but not loaded to this
1522ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // MCJIT instance, since these conditions are tested by our caller,
1532ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // generateCodeForModule.
154ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor
155ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  legacy::PassManager PM;
156ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor
1573f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor  // The RuntimeDyld will take ownership of this shortly
158ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SmallVector<char, 4096> ObjBufferSV;
159ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  raw_svector_ostream ObjStream(ObjBufferSV);
1603f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor
16131649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach  // Turn the machine code intermediate representation into bytes in memory
16231649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach  // that may be executed.
163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (TM->addPassesToEmitMC(PM, Ctx, ObjStream, !getVerifyModules()))
16431649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach    report_fatal_error("Target does not support MC emission!");
16531649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach
16631649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach  // Initialize passes.
1678e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  PM.run(*M);
1683f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor  // Flush the output buffer to get the generated code into memory
169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
170ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::unique_ptr<MemoryBuffer> CompiledObjBuffer(
171ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                new ObjectMemoryBuffer(std::move(ObjBufferSV)));
1721c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor
1731c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor  // If we have an object cache, tell it about the new object.
1741c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor  // Note that we're using the compiled image, not the loaded image (as below).
1751c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor  if (ObjCache) {
1761c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor    // MemoryBuffer is a thin wrapper around the actual memory, so it's OK
1771c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor    // to create a temporary object here and delete it after the call.
178ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    MemoryBufferRef MB = CompiledObjBuffer->getMemBufferRef();
17937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ObjCache->notifyObjectCompiled(M, MB);
1801c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor  }
1811c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor
182ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return CompiledObjBuffer;
1831c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor}
1841c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor
1858e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylorvoid MCJIT::generateCodeForModule(Module *M) {
1866169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  // Get a thread lock to make sure we aren't trying to load multiple times
1876169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
1886169453ba37ac353655f2475f336e66f31276752Andrew Kaylor
1898e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  // This must be a module which has already been added to this MCJIT instance.
1902ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  assert(OwnedModules.ownsModule(M) &&
1912ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor         "MCJIT::generateCodeForModule: Unknown module.");
1921c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor
1931c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor  // Re-compilation is not supported
1942ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  if (OwnedModules.hasModuleBeenLoaded(M))
1951c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor    return;
1961c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor
197ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::unique_ptr<MemoryBuffer> ObjectToLoad;
1981c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor  // Try to load the pre-compiled object from cache if possible
199ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (ObjCache)
200ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    ObjectToLoad = ObjCache->getObject(M);
2011c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor
202de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  assert(M->getDataLayout() == getDataLayout() && "DataLayout Mismatch");
203f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2041c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor  // If the cache did not contain a suitable object, compile the object
2051c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor  if (!ObjectToLoad) {
20637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ObjectToLoad = emitObject(M);
20737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert(ObjectToLoad && "Compilation did not produce an object.");
2081c489455ea5fac43a5f20911dfb5486630eb0160Andrew Kaylor  }
209f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach
210f922910494377909b4cf2a0b73f509b2b1925799Jim Grosbach  // Load the object into the dynamic linker.
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // MCJIT now owns the ObjectImage pointer (via its LoadedObjects list).
212de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Expected<std::unique_ptr<object::ObjectFile>> LoadedObject =
213ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    object::ObjectFile::createObjectFile(ObjectToLoad->getMemBufferRef());
214de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!LoadedObject) {
215de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    std::string Buf;
216de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    raw_string_ostream OS(Buf);
217de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    logAllUnhandledErrors(LoadedObject.takeError(), OS, "");
218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    OS.flush();
219de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    report_fatal_error(Buf);
220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
221ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  std::unique_ptr<RuntimeDyld::LoadedObjectInfo> L =
222ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Dyld.loadObject(*LoadedObject.get());
223ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor
224ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Dyld.hasError())
225ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    report_fatal_error(Dyld.getErrorString());
2263f23cef24fc9200def464bd4bce820678b5715deAndrew Kaylor
227ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  NotifyObjectEmitted(*LoadedObject.get(), *L);
228776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor
229ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Buffers.push_back(std::move(ObjectToLoad));
230ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  LoadedObjects.push_back(std::move(*LoadedObject));
23137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
2322ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  OwnedModules.markModuleAsLoaded(M);
2338e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor}
2348e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
2358e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylorvoid MCJIT::finalizeLoadedModules() {
2366169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
2376169453ba37ac353655f2475f336e66f31276752Andrew Kaylor
2388e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  // Resolve any outstanding relocations.
2398e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  Dyld.resolveRelocations();
2408e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
2412ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  OwnedModules.markAllLoadedModulesAsFinalized();
2428e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
2432ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // Register EH frame data for any module we own which has been loaded
244528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor  Dyld.registerEHFrames();
245528f6d787b1a847e61eb2f1114559f423fdeb68cAndrew Kaylor
2468e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  // Set page permissions.
2470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  MemMgr->finalizeMemory();
2486aec29848676494867e26307698155bc2c5a4033Daniel Dunbar}
2496aec29848676494867e26307698155bc2c5a4033Daniel Dunbar
2508e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor// FIXME: Rename this.
25128989889bf3aa3314562d438aece245b71176ec4Andrew Kaylorvoid MCJIT::finalizeObject() {
2526169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
2536169453ba37ac353655f2475f336e66f31276752Andrew Kaylor
25437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Generate code for module is going to move objects out of the 'added' list,
25537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // so we need to copy that out before using it:
25637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallVector<Module*, 16> ModsToAdd;
25737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (auto M : OwnedModules.added())
25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ModsToAdd.push_back(M);
25937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (auto M : ModsToAdd)
2612ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor    generateCodeForModule(M);
26228989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor
2632ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  finalizeLoadedModules();
2648e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor}
2658e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
2668e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylorvoid MCJIT::finalizeModule(Module *M) {
2676169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
2686169453ba37ac353655f2475f336e66f31276752Andrew Kaylor
2698e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  // This must be a module which has already been added to this MCJIT instance.
2702ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  assert(OwnedModules.ownsModule(M) && "MCJIT::finalizeModule: Unknown module.");
2718e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
2728e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  // If the module hasn't been compiled, just do that.
2732ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  if (!OwnedModules.hasModuleBeenLoaded(M))
2748e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor    generateCodeForModule(M);
2758e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
2762ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  finalizeLoadedModules();
27728989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor}
27828989889bf3aa3314562d438aece245b71176ec4Andrew Kaylor
2790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga NainarRuntimeDyld::SymbolInfo MCJIT::findExistingSymbol(const std::string &Name) {
28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallString<128> FullName;
281f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Mangler::getNameWithPrefix(FullName, Name, getDataLayout());
282f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
283f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (void *Addr = getPointerToGlobalIfAvailable(FullName))
284f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return RuntimeDyld::SymbolInfo(static_cast<uint64_t>(
285f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                     reinterpret_cast<uintptr_t>(Addr)),
286f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                   JITSymbolFlags::Exported);
287f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2880c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return Dyld.getSymbol(FullName);
2898e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor}
2908e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
2918e9ec015348c5419b905c2ca6e39534429eda073Andrew KaylorModule *MCJIT::findModuleForSymbol(const std::string &Name,
2928e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor                                   bool CheckFunctionsOnly) {
2936169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
2946169453ba37ac353655f2475f336e66f31276752Andrew Kaylor
2958e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  // If it hasn't already been generated, see if it's in one of our modules.
2962ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  for (ModulePtrSet::iterator I = OwnedModules.begin_added(),
2972ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor                              E = OwnedModules.end_added();
2982ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor       I != E; ++I) {
2992ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor    Module *M = *I;
3008e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor    Function *F = M->getFunction(Name);
30159bbf5a759a4891ea90ac67f13485f67ef42234cAndrew Kaylor    if (F && !F->isDeclaration())
3028e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor      return M;
3038e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor    if (!CheckFunctionsOnly) {
3048e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor      GlobalVariable *G = M->getGlobalVariable(Name);
30559bbf5a759a4891ea90ac67f13485f67ef42234cAndrew Kaylor      if (G && !G->isDeclaration())
3068e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor        return M;
3078e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor      // FIXME: Do we need to worry about global aliases?
3088e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor    }
3098e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  }
3108e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  // We didn't find the symbol in any of our modules.
311dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
3128e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor}
3138e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
3148e9ec015348c5419b905c2ca6e39534429eda073Andrew Kayloruint64_t MCJIT::getSymbolAddress(const std::string &Name,
3150c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                 bool CheckFunctionsOnly) {
3160c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return findSymbol(Name, CheckFunctionsOnly).getAddress();
3170c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
3180c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
3190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga NainarRuntimeDyld::SymbolInfo MCJIT::findSymbol(const std::string &Name,
3200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                                          bool CheckFunctionsOnly) {
3216169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
3226169453ba37ac353655f2475f336e66f31276752Andrew Kaylor
3238e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  // First, check to see if we already have this symbol.
3240c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (auto Sym = findExistingSymbol(Name))
3250c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return Sym;
3268e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
32737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (object::OwningBinary<object::Archive> &OB : Archives) {
32837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    object::Archive *A = OB.getBinary();
32936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Look for our symbols in each Archive
330de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    auto OptionalChildOrErr = A->findSym(Name);
331de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!OptionalChildOrErr)
332de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      report_fatal_error(OptionalChildOrErr.takeError());
333de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    auto &OptionalChild = *OptionalChildOrErr;
334de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (OptionalChild) {
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // FIXME: Support nested archives?
336de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Expected<std::unique_ptr<object::Binary>> ChildBinOrErr =
337de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          OptionalChild->getAsBinary();
338de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!ChildBinOrErr) {
339de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        // TODO: Actually report errors helpfully.
340de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        consumeError(ChildBinOrErr.takeError());
341c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        continue;
342de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      }
34337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      std::unique_ptr<object::Binary> &ChildBin = ChildBinOrErr.get();
344c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (ChildBin->isObject()) {
345dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        std::unique_ptr<object::ObjectFile> OF(
346dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            static_cast<object::ObjectFile *>(ChildBin.release()));
34736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        // This causes the object file to be loaded.
348dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        addObjectFile(std::move(OF));
34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        // The address should be here now.
3500c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        if (auto Sym = findExistingSymbol(Name))
3510c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar          return Sym;
35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
3568e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  // If it hasn't already been generated, see if it's in one of our modules.
3578e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  Module *M = findModuleForSymbol(Name, CheckFunctionsOnly);
35837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (M) {
35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    generateCodeForModule(M);
36037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
36137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Check the RuntimeDyld table again, it should be there now.
3620c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return findExistingSymbol(Name);
36337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
3648e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
36537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // If a LazyFunctionCreator is installed, use it to get/create the function.
36637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // FIXME: Should we instead have a LazySymbolCreator callback?
3670c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (LazyFunctionCreator) {
3680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    auto Addr = static_cast<uint64_t>(
3690c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar                  reinterpret_cast<uintptr_t>(LazyFunctionCreator(Name)));
3700c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);
3710c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
3728e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
3730c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return nullptr;
3748e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor}
3758e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
3768e9ec015348c5419b905c2ca6e39534429eda073Andrew Kayloruint64_t MCJIT::getGlobalValueAddress(const std::string &Name) {
3776169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
3788e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  uint64_t Result = getSymbolAddress(Name, false);
3798e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  if (Result != 0)
3808e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor    finalizeLoadedModules();
3818e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  return Result;
3828e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor}
3838e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
3848e9ec015348c5419b905c2ca6e39534429eda073Andrew Kayloruint64_t MCJIT::getFunctionAddress(const std::string &Name) {
3856169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
3868e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  uint64_t Result = getSymbolAddress(Name, true);
3878e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  if (Result != 0)
3888e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor    finalizeLoadedModules();
3898e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  return Result;
3908e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor}
3918e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
3928e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor// Deprecated.  Use getFunctionAddress instead.
3938e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylorvoid *MCJIT::getPointerToFunction(Function *F) {
3946169453ba37ac353655f2475f336e66f31276752Andrew Kaylor  MutexGuard locked(lock);
395ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor
396f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Mangler Mang;
39737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallString<128> Name;
39837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  TM->getNameWithPrefix(Name, F, Mang);
39937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
40034714a06096f854c76371295d8c20b017fbba50bJim Grosbach  if (F->isDeclaration() || F->hasAvailableExternallyLinkage()) {
40134714a06096f854c76371295d8c20b017fbba50bJim Grosbach    bool AbortOnFailure = !F->hasExternalWeakLinkage();
40237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    void *Addr = getPointerToNamedFunction(Name, AbortOnFailure);
40337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    updateGlobalMapping(F, Addr);
40434714a06096f854c76371295d8c20b017fbba50bJim Grosbach    return Addr;
40534714a06096f854c76371295d8c20b017fbba50bJim Grosbach  }
40634714a06096f854c76371295d8c20b017fbba50bJim Grosbach
4078e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  Module *M = F->getParent();
4082ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  bool HasBeenAddedButNotLoaded = OwnedModules.hasModuleBeenAddedButNotLoaded(M);
4098e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
4108e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  // Make sure the relevant module has been compiled and loaded.
4112ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  if (HasBeenAddedButNotLoaded)
4128e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor    generateCodeForModule(M);
41337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  else if (!OwnedModules.hasModuleBeenLoaded(M)) {
4142ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor    // If this function doesn't belong to one of our modules, we're done.
41537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // FIXME: Asking for the pointer to a function that hasn't been registered,
41637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    //        and isn't a declaration (which is handled above) should probably
41737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    //        be an assertion.
418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return nullptr;
41937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
4208e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
421ea708d1071898bd8fda58f9d58d1d3fe38faf9f2Andrew Kaylor  // FIXME: Should the Dyld be retaining module information? Probably not.
42235ed842773da41779d57d3ed23f440202d0be198Jim Grosbach  //
42335ed842773da41779d57d3ed23f440202d0be198Jim Grosbach  // This is the accessor for the target address, so make sure to check the
42435ed842773da41779d57d3ed23f440202d0be198Jim Grosbach  // load address of the symbol, not the local address.
4254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  return (void*)Dyld.getSymbol(Name).getAddress();
4266aec29848676494867e26307698155bc2c5a4033Daniel Dunbar}
4276aec29848676494867e26307698155bc2c5a4033Daniel Dunbar
4282ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylorvoid MCJIT::runStaticConstructorsDestructorsInModulePtrSet(
4292ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor    bool isDtors, ModulePtrSet::iterator I, ModulePtrSet::iterator E) {
4302ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  for (; I != E; ++I) {
43137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ExecutionEngine::runStaticConstructorsDestructors(**I, isDtors);
4322ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  }
4332ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor}
4342ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor
4352ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylorvoid MCJIT::runStaticConstructorsDestructors(bool isDtors) {
4362ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  // Execute global ctors/dtors for each module in the program.
4372ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  runStaticConstructorsDestructorsInModulePtrSet(
4382ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor      isDtors, OwnedModules.begin_added(), OwnedModules.end_added());
4392ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  runStaticConstructorsDestructorsInModulePtrSet(
4402ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor      isDtors, OwnedModules.begin_loaded(), OwnedModules.end_loaded());
4412ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  runStaticConstructorsDestructorsInModulePtrSet(
4422ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor      isDtors, OwnedModules.begin_finalized(), OwnedModules.end_finalized());
4432ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor}
4442ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor
4452ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew KaylorFunction *MCJIT::FindFunctionNamedInModulePtrSet(const char *FnName,
4462ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor                                                 ModulePtrSet::iterator I,
4472ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor                                                 ModulePtrSet::iterator E) {
4482ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  for (; I != E; ++I) {
449ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Function *F = (*I)->getFunction(FnName);
450ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (F && !F->isDeclaration())
4512ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor      return F;
4522ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  }
453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
4542ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor}
4552ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor
456f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarGlobalVariable *MCJIT::FindGlobalVariableNamedInModulePtrSet(const char *Name,
457f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                                             bool AllowInternal,
458f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                                             ModulePtrSet::iterator I,
459f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                                             ModulePtrSet::iterator E) {
460f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (; I != E; ++I) {
461f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    GlobalVariable *GV = (*I)->getGlobalVariable(Name, AllowInternal);
462f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (GV && !GV->isDeclaration())
463f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return GV;
464f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
465f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return nullptr;
466f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
467f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
468f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
4692ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew KaylorFunction *MCJIT::FindFunctionNamed(const char *FnName) {
4702ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  Function *F = FindFunctionNamedInModulePtrSet(
4712ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor      FnName, OwnedModules.begin_added(), OwnedModules.end_added());
4722ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  if (!F)
4732ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor    F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_loaded(),
4742ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor                                        OwnedModules.end_loaded());
4752ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  if (!F)
4762ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor    F = FindFunctionNamedInModulePtrSet(FnName, OwnedModules.begin_finalized(),
4772ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor                                        OwnedModules.end_finalized());
4782ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor  return F;
4792ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor}
4802ad18efdc73bc2356aa7fbf811d5ecbbaac0f2c9Andrew Kaylor
481f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarGlobalVariable *MCJIT::FindGlobalVariableNamed(const char *Name, bool AllowInternal) {
482f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  GlobalVariable *GV = FindGlobalVariableNamedInModulePtrSet(
483f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Name, AllowInternal, OwnedModules.begin_added(), OwnedModules.end_added());
484f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!GV)
485f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_loaded(),
486f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                        OwnedModules.end_loaded());
487f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!GV)
488f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    GV = FindGlobalVariableNamedInModulePtrSet(Name, AllowInternal, OwnedModules.begin_finalized(),
489f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                        OwnedModules.end_finalized());
490f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return GV;
491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
492f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
4936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarGenericValue MCJIT::runFunction(Function *F, ArrayRef<GenericValue> ArgValues) {
49434714a06096f854c76371295d8c20b017fbba50bJim Grosbach  assert(F && "Function *F was null at entry to run()");
49534714a06096f854c76371295d8c20b017fbba50bJim Grosbach
49631649e61bcead26a63c7cd452da90fff5e000b91Jim Grosbach  void *FPtr = getPointerToFunction(F);
497de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  finalizeModule(F->getParent());
49834714a06096f854c76371295d8c20b017fbba50bJim Grosbach  assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
499db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  FunctionType *FTy = F->getFunctionType();
500db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner  Type *RetTy = FTy->getReturnType();
50134714a06096f854c76371295d8c20b017fbba50bJim Grosbach
50234714a06096f854c76371295d8c20b017fbba50bJim Grosbach  assert((FTy->getNumParams() == ArgValues.size() ||
50334714a06096f854c76371295d8c20b017fbba50bJim Grosbach          (FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
50434714a06096f854c76371295d8c20b017fbba50bJim Grosbach         "Wrong number of arguments passed into function!");
50534714a06096f854c76371295d8c20b017fbba50bJim Grosbach  assert(FTy->getNumParams() == ArgValues.size() &&
50634714a06096f854c76371295d8c20b017fbba50bJim Grosbach         "This doesn't support passing arguments through varargs (yet)!");
50734714a06096f854c76371295d8c20b017fbba50bJim Grosbach
50834714a06096f854c76371295d8c20b017fbba50bJim Grosbach  // Handle some common cases first.  These cases correspond to common `main'
50934714a06096f854c76371295d8c20b017fbba50bJim Grosbach  // prototypes.
51034714a06096f854c76371295d8c20b017fbba50bJim Grosbach  if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
51134714a06096f854c76371295d8c20b017fbba50bJim Grosbach    switch (ArgValues.size()) {
51234714a06096f854c76371295d8c20b017fbba50bJim Grosbach    case 3:
51334714a06096f854c76371295d8c20b017fbba50bJim Grosbach      if (FTy->getParamType(0)->isIntegerTy(32) &&
51434714a06096f854c76371295d8c20b017fbba50bJim Grosbach          FTy->getParamType(1)->isPointerTy() &&
51534714a06096f854c76371295d8c20b017fbba50bJim Grosbach          FTy->getParamType(2)->isPointerTy()) {
51634714a06096f854c76371295d8c20b017fbba50bJim Grosbach        int (*PF)(int, char **, const char **) =
51734714a06096f854c76371295d8c20b017fbba50bJim Grosbach          (int(*)(int, char **, const char **))(intptr_t)FPtr;
51834714a06096f854c76371295d8c20b017fbba50bJim Grosbach
51934714a06096f854c76371295d8c20b017fbba50bJim Grosbach        // Call the function.
52034714a06096f854c76371295d8c20b017fbba50bJim Grosbach        GenericValue rv;
52134714a06096f854c76371295d8c20b017fbba50bJim Grosbach        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
52234714a06096f854c76371295d8c20b017fbba50bJim Grosbach                                 (char **)GVTOP(ArgValues[1]),
52334714a06096f854c76371295d8c20b017fbba50bJim Grosbach                                 (const char **)GVTOP(ArgValues[2])));
52434714a06096f854c76371295d8c20b017fbba50bJim Grosbach        return rv;
52534714a06096f854c76371295d8c20b017fbba50bJim Grosbach      }
52634714a06096f854c76371295d8c20b017fbba50bJim Grosbach      break;
52734714a06096f854c76371295d8c20b017fbba50bJim Grosbach    case 2:
52834714a06096f854c76371295d8c20b017fbba50bJim Grosbach      if (FTy->getParamType(0)->isIntegerTy(32) &&
52934714a06096f854c76371295d8c20b017fbba50bJim Grosbach          FTy->getParamType(1)->isPointerTy()) {
53034714a06096f854c76371295d8c20b017fbba50bJim Grosbach        int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
53134714a06096f854c76371295d8c20b017fbba50bJim Grosbach
53234714a06096f854c76371295d8c20b017fbba50bJim Grosbach        // Call the function.
53334714a06096f854c76371295d8c20b017fbba50bJim Grosbach        GenericValue rv;
53434714a06096f854c76371295d8c20b017fbba50bJim Grosbach        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
53534714a06096f854c76371295d8c20b017fbba50bJim Grosbach                                 (char **)GVTOP(ArgValues[1])));
53634714a06096f854c76371295d8c20b017fbba50bJim Grosbach        return rv;
53734714a06096f854c76371295d8c20b017fbba50bJim Grosbach      }
53834714a06096f854c76371295d8c20b017fbba50bJim Grosbach      break;
53934714a06096f854c76371295d8c20b017fbba50bJim Grosbach    case 1:
54034714a06096f854c76371295d8c20b017fbba50bJim Grosbach      if (FTy->getNumParams() == 1 &&
54134714a06096f854c76371295d8c20b017fbba50bJim Grosbach          FTy->getParamType(0)->isIntegerTy(32)) {
54234714a06096f854c76371295d8c20b017fbba50bJim Grosbach        GenericValue rv;
54334714a06096f854c76371295d8c20b017fbba50bJim Grosbach        int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
54434714a06096f854c76371295d8c20b017fbba50bJim Grosbach        rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
54534714a06096f854c76371295d8c20b017fbba50bJim Grosbach        return rv;
54634714a06096f854c76371295d8c20b017fbba50bJim Grosbach      }
54734714a06096f854c76371295d8c20b017fbba50bJim Grosbach      break;
54834714a06096f854c76371295d8c20b017fbba50bJim Grosbach    }
54934714a06096f854c76371295d8c20b017fbba50bJim Grosbach  }
55034714a06096f854c76371295d8c20b017fbba50bJim Grosbach
55134714a06096f854c76371295d8c20b017fbba50bJim Grosbach  // Handle cases where no arguments are passed first.
55234714a06096f854c76371295d8c20b017fbba50bJim Grosbach  if (ArgValues.empty()) {
55334714a06096f854c76371295d8c20b017fbba50bJim Grosbach    GenericValue rv;
55434714a06096f854c76371295d8c20b017fbba50bJim Grosbach    switch (RetTy->getTypeID()) {
55534714a06096f854c76371295d8c20b017fbba50bJim Grosbach    default: llvm_unreachable("Unknown return type for function call!");
55634714a06096f854c76371295d8c20b017fbba50bJim Grosbach    case Type::IntegerTyID: {
55734714a06096f854c76371295d8c20b017fbba50bJim Grosbach      unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
55834714a06096f854c76371295d8c20b017fbba50bJim Grosbach      if (BitWidth == 1)
55934714a06096f854c76371295d8c20b017fbba50bJim Grosbach        rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)());
56034714a06096f854c76371295d8c20b017fbba50bJim Grosbach      else if (BitWidth <= 8)
56134714a06096f854c76371295d8c20b017fbba50bJim Grosbach        rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)());
56234714a06096f854c76371295d8c20b017fbba50bJim Grosbach      else if (BitWidth <= 16)
56334714a06096f854c76371295d8c20b017fbba50bJim Grosbach        rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)());
56434714a06096f854c76371295d8c20b017fbba50bJim Grosbach      else if (BitWidth <= 32)
56534714a06096f854c76371295d8c20b017fbba50bJim Grosbach        rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)());
56634714a06096f854c76371295d8c20b017fbba50bJim Grosbach      else if (BitWidth <= 64)
56734714a06096f854c76371295d8c20b017fbba50bJim Grosbach        rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)());
56834714a06096f854c76371295d8c20b017fbba50bJim Grosbach      else
56934714a06096f854c76371295d8c20b017fbba50bJim Grosbach        llvm_unreachable("Integer types > 64 bits not supported");
57034714a06096f854c76371295d8c20b017fbba50bJim Grosbach      return rv;
57134714a06096f854c76371295d8c20b017fbba50bJim Grosbach    }
57234714a06096f854c76371295d8c20b017fbba50bJim Grosbach    case Type::VoidTyID:
57334714a06096f854c76371295d8c20b017fbba50bJim Grosbach      rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
57434714a06096f854c76371295d8c20b017fbba50bJim Grosbach      return rv;
57534714a06096f854c76371295d8c20b017fbba50bJim Grosbach    case Type::FloatTyID:
57634714a06096f854c76371295d8c20b017fbba50bJim Grosbach      rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
57734714a06096f854c76371295d8c20b017fbba50bJim Grosbach      return rv;
57834714a06096f854c76371295d8c20b017fbba50bJim Grosbach    case Type::DoubleTyID:
57934714a06096f854c76371295d8c20b017fbba50bJim Grosbach      rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
58034714a06096f854c76371295d8c20b017fbba50bJim Grosbach      return rv;
58134714a06096f854c76371295d8c20b017fbba50bJim Grosbach    case Type::X86_FP80TyID:
58234714a06096f854c76371295d8c20b017fbba50bJim Grosbach    case Type::FP128TyID:
58334714a06096f854c76371295d8c20b017fbba50bJim Grosbach    case Type::PPC_FP128TyID:
58434714a06096f854c76371295d8c20b017fbba50bJim Grosbach      llvm_unreachable("long double not supported yet");
58534714a06096f854c76371295d8c20b017fbba50bJim Grosbach    case Type::PointerTyID:
58634714a06096f854c76371295d8c20b017fbba50bJim Grosbach      return PTOGV(((void*(*)())(intptr_t)FPtr)());
58734714a06096f854c76371295d8c20b017fbba50bJim Grosbach    }
58834714a06096f854c76371295d8c20b017fbba50bJim Grosbach  }
58934714a06096f854c76371295d8c20b017fbba50bJim Grosbach
590858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper  llvm_unreachable("Full-featured argument passing not supported yet!");
5916aec29848676494867e26307698155bc2c5a4033Daniel Dunbar}
59230b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev
59337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid *MCJIT::getPointerToNamedFunction(StringRef Name, bool AbortOnFailure) {
5948e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  if (!isSymbolSearchingDisabled()) {
5950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    void *ptr =
5960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      reinterpret_cast<void*>(
5970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar        static_cast<uintptr_t>(Resolver.findSymbol(Name).getAddress()));
59830b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev    if (ptr)
59930b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev      return ptr;
60030b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev  }
60130b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev
60230b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev  /// If a LazyFunctionCreator is installed, use it to get/create the function.
60330b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev  if (LazyFunctionCreator)
60430b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev    if (void *RP = LazyFunctionCreator(Name))
60530b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev      return RP;
60630b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev
60730b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev  if (AbortOnFailure) {
60830b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev    report_fatal_error("Program used external function '"+Name+
6095fe019835c269ccbfe185276269bc53b3f9a7a86Eli Bendersky                       "' which could not be resolved!");
61030b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev  }
611dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
61230b9e322e159df8eaabb5b194cec6e11ba99c261Danil Malyshev}
613776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor
614776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid MCJIT::RegisterJITEventListener(JITEventListener *L) {
615dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!L)
616776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor    return;
617776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  MutexGuard locked(lock);
618776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  EventListeners.push_back(L);
619776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor}
620ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
621776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylorvoid MCJIT::UnregisterJITEventListener(JITEventListener *L) {
622dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!L)
623776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor    return;
624776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  MutexGuard locked(lock);
62537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  auto I = std::find(EventListeners.rbegin(), EventListeners.rend(), L);
626776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  if (I != EventListeners.rend()) {
627776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor    std::swap(*I, EventListeners.back());
628776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor    EventListeners.pop_back();
629776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  }
630776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor}
631ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
632ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid MCJIT::NotifyObjectEmitted(const object::ObjectFile& Obj,
633ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                const RuntimeDyld::LoadedObjectInfo &L) {
634776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  MutexGuard locked(lock);
6350c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  MemMgr->notifyObjectLoaded(this, Obj);
636776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  for (unsigned I = 0, S = EventListeners.size(); I < S; ++I) {
637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    EventListeners[I]->NotifyObjectEmitted(Obj, L);
638776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  }
639776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor}
640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
641ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid MCJIT::NotifyFreeingObject(const object::ObjectFile& Obj) {
642776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor  MutexGuard locked(lock);
64337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  for (JITEventListener *L : EventListeners)
64437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    L->NotifyFreeingObject(Obj);
645776054dd938472828ac3ebf75b05e21171ef4ecfAndrew Kaylor}
6468e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor
6470c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga NainarRuntimeDyld::SymbolInfo
6480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga NainarLinkingSymbolResolver::findSymbol(const std::string &Name) {
6490c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  auto Result = ParentEngine.findSymbol(Name, false);
65052c9016db0560644a03ca661302e45143372f2fcAndrew Kaylor  // If the symbols wasn't found and it begins with an underscore, try again
65152c9016db0560644a03ca661302e45143372f2fcAndrew Kaylor  // without the underscore.
65252c9016db0560644a03ca661302e45143372f2fcAndrew Kaylor  if (!Result && Name[0] == '_')
6530c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    Result = ParentEngine.findSymbol(Name.substr(1), false);
6548e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor  if (Result)
6558e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor    return Result;
6560c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (ParentEngine.isSymbolSearchingDisabled())
6570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return nullptr;
6580c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return ClientResolver->findSymbol(Name);
6598e9ec015348c5419b905c2ca6e39534429eda073Andrew Kaylor}
660