// Copyright Microsoft and CHERIoT Contributors.
// SPDX-License-Identifier: MIT

#pragma once
/**
 * C++ helpers for operating on capabilities.
 */
#include <cheri.h>
#include <cstddef>
#include <cstdint>
#include <initializer_list>
#include <magic_enum/magic_enum.hpp>

namespace CHERI
{
	/**
	 * The complete set of architectural permissions.
	 */
	enum class Permission : uint32_t
	{
		/**
		 * Capability refers to global memory (this capability may be stored
		 * anywhere).
		 */
		Global = 0,
		/**
		 * Global capabilities can be loaded through this capability.  Without
		 *  this permission, any capability loaded via this capability will
		 *  have `Global` and `LoadGlobal` removed.
		 */
		LoadGlobal = 1,
		/**
		 * Capability may be used to store.  Any store via a capability without
		 * this permission will trap.
		 */
		Store = 2,
		/**
		 * Capabilities with store permission may be loaded through this
		 * capability.  Without this, any loaded capability will have
		 * `LoadMutable` and `Store` removed.
		 */
		LoadMutable = 3,
		/**
		 * This capability may be used to store capabilities that do not have
		 * `Global` permission.
		 */
		StoreLocal = 4,
		/**
		 * This capability can be used to load.
		 */
		Load = 5,
		/**
		 * Any load and store permissions on this capability convey the right to
		 * load or store capabilities in addition to data.
		 */
		LoadStoreCapability = 6,
		/**
		 * If installed as the program counter capability, running code may
		 * access privileged system registers.
		 */
		AccessSystemRegisters = 7,
		/**
		 * This capability may be used as a jump target and used to execute
		 * instructions.
		 */
		Execute = 8,
		/**
		 * This capability may be used to unseal other capabilities.  The
		 * 'address' range is in the sealing type namespace and not in the
		 * memory namespace.
		 */
		Unseal = 9,
		/**
		 * This capability may be used to seal other capabilities.  The
		 * 'address' range is in the sealing type namespace and not in the
		 * memory namespace.
		 */
		Seal = 10,
		/**
		 * Software defined permission bit, no architectural meaning.
		 */
		User0 = 11
	};

	/**
	 * Class encapsulating a set of permissions.
	 */
	class PermissionSet
	{
		/**
		 * Helper that returns the bit associated with a given permission.
		 */
		static constexpr uint32_t permission_bit(Permission p)
		{
			return 1 << static_cast<uint32_t>(p);
		}

		/**
		 * Helper for building permissions, adds a permission to the raw
		 * bitfield.
		 */
		__always_inline constexpr void add_permission(Permission p)
		{
			rawPermissions |= permission_bit(p);
		}

		/**
		 * Private constructor for creating a permission set from a raw bitmask.
		 * This should never be used accidentally and so is hidden behind a
		 * factory method with an explicit name.  Callers should use
		 * `PermissionSet::from_raw`.
		 */
		constexpr PermissionSet(uint32_t rawPermissions)
		  : rawPermissions(rawPermissions)
		{
		}

		public:
		/**
		 * Computes (at compile time) a bitmask containing the set of valid
		 * permission bits.
		 *
		 * FIXME would ideally make this private and expose a public static
		 * constexpr field but this seems to trigger a compiler bug when trying
		 * to initialise said field using this function.
		 */
		static constexpr uint32_t valid_permissions_mask()
		{
			uint32_t mask = 0;
			for (auto permission : magic_enum::enum_values<Permission>())
			{
				mask |= 1 << static_cast<uint32_t>(permission);
			}
			return mask;
		}

		private:
		/**
		 * Permissions iterator.  Stores the permissions and iterates over them
		 * one bit at a time.
		 */
		class Iterator
		{
			/// `PermissionSet` may construct this.
			friend class PermissionSet;
			/// The raw permissions bitmap.
			uint32_t permissions;
			/// Constructor, take a raw permissions bitmap.
			constexpr Iterator(uint32_t rawPermissions)
			  : permissions(rawPermissions)
			{
			}

			public:
			/**
			 * Dereference, returns the lowest-numbered permission.
			 */
			constexpr Permission operator*()
			{
				return Permission(__builtin_ffs(permissions) - 1);
			}

			/**
			 * Preincrement, drops the lowest-numbered permission.
			 */
			constexpr Iterator &operator++()
			{
				permissions &= ~(1 << (__builtin_ffs(permissions) - 1));
				return *this;
			}

			/**
			 * Returns true if the other iterator has a different set of
			 * permissions.
			 */
			constexpr bool operator!=(const Iterator Other)
			{
				return permissions != Other.permissions;
			}
		};

		public:
		/**
		 * The raw bitmap of permissions.  This is public so that this class
		 * meets the requirements of a structural type and can therefore be
		 * used as a template parameter.  This field should never be directly
		 * modified.
		 */
		uint32_t rawPermissions = 0;

		/**
		 * Constructs a permission set from a raw permission mask.
		 */
		static constexpr PermissionSet from_raw(uint32_t raw)
		{
			raw &= valid_permissions_mask();
			return {raw};
		}

		/**
		 * Constructs a permission set from a single permission.
		 */
		constexpr PermissionSet(Permission p)
		{
			add_permission(p);
		}

		/**
		 * Construct a permission set from a list of permissions.
		 */
		__always_inline constexpr PermissionSet(
		  std::initializer_list<Permission> permissions)
		{
			for (auto p : permissions)
			{
				add_permission(p);
			}
		}

		/**
		 * Copy constructor.
		 */
		constexpr PermissionSet(const PermissionSet &other)

		  = default;

		/**
		 * Returns a permission set representing all permissions.
		 */
		constexpr static PermissionSet omnipotent()
		{
			return PermissionSet{valid_permissions_mask()};
		}

		/**
		 * And-permissions operation, creates a new permission set containing
		 * only permissions present in both this set and the argument.
		 */
		constexpr PermissionSet operator&(PermissionSet p)
		{
			return PermissionSet{rawPermissions & p.rawPermissions};
		}

		/**
		 * And-permissions operation, removes all permissions that are not
		 * present in both permission sets.
		 */
		constexpr PermissionSet &operator&=(PermissionSet p)
		{
			rawPermissions &= p.rawPermissions;
			return *this;
		}

		/**
		 * Constructs a new permission set without the specified permission.
		 */
		[[nodiscard]] constexpr PermissionSet without(Permission p) const
		{
			return {rawPermissions & ~permission_bit(p)};
		}

		/**
		 * Constructs a new permission set without the specified permissions.
		 */
		template<std::same_as<Permission>... Permissions>
		[[nodiscard]] constexpr PermissionSet without(Permission p,
		                                              Permissions... ps) const
		{
			return this->without(p).without(ps...);
		}

		/**
		 * Returns true if, and only if, this permission set can be derived
		 * from the argument set.
		 */
		[[nodiscard]] constexpr bool can_derive_from(PermissionSet other) const
		{
			return (rawPermissions & other.rawPermissions) == rawPermissions;
		}

		/**
		 * Returns true if this permission set contains the specified
		 * permission.
		 */
		[[nodiscard]] constexpr bool contains(Permission permission) const
		{
			return (permission_bit(permission) & rawPermissions) ==
			       permission_bit(permission);
		}

		/**
		 * Returns true if this permission set contains the specified
		 * permissions.
		 */
		template<std::same_as<Permission>... Permissions>
		[[nodiscard]] constexpr bool contains(Permission p,
		                                      Permissions... ps) const
		{
			return this->contains(p) && this->contains(ps...);
		}

		/**
		 * Returns the raw permission mask as an integer containing a bitfield
		 * of permissions.
		 */
		[[nodiscard]] constexpr uint32_t as_raw() const
		{
			return rawPermissions;
		}

		/**
		 * Returns an iterator over the permissions starting at the
		 * lowest-numbered permission.
		 */
		[[nodiscard]] constexpr Iterator begin() const
		{
			return {rawPermissions};
		}

		/**
		 * Returns an end iterator.
		 */
		[[nodiscard]] constexpr Iterator end() const
		{
			// Each increment of an iterator will drop one permission and so an
			// iterator will compare equal to {0} once all permissions have
			// been dropped.
			return {0};
		}

		/**
		 * Three-way comparison.  Treats a superset as greater-than, identical
		 * permissions as equivalent, and sets that don't have a superset
		 * releationship as unordered.
		 */
		constexpr auto operator<=>(const PermissionSet Other) const
		{
			if (rawPermissions == Other.rawPermissions)
			{
				return std::partial_ordering::equivalent;
			}
			if (can_derive_from(Other))
			{
				return std::partial_ordering::less;
			}
			if (Other.can_derive_from(*this))
			{
				return std::partial_ordering::greater;
			}
			return std::partial_ordering::unordered;
		}

		/**
		 * Equality operator, wraps the three-way compare operator.
		 */
		constexpr bool operator==(PermissionSet other) const
		{
			// Clang-tidy spuriously suggests that this 0 should be nullptr.
			return (*this <=> other) == 0; // NOLINT(modernize-use-nullptr)
		}
	};

	/**
	 * Helper class for accessing capability properties on pointers.
	 */
	template<typename T>
	class Capability
	{
		protected:
		/// The capability that this class wraps.
		T *ptr;

		private:
		/**
		 * Constructs a PermissionSet with the permissions of the given pointer.
		 */
		static PermissionSet permission_set_from_pointer(const void *p)
		{
			auto perms = __builtin_cheri_perms_get(p);
			auto mask  = PermissionSet::valid_permissions_mask();
			/* FIXME teach the compiler that the builtin always returns a value
			 * that is a subset of the mask, otherwise it unnecessarily
			 * constructs and applies the mask in from_raw */
			__builtin_assume((perms & ~mask) == 0);
			return PermissionSet::from_raw(perms);
		}

		/**
		 * Base class for the proxies that accessors in this class return.
		 */
		class PropertyProxyBase
		{
			/**
			 * The capability that this proxy refers to.
			 */
			Capability &cap;

			protected:
			/**
			 * Replaces the underlying capability
			 */
			template<typename U>
			void set(U *newPtr)
			{
				cap.ptr = static_cast<T *>(newPtr);
			}

			/**
			 * Returns the capability's pointer.
			 */
			[[nodiscard]] T *ptr() const
			{
				return cap.ptr;
			}

			public:
			/// Constructor, takes the capability whose property this class is
			/// proxying.
			PropertyProxyBase(Capability &c) : cap(c) {}
		};

		/**
		 * Proxy for accessing a capability's address.
		 */
		struct AddressProxy : public PropertyProxyBase
		{
			/// Inherit the constructor from the base class.
			using PropertyProxyBase::PropertyProxyBase;
			/// Inherit the pointer accesors
			/// @{
			using PropertyProxyBase::ptr;
			using PropertyProxyBase::set;
			/// @}

			/**
			 * Implicit casts can convert this to an address.
			 */
			operator ptraddr_t() const
			{
				return __builtin_cheri_address_get(ptr());
			}

			/**
			 * Set the address in the underlying capability.
			 */
			AddressProxy &operator=(ptraddr_t addr)
			{
				set(__builtin_cheri_address_set(ptr(), addr));
				return *this;
			}

			/**
			 * Set the address in the underlying capability given another
			 * address proxy.
			 */
			AddressProxy &operator=(AddressProxy addr)
			{
				set(__builtin_cheri_address_set(ptr(), addr));
				return *this;
			}

			/**
			 * Add a displacement to the capability's address.
			 */
			AddressProxy &operator+=(ptrdiff_t displacement)
			{
				set(__builtin_cheri_offset_increment(ptr(), displacement));
				return *this;
			}

			/**
			 * Subtract a displacement from the capability's address.
			 */
			AddressProxy &operator-=(ptrdiff_t displacement)
			{
				set(__builtin_cheri_offset_increment(ptr(), -displacement));
				return *this;
			}
		};

		/**
		 * Proxy for accessing an object's bounds.
		 */
		struct BoundsProxy : public PropertyProxyBase
		{
			/// Inherit the constructor from the base class.
			using PropertyProxyBase::PropertyProxyBase;
			/// Inherit the pointer accesors
			/// @{
			using PropertyProxyBase::ptr;
			using PropertyProxyBase::set;
			/// @}

			/**
			 * Return the object's bounds (displacement from the address to the
			 * end).
			 */
			operator ptrdiff_t() const
			{
				return __builtin_cheri_length_get(ptr()) -
				       (__builtin_cheri_address_get(ptr()) -
				        __builtin_cheri_base_get(ptr()));
			}

			/**
			 * Set the capability's bounds, giving an invalid capability if this
			 * cannot be represented exactly.
			 */
			BoundsProxy &operator=(size_t bounds)
			{
				set(__builtin_cheri_bounds_set_exact(ptr(), bounds));
				return *this;
			}

			/**
			 * Set the bounds, adding some padding (up to the bounds of the
			 * original capability) if necessary for alignment.
			 */
			BoundsProxy &set_inexact(size_t bounds)
			{
				set(__builtin_cheri_bounds_set(ptr(), bounds));
				return *this;
			}
		};

		/**
		 * Proxy for accessing a capability's permissions
		 */
		struct PermissionsProxy : public PropertyProxyBase
		{
			/// Inherit the constructor from the base class.
			using PropertyProxyBase::PropertyProxyBase;
			/// Inherit the pointer accesors
			/// @{
			using PropertyProxyBase::ptr;
			using PropertyProxyBase::set;
			/// @}

			/**
			 * Implicitly convert to a permission set.
			 */
			operator PermissionSet() const
			{
				return permission_set_from_pointer(ptr());
			}

			/**
			 * And-permissions operation, removes all permissions that are not
			 * present in both permission sets from the capability.
			 */
			PermissionsProxy &operator&=(PermissionSet permissions)
			{
				set(__builtin_cheri_perms_and(ptr(), permissions.as_raw()));
				return *this;
			}

			/**
			 * Returns a permission set containing only the permissions held by
			 * the capability and the argument.
			 */
			constexpr PermissionSet operator&(PermissionSet p)
			{
				return static_cast<PermissionSet>(*this) & p;
			}

			/**
			 * Constructs a new permission set without the specified
			 * permissions.
			 */
			template<std::same_as<Permission>... Permissions>
			constexpr PermissionSet without(Permissions... ps) const
			{
				return static_cast<PermissionSet>(*this).without(ps...);
			}

			/**
			 * Returns true if, and only if, this permission set can be derived
			 * from the argument set.
			 */
			[[nodiscard]] constexpr bool
			can_derive_from(PermissionSet other) const
			{
				return static_cast<PermissionSet>(*this).can_derive_from(other);
			}

			/**
			 * Returns true if this permission set contains the specified
			 * permissions.
			 */
			template<std::same_as<Permission>... Permissions>
			constexpr bool contains(Permissions... permissions) const
			{
				return static_cast<PermissionSet>(*this).contains(
				  permissions...);
			}

			/**
			 * Returns the raw permission mask as an integer containing a
			 * bitfield of permissions.
			 */
			[[nodiscard]] constexpr uint32_t as_raw() const
			{
				return static_cast<PermissionSet>(*this).as_raw();
			}

			/**
			 * Returns an iterator over the permissions starting at the
			 * lowest-numbered permission.
			 */
			auto begin()
			{
				return static_cast<PermissionSet>(*this).begin();
			}

			/**
			 * Returns an end iterator.
			 */
			auto end()
			{
				return static_cast<PermissionSet>(*this).end();
			}

			/**
			 * Comparison operator.
			 */
			constexpr std::partial_ordering
			operator<=>(const PermissionSet Other) const
			{
				return static_cast<PermissionSet>(*this) <=> Other;
			}

			/**
			 * Equality operator, wraps the three-way compare operator.
			 */
			constexpr bool operator==(const PermissionSet Other) const
			{
				return (*this <=> Other) == 0;
			}
		};

		/// The property proxy base is allowed to directly access the pointer
		/// that this class wraps.
		friend class PropertyProxyBase;

		public:
		/// Constructor from a null pointer.
		constexpr Capability(std::nullptr_t) : ptr(nullptr) {}
		/// Default constructor, initialises with a null pointer.
		constexpr Capability() : ptr(nullptr) {}
		/// Constructor, takes an existing pointer to wrap
		constexpr Capability(T *p) : ptr(p) {}
		/// Copy constructor, aliases the object that is pointed to by `ptr`.
		constexpr Capability(const Capability &other) : ptr(other.ptr) {}
		/// Move constructor.
		constexpr Capability(Capability &&other) : ptr(other.ptr)
		{
			other.ptr = nullptr;
		}

		/**
		 * Replace the pointer that this capability wraps with another.
		 */
		Capability &operator=(const Capability &other)
		{
			ptr = other.ptr;
			return *this;
		}

		/**
		 * Transfer the pointer that this capability wraps from .
		 */
		Capability &operator=(Capability &&other)
		{
			ptr       = other.ptr;
			other.ptr = nullptr;
			return *this;
		}

		/**
		 * Access the address of the capability.
		 */
		AddressProxy address() [[clang::lifetimebound]]
		{
			return {*this};
		}

		/**
		 * Return the address as an integer from a `const` capability.
		 */
		[[nodiscard]] ptraddr_t address() const
		{
			return __builtin_cheri_address_get(ptr);
		}

		/**
		 * Access (read, set) the capability's bounds.
		 */
		BoundsProxy bounds() [[clang::lifetimebound]]
		{
			return {*this};
		}

		/**
		 * Return the bounds as an integer.
		 */
		[[nodiscard]] ptrdiff_t bounds() const
		{
			return __builtin_cheri_length_get(ptr) -
			       (__builtin_cheri_address_get(ptr()) -
			        __builtin_cheri_base_get(ptr()));
		}

		/**
		 * Access the permissions of this capability.
		 */
		PermissionsProxy permissions() [[clang::lifetimebound]]
		{
			return {*this};
		}

		/**
		 * Get a copy of the permissions from a `const` capability.
		 */
		[[nodiscard]] PermissionSet permissions() const
		{
			return permission_set_from_pointer(ptr);
		}

		/**
		 * Pointer subtraction.
		 */
		Capability operator-(ptrdiff_t diff)
		{
			return {ptr - diff};
		}

		/**
		 * Pointer subtraction.
		 */
		Capability &operator-=(ptrdiff_t diff)
		{
			ptr -= diff;
			return *this;
		}

		/**
		 * Pointer addition.
		 */
		Capability operator+(ptrdiff_t diff)
		{
			return {ptr + diff};
		}

		/**
		 * Pointer addition.
		 */
		Capability &operator+=(ptrdiff_t diff)
		{
			ptr += diff;
			return *this;
		}

		/**
		 * Returns the tag bit indicating whether this is a valid capability.
		 */
		[[nodiscard]] bool is_valid() const
		{
			// The clang static analyser doesn't yet know that null is untagged
			// and so warns of possible null dereferences after this method
			// returns true.  Explicitly assume that a tagged thing is non-null
			// to fix this.
			if (__builtin_cheri_tag_get(ptr))
			{
				__builtin_assume(ptr != nullptr);
				return true;
			}
			return false;
		}

		/**
		 * Return whether this is a sealed capability.
		 */
		[[nodiscard]] bool is_sealed() const
		{
			return __builtin_cheri_type_get(ptr) != 0;
		}

		/**
		 * Returns the type of this capability, 0 if this is not a sealed
		 * capability.
		 */
		[[nodiscard]] uint32_t type() const
		{
			return __builtin_cheri_type_get(ptr);
		}

		/**
		 * Returns the base address of this capability.
		 */
		[[nodiscard]] ptraddr_t base() const
		{
			return __builtin_cheri_base_get(ptr);
		}

		/**
		 * Returns the length of this capability.
		 */
		[[nodiscard]] size_t length() const
		{
			return __builtin_cheri_length_get(ptr);
		}

		/**
		 * Returns the address of the top of this capability.
		 */
		[[nodiscard]] ptraddr_t top() const
		{
			return base() + length();
		}

		/**
		 * Capability comparison.  Defines ordered comparison for capabilities
		 * with the same bounds and permissions.  All other capabilities are
		 * either equivalent (identical bit pattern, including the tag bit) or
		 * unordered.
		 */
		constexpr std::partial_ordering operator<=>(T *other) const
		{
			return (*this <=> Capability<T>{other}) == 0;
		}

		/**
		 * Comparison against null pointer.
		 *
		 * Returns equivalent if this is a canonical null pointer, returns
		 * unordered for any other (tagged or untagged) value.  Callers may
		 * often want `is_valid` instead of this.
		 */
		constexpr std::partial_ordering operator<=>(std::nullptr_t) const
		{
			if (__builtin_cheri_equal_exact(ptr, nullptr))
			{
				return std::partial_ordering::equivalent;
			}
			return std::partial_ordering::unordered;
		}

		constexpr bool operator==(const Capability Other) const
		{
			return __builtin_cheri_equal_exact(ptr, Other.ptr);
		}

		/**
		 * Capability comparison.  Defines ordered comparison for capabilities
		 * with the same bounds and permissions.  All other capabilities are
		 * either equivalent (identical bit pattern, including the tag bit) or
		 * unordered.
		 *
		 * Callers may want to compare addresses, rather than capabilities, if
		 * they want a defined comparison that is stable between two objects.
		 */
		constexpr std::partial_ordering
		operator<=>(const Capability Other) const
		{
			if (__builtin_cheri_equal_exact(ptr, Other.ptr))
			{
				return std::partial_ordering::equivalent;
			}
			// If neither capability is sealed, check if everything except the
			// address is the same and define ordered comparison on pointers to
			// the same object.
			if (!(is_sealed() || Other.is_sealed()) &&
			    __builtin_cheri_equal_exact(__builtin_address_set(
			      ptr, __builtin_address_get(Other), Other)))
			{
				return static_cast<ptraddr_t>(ptr) <=>
				       static_cast<ptraddr_t>(Other);
			}
			// Comparison of pointers to different objects is ub, you probably
			// want address comparison:
			return std::partial_ordering::unordered;
		}

		/**
		 * Equality operator, wraps the three-way compare operator.
		 */
		constexpr bool operator==(std::nullptr_t) const
		{
			return (*this <=> nullptr) == 0;
		}

		/**
		 * Implicit cast to the raw pointer type.
		 */
		template<typename U = T>
		requires(!std::same_as<U, void>) operator U *()
		{
			return ptr;
		}

		/**
		 * Implicit cast to a raw pointer type.
		 */
		operator void *()
		{
			return ptr;
		}

		/**
		 * Access fields of the target as if this were a raw pointer.
		 */
		T *operator->()
		{
			return ptr;
		}

		/**
		 * Explicitly get the raw pointer.
		 */
		T *get()
		{
			return ptr;
		}

		/**
		 * Dereference operator.
		 */
		template<typename U = T>
		requires(!std::same_as<U, void>) U &operator*()
		{
			return *ptr;
		}

		/**
		 * Cast this capability to some other type.
		 */
		template<typename U>
		Capability<U> cast()
		{
			return {static_cast<U *>(ptr)};
		}

		/**
		 * Returns true if the tags of `this` and `other` match and if `this`
		 * conveys no rights that are not present in `other`.  Returns false in
		 * all other cases.
		 */
		template<typename U>
		bool is_subset_of(Capability<U> other)
		{
			return __builtin_cheri_subset_test(other.ptr, ptr);
		}

		/**
		 * Seal this capability with the given key.
		 */
		Capability<T> &seal(void *key)
		{
			ptr = static_cast<T *>(__builtin_cheri_seal(ptr, key));
			return *this;
		}

		/**
		 * Unseal this capability with the given key.
		 */
		Capability<T> &unseal(void *key)
		{
#ifdef FLUTE
			// Flute still throws exceptions on invalid use.  As a temporary
			// work-around, add a quick check that this thing has the sealing
			// type and don't unseal if it hasn't.  This isn't a complete test,
			// it's just sufficient to get the tests passing on Flute.
			if (type() != __builtin_cheri_address_get(key))
			{
				ptr = nullptr;
			}
			else
#endif
			{
				ptr = static_cast<T *>(__builtin_cheri_unseal(ptr, key));
			}
			return *this;
		}

		/**
		 * Subscript operator.
		 */
		template<typename U = T>
		requires(!std::same_as<U, void>) U &operator[](size_t index)
		{
			return ptr[index];
		}

		/**
		 * Returns true if the capability is `align`-byte aligned, false
		 * otherwise.
		 */
		bool is_aligned(size_t align)
		{
			return __builtin_is_aligned(ptr, align);
		}

		/**
		 * Aligns the capability down to the nearest `align`-byte boundary.
		 */
		Capability &align_down(size_t align)
		{
			ptr = __builtin_align_down(ptr, align);
			return *this;
		}

		/**
		 * Aligns the capability up to the nearest `align`-byte boundary.
		 */
		Capability &align_up(size_t align)
		{
			ptr = __builtin_align_up(ptr, align);
			return *this;
		}
	};

	/**
	 * Rounds `len` up to a CHERI representable length for the current
	 * architecture.
	 */
	__always_inline inline size_t representable_length(size_t length)
	{
		return __builtin_cheri_round_representable_length(length);
	}

	/**
	 * Returns the alignment mask required for a given length.
	 */
	__always_inline inline size_t representable_alignment_mask(size_t length)
	{
		return __builtin_cheri_representable_alignment_mask(length);
	}

	/// Can the range [base, base + size) be precisely covered by a capability?
	inline bool is_precise_range(ptraddr_t base, size_t size)
	{
		return (base & ~representable_alignment_mask(size)) == 0 &&
		       representable_length(size) == size;
	}

	/**
	 * Concept that matches pointers.
	 */
	template<typename T>
	concept IsPointer = std::is_pointer_v<T>;

	/**
	 * Concept that matches smart pointers, i.e., classes which implements
	 * a `get` method returning a pointer, and supports `operator=` with
	 * the return value of `get`. This will match `Capability`, standard
	 * library smart pointers, etc.
	 */
	template<typename T>
	concept IsSmartPointerLike = requires(T b)
	{
		{
			b.get()
			} -> IsPointer;
	}
	&&requires(T b)
	{
		b = b.get();
	};

	/**
	 * Checks that `ptr` is valid, unsealed, has at least `Permissions`,
	 * and has at least `Space` bytes after the current offset.
	 *
	 * `ptr` can be a pointer, or a smart pointer, i.e., any class that
	 * supports a `get` method returning a pointer, and `operator=`. This
	 * includes `Capability` and standard library smart pointers.
	 *
	 * If the permissions do not include Global, then this will also check
	 * that the capability does not point to the current thread's stack.
	 * This behaviour can be disabled (for example, for use in a shared
	 * library) by passing `false` for `CheckStack`.
	 *
	 * If `EnforceStrictPermissions` is set to `true`, this will also set
	 * the permissions of passed capability reference to `Permissions`, and
	 * its bounds to `space`. This is useful for detecting cases where
	 * compartments ask for less permissions than they actually require.
	 *
	 * This function is provided as a wrapper for the `::check_pointer` C
	 * API. It is always inlined. For each call site, it materialises the
	 * constants needed before performing an indirect call to
	 * `::check_pointer`.
	 */
	template<PermissionSet Permissions = PermissionSet{Permission::Load},
	         bool          CheckStack  = true,
	         bool          EnforceStrictPermissions = false>
	__always_inline inline bool check_pointer(
	  auto  &ptr,
	  size_t space = sizeof(
	    std::remove_pointer<
	      decltype(ptr)>)) requires(std::
	                                  is_pointer_v<
	                                    std::remove_cvref_t<decltype(ptr)>> ||
	                                IsSmartPointerLike<
	                                  std::remove_cvref_t<decltype(ptr)>>)
	{
		// We can skip a stack check if we've asked for Global because the
		// stack does not have this permission.
		constexpr bool StackCheckNeeded =
		  CheckStack && !Permissions.contains(Permission::Global);
		constexpr bool IsRawPointer =
		  std::is_pointer_v<std::remove_cvref_t<decltype(ptr)>>;

		bool isValid;
		if constexpr (IsRawPointer)
		{
			// If passed `ptr` as a raw capability (e.g., `void*`),
			// pass it as-is to ::check_pointer.
			isValid = ::check_pointer(
			  ptr, space, Permissions.as_raw(), StackCheckNeeded);
		}
		else
		{
			// Otherwise, call `get` on `ptr` to retrieve a raw
			// capability.
			isValid = ::check_pointer(
			  ptr.get(), space, Permissions.as_raw(), StackCheckNeeded);
		}
		// If passed `EnforceStrictPermissions`, set the permissions
		// of `ptr` to `Permissions`, and its bounds to `space`
		if constexpr (EnforceStrictPermissions)
		{
			if (isValid)
			{
				if constexpr (IsRawPointer)
				{
					Capability cap{ptr};
					cap.permissions() &= Permissions;
					cap.bounds() = space;
					ptr          = cap.get();
				}
				else
				{
					Capability cap{ptr.get()};
					cap.permissions() &= Permissions;
					cap.bounds() = space;
					ptr          = cap.get();
				}
			}
		}
		return isValid;
	}

	/**
	 * Invokes the passed callable object with interrupts disabled.
	 */
	template<typename T>
	[[cheri::interrupt_state(disabled)]] auto with_interrupts_disabled(T &&fn)
	{
		return fn();
	}

	/**
	 * The codes used in the cause field of the mtval CSR when the processor
	 * takes a CHERI exception.
	 */
	enum class CauseCode
	{
		/**
		 * No exception. This value is passed to the error handler after a
		 * forced unwind in a called compartment.
		 */
		None = 0,
		/**
		 * Attempted to use a capability outside its bounds.
		 */
		BoundsViolation = 1,
		/**
		 * Attempted to use an untagged capability to authorize something.
		 */
		TagViolation = 2,
		/**
		 * Attempted to use a sealed capability to authorize something.
		 */
		SealViolation = 3,
		/**
		 * Attempted to jump to a capability without `Permission::Execute`.
		 */
		PermitExecuteViolation = 0x11,
		/**
		 * Attempted to load via a capability without `Permission::Load`.
		 */
		PermitLoadViolation = 0x12,
		/**
		 * Attempted to store via a capability without `Permission::Store`.
		 */
		PermitStoreViolation = 0x13,
		/**
		 * Attempted to store a tagged capability via a capability without
		 * `Permission::LoadStoreCapability`.
		 */
		PermitStoreCapabilityViolation = 0x15,
		/**
		 * Attempted to store a tagged capability without `Permission::Global`
		 * via capability without `Permission::StoreLocal`.
		 */
		PermitStoreLocalCapabilityViolation = 0x16,
		/**
		 * Attempted to access a restricted CSR or SCR with PCC without
		 * `Permission::AccessSystemRegisters`.
		 */
		PermitAccessSystemRegistersViolation = 0x18,
		/**
		 * Used to represent a value that has no valid meaning in hardware.
		 */
		Invalid = -1
	};

	/**
	 * Register numbers as reported in cap idx field of  `mtval` CSR when
	 * a CHERI exception is taken. Values less than 32 refer to general
	 * purpose registers and others to SCRs (of these, only PCC can actually
	 * cause an exception).
	 */
	enum class RegisterNumber
	{
		/**
		 * The zero register, which always contains the `NULL` capability.
		 */
		CZR = 0x0,
		/**
		 * `$c1` / `$cra` used by the ABI as the return address.
		 * Not preserved across calls.
		 */
		CRA = 0x1,
		/**
		 * `$c2` / `$csp` used by the ABI as the stack pointer.
		 * Preserved across calls.
		 */
		CSP = 0x2,
		/**
		 * `$c3` / `$cgp` used by the ABI as the global pointer.
		 * Not allocatable by the compiler, set by the switcher on compartment
		 * entry.
		 */
		CGP = 0x3,
		/**
		 * `$c4` / `$ctp` used by the ABI as the thread pointer.
		 * Currently unused by the compiler.
		 * Not preserved across compartment calls.
		 */
		CTP = 0x4,
		/**
		 * `$c5` / `$ct0` used by the ABI as temporary register.
		 * Not preserved across calls.
		 */
		CT0 = 0x5,
		/**
		 * `$c6` / `$ct1` used by the ABI as temporary register.
		 * Not preserved across calls.
		 */
		CT1 = 0x6,
		/**
		 * `$c7` / `$ct2` used by the ABI as temporary register.
		 * Not preserved across calls.
		 */
		CT2 = 0x7,
		/**
		 * `$c8` / `$cs0` used by the ABI as a callee-saved register.
		 * Preserved across calls.
		 */
		CS0 = 0x8,
		/**
		 * `$c9` / `$cs1` used by the ABI as a callee-saved register.
		 * Preserved across calls.
		 */
		CS1 = 0x9,
		/**
		 * `$c10` / `$ca0` used by the ABI as an argument register.
		 * Not preserved across calls.
		 */
		CA0 = 0xa,
		/**
		 * `$c11` / `$ca1` used by the ABI as an argument register.
		 * Not preserved across calls.
		 */
		CA1 = 0xb,
		/**
		 * `$c12` / `$ca2` used by the ABI as an argument register.
		 * Not preserved across calls.
		 */
		CA2 = 0xc,
		/**
		 * `$c13` / `$ca3` used by the ABI as an argument register.
		 * Not preserved across calls.
		 */
		CA3 = 0xd,
		/**
		 * `$c14` / `$ca4` used by the ABI as an argument register.
		 * Not preserved across calls.
		 */
		CA4 = 0xe,
		/**
		 * `$c15` / `$ca5` used by the ABI as an argument register.
		 * Not preserved across calls.
		 */
		CA5 = 0xf,
		/**
		 * The Program Counter Capability.
		 *
		 * Special capability register used to authorize instruction fetch. The
		 * address is that of the faulting instruction. Also used for accessing
		 * read-only globals.
		 */
		PCC = 0x20,
		/**
		 * Machine-mode Trap Code Capability.
		 *
		 * Special capability register that
		 * is installed in PCC when the CPU takes a trap. The address has the
		 * same semantics as the RISC-V `mtvec` CSR. Only accessible when PCC
		 * has the AccessSystemRegisters permission.
		 */
		MTCC = 0x3c,
		/**
		 * Machine-mode Tusted Data Capability.
		 *
		 * Special capability register that contains the memory root capability
		 * on boot. Only accessible when PCC has the AccessSystemRegisters
		 * permission.  Use by the RTOS to store a capability to the trusted
		 * stack.
		 */
		MTDC = 0x3d,
		/**
		 * Machine-mode Scratch Capability. Special capabiltiy register that
		 * contains the sealing root capability on boot. Only accessible when
		 * PCC has the AccessSystemRegisters permission.
		 */
		MScratchC = 0x3e,
		/**
		 * Machine-mode Exception Program Counter Capability. Special capability
		 * register that contains the PCC of the faulting instruction on trap.
		 * The address has the same semantics as the RISC-V `mepc` CSR. Only
		 * accessible when PCC has the AccessSystemRegisters permission.
		 */
		MEPCC = 0x3f,
		/**
		 * Indicates a value that is not used by the hardware to refer to a
		 * register.
		 */
		Invalid = -1
	};

	/**
	 * Decompose the value reported in the `mtval` CSR on CHERI exception
	 * into a pair of `CauseCode` and `RegisterNumber`.
	 *
	 * Will return `CauseCode::Invalid` if the code field is not one
	 * of the defined causes and `RegisterNumber::Invalid` if the register
	 * number is not a valid register number. Other bits of mtval are ignored.
	 */
	inline std::pair<CauseCode, RegisterNumber>
	extract_cheri_mtval(uint32_t mtval)
	{
		auto causeCode = magic_enum::enum_cast<CauseCode>(mtval & 0x1f)
		                   .value_or(CauseCode::Invalid);
		auto registerNumber =
		  magic_enum::enum_cast<RegisterNumber>((mtval >> 5) & 0x3f)
		    .value_or(RegisterNumber::Invalid);
		return {causeCode, registerNumber};
	}
} // namespace CHERI
