1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Basic utilities for dealing with memory, values, and types. 4 5 use crate::prelude::*; 6 7 // TODO: `Alignment` should be moved here as well, Rust moved it upstream in 1.96. 8 pub use crate::ptr::Alignment; 9 10 /// Trait indicating that [`Align<N>`] is a valid alignment. 11 pub trait ValidAlign { 12 #[doc(hidden)] 13 type Repr: Copy; 14 } 15 16 /// Zero-sized type that provides the alignment specified via the generic parameter. 17 /// 18 /// # Examples 19 /// 20 /// ``` 21 /// # use kernel::mem::Align; 22 /// const ALIGN: usize = 128; 23 /// struct MyStruct { 24 /// _align: Align<ALIGN>, 25 /// } 26 /// assert_eq!(align_of::<MyStruct>(), ALIGN); 27 /// ``` 28 #[repr(transparent)] 29 #[derive(Default, Clone, Copy)] 30 pub struct Align<const N: usize>([<Self as ValidAlign>::Repr; 0]) 31 where 32 Self: ValidAlign; 33 34 impl<const N: usize> Align<N> 35 where 36 Self: ValidAlign, 37 { 38 /// Create a new [`Align<N>`]. 39 #[inline] 40 pub const fn new() -> Self { 41 Align([]) 42 } 43 } 44 45 macro_rules! impl_align { 46 () => {}; 47 ($a:literal $($rest:literal)*) => { 48 const _: () = { 49 #[repr(align($a))] 50 #[derive(Clone, Copy)] 51 pub struct Repr; 52 53 impl ValidAlign for Align<$a> { 54 type Repr = Repr; 55 } 56 }; 57 58 impl_align!($($rest)*); 59 } 60 } 61 62 impl_align!(1 2 4 8 16 32 64 128 256 512 1024 2048 4096 8192 16384 32768 65536); 63 64 impl<const N: usize> core::fmt::Debug for Align<N> 65 where 66 Self: ValidAlign, 67 { 68 #[inline] 69 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 70 write!(f, "Align<{N}>") 71 } 72 } 73 74 /// Transmute between two types. 75 /// 76 /// Use this instead of [`core::mem::transmute`] when it is known that sizes are identical but this 77 /// cannot be proven by the compiler. 78 /// 79 /// This is equivalent to Rust's `transmute_unchecked` intrinsics. 80 /// 81 /// # Safety 82 /// 83 /// All safety requirements of [`core::mem::transmute`] apply, plus that the size `Src` and `Dst` 84 /// must match. 85 /// 86 /// # Examples 87 /// 88 /// This can be used when types are known to have the same size, but only at runtime. 89 /// 90 /// ```no_run 91 /// # use core::any::TypeId; 92 /// fn to_u32<T: 'static>(v: T) -> Option<u32> { 93 /// if TypeId::of::<T>() != TypeId::of::<u32>() { 94 /// return None; 95 /// } 96 /// 97 /// // `core::mem::transmute` won't work here. 98 /// // SAFETY: We've checked that `T` is `u32`! 99 /// Some(unsafe { kernel::mem::transmute_unchecked(v) }) 100 /// } 101 /// 102 /// to_u32(1u32); 103 /// ``` 104 #[inline(always)] 105 pub const unsafe fn transmute_unchecked<Src, Dst>(val: Src) -> Dst { 106 // SAFETY: This is identical to `transmute` except that we bypassed the size check; which is 107 // true per safety requirement. 108 unsafe { core::mem::transmute_copy(&core::mem::ManuallyDrop::new(val)) } 109 } 110 111 /// Version of `transmute` that performs size check at monomorphization-time. 112 /// 113 /// Use this instead of [`core::mem::transmute`] when it is known that sizes are identical but this 114 /// cannot be proven by the compiler during type checking and can be proven during monomorphization. 115 /// 116 /// The signature is equivalent to Rust standard library's unstable `transmute_neo` and that of 117 /// [RFC 3844](https://github.com/rust-lang/rfcs/pull/3844). 118 /// 119 /// # Safety 120 /// 121 /// Same as [`core::mem::transmute`]. 122 /// 123 /// # Examples 124 /// 125 /// This is typically used in generic code where it's known that type will have the same size, but 126 /// the compiler cannot prove it generically. 127 /// 128 /// ```no_run 129 /// trait IsU32 {} 130 /// impl IsU32 for u32 {} 131 /// 132 /// fn to_u32<T: IsU32>(v: T) -> u32 { 133 /// // `core::mem::transmute` won't work here. 134 /// // SAFETY: We know that `v` is u32! 135 /// unsafe { kernel::mem::transmute(v) } 136 /// } 137 /// 138 /// to_u32(1u32); 139 /// ``` 140 #[inline(always)] 141 pub const unsafe fn transmute<Src, Dst>(val: Src) -> Dst { 142 const_assert!(size_of::<Src>() == size_of::<Dst>()); 143 144 // SAFETY: Size is checked above. Other safety requirements follow those of the function. 145 unsafe { transmute_unchecked(val) } 146 } 147 148 /// Safely transmutes a value of one type to a value of another type of the same size. 149 /// 150 /// The sizes are checked during monomorphization. 151 /// 152 /// This can be considered as generic version of [`zerocopy::transmute!`] macro that defers the size 153 /// check and thus can be used in more cases. 154 /// 155 /// # Examples 156 /// 157 /// ```no_run 158 /// fn to_u32<T: FromBytes + IntoBytes>(v: T) -> u32 { 159 /// // `zerocopy::transmute!` won't work here. 160 /// kernel::mem::safe_transmute(v) 161 /// } 162 /// 163 /// to_u32(1i32); 164 /// ``` 165 #[inline(always)] 166 pub const fn safe_transmute<Src: IntoBytes, Dst: FromBytes>(val: Src) -> Dst { 167 // SAFETY: `transmute` is safe with `IntoBytes` and `FromBytes` bounds. 168 unsafe { transmute(val) } 169 } 170 171 /// Type that is layout-compatible with a primitive representation. 172 /// 173 /// # Safety 174 /// 175 /// - [`Self`] must have the same size and alignment as [`Self::Repr`]. 176 /// - [`Self`] must be [transmutable] to [`Self::Repr`]. 177 /// - Neither [`Self`] nor [`Self::Repr`] contains interior mutability. 178 /// 179 /// The above basically says that `&Self` can be transmuted to `&Self::Repr`. 180 /// 181 /// [transmutable]: core::mem::transmute 182 pub unsafe trait AsRepr: Sized { 183 /// Primitive representation of this type. 184 type Repr; 185 186 /// Convert from [`&Self`](Self) to [`&Self::Repr`](AsRepr::Repr). 187 #[inline(always)] 188 fn as_repr(this: &Self) -> &Self::Repr { 189 // SAFETY: Per safety requirement of the trait. 190 unsafe { core::mem::transmute(this) } 191 } 192 193 /// Convert from [`Self`] to [`Self::Repr`]. 194 #[inline(always)] 195 fn into_repr(this: Self) -> Self::Repr { 196 // SAFETY: Per safety requirement of the trait. 197 unsafe { transmute(this) } 198 } 199 200 /// Convert from [`Self::Repr`] to [`Self`]. 201 /// 202 /// # Safety 203 /// 204 /// `repr` must be a valid bit pattern of [`Self`] and satisfy type-specific invariants of it. 205 /// 206 /// Alternatively, if `repr` is previously obtained using [`Self::into_repr`], and each 207 /// `from_repr_unchecked` should correspond to a unique `into_repr` call, then it is safe to 208 /// call as well (this means that we're undoing a `into_repr` call getting the exact bytes 209 /// back). 210 /// 211 /// No guarantee is made if the result of a `into_repr` is passed to multiple 212 /// `from_repr_unchecked` (i.e. copies are made), to allow for cases where `Repr` is a pointer 213 /// and the user of the API wants ownership transfer. Users that want the ability to call 214 /// `from_repr_unchecked` after copying can require `Copy` bound explicitly. 215 #[inline(always)] 216 unsafe fn from_repr_unchecked(repr: Self::Repr) -> Self { 217 // SAFETY: Per safety requirement, `repr` is valid repr of `Self`, or it is previously from 218 // `into_repr`, in which case we're undoing the transmute so it is also safe. 219 unsafe { transmute(repr) } 220 } 221 } 222 223 /// Type that is bi-directionally transmutable with a primitive representation. 224 /// 225 /// # Safety 226 /// 227 /// - [`Self`] must be [transmutable] from [`Self::Repr`]. 228 /// 229 /// [transmutable]: core::mem::transmute 230 /// [`Self::Repr`]: AsRepr::Repr 231 pub unsafe trait AsReprMut: AsRepr { 232 /// Convert from `&mut Self` to [`&mut Self::Repr`](AsRepr::Repr). 233 #[inline(always)] 234 fn as_repr_mut(this: &mut Self) -> &mut Self::Repr { 235 // SAFETY: Per safety requirement of the trait. 236 unsafe { core::mem::transmute(this) } 237 } 238 239 /// Convert from [`Self::Repr`](AsRepr::Repr) to `Self`. 240 #[inline(always)] 241 fn from_repr(repr: Self::Repr) -> Self { 242 // SAFETY: Per safety requirement of the trait. 243 unsafe { transmute(repr) } 244 } 245 } 246 247 // SAFETY: `bool` has the same size and alignment as `u8`, and Rust guarantees that `bool` has 248 // only two valid bit patterns: 0 (`false`) and 1 (`true`). Thus `bool` can be transmuted to `u8`. 249 // Neither types contain interior mutability. 250 unsafe impl AsRepr for bool { 251 type Repr = u8; 252 } 253 254 // SAFETY: `*mut T` has the same size and alignment with `*const c_void`, and thus `*mut T` is 255 // transmutable to `*const c_void`. Neither types contain interior mutability. 256 unsafe impl<T> AsRepr for *mut T { 257 type Repr = *const c_void; 258 } 259 260 // SAFETY: `*mut T` is transmutable from `*const c_void`. 261 unsafe impl<T> AsReprMut for *mut T {} 262 263 // SAFETY: `*const T` has the same size and alignment with `*const c_void`, and is transmutable to 264 // `*const c_void`. Neither types contain interior mutability. 265 unsafe impl<T> AsRepr for *const T { 266 type Repr = *const c_void; 267 } 268 269 // SAFETY: `*const T` is transmutable from `*const c_void`. 270 unsafe impl<T> AsReprMut for *const T {} 271 272 macro_rules! int_impl { 273 ($($unsigned:ident $signed:ident ,)*) => {$( 274 // SAFETY: `$unsigned` has the same size and alignment with itself, and is transmutable to 275 // itself. It does not contain interior mutability. 276 unsafe impl AsRepr for $unsigned { 277 type Repr = $unsigned; 278 } 279 280 // SAFETY: `$unsigned` is transmutable from itself. 281 unsafe impl AsReprMut for $unsigned {} 282 283 // SAFETY: `$signed` has the same size and alignment with `$unsigned`, and is transmutable 284 // to it Neither types contain interior mutability. 285 unsafe impl AsRepr for $signed { 286 type Repr = $unsigned; 287 } 288 289 // SAFETY: `$signed` is transmutable from `$unsigned`. 290 unsafe impl AsReprMut for $signed {} 291 )*}; 292 } 293 294 int_impl! { 295 u8 i8, 296 u16 i16, 297 u32 i32, 298 u64 i64, 299 // `usize` is not normalized to particular integer for portability. 300 usize isize, 301 } 302