//===--- TargetProcessControlTypes.h -- Shared Core/TPC types ---*- C++ -*-===// // // 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 // //===----------------------------------------------------------------------===// // // TargetProcessControl types that are used by both the Orc and // OrcTargetProcess libraries. // //===----------------------------------------------------------------------===// #ifndef LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H #define LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/Shared/AllocationActions.h" #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h" #include "llvm/ExecutionEngine/Orc/Shared/MemoryFlags.h" #include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h" #include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h" #include "llvm/Support/Memory.h" #include namespace llvm { namespace orc { namespace tpctypes { struct RemoteAllocGroup { RemoteAllocGroup() = default; RemoteAllocGroup(MemProt Prot) : Prot(Prot) {} RemoteAllocGroup(MemProt Prot, bool FinalizeLifetime) : Prot(Prot), FinalizeLifetime(FinalizeLifetime) {} RemoteAllocGroup(const AllocGroup &AG) : Prot(AG.getMemProt()) { assert(AG.getMemLifetimePolicy() != orc::MemLifetimePolicy::NoAlloc && "Cannot use no-alloc memory in a remote alloc request"); FinalizeLifetime = AG.getMemLifetimePolicy() == orc::MemLifetimePolicy::Finalize; } MemProt Prot; bool FinalizeLifetime = false; }; struct SegFinalizeRequest { RemoteAllocGroup RAG; ExecutorAddr Addr; uint64_t Size; ArrayRef Content; }; struct FinalizeRequest { std::vector Segments; shared::AllocActions Actions; }; struct SharedMemorySegFinalizeRequest { RemoteAllocGroup RAG; ExecutorAddr Addr; uint64_t Size; }; struct SharedMemoryFinalizeRequest { std::vector Segments; shared::AllocActions Actions; }; template struct UIntWrite { UIntWrite() = default; UIntWrite(ExecutorAddr Addr, T Value) : Addr(Addr), Value(Value) {} ExecutorAddr Addr; T Value = 0; }; /// Describes a write to a uint8_t. using UInt8Write = UIntWrite; /// Describes a write to a uint16_t. using UInt16Write = UIntWrite; /// Describes a write to a uint32_t. using UInt32Write = UIntWrite; /// Describes a write to a uint64_t. using UInt64Write = UIntWrite; /// Describes a write to a buffer. /// For use with TargetProcessControl::MemoryAccess objects. struct BufferWrite { BufferWrite() = default; BufferWrite(ExecutorAddr Addr, StringRef Buffer) : Addr(Addr), Buffer(Buffer) {} ExecutorAddr Addr; StringRef Buffer; }; /// A handle used to represent a loaded dylib in the target process. using DylibHandle = ExecutorAddr; using LookupResult = std::vector; } // end namespace tpctypes namespace shared { class SPSRemoteAllocGroup; using SPSSegFinalizeRequest = SPSTuple>; using SPSFinalizeRequest = SPSTuple, SPSSequence>; using SPSSharedMemorySegFinalizeRequest = SPSTuple; using SPSSharedMemoryFinalizeRequest = SPSTuple, SPSSequence>; template using SPSMemoryAccessUIntWrite = SPSTuple; using SPSMemoryAccessUInt8Write = SPSMemoryAccessUIntWrite; using SPSMemoryAccessUInt16Write = SPSMemoryAccessUIntWrite; using SPSMemoryAccessUInt32Write = SPSMemoryAccessUIntWrite; using SPSMemoryAccessUInt64Write = SPSMemoryAccessUIntWrite; using SPSMemoryAccessBufferWrite = SPSTuple>; template <> class SPSSerializationTraits { enum WireBits { ReadBit = 1 << 0, WriteBit = 1 << 1, ExecBit = 1 << 2, FinalizeBit = 1 << 3 }; public: static size_t size(const tpctypes::RemoteAllocGroup &RAG) { // All AllocGroup values encode to the same size. return SPSArgList::size(uint8_t(0)); } static bool serialize(SPSOutputBuffer &OB, const tpctypes::RemoteAllocGroup &RAG) { uint8_t WireValue = 0; if ((RAG.Prot & MemProt::Read) != MemProt::None) WireValue |= ReadBit; if ((RAG.Prot & MemProt::Write) != MemProt::None) WireValue |= WriteBit; if ((RAG.Prot & MemProt::Exec) != MemProt::None) WireValue |= ExecBit; if (RAG.FinalizeLifetime) WireValue |= FinalizeBit; return SPSArgList::serialize(OB, WireValue); } static bool deserialize(SPSInputBuffer &IB, tpctypes::RemoteAllocGroup &RAG) { uint8_t Val; if (!SPSArgList::deserialize(IB, Val)) return false; MemProt MP = MemProt::None; if (Val & ReadBit) MP |= MemProt::Read; if (Val & WriteBit) MP |= MemProt::Write; if (Val & ExecBit) MP |= MemProt::Exec; bool FinalizeLifetime = (Val & FinalizeBit) ? true : false; RAG = {MP, FinalizeLifetime}; return true; } }; template <> class SPSSerializationTraits { using SFRAL = SPSSegFinalizeRequest::AsArgList; public: static size_t size(const tpctypes::SegFinalizeRequest &SFR) { return SFRAL::size(SFR.RAG, SFR.Addr, SFR.Size, SFR.Content); } static bool serialize(SPSOutputBuffer &OB, const tpctypes::SegFinalizeRequest &SFR) { return SFRAL::serialize(OB, SFR.RAG, SFR.Addr, SFR.Size, SFR.Content); } static bool deserialize(SPSInputBuffer &IB, tpctypes::SegFinalizeRequest &SFR) { return SFRAL::deserialize(IB, SFR.RAG, SFR.Addr, SFR.Size, SFR.Content); } }; template <> class SPSSerializationTraits { using FRAL = SPSFinalizeRequest::AsArgList; public: static size_t size(const tpctypes::FinalizeRequest &FR) { return FRAL::size(FR.Segments, FR.Actions); } static bool serialize(SPSOutputBuffer &OB, const tpctypes::FinalizeRequest &FR) { return FRAL::serialize(OB, FR.Segments, FR.Actions); } static bool deserialize(SPSInputBuffer &IB, tpctypes::FinalizeRequest &FR) { return FRAL::deserialize(IB, FR.Segments, FR.Actions); } }; template <> class SPSSerializationTraits { using SFRAL = SPSSharedMemorySegFinalizeRequest::AsArgList; public: static size_t size(const tpctypes::SharedMemorySegFinalizeRequest &SFR) { return SFRAL::size(SFR.RAG, SFR.Addr, SFR.Size); } static bool serialize(SPSOutputBuffer &OB, const tpctypes::SharedMemorySegFinalizeRequest &SFR) { return SFRAL::serialize(OB, SFR.RAG, SFR.Addr, SFR.Size); } static bool deserialize(SPSInputBuffer &IB, tpctypes::SharedMemorySegFinalizeRequest &SFR) { return SFRAL::deserialize(IB, SFR.RAG, SFR.Addr, SFR.Size); } }; template <> class SPSSerializationTraits { using FRAL = SPSSharedMemoryFinalizeRequest::AsArgList; public: static size_t size(const tpctypes::SharedMemoryFinalizeRequest &FR) { return FRAL::size(FR.Segments, FR.Actions); } static bool serialize(SPSOutputBuffer &OB, const tpctypes::SharedMemoryFinalizeRequest &FR) { return FRAL::serialize(OB, FR.Segments, FR.Actions); } static bool deserialize(SPSInputBuffer &IB, tpctypes::SharedMemoryFinalizeRequest &FR) { return FRAL::deserialize(IB, FR.Segments, FR.Actions); } }; template class SPSSerializationTraits, tpctypes::UIntWrite> { public: static size_t size(const tpctypes::UIntWrite &W) { return SPSTuple::AsArgList::size(W.Addr, W.Value); } static bool serialize(SPSOutputBuffer &OB, const tpctypes::UIntWrite &W) { return SPSTuple::AsArgList::serialize(OB, W.Addr, W.Value); } static bool deserialize(SPSInputBuffer &IB, tpctypes::UIntWrite &W) { return SPSTuple::AsArgList::deserialize(IB, W.Addr, W.Value); } }; template <> class SPSSerializationTraits { public: static size_t size(const tpctypes::BufferWrite &W) { return SPSTuple>::AsArgList::size( W.Addr, W.Buffer); } static bool serialize(SPSOutputBuffer &OB, const tpctypes::BufferWrite &W) { return SPSTuple>::AsArgList ::serialize( OB, W.Addr, W.Buffer); } static bool deserialize(SPSInputBuffer &IB, tpctypes::BufferWrite &W) { return SPSTuple>::AsArgList ::deserialize(IB, W.Addr, W.Buffer); } }; } // end namespace shared } // end namespace orc } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H