Skip to content

Commit c322356

Browse files
committed
cheri: add cheri feature, cheri_address_get and cheri_without_provenance intrinsics
1 parent 889c794 commit c322356

File tree

9 files changed

+84
-21
lines changed

9 files changed

+84
-21
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,11 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
466466
// not the optimization stage.)
467467
sym::is_val_statically_known => ecx.write_scalar(Scalar::from_bool(false), dest)?,
468468

469+
sym::cheri_without_provenance => {
470+
let addr = ecx.read_scalar(&args[0])?.to_target_usize(ecx)?;
471+
ecx.write_pointer(Pointer::without_provenance(addr), dest)?
472+
}
473+
469474
// We handle these here since Miri does not want to have them.
470475
sym::assert_inhabited
471476
| sym::assert_zero_valid

compiler/rustc_hir_analysis/src/check/intrinsic.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,9 @@ fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -> hi
135135
| sym::round_ties_even_f32
136136
| sym::round_ties_even_f64
137137
| sym::round_ties_even_f128
138-
| sym::const_eval_select => hir::Safety::Safe,
138+
| sym::const_eval_select
139+
| sym::cheri_address_get
140+
| sym::cheri_without_provenance => hir::Safety::Safe,
139141
_ => hir::Safety::Unsafe,
140142
};
141143

@@ -664,6 +666,13 @@ pub(crate) fn check_intrinsic_type(
664666
| sym::atomic_umin => (1, 1, vec![Ty::new_mut_ptr(tcx, param(0)), param(0)], param(0)),
665667
sym::atomic_fence | sym::atomic_singlethreadfence => (0, 1, Vec::new(), tcx.types.unit),
666668

669+
// CHERI-specific intrinsics
670+
sym::cheri_without_provenance => {
671+
(1, 0, vec![tcx.types.usize], Ty::new_mut_ptr(tcx, param(0)))
672+
}
673+
sym::cheri_address_get => {
674+
(0, 0, vec![Ty::new_imm_ptr(tcx, tcx.types.unit)], tcx.types.usize)
675+
}
667676
other => {
668677
tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span, name: other });
669678
return;

compiler/rustc_span/src/symbol.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,9 @@ symbols! {
641641
char,
642642
char_is_ascii,
643643
char_to_digit,
644+
cheri,
645+
cheri_address_get,
646+
cheri_without_provenance,
644647
child_id,
645648
child_kill,
646649
client,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//! Some intrinsics specific to CHERI systems.
2+
3+
/// Create an pointer without provenance metadata from the given value.
4+
#[inline]
5+
#[rustc_intrinsic]
6+
#[rustc_nounwind]
7+
#[rustc_intrinsic_const_stable_indirect]
8+
pub const fn cheri_without_provenance<T>(value: usize) -> *mut T;
9+
10+
/// Retrieve the address of the pointer.
11+
#[inline]
12+
#[rustc_intrinsic]
13+
#[rustc_nounwind]
14+
pub fn cheri_address_get(ptr: *const ()) -> usize;

library/core/src/intrinsics/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ pub mod fallback;
6363
pub mod mir;
6464
pub mod simd;
6565

66+
#[cfg(target_family = "cheri")]
67+
pub mod cheri;
68+
6669
// These imports are used for simplifying intra-doc links
6770
#[allow(unused_imports)]
6871
#[cfg(all(target_has_atomic = "8", target_has_atomic = "32", target_has_atomic = "ptr"))]

library/core/src/ptr/const_ptr.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::*;
22
use crate::cmp::Ordering::{Equal, Greater, Less};
33
use crate::intrinsics::const_eval_select;
4-
use crate::mem::{self, SizedTypeProperties};
4+
use crate::mem::SizedTypeProperties;
55
use crate::slice::{self, SliceIndex};
66

77
impl<T: PointeeSized> *const T {
@@ -172,12 +172,21 @@ impl<T: PointeeSized> *const T {
172172
#[inline(always)]
173173
#[stable(feature = "strict_provenance", since = "1.84.0")]
174174
pub fn addr(self) -> usize {
175-
// A pointer-to-integer transmute currently has exactly the right semantics: it returns the
176-
// address without exposing the provenance. Note that this is *not* a stable guarantee about
177-
// transmute semantics, it relies on sysroot crates having special status.
178-
// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
179-
// provenance).
180-
unsafe { mem::transmute(self.cast::<()>()) }
175+
176+
#[cfg(target_family = "cheri")]
177+
{
178+
crate::intrinsics::cheri::cheri_address_get(self.cast::<()>())
179+
}
180+
181+
#[cfg(not(target_family = "cheri"))]
182+
{
183+
// A pointer-to-integer transmute currently has exactly the right semantics: it returns the
184+
// address without exposing the provenance. Note that this is *not* a stable guarantee about
185+
// transmute semantics, it relies on sysroot crates having special status.
186+
// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
187+
// provenance).
188+
unsafe { crate::mem::transmute(self.cast::<()>()) }
189+
}
181190
}
182191

183192
/// Exposes the ["provenance"][crate::ptr#provenance] part of the pointer for future use in

library/core/src/ptr/mod.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -915,12 +915,20 @@ pub const fn dangling<T>() -> *const T {
915915
#[stable(feature = "strict_provenance", since = "1.84.0")]
916916
#[rustc_const_stable(feature = "strict_provenance", since = "1.84.0")]
917917
pub const fn without_provenance_mut<T>(addr: usize) -> *mut T {
918-
// An int-to-pointer transmute currently has exactly the intended semantics: it creates a
919-
// pointer without provenance. Note that this is *not* a stable guarantee about transmute
920-
// semantics, it relies on sysroot crates having special status.
921-
// SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
922-
// pointer).
923-
unsafe { mem::transmute(addr) }
918+
#[cfg(target_family = "cheri")]
919+
{
920+
crate::intrinsics::cheri::cheri_without_provenance(addr)
921+
}
922+
923+
#[cfg(not(target_family = "cheri"))]
924+
{
925+
// An int-to-pointer transmute currently has exactly the intended semantics: it creates a
926+
// pointer without provenance. Note that this is *not* a stable guarantee about transmute
927+
// semantics, it relies on sysroot crates having special status.
928+
// SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that
929+
// pointer).
930+
unsafe { mem::transmute(addr) }
931+
}
924932
}
925933

926934
/// Creates a new pointer that is dangling, but non-null and well-aligned.

library/core/src/ptr/mut_ptr.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use super::*;
22
use crate::cmp::Ordering::{Equal, Greater, Less};
33
use crate::intrinsics::const_eval_select;
44
use crate::marker::PointeeSized;
5-
use crate::mem::{self, SizedTypeProperties};
5+
use crate::mem::SizedTypeProperties;
66
use crate::slice::{self, SliceIndex};
77

88
impl<T: PointeeSized> *mut T {
@@ -160,12 +160,20 @@ impl<T: PointeeSized> *mut T {
160160
#[inline(always)]
161161
#[stable(feature = "strict_provenance", since = "1.84.0")]
162162
pub fn addr(self) -> usize {
163-
// A pointer-to-integer transmute currently has exactly the right semantics: it returns the
164-
// address without exposing the provenance. Note that this is *not* a stable guarantee about
165-
// transmute semantics, it relies on sysroot crates having special status.
166-
// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
167-
// provenance).
168-
unsafe { mem::transmute(self.cast::<()>()) }
163+
#[cfg(target_family = "cheri")]
164+
{
165+
crate::intrinsics::cheri::cheri_address_get(self.cast::<()>())
166+
}
167+
168+
#[cfg(not(target_family = "cheri"))]
169+
{
170+
// A pointer-to-integer transmute currently has exactly the right semantics: it returns the
171+
// address without exposing the provenance. Note that this is *not* a stable guarantee about
172+
// transmute semantics, it relies on sysroot crates having special status.
173+
// SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
174+
// provenance).
175+
unsafe { crate::mem::transmute(self.cast::<()>()) }
176+
}
169177
}
170178

171179
/// Exposes the ["provenance"][crate::ptr#provenance] part of the pointer for future use in

src/tools/tidy/src/pal.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ const EXCEPTION_PATHS: &[&str] = &[
4444
"library/unwind",
4545
"library/rtstartup", // Not sure what to do about this. magic stuff for mingw
4646
"library/test", // Probably should defer to unstable `std::sys` APIs.
47+
// With the addition of CHERI-like platforms, some CHERI-specific intrinsics must be added.
48+
"library/core/src/intrinsics/mod.rs",
49+
// With the addition of CHERI-specific intrinsics for CHERI-like platforms, `ptr` too must have platform specific code (to use those intrinsics).
50+
"library/core/src/ptr",
4751
// The `VaList` implementation must have platform specific code.
4852
// The Windows implementation of a `va_list` is always a character
4953
// pointer regardless of the target architecture. As a result,

0 commit comments

Comments
 (0)