| #include "../RemoteJITUtils.h" |
| #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" |
| #include "llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h" |
| #include "llvm/ExecutionEngine/Orc/OrcABISupport.h" |
| #include "llvm/Support/CommandLine.h" |
| #include "llvm/Support/DynamicLibrary.h" |
| #include "llvm/Support/Error.h" |
| #include "llvm/Support/raw_ostream.h" |
| #include "llvm/Support/TargetSelect.h" |
| #include <cstdint> |
| #include <cstdio> |
| #include <cstring> |
| #include <string> |
| #include <netinet/in.h> |
| #include <sys/socket.h> |
| |
| using namespace llvm; |
| using namespace llvm::orc; |
| |
| // Command line argument for TCP port. |
| cl::opt<uint32_t> Port("port", |
| cl::desc("TCP port to listen on"), |
| cl::init(20000)); |
| |
| ExitOnError ExitOnErr; |
| |
| using MainFun = int (*)(int, const char*[]); |
| |
| template <typename NativePtrT> |
| NativePtrT MakeNative(uint64_t P) { |
| return reinterpret_cast<NativePtrT>(static_cast<uintptr_t>(P)); |
| } |
| |
| extern "C" |
| void printExprResult(double Val) { |
| printf("Expression evaluated to: %f\n", Val); |
| } |
| |
| // --- LAZY COMPILE TEST --- |
| int main(int argc, char* argv[]) { |
| if (argc == 0) |
| ExitOnErr.setBanner("jit_server: "); |
| else |
| ExitOnErr.setBanner(std::string(argv[0]) + ": "); |
| |
| // --- Initialize LLVM --- |
| cl::ParseCommandLineOptions(argc, argv, "LLVM lazy JIT example.\n"); |
| |
| InitializeNativeTarget(); |
| InitializeNativeTargetAsmPrinter(); |
| InitializeNativeTargetAsmParser(); |
| |
| if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) { |
| errs() << "Error loading program symbols.\n"; |
| return 1; |
| } |
| |
| // --- Initialize remote connection --- |
| |
| int sockfd = socket(PF_INET, SOCK_STREAM, 0); |
| sockaddr_in servAddr, clientAddr; |
| socklen_t clientAddrLen = sizeof(clientAddr); |
| memset(&servAddr, 0, sizeof(servAddr)); |
| servAddr.sin_family = PF_INET; |
| servAddr.sin_family = INADDR_ANY; |
| servAddr.sin_port = htons(Port); |
| |
| { |
| // avoid "Address already in use" error. |
| int yes = 1; |
| if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) { |
| errs() << "Error calling setsockopt.\n"; |
| return 1; |
| } |
| } |
| |
| if (bind(sockfd, reinterpret_cast<sockaddr*>(&servAddr), |
| sizeof(servAddr)) < 0) { |
| errs() << "Error on binding.\n"; |
| return 1; |
| } |
| listen(sockfd, 1); |
| int newsockfd = accept(sockfd, reinterpret_cast<sockaddr*>(&clientAddr), |
| &clientAddrLen); |
| |
| auto SymbolLookup = |
| [](const std::string &Name) { |
| return RTDyldMemoryManager::getSymbolAddressInProcess(Name); |
| }; |
| |
| auto RegisterEHFrames = |
| [](uint8_t *Addr, uint32_t Size) { |
| RTDyldMemoryManager::registerEHFramesInProcess(Addr, Size); |
| }; |
| |
| auto DeregisterEHFrames = |
| [](uint8_t *Addr, uint32_t Size) { |
| RTDyldMemoryManager::deregisterEHFramesInProcess(Addr, Size); |
| }; |
| |
| FDRPCChannel TCPChannel(newsockfd, newsockfd); |
| |
| using MyServerT = remote::OrcRemoteTargetServer<FDRPCChannel, OrcX86_64_SysV>; |
| |
| MyServerT Server(TCPChannel, SymbolLookup, RegisterEHFrames, DeregisterEHFrames); |
| |
| while (!Server.receivedTerminate()) |
| ExitOnErr(Server.handleOne()); |
| |
| return 0; |
| } |