diff --git a/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h b/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h --- a/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/RPC/RPCSerialization.h @@ -596,7 +596,7 @@ static Error serialize(ChannelT &C, const Optional &O) { if (auto Err = serializeSeq(C, O != None)) return Err; - if (O != None) + if (O) if (auto Err = serializeSeq(C, *O)) return Err; return Error::success(); diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h --- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h @@ -91,12 +91,9 @@ class WrapperFunctionResult { public: /// Create a default WrapperFunctionResult. - WrapperFunctionResult() - : R{ - 0, - {.ValuePtr = nullptr}, - nullptr, - } {} + WrapperFunctionResult() { + zeroInit(R); + } /// Create a WrapperFunctionResult from a CWrapperFunctionResult. This /// instance takes ownership of the result object and will automatically @@ -106,13 +103,14 @@ WrapperFunctionResult(const WrapperFunctionResult &) = delete; WrapperFunctionResult &operator=(const WrapperFunctionResult &) = delete; - WrapperFunctionResult(WrapperFunctionResult &&Other) - : R({0, {.ValuePtr = nullptr}, nullptr}) { + WrapperFunctionResult(WrapperFunctionResult &&Other) { + zeroInit(R); std::swap(R, Other.R); } WrapperFunctionResult &operator=(WrapperFunctionResult &&Other) { - CWrapperFunctionResult Tmp = {0, {.ValuePtr = nullptr}, nullptr}; + CWrapperFunctionResult Tmp; + zeroInit(Tmp); std::swap(Tmp, Other.R); std::swap(R, Tmp); return *this; @@ -125,7 +123,8 @@ /// Relinquish ownership of and return the CWrapperFunctionResult. CWrapperFunctionResult release() { - CWrapperFunctionResult Tmp = {0, {.ValuePtr = nullptr}, nullptr}; + CWrapperFunctionResult Tmp; + zeroInit(Tmp); std::swap(R, Tmp); return Tmp; } @@ -146,6 +145,7 @@ CWrapperFunctionResult R; R.Size = sizeof(T); memcpy(&R.Data.Value, Value, R.Size); + R.Destroy = nullptr; return R; } @@ -160,6 +160,12 @@ uint64_t Size); private: + void zeroInit(CWrapperFunctionResult &R) { + R.Size = 0; + R.Data.ValuePtr = nullptr; + R.Destroy = nullptr; + } + CWrapperFunctionResult R; }; diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h --- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/OrcRPCTPCServer.h @@ -249,7 +249,12 @@ } static Error deserialize(ChannelT &C, tpctypes::WrapperFunctionResult &E) { - tpctypes::CWrapperFunctionResult R = {0, {.ValuePtr = 0}, nullptr}; + tpctypes::CWrapperFunctionResult R; + + R.Size = 0; + R.Data.ValuePtr = nullptr; + R.Destroy = nullptr; + if (auto Err = deserializeSeq(C, R.Size)) return Err; if (R.Size == 0) @@ -465,7 +470,7 @@ uint64_t TotalSize = 0; - for (auto &E : Request) { + for (const auto &E : Request) { uint64_t Size = alignTo(E.Size, PageSize); uint16_t Align = E.Alignment; @@ -490,7 +495,7 @@ // Carve up sections to return. uint64_t SectionBase = 0; - for (auto &E : Request) { + for (const auto &E : Request) { uint64_t SectionSize = alignTo(E.Size, PageSize); Allocs.push_back({E.Prot, pointerToJITTargetAddress(MB.base()) + SectionBase, @@ -502,7 +507,7 @@ } Error finalizeMemory(const orcrpctpc::ReleaseOrFinalizeMemRequest &FMR) { - for (auto &E : FMR) { + for (const auto &E : FMR) { sys::MemoryBlock MB(jitTargetAddressToPointer(E.Address), E.Size); auto PF = orcrpctpc::fromWireProtectionFlags(E.Prot); @@ -516,7 +521,7 @@ } Error releaseMemory(const orcrpctpc::ReleaseOrFinalizeMemRequest &RMR) { - for (auto &E : RMR) { + for (const auto &E : RMR) { sys::MemoryBlock MB(jitTargetAddressToPointer(E.Address), E.Size); if (auto EC = sys::Memory::releaseMappedMemory(MB)) @@ -543,7 +548,7 @@ lookupSymbols(const std::vector &Request) { std::vector Result; - for (auto &E : Request) { + for (const auto &E : Request) { auto I = Dylibs.find(E.first); if (I == Dylibs.end()) return make_error("Unrecognized handle", @@ -551,13 +556,13 @@ auto &DL = I->second; Result.push_back({}); - for (auto &KV : E.second) { + for (const auto &KV : E.second) { auto &SymString = KV.first; bool WeakReference = KV.second; const char *Sym = SymString.c_str(); #ifdef __APPLE__ - if (*Sym != '\0') + if (*Sym == '_') ++Sym; #endif diff --git a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h --- a/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/TargetProcess/RegisterEHFrames.h @@ -11,8 +11,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAME_H -#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAME_H +#ifndef LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H +#define LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H #include "llvm/ExecutionEngine/Orc/Shared/TargetProcessControlTypes.h" #include "llvm/Support/Error.h" @@ -38,4 +38,4 @@ extern "C" llvm::orc::tpctypes::CWrapperFunctionResult llvm_orc_deregisterEHFrameSectionWrapper(uint8_t *Data, uint64_t Size); -#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAME_H +#endif // LLVM_EXECUTIONENGINE_ORC_TARGETPROCESS_REGISTEREHFRAMES_H diff --git a/llvm/lib/ExecutionEngine/OrcTargetProcess/TargetExecutionUtils.cpp b/llvm/lib/ExecutionEngine/OrcTargetProcess/TargetExecutionUtils.cpp --- a/llvm/lib/ExecutionEngine/OrcTargetProcess/TargetExecutionUtils.cpp +++ b/llvm/lib/ExecutionEngine/OrcTargetProcess/TargetExecutionUtils.cpp @@ -28,7 +28,7 @@ ArgV.push_back(ArgVStorage.back().get()); } - for (auto &Arg : Args) { + for (const auto &Arg : Args) { ArgVStorage.push_back(std::make_unique(Arg.size() + 1)); llvm::copy(Arg, &ArgVStorage.back()[0]); ArgVStorage.back()[Arg.size()] = '\0'; diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp --- a/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink-executor/llvm-jitlink-executor.cpp @@ -6,9 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This utility provides a simple command line interface to the llvm jitlink -// library, which makes relocatable object files executable in memory. Its -// primary function is as a testing utility for the jitlink library. +// Simple out-of-process executor for llvm-jitlink. // //===----------------------------------------------------------------------===// @@ -48,6 +46,7 @@ int openListener(std::string Host, int Port) { #ifndef LLVM_ON_UNIX + // FIXME: Add TCP support for Windows. printErrorAndExit("listen option not supported"); #else int SockFD = socket(PF_INET, SOCK_STREAM, 0); @@ -87,7 +86,7 @@ if (argc < 2) printErrorAndExit("insufficient arguments"); else { - StringRef Arg1(argv[1]); + StringRef Arg1 = argv[1]; StringRef SpecifierType, Specifier; std::tie(SpecifierType, Specifier) = Arg1.split('='); if (SpecifierType == "filedescs") { diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp --- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp +++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp @@ -579,6 +579,7 @@ Expected> LLVMJITLinkRemoteTargetProcessControl::LaunchExecutor() { #ifndef LLVM_ON_UNIX + // FIXME: Add support for Windows. return make_error("-" + OutOfProcessExecutor.ArgStr + " not supported on non-unix platforms", inconvertibleErrorCode()); @@ -586,14 +587,19 @@ rpc::registerStringError(); - int PipeFD[2][2]; + constexpr int ReadEnd = 0; + constexpr int WriteEnd = 1; + + // Pipe FDs. + int ToExecutor[2]; + int FromExecutor[2]; + pid_t ChildPID; - // Create two pipes. - if (pipe(PipeFD[0]) != 0 || pipe(PipeFD[1]) != 0) { + // Create pipes to/from the executor.. + if (pipe(ToExecutor) != 0 || pipe(FromExecutor) != 0) return make_error("Unable to create pipe for executor", inconvertibleErrorCode()); - } ChildPID = fork(); @@ -601,8 +607,8 @@ // In the child... // Close the parent ends of the pipes - close(PipeFD[0][1]); - close(PipeFD[1][0]); + close(ToExecutor[WriteEnd]); + close(FromExecutor[ReadEnd]); // Execute the child process. std::unique_ptr ExecutorPath, FDSpecifier; @@ -614,9 +620,9 @@ strcpy(ExecutorPath.get(), OOPExecutor.data()); std::string FDSpecifierStr("filedescs="); - FDSpecifierStr += utostr(PipeFD[0][0]); + FDSpecifierStr += utostr(ToExecutor[ReadEnd]); FDSpecifierStr += ','; - FDSpecifierStr += utostr(PipeFD[1][1]); + FDSpecifierStr += utostr(FromExecutor[WriteEnd]); FDSpecifier = std::make_unique(FDSpecifierStr.size() + 1); strcpy(FDSpecifier.get(), FDSpecifierStr.c_str()); } @@ -624,20 +630,22 @@ char *const Args[] = {ExecutorPath.get(), FDSpecifier.get(), nullptr}; int RC = execvp(ExecutorPath.get(), Args); if (RC != 0) { - errs() << "unable to launch out-of-process executor\n"; + errs() << "unable to launch out-of-process executor \"" + << ExecutorPath.get() << "\"\n"; exit(1); } } // else we're the parent... // Close the child ends of the pipes - close(PipeFD[0][0]); - close(PipeFD[1][1]); + close(ToExecutor[ReadEnd]); + close(FromExecutor[WriteEnd]); // Return an RPC channel connected to our end of the pipes. auto SSP = std::make_shared(); auto Channel = - std::make_unique(PipeFD[1][0], PipeFD[0][1]); + std::make_unique(FromExecutor[ReadEnd], + ToExecutor[WriteEnd]); auto Endpoint = std::make_unique(*Channel, true); auto ReportError = [](Error Err) { @@ -658,6 +666,7 @@ Expected> LLVMJITLinkRemoteTargetProcessControl::ConnectToExecutor() { #ifndef LLVM_ON_UNIX + // FIXME: Add TCP support for Windows. return make_error("-" + OutOfProcessExecutorConnect.ArgStr + " not supported on non-unix platforms", inconvertibleErrorCode());