[Orc] Add support classes for inspecting and running C++ static ctor/dtors, and
[oota-llvm.git] / tools / lli / OrcLazyJIT.cpp
index d17672c14457f601e55034aec40ee30e4f962c67..236de7c31d26d547239bb712d6fe7b64d9c65129 100644 (file)
@@ -9,34 +9,52 @@
 
 #include "OrcLazyJIT.h"
 #include "llvm/ExecutionEngine/Orc/OrcTargetSupport.h"
+#include "llvm/Support/DynamicLibrary.h"
 
 using namespace llvm;
 
-std::unique_ptr<OrcLazyJIT::CompileCallbackMgr>
-OrcLazyJIT::createCallbackMgr(Triple T, LLVMContext &Context) {
+OrcLazyJIT::CallbackManagerBuilder
+OrcLazyJIT::createCallbackManagerBuilder(Triple T) {
   switch (T.getArch()) {
-    default:
-      // Flag error.
-      Error = true;
-      return nullptr;
+    default: return nullptr;
 
     case Triple::x86_64: {
       typedef orc::JITCompileCallbackManager<CompileLayerT,
                                              orc::OrcX86_64> CCMgrT;
-      return make_unique<CCMgrT>(CompileLayer, CCMgrMemMgr, Context, 0, 64);
+      return [](CompileLayerT &CompileLayer, RuntimeDyld::MemoryManager &MemMgr,
+                LLVMContext &Context) {
+               return make_unique<CCMgrT>(CompileLayer, MemMgr, Context, 0, 64);
+             };
     }
   }
 }
 
 int llvm::runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]) {
-  OrcLazyJIT J(std::unique_ptr<TargetMachine>(EngineBuilder().selectTarget()),
-               getGlobalContext());
+  // Add the program's symbols into the JIT's search space.
+  if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {
+    errs() << "Error loading program symbols.\n";
+    return 1;
+  }
+
+  // Grab a target machine and try to build a factory function for the
+  // target-specific Orc callback manager.
+  auto TM = std::unique_ptr<TargetMachine>(EngineBuilder().selectTarget());
+  auto &Context = getGlobalContext();
+  auto CallbackMgrBuilder =
+    OrcLazyJIT::createCallbackManagerBuilder(Triple(TM->getTargetTriple()));
 
-  if (!J.Ok()) {
-    errs() << "Could not construct JIT.\n";
+  // If we couldn't build the factory function then there must not be a callback
+  // manager for this target. Bail out.
+  if (!CallbackMgrBuilder) {
+    errs() << "No callback manager available for target '"
+           << TM->getTargetTriple() << "'.\n";
     return 1;
   }
 
+  // Everything looks good. Build the JIT.
+  OrcLazyJIT J(std::move(TM), Context, CallbackMgrBuilder);
+
+  // Add the module, look up main and run it.
   auto MainHandle = J.addModule(std::move(M));
   auto MainSym = J.findSymbolIn(MainHandle, "main");
 
@@ -46,8 +64,6 @@ int llvm::runOrcLazyJIT(std::unique_ptr<Module> M, int ArgC, char* ArgV[]) {
   }
 
   typedef int (*MainFnPtr)(int, char*[]);
-  auto Main = reinterpret_cast<MainFnPtr>(
-                static_cast<uintptr_t>(MainSym.getAddress()));
-
+  auto Main = OrcLazyJIT::fromTargetAddress<MainFnPtr>(MainSym.getAddress());
   return Main(ArgC, ArgV);
 }