Home | History | Annotate | Download | only in Server
      1 #include "llvm/Support/CommandLine.h"
      2 #include "llvm/Support/DynamicLibrary.h"
      3 #include "llvm/Support/TargetSelect.h"
      4 #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h"
      5 #include "llvm/ExecutionEngine/Orc/OrcABISupport.h"
      6 
      7 #include "../RemoteJITUtils.h"
      8 
      9 #include <cstring>
     10 #include <unistd.h>
     11 #include <netinet/in.h>
     12 #include <sys/socket.h>
     13 
     14 
     15 using namespace llvm;
     16 using namespace llvm::orc;
     17 
     18 // Command line argument for TCP port.
     19 cl::opt<uint32_t> Port("port",
     20                        cl::desc("TCP port to listen on"),
     21                        cl::init(20000));
     22 
     23 ExitOnError ExitOnErr;
     24 
     25 typedef int (*MainFun)(int, const char*[]);
     26 
     27 template <typename NativePtrT>
     28 NativePtrT MakeNative(uint64_t P) {
     29   return reinterpret_cast<NativePtrT>(static_cast<uintptr_t>(P));
     30 }
     31 
     32 extern "C"
     33 void printExprResult(double Val) {
     34   printf("Expression evaluated to: %f\n", Val);
     35 }
     36 
     37 // --- LAZY COMPILE TEST ---
     38 int main(int argc, char* argv[]) {
     39 
     40   if (argc == 0)
     41     ExitOnErr.setBanner("jit_server: ");
     42   else
     43     ExitOnErr.setBanner(std::string(argv[0]) + ": ");
     44 
     45   // --- Initialize LLVM ---
     46   cl::ParseCommandLineOptions(argc, argv, "LLVM lazy JIT example.\n");
     47 
     48   InitializeNativeTarget();
     49   InitializeNativeTargetAsmPrinter();
     50   InitializeNativeTargetAsmParser();
     51 
     52   if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {
     53     errs() << "Error loading program symbols.\n";
     54     return 1;
     55   }
     56 
     57   // --- Initialize remote connection ---
     58 
     59   int sockfd = socket(PF_INET, SOCK_STREAM, 0);
     60   sockaddr_in servAddr, clientAddr;
     61   socklen_t clientAddrLen = sizeof(clientAddr);
     62   bzero(&servAddr, sizeof(servAddr));
     63   servAddr.sin_family = PF_INET;
     64   servAddr.sin_family = INADDR_ANY;
     65   servAddr.sin_port = htons(Port);
     66 
     67   {
     68     // avoid "Address already in use" error.
     69     int yes=1;
     70     if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {
     71       errs() << "Error calling setsockopt.\n";
     72       return 1;
     73     }
     74   }
     75 
     76   if (bind(sockfd, reinterpret_cast<sockaddr*>(&servAddr),
     77            sizeof(servAddr)) < 0) {
     78     errs() << "Error on binding.\n";
     79     return 1;
     80   }
     81   listen(sockfd, 1);
     82   int newsockfd = accept(sockfd, reinterpret_cast<sockaddr*>(&clientAddr),
     83                          &clientAddrLen);
     84 
     85   auto SymbolLookup =
     86     [](const std::string &Name) {
     87       return RTDyldMemoryManager::getSymbolAddressInProcess(Name);
     88     };
     89 
     90   auto RegisterEHFrames =
     91     [](uint8_t *Addr, uint32_t Size) {
     92       RTDyldMemoryManager::registerEHFramesInProcess(Addr, Size);
     93     };
     94 
     95   auto DeregisterEHFrames =
     96     [](uint8_t *Addr, uint32_t Size) {
     97       RTDyldMemoryManager::deregisterEHFramesInProcess(Addr, Size);
     98     };
     99 
    100   FDRPCChannel TCPChannel(newsockfd, newsockfd);
    101   typedef remote::OrcRemoteTargetServer<FDRPCChannel, OrcX86_64_SysV> MyServerT;
    102 
    103   MyServerT Server(TCPChannel, SymbolLookup, RegisterEHFrames, DeregisterEHFrames);
    104 
    105   while (1) {
    106     MyServerT::JITFuncId Id = MyServerT::InvalidId;
    107     ExitOnErr(Server.startReceivingFunction(TCPChannel, (uint32_t&)Id));
    108     switch (Id) {
    109     case MyServerT::TerminateSessionId:
    110       ExitOnErr(Server.handleTerminateSession());
    111       return 0;
    112     default:
    113       ExitOnErr(Server.handleKnownFunction(Id));
    114       break;
    115     }
    116   }
    117 
    118   llvm_unreachable("Fell through server command loop.");
    119 }
    120