//===--- 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/ExecutorAddress.h"
#include "llvm/ExecutionEngine/Orc/Shared/SimplePackedSerialization.h"
#include "llvm/ExecutionEngine/Orc/Shared/WrapperFunctionUtils.h"
#include "llvm/Support/Memory.h"

#include <vector>

namespace llvm {
namespace orc {
namespace tpctypes {

enum WireProtectionFlags : uint8_t {
  WPF_None = 0,
  WPF_Read = 1U << 0,
  WPF_Write = 1U << 1,
  WPF_Exec = 1U << 2,
  LLVM_MARK_AS_BITMASK_ENUM(WPF_Exec)
};

/// Convert from sys::Memory::ProtectionFlags
inline WireProtectionFlags
toWireProtectionFlags(sys::Memory::ProtectionFlags PF) {
  WireProtectionFlags WPF = WPF_None;
  if (PF & sys::Memory::MF_READ)
    WPF |= WPF_Read;
  if (PF & sys::Memory::MF_WRITE)
    WPF |= WPF_Write;
  if (PF & sys::Memory::MF_EXEC)
    WPF |= WPF_Exec;
  return WPF;
}

inline sys::Memory::ProtectionFlags
fromWireProtectionFlags(WireProtectionFlags WPF) {
  int PF = 0;
  if (WPF & WPF_Read)
    PF |= sys::Memory::MF_READ;
  if (WPF & WPF_Write)
    PF |= sys::Memory::MF_WRITE;
  if (WPF & WPF_Exec)
    PF |= sys::Memory::MF_EXEC;
  return static_cast<sys::Memory::ProtectionFlags>(PF);
}

inline std::string getWireProtectionFlagsStr(WireProtectionFlags WPF) {
  std::string Result;
  Result += (WPF & WPF_Read) ? 'R' : '-';
  Result += (WPF & WPF_Write) ? 'W' : '-';
  Result += (WPF & WPF_Exec) ? 'X' : '-';
  return Result;
}

struct WrapperFunctionCall {
  ExecutorAddr Func;
  ExecutorAddrRange ArgData;

  WrapperFunctionCall() = default;
  WrapperFunctionCall(ExecutorAddr Func, ExecutorAddr ArgData,
                      ExecutorAddrDiff ArgSize)
      : Func(Func), ArgData(ArgData, ArgSize) {}
  WrapperFunctionCall(ExecutorAddr Func, ExecutorAddrRange ArgData)
      : Func(Func), ArgData(ArgData) {}

  shared::WrapperFunctionResult run() {
    using FnTy =
        shared::CWrapperFunctionResult(const char *ArgData, size_t ArgSize);
    return shared::WrapperFunctionResult(
        Func.toPtr<FnTy *>()(ArgData.Start.toPtr<const char *>(),
                             static_cast<size_t>(ArgData.size().getValue())));
  }

  /// Run call and deserialize result using SPS.
  template <typename SPSRetT, typename RetT> Error runWithSPSRet(RetT &RetVal) {
    auto WFR = run();
    if (const char *ErrMsg = WFR.getOutOfBandError())
      return make_error<StringError>(ErrMsg, inconvertibleErrorCode());
    shared::SPSInputBuffer IB(WFR.data(), WFR.size());
    if (!shared::SPSSerializationTraits<SPSRetT, RetT>::deserialize(IB, RetVal))
      return make_error<StringError>("Could not deserialize result from "
                                     "serialized wrapper function call",
                                     inconvertibleErrorCode());
    return Error::success();
  }

  /// Overload for SPS functions returning void.
  Error runWithSPSRet() {
    shared::SPSEmpty E;
    return runWithSPSRet<shared::SPSEmpty>(E);
  }
};

struct AllocationActionsPair {
  WrapperFunctionCall Finalize;
  WrapperFunctionCall Deallocate;
};

struct SegFinalizeRequest {
  WireProtectionFlags Prot;
  ExecutorAddr Addr;
  uint64_t Size;
  ArrayRef<char> Content;
};

struct FinalizeRequest {
  std::vector<SegFinalizeRequest> Segments;
  std::vector<AllocationActionsPair> Actions;
};

template <typename T> 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<uint8_t>;

/// Describes a write to a uint16_t.
using UInt16Write = UIntWrite<uint16_t>;

/// Describes a write to a uint32_t.
using UInt32Write = UIntWrite<uint32_t>;

/// Describes a write to a uint64_t.
using UInt64Write = UIntWrite<uint64_t>;

/// 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 = JITTargetAddress;

using LookupResult = std::vector<JITTargetAddress>;

} // end namespace tpctypes

namespace shared {

class SPSMemoryProtectionFlags {};

using SPSWrapperFunctionCall = SPSTuple<SPSExecutorAddr, SPSExecutorAddrRange>;

using SPSSegFinalizeRequest =
    SPSTuple<SPSMemoryProtectionFlags, SPSExecutorAddr, uint64_t,
             SPSSequence<char>>;

using SPSAllocationActionsPair =
    SPSTuple<SPSWrapperFunctionCall, SPSWrapperFunctionCall>;

using SPSFinalizeRequest = SPSTuple<SPSSequence<SPSSegFinalizeRequest>,
                                    SPSSequence<SPSAllocationActionsPair>>;

template <typename T>
using SPSMemoryAccessUIntWrite = SPSTuple<SPSExecutorAddr, T>;

using SPSMemoryAccessUInt8Write = SPSMemoryAccessUIntWrite<uint8_t>;
using SPSMemoryAccessUInt16Write = SPSMemoryAccessUIntWrite<uint16_t>;
using SPSMemoryAccessUInt32Write = SPSMemoryAccessUIntWrite<uint32_t>;
using SPSMemoryAccessUInt64Write = SPSMemoryAccessUIntWrite<uint64_t>;

using SPSMemoryAccessBufferWrite = SPSTuple<SPSExecutorAddr, SPSSequence<char>>;

template <>
class SPSSerializationTraits<SPSMemoryProtectionFlags,
                             tpctypes::WireProtectionFlags> {
public:
  static size_t size(const tpctypes::WireProtectionFlags &WPF) {
    return SPSArgList<uint8_t>::size(static_cast<uint8_t>(WPF));
  }

  static bool serialize(SPSOutputBuffer &OB,
                        const tpctypes::WireProtectionFlags &WPF) {
    return SPSArgList<uint8_t>::serialize(OB, static_cast<uint8_t>(WPF));
  }

  static bool deserialize(SPSInputBuffer &IB,
                          tpctypes::WireProtectionFlags &WPF) {
    uint8_t Val;
    if (!SPSArgList<uint8_t>::deserialize(IB, Val))
      return false;
    WPF = static_cast<tpctypes::WireProtectionFlags>(Val);
    return true;
  }
};

template <>
class SPSSerializationTraits<SPSWrapperFunctionCall,
                             tpctypes::WrapperFunctionCall> {
  using AL = SPSWrapperFunctionCall::AsArgList;

public:
  static size_t size(const tpctypes::WrapperFunctionCall &WFC) {
    return AL::size(WFC.Func, WFC.ArgData);
  }

  static bool serialize(SPSOutputBuffer &OB,
                        const tpctypes::WrapperFunctionCall &WFC) {
    return AL::serialize(OB, WFC.Func, WFC.ArgData);
  }

  static bool deserialize(SPSInputBuffer &IB,
                          tpctypes::WrapperFunctionCall &WFC) {
    return AL::deserialize(IB, WFC.Func, WFC.ArgData);
  }
};

template <>
class SPSSerializationTraits<SPSAllocationActionsPair,
                             tpctypes::AllocationActionsPair> {
  using AL = SPSAllocationActionsPair::AsArgList;

public:
  static size_t size(const tpctypes::AllocationActionsPair &AAP) {
    return AL::size(AAP.Finalize, AAP.Deallocate);
  }

  static bool serialize(SPSOutputBuffer &OB,
                        const tpctypes::AllocationActionsPair &AAP) {
    return AL::serialize(OB, AAP.Finalize, AAP.Deallocate);
  }

  static bool deserialize(SPSInputBuffer &IB,
                          tpctypes::AllocationActionsPair &AAP) {
    return AL::deserialize(IB, AAP.Finalize, AAP.Deallocate);
  }
};

template <>
class SPSSerializationTraits<SPSSegFinalizeRequest,
                             tpctypes::SegFinalizeRequest> {
  using SFRAL = SPSSegFinalizeRequest::AsArgList;

public:
  static size_t size(const tpctypes::SegFinalizeRequest &SFR) {
    return SFRAL::size(SFR.Prot, SFR.Addr, SFR.Size, SFR.Content);
  }

  static bool serialize(SPSOutputBuffer &OB,
                        const tpctypes::SegFinalizeRequest &SFR) {
    return SFRAL::serialize(OB, SFR.Prot, SFR.Addr, SFR.Size, SFR.Content);
  }

  static bool deserialize(SPSInputBuffer &IB,
                          tpctypes::SegFinalizeRequest &SFR) {
    return SFRAL::deserialize(IB, SFR.Prot, SFR.Addr, SFR.Size, SFR.Content);
  }
};

template <>
class SPSSerializationTraits<SPSFinalizeRequest, tpctypes::FinalizeRequest> {
  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 <typename T>
class SPSSerializationTraits<SPSMemoryAccessUIntWrite<T>,
                             tpctypes::UIntWrite<T>> {
public:
  static size_t size(const tpctypes::UIntWrite<T> &W) {
    return SPSTuple<SPSExecutorAddr, T>::AsArgList::size(W.Addr, W.Value);
  }

  static bool serialize(SPSOutputBuffer &OB, const tpctypes::UIntWrite<T> &W) {
    return SPSTuple<SPSExecutorAddr, T>::AsArgList::serialize(OB, W.Addr,
                                                              W.Value);
  }

  static bool deserialize(SPSInputBuffer &IB, tpctypes::UIntWrite<T> &W) {
    return SPSTuple<SPSExecutorAddr, T>::AsArgList::deserialize(IB, W.Addr,
                                                                W.Value);
  }
};

template <>
class SPSSerializationTraits<SPSMemoryAccessBufferWrite,
                             tpctypes::BufferWrite> {
public:
  static size_t size(const tpctypes::BufferWrite &W) {
    return SPSTuple<SPSExecutorAddr, SPSSequence<char>>::AsArgList::size(
        W.Addr, W.Buffer);
  }

  static bool serialize(SPSOutputBuffer &OB, const tpctypes::BufferWrite &W) {
    return SPSTuple<SPSExecutorAddr, SPSSequence<char>>::AsArgList ::serialize(
        OB, W.Addr, W.Buffer);
  }

  static bool deserialize(SPSInputBuffer &IB, tpctypes::BufferWrite &W) {
    return SPSTuple<SPSExecutorAddr,
                    SPSSequence<char>>::AsArgList ::deserialize(IB, W.Addr,
                                                                W.Buffer);
  }
};


} // end namespace shared
} // end namespace orc
} // end namespace llvm

#endif // LLVM_EXECUTIONENGINE_ORC_SHARED_TARGETPROCESSCONTROLTYPES_H
