mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] rust: transmute: Add implementation for FromBytes trait
@ 2024-10-09  1:47 Christian dos Santos de Lima
  2024-10-09  7:37 ` Alice Ryhl
                   ` (2 more replies)
  0 siblings, 3 replies; 5+ messages in thread
From: Christian dos Santos de Lima @ 2024-10-09  1:47 UTC (permalink / raw)
  To: rust-for-linux, linux-kernel, Miguel Ojeda, Alex Gaynor,
	Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross

Add implementation and documentation for FromBytes trait.

Add new feature block in order to allow using ToBytes
and bound to from_bytes_mut function.

Link: https://github.com/Rust-for-Linux/linux/issues/1119
Signed-off-by: Christian dos Santos de Lima <christiansantoslima21@gmail.com>
---
 rust/kernel/lib.rs       |   2 +
 rust/kernel/transmute.rs | 302 +++++++++++++++++++++++++++++++++++++--
 2 files changed, 290 insertions(+), 14 deletions(-)

diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
index dc37aef6a008..5215f5744e12 100644
--- a/rust/kernel/lib.rs
+++ b/rust/kernel/lib.rs
@@ -18,6 +18,8 @@
 #![feature(lint_reasons)]
 #![feature(new_uninit)]
 #![feature(unsize)]
+#![feature(portable_simd)]
+#![feature(trivial_bounds)]
 
 // Ensure conditional compilation based on the kernel configuration works;
 // otherwise we may silently break things like initcall handling.
diff --git a/rust/kernel/transmute.rs b/rust/kernel/transmute.rs
index 1c7d43771a37..f2d99c136017 100644
--- a/rust/kernel/transmute.rs
+++ b/rust/kernel/transmute.rs
@@ -12,24 +12,298 @@
 /// # Safety
 ///
 /// All bit-patterns must be valid for this type. This type must not have interior mutability.
-pub unsafe trait FromBytes {}
+pub unsafe trait FromBytes {
+    ///Converts a slice of Bytes into a Reference to Self
+    ///
+    /// # Examples
+    /// ```
+    ///    pub unsafe trait FromBytes {
+    ///        unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self;
+    ///        unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    ///        where
+    ///            Self: ToBytes;
+    ///    }
+    ///
+    ///unsafe impl FromBytes for u32 {
+    ///    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+    ///        let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+    ///        &*slice_ptr
+    ///    }
+    ///
+    ///    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    ///    where
+    ///        Self: ToBytes,
+    ///    {
+    ///        let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+    ///        &mut *slice_ptr
+    ///    }
+    ///}
+    ///
+    ///let slice_of_bytes : &[u8] = &[1, 2, 3, 4];
+    ///let result = u32::from_bytes(slice_of_bytes);
+    ///assert_eq!(*result, 0x4030201);
+    ///```
+    ///# Safety
+    ///
+    ///Guarantee that all values are initiliazed
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self;
+    ///Converts a mutabble slice of Bytes into a mutable Reference to Self
+    /// # Safety
+    ///
+    /// ToBytes in order to allow only types that implements ToBytes
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes;
+}
 
-macro_rules! impl_frombytes {
-    ($($({$($generics:tt)*})? $t:ty, )*) => {
-        // SAFETY: Safety comments written in the macro invocation.
-        $(unsafe impl$($($generics)*)? FromBytes for $t {})*
-    };
+// SAFETY: All bit patterns are acceptable values of the types below.
+unsafe impl FromBytes for u8 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
 }
 
-impl_frombytes! {
-    // SAFETY: All bit patterns are acceptable values of the types below.
-    u8, u16, u32, u64, usize,
-    i8, i16, i32, i64, isize,
+unsafe impl FromBytes for u16 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for u32 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for u64 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for usize {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for i8 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for i16 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for i32 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for i64 {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+
+unsafe impl FromBytes for isize {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
+            &*slice_ptr
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
+            &mut *slice_ptr
+        }
+    }
+}
+// SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
+// patterns are also acceptable for arrays of that type.
+unsafe impl<T: FromBytes> FromBytes for [T] {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const T;
+            let slice_len = slice_of_bytes.len() / core::mem::size_of::<T>();
+            core::slice::from_raw_parts(slice_ptr, slice_len)
+        }
+    }
+
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut T;
+            let slice_len = slice_of_bytes.len() / core::mem::size_of::<T>();
+            core::slice::from_raw_parts_mut(slice_ptr, slice_len)
+        }
+    }
+}
+
+/// # Examples
+///```
+///let slice_of_bytes: &[u8] = &[
+///    1, 0, 0, 0,
+///    2, 0, 0, 0,
+///    3, 0, 0, 0,
+///    4, 0, 0, 0,
+///    5, 0, 0, 0,
+///    6, 0, 0, 0,
+///    7, 0, 0, 0,
+///    8, 0, 0, 0,
+///];
+///
+///let foo = <[u32; 8]>::from_bytes(slice_of_bytes);
+///let expected: [u32; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
+///
+///assert_eq!(*foo, expected);
+///```
+unsafe impl<T: FromBytes, const N: usize> FromBytes for [T; N] {
+    unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *const T;
+            &*(slice_ptr as *const [T; N])
+        }
+    }
 
-    // SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
-    // patterns are also acceptable for arrays of that type.
-    {<T: FromBytes>} [T],
-    {<T: FromBytes, const N: usize>} [T; N],
+    unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
+    where
+        Self: ToBytes,
+    {
+        unsafe {
+            let slice_ptr = slice_of_bytes.as_ptr() as *mut T;
+            &mut *(slice_ptr as *mut [T; N])
+        }
+    }
 }
 
 /// Types that can be viewed as an immutable slice of initialized bytes.
-- 
2.46.2


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2024-10-09 16:36 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-09  1:47 [PATCH] rust: transmute: Add implementation for FromBytes trait Christian dos Santos de Lima
2024-10-09  7:37 ` Alice Ryhl
2024-10-09 12:32 ` Miguel Ojeda
2024-10-09 13:03 ` Dirk Behme
2024-10-09 16:35   ` Benno Lossin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®