• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
MakeNative(uint64_t P)28 NativePtrT MakeNative(uint64_t P) {
29   return reinterpret_cast<NativePtrT>(static_cast<uintptr_t>(P));
30 }
31 
32 extern "C"
printExprResult(double Val)33 void printExprResult(double Val) {
34   printf("Expression evaluated to: %f\n", Val);
35 }
36 
37 // --- LAZY COMPILE TEST ---
main(int argc,char * argv[])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