// Copyright 2023 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_ABI_PTR_H_
#define SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_ABI_PTR_H_

#include <lib/stdcompat/version.h>

#include <cassert>
#include <cstdint>

#if __cpp_impl_three_way_comparison >= 201907L
#include <compare>
#endif

#include "layout.h"

namespace elfldltl {

// See below.
struct LocalAbiTraits;

// elfldltl::AbiPtr<T> is like a T* but can support a stable and cross-friendly
// ABI.  It can be used to store pointers that use a different byte order,
// address size, or address space, than the current process.  Its main purpose
// is for conversions from pointers in the local address space into pointers in
// a different address space and possibly different format.  The conversions
// are handled elsewhere (TODO(mcgrathr): not yet implemented).
//
// The byte order and address are represented by an elfldltl::Elf<...> type in
// the Elf template parameter; it defaults to the native elfldltl::Elf<>.  The
// type in the Traits template parameter determines whether these are actually
// used in how the pointer is stored; it defaults to LocalAbiTraits, which just
// stores a normal native pointer regardless of the Elf size and encoding.
//
// elfldltl::AbiPtr<T> should be used instead of normal T* in all data
// structures that will exist in one process address space but be populated by
// code running in a different address space.  Such data structures should be
// templated on Elf and AbiTraits classes that are propagated to the
// elfldltl::AbiPtr<T, ...> instantiations they use for pointer-type members.
//
// elfldltl::AbiPtr<T> always supports all the arithmetic operators that real
// T* pointers do.  The Traits type might or might not allow converting the
// stored pointer to a real pointer in the local address space.  If it does,
// then elfldltl::AbiPtr<T> can be used like a smart-pointer type with `get()`
// and `*` and `->` operators and can be constructed from real T* pointers.
//
// The Traits template API is described below.  The default LocalAbiTraits type
// just uses a normal pointer and supports all the the smart-pointer methods
// and operators.
template <typename T, class Elf = elfldltl::Elf<>, class Traits = LocalAbiTraits>
struct AbiPtr {
 public:
  using value_type = T;

  // This is the type used to represent an address in the target address space.
  using Addr = typename Elf::Addr;

  // No matter how the pointer is represented, sizes of objects or arrays it
  // points to must fit into size_type.
  using size_type = typename Elf::size_type;

  // The Traits type determines the underlying type stored.
  using StorageType = typename Traits::template StorageType<Elf, T>;

  constexpr AbiPtr() = default;

  constexpr AbiPtr(const AbiPtr&) = default;

  // If Traits::Get<T> is supported, then Traits::Make<T> is too.
  // In this case, the AbiPtr can be constructed from a normal pointer.
  template <class TT = Traits,
            typename = decltype(TT::template Get<value_type>(std::declval<StorageType>()))>
  constexpr explicit AbiPtr(value_type* ptr) : storage_(Traits::template Make<value_type>(ptr)) {}

  constexpr AbiPtr& operator=(const AbiPtr&) = default;

  template <class TT = Traits,
            typename = decltype(TT::template Get<value_type>(std::declval<StorageType>()))>
  constexpr AbiPtr& operator=(value_type* ptr) {
    *this = AbiPtr{ptr};
    return *this;
  }

  // AbiPtr<T> is convertible to AbiPtr<const T> just like T* to const T*.
  template <typename TT = T, typename = std::enable_if_t<!std::is_const_v<TT>>>
  constexpr operator AbiPtr<const TT, Elf, Traits>() const {
    static_assert(std::is_same_v<TT, T>);
    static_assert(!std::is_const_v<TT>);
    return Reinterpret<const T>();
  }

  static constexpr AbiPtr FromAddress(Addr address) {
    return AbiPtr{Traits::template FromAddress<Elf, T>(address), std::in_place};
  }

  // Like `reinterpret_cast<Other*>(this->get())`.
  template <typename Other>
  constexpr AbiPtr<Other, Elf, Traits> Reinterpret() const {
    return AbiPtr<Other, Elf, Traits>::FromAddress(address());
  }

  constexpr explicit operator bool() const { return *this != AbiPtr{}; }

  constexpr bool operator==(const AbiPtr& other) const {
    return ComparisonValue() == other.ComparisonValue();
  }

  constexpr bool operator!=(const AbiPtr& other) const {
    return ComparisonValue() != other.ComparisonValue();
  }

#if __cpp_impl_three_way_comparison >= 201907L

  constexpr std::strong_ordering operator<=>(const AbiPtr& other) const {
    return ComparisonValue() <=> other.ComparisonValue();
  }

#else  // No operator<=> support.

  constexpr bool operator<(const AbiPtr& other) const {
    return ComparisonValue() < other.ComparisonValue();
  }

  constexpr bool operator>(const AbiPtr& other) const {
    return ComparisonValue() > other.ComparisonValue();
  }

  constexpr bool operator<=(const AbiPtr& other) const {
    return ComparisonValue() <= other.ComparisonValue();
  }

  constexpr bool operator>=(const AbiPtr& other) const {
    return ComparisonValue() >= other.ComparisonValue();
  }

#endif  // operator<=> support.

  constexpr AbiPtr operator+(size_type n) const {
    return AbiPtr{storage_ + (n * kScale), std::in_place};
  }

  constexpr AbiPtr operator-(size_type n) const {
    return AbiPtr{storage_ - (n * kScale), std::in_place};
  }

  constexpr size_type operator-(const AbiPtr& other) const {
    return static_cast<size_type>(storage_ - other.storage_) / kScale;
  }

  constexpr AbiPtr& operator+=(size_type n) {
    *this = *this + n;
    return *this;
  }

  constexpr AbiPtr& operator-=(size_type n) {
    *this = *this - n;
    return *this;
  }

  // This just returns the address in the target address space.
  constexpr size_type address() const {
    return static_cast<size_type>(Traits::GetAddress(storage_));
  }

  // Dereferencing methods are only available if enabled by the Traits type.

  template <typename TT = Traits,
            typename = decltype(TT::template Get<T>(std::declval<StorageType>()))>
  constexpr T* get() const {
    return Traits::template Get<T>(storage_);
  }

  template <typename TT = Traits,
            typename = decltype(TT::template Get<T>(std::declval<StorageType>()))>
  constexpr T* operator->() const {
    return get();
  }

  template <typename TT = Traits,
            typename = decltype(TT::template Get<T>(std::declval<StorageType>()))>
  constexpr T& operator*() const {
    return *get();
  }

 private:
  static constexpr size_type kScale = Traits::template kScale<T>;

  constexpr explicit AbiPtr(StorageType storage, std::in_place_t in_place) : storage_{storage} {}

  constexpr auto ComparisonValue() const { return Traits::ComparisonValue(storage_); }

  constexpr size_type Scale(size_type n) { return n * kScale; }

  StorageType storage_{};
};

// Deduction guide.
template <typename T>
AbiPtr(T*) -> AbiPtr<T>;

// This is the default Traits type for AbiPtr and things that use it.
// It also serves as the exemplar for the template API.  Comments here
// describe what any Traits type must define.
struct LocalAbiTraits {
  // This must be defined to some type that admits + and - operators with
  // integer types, and operator- with itself.
  template <class Elf, typename T>
  using StorageType = T*;

  // This must be defined to a factor by which an integer should be scaled up
  // before adding or subtracting to StorageType<..., T>, and by which the
  // value of subtracting two StorageType<..., T> values should be scaled down.
  template <typename T>
  static constexpr uint32_t kScale = 1;

  // This must be defined to accept any StorageType<...> argument and yield the
  // address in the target address space as some unsigned integer type.
  static uintptr_t GetAddress(const void* ptr) { return reinterpret_cast<uintptr_t>(ptr); }

  // This must be defined to accept any StorageType<...> argument and yield an
  // integer type that admits operator<=> for comparison of two pointers it's
  // valid to compare by C rules.
  template <typename T>
  static constexpr auto ComparisonValue(T* ptr) {
    return ptr;
  }

  // This must be defined to accept Elf::Addr (or Elf::size_type, since they
  // are mutually convertible).
  template <class Elf, typename T>
  static StorageType<Elf, T> FromAddress(typename Elf::size_type address) {
    return reinterpret_cast<T*>(static_cast<uintptr_t>(address));
  }

  // The last two functions don't have to be defined, but if one is defined
  // then both must be defined.  They convert between a local T* pointer and
  // StorageType<Elf,T> and are only defined when such a conversion exists.

  template <class Elf, typename T>
  static constexpr StorageType<Elf, T> Make(T* ptr) {
    return ptr;
  }

  template <class Elf, typename T>
  static constexpr T* Get(StorageType<Elf, T> ptr) {
    return ptr;
  }
};

// This is a baseline Traits type for storing pointers in a different address
// space and pointer encoding.  An AbiPtr<..., RemoteAbiTraits> type doesn't
// support the get() method and the pointer-like operators.
//
// elfldltl::AbiPtr<T, Elf, elfldltl::RemoteAbiTraits> has in every context the
// same layout that elfldltl::AbiPtr<T> does wherever elfldltl::Elf<> is Elf.
struct RemoteAbiTraits {
  template <class Elf, typename T>
  using StorageType = typename Elf::Addr;

  template <typename T>
  static constexpr uint32_t kScale = sizeof(T);

  template <typename Addr>
  static constexpr auto GetAddress(Addr ptr) {
    return ptr();
  }

  template <typename Addr>
  static constexpr auto ComparisonValue(Addr ptr) {
    return ptr();
  }

  // This must be defined to accept Elf::Addr (or Elf::size_type, since they
  // are mutually convertible).
  template <class Elf, typename T>
  static constexpr StorageType<Elf, T> FromAddress(typename Elf::Addr address) {
    return address;
  }
};

}  // namespace elfldltl

#endif  // SRC_LIB_ELFLDLTL_INCLUDE_LIB_ELFLDLTL_ABI_PTR_H_
