12#include <initializer_list>
13#include <magic_enum/magic_enum.hpp>
94 static constexpr uint32_t permission_bit(
Permission p)
96 return 1 <<
static_cast<uint32_t
>(p);
103 __always_inline
constexpr void add_permission(
Permission p)
131 for (
auto permission : magic_enum::enum_values<Permission>())
133 mask |= 1 <<
static_cast<uint32_t
>(permission);
148 uint32_t permissions;
159 constexpr Permission operator*()
161 return static_cast<Permission
>(__builtin_ffs(permissions) - 1);
167 constexpr Iterator &operator++()
169 permissions &= ~(1 << (__builtin_ffs(permissions) - 1));
177 constexpr bool operator!=(
const Iterator Other)
179 return permissions != Other.permissions;
195 static constexpr PermissionSet
from_raw(uint32_t raw)
213 std::initializer_list<Permission> permissions)
215 for (
auto p : permissions)
266 template<std::same_as<Permission>... Permissions>
268 Permissions... ps)
const
289 permission_bit(permission);
296 template<std::same_as<Permission>... Permissions>
298 Permissions... ps)
const
307 [[nodiscard]]
constexpr uint32_t
as_raw()
const
316 [[nodiscard]]
constexpr Iterator
begin()
const
324 [[nodiscard]]
constexpr Iterator
end()
const
341 return std::partial_ordering::equivalent;
345 return std::partial_ordering::less;
349 return std::partial_ordering::greater;
351 return std::partial_ordering::unordered;
360 return (*this <=> other) == 0;
370 return __builtin_cheri_round_representable_length(length);
378 return __builtin_cheri_representable_alignment_mask(length);
388#if __has_extension(cheri_sealed_pointers)
397 struct remove_sealed;
403 struct remove_sealed<T *__sealed_capability>
414 static constexpr bool value =
424 static constexpr bool value =
455 static constexpr bool value =
475 is_sealed_capability<T>::value;
480 template<
typename T,
bool IsSealedT = false>
484 static constexpr bool IsSealed = IsSealedT;
486 std::conditional_t<IsSealed, CHERI_SEALED(T *), T *>;
496 static PermissionSet permission_set_from_pointer(
const volatile void *p)
498 auto perms = __builtin_cheri_perms_get(p);
503 __builtin_assume((perms & ~mask) == 0);
524 cap.
ptr =
static_cast<T *
>(newPtr);
530 [[nodiscard]]
auto ptr()
const
544 struct AddressProxy :
public PropertyProxyBase
547 using PropertyProxyBase::PropertyProxyBase;
550 using PropertyProxyBase::ptr;
551 using PropertyProxyBase::set;
557 operator ptraddr_t()
const
559 return __builtin_cheri_address_get(
ptr());
565 AddressProxy &operator=(ptraddr_t addr)
567 set(__builtin_cheri_address_set(
ptr(), addr));
575 AddressProxy &operator=(AddressProxy addr)
577 set(__builtin_cheri_address_set(
ptr(), addr));
584 AddressProxy &operator+=(ptrdiff_t displacement)
586 set(__builtin_cheri_offset_increment(
ptr(), displacement));
593 AddressProxy &operator-=(ptrdiff_t displacement)
595 set(__builtin_cheri_offset_increment(
ptr(), -displacement));
603 struct BoundsProxy :
public PropertyProxyBase
606 using PropertyProxyBase::PropertyProxyBase;
609 using PropertyProxyBase::ptr;
610 using PropertyProxyBase::set;
617 operator ptrdiff_t()
const
619#if __has_builtin(__builtin_cheri_top_get)
620 return __builtin_cheri_top_get(
ptr()) -
621 __builtin_cheri_address_get(
ptr());
623 return __builtin_cheri_length_get(
ptr()) -
624 (__builtin_cheri_address_get(
ptr()) -
625 __builtin_cheri_base_get(
ptr()));
633 BoundsProxy &operator=(
size_t bounds)
635 set(__builtin_cheri_bounds_set_exact(
ptr(),
bounds));
643 BoundsProxy &set_inexact(
size_t bounds)
645 set(__builtin_cheri_bounds_set(
ptr(),
bounds));
650 BoundsProxy &set_inexact_at_most_slow(
size_t bounds)
652 ptraddr_t newBaseAddress = this->cap.address();
657 static constexpr size_t MantissaBits = 9;
663 size_t maximumLength = ((1 << MantissaBits) - 1)
664 << __builtin_ctz(newBaseAddress);
674 size_t alignedLength =
678 bounds = std::min<size_t>(alignedLength, maximumLength);
696 __always_inline BoundsProxy &set_inexact_at_most(
size_t bounds)
704 set(
static_cast<T *
>(p));
708 return set_inexact_at_most_slow(
bounds);
715 struct PermissionsProxy :
public PropertyProxyBase
718 using PropertyProxyBase::PropertyProxyBase;
721 using PropertyProxyBase::ptr;
722 using PropertyProxyBase::set;
728 operator PermissionSet()
const
730 return permission_set_from_pointer(
ptr());
737 PermissionsProxy &operator&=(PermissionSet
permissions)
747 constexpr PermissionSet operator&(PermissionSet p)
749 return static_cast<PermissionSet
>(*this) & p;
756 template<std::same_as<Permission>... Permissions>
757 [[nodiscard]]
constexpr PermissionSet
758 without(Permissions... ps)
const
760 return static_cast<PermissionSet
>(*this).without(ps...);
767 [[nodiscard]]
constexpr bool
768 can_derive_from(PermissionSet other)
const
770 return static_cast<PermissionSet
>(*this).can_derive_from(other);
777 template<std::same_as<Permission>... Permissions>
778 [[nodiscard]]
constexpr bool
781 return static_cast<PermissionSet
>(*this).contains(
789 [[nodiscard]]
constexpr uint32_t as_raw()
const
791 return static_cast<PermissionSet
>(*this).as_raw();
800 return static_cast<PermissionSet
>(*this).begin();
808 return static_cast<PermissionSet
>(*this).end();
814 constexpr std::partial_ordering
815 operator<=>(
const PermissionSet Other)
const
817 return static_cast<PermissionSet
>(*this) <=> Other;
823 constexpr bool operator==(
const PermissionSet Other)
const
825 return (*this <=> Other) == 0;
831 friend class PropertyProxyBase;
851 AddressProxy
address() [[clang::lifetimebound]]
861 return __builtin_cheri_address_get(
ptr);
867 BoundsProxy
bounds() [[clang::lifetimebound]]
875 [[nodiscard]] __always_inline ptrdiff_t
bounds()
const
893 return permission_set_from_pointer(
ptr);
904 template<std::same_as<Permission>... Permissions>
961 if (__builtin_cheri_tag_get(
ptr))
963 __builtin_assume(
ptr !=
nullptr);
981 if (__builtin_cheri_tag_get_temporal(
ptr))
983 __builtin_assume(
ptr !=
nullptr);
994 return __builtin_cheri_type_get(
ptr) != 0;
1001 [[nodiscard]] uint32_t
type()
const
1003 return __builtin_cheri_type_get(
ptr);
1009 [[nodiscard]] ptraddr_t
base()
const
1011 return __builtin_cheri_base_get(
ptr);
1019 return __builtin_cheri_length_get(
ptr);
1025 [[nodiscard]] ptraddr_t
top()
const
1027#if __has_builtin(__builtin_cheri_top_get)
1028 return __builtin_cheri_top_get(
ptr);
1054 if (__builtin_cheri_equal_exact(
ptr,
nullptr))
1056 return std::partial_ordering::equivalent;
1058 return std::partial_ordering::unordered;
1061 constexpr bool operator==(
const Capability Other)
const
1063 return __builtin_cheri_equal_exact(
ptr, Other.
ptr);
1075 constexpr std::partial_ordering
1078 if (__builtin_cheri_equal_exact(
ptr, Other.
ptr))
1080 return std::partial_ordering::equivalent;
1086 __builtin_cheri_equal_exact(__builtin_address_set(
1087 ptr, __builtin_address_get(Other), Other)))
1089 return static_cast<ptraddr_t
>(
ptr) <=>
1090 static_cast<ptraddr_t
>(Other);
1094 return std::partial_ordering::unordered;
1102 return (*this <=>
nullptr) == 0;
1108 template<
typename U = T>
1109 requires(!std::same_as<U, void> && !IsSealed)
1110 operator U *()
const
1118 template<
typename U = T>
1119 requires(!std::same_as<U, void> && IsSealed)
1120 operator CHERI_SEALED(U *)()
const
1128 operator void *()
const
1145 requires std::is_convertible_v<PointerType, T *>
1153 template<
typename U = T>
1154 requires(!std::same_as<U, void> && !IsSealed)
1155 U &
operator*()
const
1163 template<
typename U>
1167 static_cast<std::conditional_t<IsSealed, CHERI_SEALED(U *), U *
>>(
1176 template<
typename U>
1179 return __builtin_cheri_subset_test(other.
ptr,
ptr);
1188 return {
reinterpret_cast<CHERI_SEALED(T *)
>(
1189 __builtin_cheri_seal(
ptr, key))};
1198#if __has_extension(cheri_sealed_pointers) && \
1199 defined(CHERIOT_NO_SEALED_POINTERS)
1201 return {
static_cast<T *
>(__builtin_cheri_unseal(
1202 reinterpret_cast<void *__sealed_capability
>(
ptr), key))};
1205 return {
static_cast<T *
>(__builtin_cheri_unseal(
ptr, key))};
1212 template<
typename U = T>
1213 requires(!std::same_as<U, void>)
1214 U &
operator[](
size_t index)
const
1225 return __builtin_is_aligned(
ptr, align);
1233 ptr = __builtin_align_down(
ptr, align);
1242 ptr = __builtin_align_up(
ptr, align);
1247 template<
typename T>
1248 Capability(T *) -> Capability<T, false>;
1250#if __has_extension(cheri_sealed_pointers) && \
1251 !defined(CHERIOT_NO_SEALED_POINTERS)
1252 template<
typename T>
1253 Capability(CHERI_SEALED(T *)) -> Capability<T, true>;
1262 static_assert(std::is_trivially_copy_constructible_v<Capability<void>> &&
1263 std::is_trivially_destructible_v<Capability<void>>);
1268 template<
typename T>
1277 template<
typename T>
1280 } &&
requires(T b) { b = b.get(); };
1310 template<PermissionSet Permissions = PermissionSet{Permission::Load},
1311 bool CheckStack =
true,
1312 bool EnforceStrictPermissions =
false>
1313 __always_inline
inline bool
1315 size_t space =
sizeof(std::remove_pointer<
decltype(ptr)>))
1316 requires(std::is_pointer_v<std::remove_cvref_t<
decltype(ptr)>> ||
1321 constexpr bool StackCheckNeeded =
1323 constexpr bool IsRawPointer =
1324 std::is_pointer_v<std::remove_cvref_t<
decltype(ptr)>>;
1327 if constexpr (IsRawPointer)
1332 ptr, space, Permissions.as_raw(), StackCheckNeeded);
1339 ptr.get(), space, Permissions.as_raw(), StackCheckNeeded);
1343 if constexpr (EnforceStrictPermissions)
1347 if constexpr (IsRawPointer)
1369 template<
typename T>
1578 inline std::pair<CauseCode, RegisterNumber>
1581 auto causeCode = magic_enum::enum_cast<CauseCode>(mtval & 0x1f)
1583 auto registerNumber =
1584 magic_enum::enum_cast<RegisterNumber>((mtval >> 5) & 0x3f)
1586 return {causeCode, registerNumber};
1595 template<
typename T,
bool IsSealed = false>
1624 : pointer(reinterpret_cast<decltype(pointer)::PointerType>(
1625 static_cast<intptr_t>(error)))
1634 return !pointer.is_valid();
1647 requires std::is_invocable_v<
decltype(onT),
1649 std::is_invocable_v<
decltype(onE),
int> &&
1650 std::convertible_to<
1651 std::invoke_result_t<
decltype(onE),
int>,
1652 std::invoke_result_t<
decltype(onT),
1658 reinterpret_cast<intptr_t
>(
static_cast<void *
>(pointer));
1665 if constexpr (std::is_void_v<
1666 std::invoke_result_t<
decltype(onT),
1673 return std::invoke_result_t<
decltype(onT),
1678 return onT(pointer);
1690 return either([](
auto) {
return 0; }, [](
int e) {
return e; });
1699 requires requires() {
1700 { pointer.get() } -> std::same_as<T *>;
1703 return either([](
auto t) {
return t.get(); },
1704 [](int) {
return nullptr; });
1713 requires requires() {
1714 { pointer.get() } -> std::same_as<T *>;
1717 return pointer.
get();
1741 requires std::is_convertible_v<
decltype(pointer), T *> &&
1743 std::invoke_result_t<
decltype(function), T *>>
1745 either([function](T *t) { function(t); }, [](int) {
return; });
1757 requires std::is_convertible_v<
decltype(pointer), T *> &&
1758 requires(std::invoke_result_t<
decltype(function), T *> r) {
1763 return either(function, [](
int e) {
1764 return std::invoke_result_t<
decltype(function), T *>{e};
1776 requires std::is_convertible_v<
decltype(pointer), T *> &&
1778 std::invoke_result_t<
decltype(function), T *>,
1781 return either(function, [](
int e) {
return e; });
1793 requires std::is_void_v<
1794 std::invoke_result_t<
decltype(function),
int>>
1796 either([](T *) {
return; }, [function](
int e) { function(e); });
1801 requires std::is_convertible_v<
1802 std::invoke_result_t<
decltype(function),
int>,
1805 return either([
this](T *) {
return *
this; },
1806 [function](
int e) {
return function(e); });
1811 template<
typename T,
bool IsSealed>
1818 static_assert(std::is_trivially_copy_constructible_v<ErrorOr<void>> &&
1819 std::is_trivially_destructible_v<ErrorOr<void>>);
C definitions for CHERI specific functionality.
@ CheriPermissionStore
Capability may be used to store.
@ CheriPermissionGlobal
Capability refers to global memory (this capability may be stored anywhere).
@ CheriPermissionStoreLocal
This capability may be used to store capabilities that do not have Global permission.
@ CheriPermissionLoadStoreCapability
Any load and store permissions on this capability convey the right to load or store capabilities in a...
@ CheriPermissionUnseal
This capability may be used to unseal other capabilities.
@ CheriPermissionUser0
Software defined permission bit, no architectural meaning.
@ CheriPermissionLoadGlobal
Global capabilities can be loaded through this capability.
@ CheriPermissionExecute
This capability may be used as a jump target and used to execute instructions.
@ CheriPermissionAccessSystemRegisters
If installed as the program counter capability, running code may access privileged system registers.
@ CheriPermissionSeal
This capability may be used to seal other capabilities.
@ CheriPermissionLoad
This capability can be used to load.
@ CheriPermissionLoadMutable
Capabilities with store permission may be loaded through this capability.
@ CheriRegisterNumberMepcc
Machine-mode Exception Program Counter Capability.
@ CheriRegisterNumberCgp
$c3 / $cgp used by the ABI as the global pointer.
@ CheriRegisterNumberCsp
$c2 / $csp used by the ABI as the stack pointer.
@ CheriRegisterNumberCT0
$c5 / $ct0 used by the ABI as temporary register.
@ CheriRegisterNumberCS0
$c8 / $cs0 used by the ABI as a callee-saved register.
@ CheriRegisterNumberCA2
$c12 / $ca2 used by the ABI as an argument register.
@ CheriRegisterNumberCT2
$c7 / $ct2 used by the ABI as temporary register.
@ CheriRegisterNumberCT1
$c6 / $ct1 used by the ABI as temporary register.
@ CheriRegisterNumberCA1
$c11 / $ca1 used by the ABI as an argument register.
@ CheriRegisterNumberCA4
$c14 / $ca4 used by the ABI as an argument register.
@ CheriRegisterNumberInvalid
Indicates a value that is not used by the hardware to refer to a register.
@ CheriRegisterNumberCA3
$c13 / $ca3 used by the ABI as an argument register.
@ CheriRegisterNumberMScratchC
Machine-mode Scratch Capability.
@ CheriRegisterNumberCtp
$c4 / $ctp used by the ABI as the thread pointer.
@ CheriRegisterNumberMtdc
Machine-mode Tusted Data Capability.
@ CheriRegisterNumberCS1
$c9 / $cs1 used by the ABI as a callee-saved register.
@ CheriRegisterNumberCra
$c1 / $cra used by the ABI as the return address.
@ CheriRegisterNumberCA5
$c15 / $ca5 used by the ABI as an argument register.
@ CheriRegisterNumberCA0
$c10 / $ca0 used by the ABI as an argument register.
@ CheriRegisterNumberCzr
The zero register, which always contains the NULL capability.
@ CheriRegisterNumberPcc
The Program Counter Capability.
@ CheriRegisterNumberMtcc
Machine-mode Trap Code Capability.
bool __cheri_libcall check_pointer(const volatile void *ptr, size_t space, uint32_t rawPermissions, bool checkStackNeeded)
Checks that ptr is valid, unsealed, has at least rawPermissions, and has at least space bytes after t...
@ CheriCauseCodePermitStoreCapabilityViolation
Attempted to store a tagged capability via a capability without Permission::LoadStoreCapability.
@ CheriCauseCodePermitStoreLocalCapabilityViolation
Attempted to store a tagged capability without Permission::Global via capability without Permission::...
@ CheriCauseCodePermitExecuteViolation
Attempted to jump to a capability without Permission::Execute.
@ CheriCauseCodePermitAccessSystemRegistersViolation
Attempted to access a restricted CSR or SCR with PCC without Permission::AccessSystemRegisters.
@ CheriCauseCodeBoundsViolation
Attempted to use a capability outside its bounds.
@ CheriCauseCodePermitLoadViolation
Attempted to load via a capability without Permission::Load.
@ CheriCauseCodeSealViolation
Attempted to use a sealed capability to authorize something.
@ CheriCauseCodeNone
No exception.
@ CheriCauseCodeInvalid
Used to represent a value that has no valid meaning in hardware.
@ CheriCauseCodeTagViolation
Attempted to use an untagged capability to authorize something.
@ CheriCauseCodePermitStoreViolation
Attempted to store via a capability without Permission::Store.
RegisterNumber
Register numbers as reported in thee cap idx field of mtval CSR when a CHERI exception is taken.
@ CS0
$c8 / $cs0 used by the ABI as a callee-saved register.
@ CA2
$c12 / $ca2 used by the ABI as an argument register.
@ CT0
$c5 / $ct0 used by the ABI as temporary register.
@ CA5
$c15 / $ca5 used by the ABI as an argument register.
@ Invalid
Indicates a value that is not used by the hardware to refer to a register.
@ CA0
$c10 / $ca0 used by the ABI as an argument register.
@ MTDC
Machine-mode Tusted Data Capability.
@ MTCC
Machine-mode Trap Code Capability.
@ CS1
$c9 / $cs1 used by the ABI as a callee-saved register.
@ CA4
$c14 / $ca4 used by the ABI as an argument register.
@ CA3
$c13 / $ca3 used by the ABI as an argument register.
@ CTP
$c4 / $ctp used by the ABI as the thread pointer.
@ CZR
The zero register, which always contains the NULL capability.
@ CT2
$c7 / $ct2 used by the ABI as temporary register.
@ CT1
$c6 / $ct1 used by the ABI as temporary register.
@ CRA
$c1 / $cra used by the ABI as the return address.
@ CA1
$c11 / $ca1 used by the ABI as an argument register.
@ CSP
$c2 / $csp used by the ABI as the stack pointer.
@ PCC
The Program Counter Capability.
@ CGP
$c3 / $cgp used by the ABI as the global pointer.
@ MScratchC
Machine-mode Scratch Capability.
@ MEPCC
Machine-mode Exception Program Counter Capability.
remove_sealed< T >::type remove_sealed_t
Helper that provides the type of an unsealed capability from a sealed capability.
auto with_interrupts_disabled(T &&fn)
Invokes the passed callable object with interrupts disabled.
std::pair< CauseCode, RegisterNumber > extract_cheri_mtval(uint32_t mtval)
Decompose the value reported in the mtval CSR on CHERI exception into a pair of CauseCode and Registe...
CauseCode
The codes used in the cause field of the mtval CSR when the processor takes a CHERI exception.
@ SealViolation
Attempted to use a sealed capability to authorize something.
@ PermitStoreViolation
Attempted to store via a capability without Permission::Store.
@ Invalid
Used to represent a value that has no valid meaning in hardware.
@ PermitAccessSystemRegistersViolation
Attempted to access a restricted CSR or SCR with PCC without Permission::AccessSystemRegisters.
@ PermitLoadViolation
Attempted to load via a capability without Permission::Load.
@ PermitStoreCapabilityViolation
Attempted to store a tagged capability via a capability without Permission::LoadStoreCapability.
@ TagViolation
Attempted to use an untagged capability to authorize something.
@ PermitStoreLocalCapabilityViolation
Attempted to store a tagged capability without Permission::Global via capability without Permission::...
@ BoundsViolation
Attempted to use a capability outside its bounds.
@ PermitExecuteViolation
Attempted to jump to a capability without Permission::Execute.
size_t representable_length(size_t length)
Rounds len up to a CHERI representable length for the current architecture.
bool is_precise_range(ptraddr_t base, size_t size)
Can the range [base, base + size) be precisely covered by a capability?
constexpr bool is_sealed_capability_v
Helper to check that a type is a sealed capability.
Permission
The complete set of architectural permissions.
@ Unseal
This capability may be used to unseal other capabilities.
@ LoadGlobal
Global capabilities can be loaded through this capability.
@ Execute
This capability may be used as a jump target and used to execute instructions.
@ Global
Capability refers to global memory (this capability may be stored anywhere).
@ AccessSystemRegisters
If installed as the program counter capability, running code may access privileged system registers.
@ LoadMutable
Capabilities with store permission may be loaded through this capability.
@ StoreLocal
This capability may be used to store capabilities that do not have Global permission.
@ Seal
This capability may be used to seal other capabilities.
@ Load
This capability can be used to load.
@ LoadStoreCapability
Any load and store permissions on this capability convey the right to load or store capabilities in a...
@ User0
Software defined permission bit, no architectural meaning.
@ Store
Capability may be used to store.
size_t representable_alignment_mask(size_t length)
Returns the alignment mask required for a given length.
Helper class for accessing capability properties on pointers.
Capability & align_up(size_t align)
Aligns the capability up to the nearest align-byte boundary.
ptraddr_t top() const
Returns the address of the top of this capability.
Capability< U, IsSealed > cast() const
Cast this capability to some other type.
Capability< T, true > seal(void *key) const
Seal this capability with the given key.
AddressProxy address()
Access the address of the capability.
constexpr Capability()
Default constructor, initialises with a null pointer.
constexpr bool operator==(std::nullptr_t) const
Equality operator, wraps the three-way compare operator.
T * operator->() const
Access fields of the target as if this were a raw pointer.
bool is_subset_of(Capability< U, IsSealed > other) const
Returns true if the tags of this and other match and if this conveys no rights that are not present i...
Capability operator-(ptrdiff_t diff)
Pointer subtraction.
PermissionSet permissions() const
Get a copy of the permissions from a const capability.
Capability & operator-=(ptrdiff_t diff)
Pointer subtraction.
bool is_valid_temporal() const
Returns the tag bit indicating whether this is a valid capability.
Capability & align_down(size_t align)
Aligns the capability down to the nearest align-byte boundary.
size_t length() const
Returns the length of this capability.
friend class PropertyProxyBase
The property proxy base is allowed to directly access the pointer that this class wraps.
constexpr std::partial_ordering operator<=>(T *other) const
Capability comparison.
ptraddr_t base() const
Returns the base address of this capability.
Capability & operator+=(ptrdiff_t diff)
Pointer addition.
bool is_valid() const
Returns the tag bit indicating whether this is a valid capability.
uint32_t type() const
Returns the type of this capability, 0 if this is not a sealed capability.
BoundsProxy bounds()
Access (read, set) the capability's bounds.
void without_permissions(Permissions... drop)
Remove some permissions from this capability.
T * get() const
Explicitly get the raw pointer.
constexpr Capability(decltype(ptr) p)
Constructor, takes an existing pointer to wrap.
ptrdiff_t bounds() const
Return the bounds as an integer.
constexpr Capability(std::nullptr_t)
Constructor from a null pointer.
constexpr Capability(const Capability &other)=default
Copy constructor, aliases the object that is pointed to by ptr.
Capability< T, false > unseal(void *key) const
Unseal this capability with the given key.
PointerType ptr
The capability that this class wraps.
PermissionsProxy permissions()
Access the permissions of this capability.
bool is_sealed() const
Return whether this is a sealed capability.
constexpr std::partial_ordering operator<=>(std::nullptr_t) const
Comparison against null pointer.
bool is_aligned(size_t align) const
Returns true if the capability is align-byte aligned, false otherwise.
Capability & operator=(const Capability &other)=default
Replace the pointer that this capability wraps with another.
Capability operator+(ptrdiff_t diff)
Pointer addition.
ptraddr_t address() const
Return the address as an integer from a const capability.
Helper for a value that encodes either a pointer or an error value in a pointer-sized value,...
T * as_raw()
Returns the underlying pointer, which may be an untagged capability with integer error value.
bool is_error()
Returns true if this holds an error value, false otherwise.
int and_then(auto &&function)
Variant on and_then that returns an int: either the value returned by the callback,...
T * as_pointer()
If this holds a pointer, return it, otherwise return nullptr.
auto or_else(auto &&function)
Monadic helper modelled on std::optional.
auto as_raw_capability()
Returns the underlying pointer, which may be an untagged capability with integer error value,...
int as_error()
If this holds an error value, return it, otherwise return 0.
ErrorOr(int error)
Initialise the value with an error value.
auto and_then(auto &&function)
Monadic helper modelled on std::optional.
ErrorOr(T *pointer)
Construct from a pointer.
auto either(auto &&onT, auto &&onE)
Generic eliminator for ErrorOr<T> values.
ErrorOr(Capability< T, IsSealed > pointer)
Construct from a CHERI::Capability.
Class encapsulating a set of permissions.
uint32_t rawPermissions
The raw bitmap of permissions.
constexpr bool operator==(PermissionSet other) const
Equality operator, wraps the three-way compare operator.
constexpr Iterator begin() const
Returns an iterator over the permissions starting at the lowest-numbered permission.
constexpr auto operator<=>(const PermissionSet Other) const
Three-way comparison.
static constexpr PermissionSet omnipotent()
Returns a permission set representing all permissions.
constexpr bool can_derive_from(PermissionSet other) const
Returns true if, and only if, this permission set can be derived from the argument set.
constexpr PermissionSet(std::initializer_list< Permission > permissions)
Construct a permission set from a list of permissions.
constexpr PermissionSet without(Permission p) const
Constructs a new permission set without the specified permission.
constexpr uint32_t as_raw() const
Returns the raw permission mask as an integer containing a bitfield of permissions.
constexpr PermissionSet & operator&=(PermissionSet p)
And-permissions operation, removes all permissions that are not present in both permission sets.
constexpr PermissionSet(Permission p)
Constructs a permission set from a single permission.
static constexpr uint32_t valid_permissions_mask()
Computes (at compile time) a bitmask containing the set of valid permission bits.
static constexpr PermissionSet from_raw(uint32_t raw)
Constructs a permission set from a raw permission mask.
constexpr PermissionSet operator&(PermissionSet p)
And-permissions operation, creates a new permission set containing only permissions present in both t...
constexpr bool contains(Permission p, Permissions... ps) const
Returns true if this permission set contains the specified permissions.
constexpr Iterator end() const
Returns an end iterator.
constexpr bool contains(Permission permission) const
Returns true if this permission set contains the specified permission.
constexpr PermissionSet(const PermissionSet &other)=default
Copy constructor.
constexpr PermissionSet without(Permission p, Permissions... ps) const
Constructs a new permission set without the specified permissions.
Concept that matches pointers.
Concept that matches smart pointers, i.e., classes which implements a get method returning a pointer,...
Type trait for checking if a type is a sealed capability.
Type trait to remove sealed from a capability type.