diff options
Diffstat (limited to 'llvm/lib/ExecutionEngine/Orc/Shared')
| -rw-r--r-- | llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp | 47 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/Orc/Shared/RPCError.cpp | 58 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp | 250 |
3 files changed, 297 insertions, 58 deletions
diff --git a/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp b/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp new file mode 100644 index 000000000000..02044e4af29a --- /dev/null +++ b/llvm/lib/ExecutionEngine/Orc/Shared/OrcRTBridge.cpp @@ -0,0 +1,47 @@ +//===------ OrcRTBridge.cpp - Executor functions for bootstrap -----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/Orc/Shared/OrcRTBridge.h" + +namespace llvm { +namespace orc { +namespace rt { + +const char *SimpleExecutorDylibManagerInstanceName = + "__llvm_orc_SimpleExecutorDylibManager_Instance"; +const char *SimpleExecutorDylibManagerOpenWrapperName = + "__llvm_orc_SimpleExecutorDylibManager_open_wrapper"; +const char *SimpleExecutorDylibManagerLookupWrapperName = + "__llvm_orc_SimpleExecutorDylibManager_lookup_wrapper"; +const char *SimpleExecutorMemoryManagerInstanceName = + "__llvm_orc_SimpleExecutorMemoryManager_Instance"; +const char *SimpleExecutorMemoryManagerReserveWrapperName = + "__llvm_orc_SimpleExecutorMemoryManager_reserve_wrapper"; +const char *SimpleExecutorMemoryManagerFinalizeWrapperName = + "__llvm_orc_SimpleExecutorMemoryManager_finalize_wrapper"; +const char *SimpleExecutorMemoryManagerDeallocateWrapperName = + "__llvm_orc_SimpleExecutorMemoryManager_deallocate_wrapper"; +const char *MemoryWriteUInt8sWrapperName = + "__llvm_orc_bootstrap_mem_write_uint8s_wrapper"; +const char *MemoryWriteUInt16sWrapperName = + "__llvm_orc_bootstrap_mem_write_uint16s_wrapper"; +const char *MemoryWriteUInt32sWrapperName = + "__llvm_orc_bootstrap_mem_write_uint32s_wrapper"; +const char *MemoryWriteUInt64sWrapperName = + "__llvm_orc_bootstrap_mem_write_uint64s_wrapper"; +const char *MemoryWriteBuffersWrapperName = + "__llvm_orc_bootstrap_mem_write_buffers_wrapper"; +const char *RegisterEHFrameSectionCustomDirectWrapperName = + "__llvm_orc_bootstrap_register_ehframe_section_custom_direct_wrapper"; +const char *DeregisterEHFrameSectionCustomDirectWrapperName = + "__llvm_orc_bootstrap_deregister_ehframe_section_custom_direct_wrapper"; +const char *RunAsMainWrapperName = "__llvm_orc_bootstrap_run_as_main_wrapper"; + +} // end namespace rt +} // end namespace orc +} // end namespace llvm diff --git a/llvm/lib/ExecutionEngine/Orc/Shared/RPCError.cpp b/llvm/lib/ExecutionEngine/Orc/Shared/RPCError.cpp deleted file mode 100644 index a55cb220f218..000000000000 --- a/llvm/lib/ExecutionEngine/Orc/Shared/RPCError.cpp +++ /dev/null @@ -1,58 +0,0 @@ -//===--------------- RPCError.cpp - RPCERror implementation ---------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// RPC Error type implmentations. -// -//===----------------------------------------------------------------------===// - -#include "llvm/ExecutionEngine/Orc/Shared/RPCUtils.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/raw_ostream.h" - -#include <string> -#include <system_error> - -char llvm::orc::shared::RPCFatalError::ID = 0; -char llvm::orc::shared::ConnectionClosed::ID = 0; -char llvm::orc::shared::ResponseAbandoned::ID = 0; -char llvm::orc::shared::CouldNotNegotiate::ID = 0; - -namespace llvm { -namespace orc { -namespace shared { - -std::error_code ConnectionClosed::convertToErrorCode() const { - return orcError(OrcErrorCode::RPCConnectionClosed); -} - -void ConnectionClosed::log(raw_ostream &OS) const { - OS << "RPC connection already closed"; -} - -std::error_code ResponseAbandoned::convertToErrorCode() const { - return orcError(OrcErrorCode::RPCResponseAbandoned); -} - -void ResponseAbandoned::log(raw_ostream &OS) const { - OS << "RPC response abandoned"; -} - -CouldNotNegotiate::CouldNotNegotiate(std::string Signature) - : Signature(std::move(Signature)) {} - -std::error_code CouldNotNegotiate::convertToErrorCode() const { - return orcError(OrcErrorCode::RPCCouldNotNegotiateFunction); -} - -void CouldNotNegotiate::log(raw_ostream &OS) const { - OS << "Could not negotiate RPC function " << Signature; -} - -} // end namespace shared -} // end namespace orc -} // end namespace llvm diff --git a/llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp b/llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp new file mode 100644 index 000000000000..64fc717b7b56 --- /dev/null +++ b/llvm/lib/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.cpp @@ -0,0 +1,250 @@ +//===------ SimpleRemoteEPCUtils.cpp - Utils for Simple Remote EPC --------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Message definitions and other utilities for SimpleRemoteEPC and +// SimpleRemoteEPCServer. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ExecutionEngine/Orc/Shared/SimpleRemoteEPCUtils.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/FormatVariadic.h" + +#if !defined(_MSC_VER) && !defined(__MINGW32__) +#include <unistd.h> +#else +#include <io.h> +#endif + +namespace { + +struct FDMsgHeader { + static constexpr unsigned MsgSizeOffset = 0; + static constexpr unsigned OpCOffset = MsgSizeOffset + sizeof(uint64_t); + static constexpr unsigned SeqNoOffset = OpCOffset + sizeof(uint64_t); + static constexpr unsigned TagAddrOffset = SeqNoOffset + sizeof(uint64_t); + static constexpr unsigned Size = TagAddrOffset + sizeof(uint64_t); +}; + +} // namespace + +namespace llvm { +namespace orc { +namespace SimpleRemoteEPCDefaultBootstrapSymbolNames { + +const char *ExecutorSessionObjectName = + "__llvm_orc_SimpleRemoteEPC_dispatch_ctx"; +const char *DispatchFnName = "__llvm_orc_SimpleRemoteEPC_dispatch_fn"; + +} // end namespace SimpleRemoteEPCDefaultBootstrapSymbolNames + +SimpleRemoteEPCTransportClient::~SimpleRemoteEPCTransportClient() {} +SimpleRemoteEPCTransport::~SimpleRemoteEPCTransport() {} + +Expected<std::unique_ptr<FDSimpleRemoteEPCTransport>> +FDSimpleRemoteEPCTransport::Create(SimpleRemoteEPCTransportClient &C, int InFD, + int OutFD) { +#if LLVM_ENABLE_THREADS + if (InFD == -1) + return make_error<StringError>("Invalid input file descriptor " + + Twine(InFD), + inconvertibleErrorCode()); + if (OutFD == -1) + return make_error<StringError>("Invalid output file descriptor " + + Twine(OutFD), + inconvertibleErrorCode()); + std::unique_ptr<FDSimpleRemoteEPCTransport> FDT( + new FDSimpleRemoteEPCTransport(C, InFD, OutFD)); + return std::move(FDT); +#else + return make_error<StringError>("FD-based SimpleRemoteEPC transport requires " + "thread support, but llvm was built with " + "LLVM_ENABLE_THREADS=Off", + inconvertibleErrorCode()); +#endif +} + +FDSimpleRemoteEPCTransport::~FDSimpleRemoteEPCTransport() { +#if LLVM_ENABLE_THREADS + ListenerThread.join(); +#endif +} + +Error FDSimpleRemoteEPCTransport::start() { +#if LLVM_ENABLE_THREADS + ListenerThread = std::thread([this]() { listenLoop(); }); + return Error::success(); +#endif + llvm_unreachable("Should not be called with LLVM_ENABLE_THREADS=Off"); +} + +Error FDSimpleRemoteEPCTransport::sendMessage(SimpleRemoteEPCOpcode OpC, + uint64_t SeqNo, + ExecutorAddr TagAddr, + ArrayRef<char> ArgBytes) { + char HeaderBuffer[FDMsgHeader::Size]; + + *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::MsgSizeOffset)) = + FDMsgHeader::Size + ArgBytes.size(); + *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::OpCOffset)) = + static_cast<uint64_t>(OpC); + *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::SeqNoOffset)) = SeqNo; + *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::TagAddrOffset)) = + TagAddr.getValue(); + + std::lock_guard<std::mutex> Lock(M); + if (Disconnected) + return make_error<StringError>("FD-transport disconnected", + inconvertibleErrorCode()); + if (int ErrNo = writeBytes(HeaderBuffer, FDMsgHeader::Size)) + return errorCodeToError(std::error_code(ErrNo, std::generic_category())); + if (int ErrNo = writeBytes(ArgBytes.data(), ArgBytes.size())) + return errorCodeToError(std::error_code(ErrNo, std::generic_category())); + return Error::success(); +} + +void FDSimpleRemoteEPCTransport::disconnect() { + if (Disconnected) + return; // Return if already disconnected. + + Disconnected = true; + bool CloseOutFD = InFD != OutFD; + + // Close InFD. + while (close(InFD) == -1) { + if (errno == EBADF) + break; + } + + // Close OutFD. + if (CloseOutFD) { + while (close(OutFD) == -1) { + if (errno == EBADF) + break; + } + } +} + +static Error makeUnexpectedEOFError() { + return make_error<StringError>("Unexpected end-of-file", + inconvertibleErrorCode()); +} + +Error FDSimpleRemoteEPCTransport::readBytes(char *Dst, size_t Size, + bool *IsEOF) { + assert(Dst && "Attempt to read into null."); + ssize_t Completed = 0; + while (Completed < static_cast<ssize_t>(Size)) { + ssize_t Read = ::read(InFD, Dst + Completed, Size - Completed); + if (Read <= 0) { + auto ErrNo = errno; + if (Read == 0) { + if (Completed == 0 && IsEOF) { + *IsEOF = true; + return Error::success(); + } else + return makeUnexpectedEOFError(); + } else if (ErrNo == EAGAIN || ErrNo == EINTR) + continue; + else { + std::lock_guard<std::mutex> Lock(M); + if (Disconnected && IsEOF) { // disconnect called, pretend this is EOF. + *IsEOF = true; + return Error::success(); + } + return errorCodeToError( + std::error_code(ErrNo, std::generic_category())); + } + } + Completed += Read; + } + return Error::success(); +} + +int FDSimpleRemoteEPCTransport::writeBytes(const char *Src, size_t Size) { + assert(Src && "Attempt to append from null."); + ssize_t Completed = 0; + while (Completed < static_cast<ssize_t>(Size)) { + ssize_t Written = ::write(OutFD, Src + Completed, Size - Completed); + if (Written < 0) { + auto ErrNo = errno; + if (ErrNo == EAGAIN || ErrNo == EINTR) + continue; + else + return ErrNo; + } + Completed += Written; + } + return 0; +} + +void FDSimpleRemoteEPCTransport::listenLoop() { + Error Err = Error::success(); + do { + + char HeaderBuffer[FDMsgHeader::Size]; + // Read the header buffer. + { + bool IsEOF = false; + if (auto Err2 = readBytes(HeaderBuffer, FDMsgHeader::Size, &IsEOF)) { + Err = joinErrors(std::move(Err), std::move(Err2)); + break; + } + if (IsEOF) + break; + } + + // Decode header buffer. + uint64_t MsgSize; + SimpleRemoteEPCOpcode OpC; + uint64_t SeqNo; + ExecutorAddr TagAddr; + + MsgSize = + *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::MsgSizeOffset)); + OpC = static_cast<SimpleRemoteEPCOpcode>(static_cast<uint64_t>( + *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::OpCOffset)))); + SeqNo = + *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::SeqNoOffset)); + TagAddr.setValue( + *((support::ulittle64_t *)(HeaderBuffer + FDMsgHeader::TagAddrOffset))); + + if (MsgSize < FDMsgHeader::Size) { + Err = joinErrors(std::move(Err), + make_error<StringError>("Message size too small", + inconvertibleErrorCode())); + break; + } + + // Read the argument bytes. + SimpleRemoteEPCArgBytesVector ArgBytes; + ArgBytes.resize(MsgSize - FDMsgHeader::Size); + if (auto Err2 = readBytes(ArgBytes.data(), ArgBytes.size())) { + Err = joinErrors(std::move(Err), std::move(Err2)); + break; + } + + if (auto Action = C.handleMessage(OpC, SeqNo, TagAddr, ArgBytes)) { + if (*Action == SimpleRemoteEPCTransportClient::EndSession) + break; + } else { + Err = joinErrors(std::move(Err), Action.takeError()); + break; + } + } while (true); + + // Attempt to close FDs, set Disconnected to true so that subsequent + // sendMessage calls fail. + disconnect(); + + // Call up to the client to handle the disconnection. + C.handleDisconnect(std::move(Err)); +} + +} // end namespace orc +} // end namespace llvm |
