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