[LLI] Replace the LLI remote-JIT support with the new ORC remote-JIT components.
[oota-llvm.git] / tools / lli / ChildTarget / ChildTarget.cpp
index 6c537d47df3d1ee5443fd94d1b6faa3d0ad1bc35..0b75e20f83e9a52e539f1080ff99f2988429470c 100644 (file)
-#include "llvm/Config/config.h"
-#include "../RPCChannel.h"
-#include "../RemoteTarget.h"
-#include "../RemoteTargetMessage.h"
-#include "llvm/Support/Memory.h"
-#include <assert.h>
-#include <map>
-#include <stdint.h>
-#include <string>
-#include <vector>
+#include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h"
+#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Process.h"
+#include <sstream>
 
-using namespace llvm;
+#include "../RemoteJITUtils.h"
 
-class LLIChildTarget {
-public:
-  void initialize();
-  LLIMessageType waitForIncomingMessage();
-  void handleMessage(LLIMessageType messageType);
-  RemoteTarget *RT;
-  RPCChannel RPC;
+using namespace llvm;
+using namespace llvm::orc;
+using namespace llvm::sys;
 
-private:
-  // Incoming message handlers
-  void handleAllocateSpace();
-  void handleLoadSection(bool IsCode);
-  void handleExecute();
+#ifdef __x86_64__
+typedef OrcX86_64 HostOrcArch;
+#else
+typedef OrcGenericArchitecture HostOrcArch;
+#endif
 
-  // Outgoing message handlers
-  void sendChildActive();
-  void sendAllocationResult(uint64_t Addr);
-  void sendLoadStatus(uint32_t Status);
-  void sendExecutionComplete(int Result);
+int main(int argc, char *argv[]) {
 
-  // OS-specific functions
-  void initializeConnection();
-  int WriteBytes(const void *Data, size_t Size) {
-    return RPC.WriteBytes(Data, Size) ? Size : -1;
+  if (argc != 3) {
+    errs() << "Usage: " << argv[0] << " <input fd> <output fd>\n";
+    return 1;
   }
-  int ReadBytes(void *Data, size_t Size) {
-    return RPC.ReadBytes(Data, Size) ? Size : -1;
-  }
-
-  // Communication handles (OS-specific)
-  void *ConnectionData;
-};
-
-int main() {
-  LLIChildTarget  ThisChild;
-  ThisChild.RT = new RemoteTarget();
-  ThisChild.initialize();
-  LLIMessageType MsgType;
-  do {
-    MsgType = ThisChild.waitForIncomingMessage();
-    ThisChild.handleMessage(MsgType);
-  } while (MsgType != LLI_Terminate &&
-           MsgType != LLI_Error);
-  delete ThisChild.RT;
-  return 0;
-}
 
-// Public methods
-void LLIChildTarget::initialize() {
-  RPC.createClient();
-  sendChildActive();
-}
+  int InFD;
+  int OutFD;
+  {
+    std::istringstream InFDStream(argv[1]), OutFDStream(argv[2]);
+    InFDStream >> InFD;
+    OutFDStream >> OutFD;
+  }
 
-LLIMessageType LLIChildTarget::waitForIncomingMessage() {
-  int32_t MsgType = -1;
-  if (ReadBytes(&MsgType, 4) > 0)
-    return (LLIMessageType)MsgType;
-  return LLI_Error;
-}
+  if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {
+    errs() << "Error loading program symbols.\n";
+    return 1;
+  }
 
-void LLIChildTarget::handleMessage(LLIMessageType messageType) {
-  switch (messageType) {
-    case LLI_AllocateSpace:
-      handleAllocateSpace();
-      break;
-    case LLI_LoadCodeSection:
-      handleLoadSection(true);
-      break;
-    case LLI_LoadDataSection:
-      handleLoadSection(false);
-      break;
-    case LLI_Execute:
-      handleExecute();
-      break;
-    case LLI_Terminate:
-      RT->stop();
-      break;
+  auto SymbolLookup = [](const std::string &Name) {
+    return RTDyldMemoryManager::getSymbolAddressInProcess(Name);
+  };
+
+  FDRPCChannel Channel(InFD, OutFD);
+  typedef remote::OrcRemoteTargetServer<FDRPCChannel, HostOrcArch> JITServer;
+  JITServer Server(Channel, SymbolLookup);
+
+  while (1) {
+    JITServer::JITProcId Id = JITServer::InvalidId;
+    if (auto EC = Server.getNextProcId(Id)) {
+      errs() << "Error: " << EC.message() << "\n";
+      return 1;
+    }
+    switch (Id) {
+    case JITServer::TerminateSessionId:
+      return 0;
     default:
-      // FIXME: Handle error!
-      break;
+      if (auto EC = Server.handleKnownProcedure(Id)) {
+        errs() << "Error: " << EC.message() << "\n";
+        return 1;
+      }
+    }
   }
-}
-
-// Incoming message handlers
-void LLIChildTarget::handleAllocateSpace() {
-  // Read and verify the message data size.
-  uint32_t DataSize = 0;
-  int rc = ReadBytes(&DataSize, 4);
-  (void)rc;
-  assert(rc == 4);
-  assert(DataSize == 8);
-
-  // Read the message arguments.
-  uint32_t Alignment = 0;
-  uint32_t AllocSize = 0;
-  rc = ReadBytes(&Alignment, 4);
-  assert(rc == 4);
-  rc = ReadBytes(&AllocSize, 4);
-  assert(rc == 4);
-
-  // Allocate the memory.
-  uint64_t Addr;
-  RT->allocateSpace(AllocSize, Alignment, Addr);
-
-  // Send AllocationResult message.
-  sendAllocationResult(Addr);
-}
-
-void LLIChildTarget::handleLoadSection(bool IsCode) {
-  // Read the message data size.
-  uint32_t DataSize = 0;
-  int rc = ReadBytes(&DataSize, 4);
-  (void)rc;
-  assert(rc == 4);
-
-  // Read the target load address.
-  uint64_t Addr = 0;
-  rc = ReadBytes(&Addr, 8);
-  assert(rc == 8);
-  size_t BufferSize = DataSize - 8;
-
-  if (!RT->isAllocatedMemory(Addr, BufferSize))
-    return sendLoadStatus(LLI_Status_NotAllocated);
-
-  // Read section data into previously allocated buffer
-  rc = ReadBytes((void*)Addr, BufferSize);
-  if (rc != (int)(BufferSize))
-    return sendLoadStatus(LLI_Status_IncompleteMsg);
-
-  // If IsCode, mark memory executable
-  if (IsCode)
-    sys::Memory::InvalidateInstructionCache((void *)Addr, BufferSize);
-
-  // Send MarkLoadComplete message.
-  sendLoadStatus(LLI_Status_Success);
-}
-
-void LLIChildTarget::handleExecute() {
-  // Read the message data size.
-  uint32_t DataSize = 0;
-  int rc = ReadBytes(&DataSize, 4);
-  (void)rc;
-  assert(rc == 4);
-  assert(DataSize == 8);
-
-  // Read the target address.
-  uint64_t Addr = 0;
-  rc = ReadBytes(&Addr, 8);
-  assert(rc == 8);
-
-  // Call function
-  int32_t Result = -1;
-  RT->executeCode(Addr, Result);
-
-  // Send ExecutionResult message.
-  sendExecutionComplete(Result);
-}
-
-// Outgoing message handlers
-void LLIChildTarget::sendChildActive() {
-  // Write the message type.
-  uint32_t MsgType = (uint32_t)LLI_ChildActive;
-  int rc = WriteBytes(&MsgType, 4);
-  (void)rc;
-  assert(rc == 4);
-
-  // Write the data size.
-  uint32_t DataSize = 0;
-  rc = WriteBytes(&DataSize, 4);
-  assert(rc == 4);
-}
-
-void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
-  // Write the message type.
-  uint32_t MsgType = (uint32_t)LLI_AllocationResult;
-  int rc = WriteBytes(&MsgType, 4);
-  (void)rc;
-  assert(rc == 4);
-
-  // Write the data size.
-  uint32_t DataSize = 8;
-  rc = WriteBytes(&DataSize, 4);
-  assert(rc == 4);
-
-  // Write the allocated address.
-  rc = WriteBytes(&Addr, 8);
-  assert(rc == 8);
-}
-
-void LLIChildTarget::sendLoadStatus(uint32_t Status) {
-  // Write the message type.
-  uint32_t MsgType = (uint32_t)LLI_LoadResult;
-  int rc = WriteBytes(&MsgType, 4);
-  (void)rc;
-  assert(rc == 4);
-
-  // Write the data size.
-  uint32_t DataSize = 4;
-  rc = WriteBytes(&DataSize, 4);
-  assert(rc == 4);
-
-  // Write the result.
-  rc = WriteBytes(&Status, 4);
-  assert(rc == 4);
-}
-
-void LLIChildTarget::sendExecutionComplete(int Result) {
-  // Write the message type.
-  uint32_t MsgType = (uint32_t)LLI_ExecutionResult;
-  int rc = WriteBytes(&MsgType, 4);
-  (void)rc;
-  assert(rc == 4);
 
+  close(InFD);
+  close(OutFD);
 
-  // Write the data size.
-  uint32_t DataSize = 4;
-  rc = WriteBytes(&DataSize, 4);
-  assert(rc == 4);
-
-  // Write the result.
-  rc = WriteBytes(&Result, 4);
-  assert(rc == 4);
+  return 0;
 }
-
-#ifdef LLVM_ON_UNIX
-#include "../Unix/RPCChannel.inc"
-#endif
-
-#ifdef LLVM_ON_WIN32
-#include "../Windows/RPCChannel.inc"
-#endif