Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3ce7f6d
Add an invalidate method on Capability for clearing the tag.
rmn30 Dec 8, 2022
5a6ad82
Add a test for some hardware features
rmn30 Nov 29, 2022
4e7b998
Update tests/isa-test.cc
rmn30 Mar 24, 2023
6b02ea2
Enable printing of function pointers in debug.hh.
ronorton Jul 1, 2024
640300f
Update ISA test for ISA changes.
ronorton Jul 1, 2024
7f50761
Move to_representable function into PermissionSet as suggested during…
ronorton Jul 2, 2024
b6538ed
Clang format.
ronorton Jul 2, 2024
b4971df
ISA Test: use token sealing key to test and perms of sealing capability.
ronorton Jul 9, 2024
22c3ba1
isa-test: extend set bounds test for rounds down variant.
rmn30 Dec 10, 2024
a8b5678
isa-test: update get_sentry functions to work with new cjal / cjalr
rmn30 Dec 10, 2024
6aeaa62
isa-test: use TEST_EQUAL where possible.
rmn30 Dec 10, 2024
2c96687
isa-test: use value of MCAUSE_CHERI from riscv/priv.h
rmn30 Dec 10, 2024
abdc353
isa-test: make use of token APIs to test sealing and sealed capabilties
rmn30 Dec 10, 2024
81ef644
isa-test: fix return type of test_isa
rmn30 Dec 10, 2024
3f3edc8
isa-test: use unwind.h instead of skipping instruction in error handler
rmn30 Dec 10, 2024
ff28234
isa-test: rename faulting_load and faulting_store
rmn30 Dec 10, 2024
80eaffb
clang_format
rmn30 Dec 10, 2024
4a710f3
isa-test: extend the store test to check memory after store
rmn30 Dec 11, 2024
c0cb6f0
Merge remote-tracking branch 'origin/main' into isa_test
rmn30 Oct 31, 2025
6ad9307
Clang format.
rmn30 Nov 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions sdk/include/cheri.hh
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,95 @@ namespace CHERI
return this->contains(p) && this->contains(ps...);
}

/**
* Returns a new PermissionSet with the maximum permissions
* representable in the format that the hardware would use if asked to
* represent this PermissionSet. If `this` is representable it will
* return a superset but otherwise there is not necessarily any
* intersection!
*/
[[nodiscard]] constexpr PermissionSet get_max_format_perms() const
{
if (this->contains(Permission::Execute,
Permission::Load,
Permission::LoadStoreCapability))
{
// Executable format
return PermissionSet{Permission::Global,
Permission::Execute,
Permission::Load,
Permission::LoadStoreCapability,
Permission::LoadGlobal,
Permission::LoadMutable,
Permission::AccessSystemRegisters};
}
if (this->contains(Permission::Load,
Permission::Store,
Permission::LoadStoreCapability))
{
// cap-rw format
return PermissionSet{Permission::Global,
Permission::Load,
Permission::Store,
Permission::LoadStoreCapability,
Permission::LoadGlobal,
Permission::LoadMutable,
Permission::StoreLocal};
}
if (this->contains(Permission::Load,
Permission::LoadStoreCapability))
{
// cap-ro format
return PermissionSet{Permission::Global,
Permission::Load,
Permission::LoadStoreCapability,
Permission::LoadGlobal,
Permission::LoadMutable};
}
if (this->contains(Permission::Store,
Permission::LoadStoreCapability))
{
// cap-wo format
return PermissionSet{Permission::Global,
Permission::Store,
Permission::LoadStoreCapability};
}
if (this->contains(Permission::Store) ||
this->contains(Permission::Load))
{
// data-rw format
return PermissionSet{
Permission::Global, Permission::Load, Permission::Store};
}
// sealing format
return PermissionSet{Permission::Global,
Permission::Seal,
Permission::Unseal,
Permission::User0};
}

/**
* Returns a new PermissionSet that is the set of permissions that the
* hardware would return if asked to encode this PermissionSet by
* CAndPerms.
*
* The returned PermissionSet will always be a (possibly empty) subset
* of `this`.
*/
[[nodiscard]] constexpr PermissionSet to_representable() const
{
return this->get_max_format_perms() & (*this);
}

/**
* Returns whether this PermissionSet is exactly representable in the
* hardware encodings.
*/
[[nodiscard]] constexpr bool is_representable() const
{
return (*this) == this->to_representable();
}

/**
* Returns the raw permission mask as an integer containing a bitfield
* of permissions.
Expand Down Expand Up @@ -689,6 +778,10 @@ namespace CHERI
*/
__always_inline BoundsProxy &set_inexact_at_most(size_t bounds)
{
#if __has_builtin(__builtin_cheri_bounds_set_round_down)
set(__builtin_cheri_bounds_set_round_down(ptr(), bounds));
return *this;
#else
// Just try to set the requested bounds, first. If that works,
// there's no need for bit-twiddling at all.
Capability p = ptr();
Expand All @@ -700,6 +793,7 @@ namespace CHERI
}

return set_inexact_at_most_slow(bounds);
#endif
}
};

Expand Down Expand Up @@ -958,6 +1052,14 @@ namespace CHERI
return false;
}

/**
* Clears the tag bit indicating whether this is a valid capability.
*/
void invalidate()
{
ptr = __builtin_cheri_tag_clear(ptr);
}

/**
* Returns the tag bit indicating whether this is a valid
* capability.
Expand Down
3 changes: 1 addition & 2 deletions sdk/include/debug.hh
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,7 @@ struct DebugFormatArgumentAdaptor<CHERI::Capability<T, Sealed>>
__always_inline static DebugFormatArgument
construct(CHERI::Capability<T, Sealed> value)
{
return {reinterpret_cast<uintptr_t>(
static_cast<const volatile void *>(value)),
return {reinterpret_cast<uintptr_t>(value.get()),
DebugFormatArgumentKind::DebugFormatArgumentPointer};
}
};
Expand Down
Loading
Loading