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