Skip to content

Commit 508534f

Browse files
Every2intel-lab-lkp
authored andcommitted
rust: transmute: Add implementation for FromBytes trait
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: Rust-for-Linux#1119 Signed-off-by: Christian dos Santos de Lima <[email protected]>
1 parent c9b5ce6 commit 508534f

File tree

2 files changed

+290
-14
lines changed

2 files changed

+290
-14
lines changed

rust/kernel/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#![feature(lint_reasons)]
1919
#![feature(new_uninit)]
2020
#![feature(unsize)]
21+
#![feature(portable_simd)]
22+
#![feature(trivial_bounds)]
2123

2224
// Ensure conditional compilation based on the kernel configuration works;
2325
// otherwise we may silently break things like initcall handling.

rust/kernel/transmute.rs

Lines changed: 288 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,298 @@
1212
/// # Safety
1313
///
1414
/// All bit-patterns must be valid for this type. This type must not have interior mutability.
15-
pub unsafe trait FromBytes {}
15+
pub unsafe trait FromBytes {
16+
///Converts a slice of Bytes into a Reference to Self
17+
///
18+
/// # Examples
19+
/// ```
20+
/// pub unsafe trait FromBytes {
21+
/// unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self;
22+
/// unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
23+
/// where
24+
/// Self: ToBytes;
25+
/// }
26+
///
27+
///unsafe impl FromBytes for u32 {
28+
/// unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
29+
/// let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
30+
/// &*slice_ptr
31+
/// }
32+
///
33+
/// unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
34+
/// where
35+
/// Self: ToBytes,
36+
/// {
37+
/// let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
38+
/// &mut *slice_ptr
39+
/// }
40+
///}
41+
///
42+
///let slice_of_bytes : &[u8] = &[1, 2, 3, 4];
43+
///let result = u32::from_bytes(slice_of_bytes);
44+
///assert_eq!(*result, 0x4030201);
45+
///```
46+
///# Safety
47+
///
48+
///Guarantee that all values are initiliazed
49+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self;
50+
///Converts a mutabble slice of Bytes into a mutable Reference to Self
51+
/// # Safety
52+
///
53+
/// ToBytes in order to allow only types that implements ToBytes
54+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
55+
where
56+
Self: ToBytes;
57+
}
1658

17-
macro_rules! impl_frombytes {
18-
($($({$($generics:tt)*})? $t:ty, )*) => {
19-
// SAFETY: Safety comments written in the macro invocation.
20-
$(unsafe impl$($($generics)*)? FromBytes for $t {})*
21-
};
59+
// SAFETY: All bit patterns are acceptable values of the types below.
60+
unsafe impl FromBytes for u8 {
61+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
62+
unsafe {
63+
let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
64+
&*slice_ptr
65+
}
66+
}
67+
68+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
69+
where
70+
Self: ToBytes,
71+
{
72+
unsafe {
73+
let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
74+
&mut *slice_ptr
75+
}
76+
}
2277
}
2378

24-
impl_frombytes! {
25-
// SAFETY: All bit patterns are acceptable values of the types below.
26-
u8, u16, u32, u64, usize,
27-
i8, i16, i32, i64, isize,
79+
unsafe impl FromBytes for u16 {
80+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
81+
unsafe {
82+
let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
83+
&*slice_ptr
84+
}
85+
}
86+
87+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
88+
where
89+
Self: ToBytes,
90+
{
91+
unsafe {
92+
let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
93+
&mut *slice_ptr
94+
}
95+
}
96+
}
97+
98+
unsafe impl FromBytes for u32 {
99+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
100+
unsafe {
101+
let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
102+
&*slice_ptr
103+
}
104+
}
105+
106+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
107+
where
108+
Self: ToBytes,
109+
{
110+
unsafe {
111+
let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
112+
&mut *slice_ptr
113+
}
114+
}
115+
}
116+
117+
unsafe impl FromBytes for u64 {
118+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
119+
unsafe {
120+
let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
121+
&*slice_ptr
122+
}
123+
}
124+
125+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
126+
where
127+
Self: ToBytes,
128+
{
129+
unsafe {
130+
let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
131+
&mut *slice_ptr
132+
}
133+
}
134+
}
135+
136+
unsafe impl FromBytes for usize {
137+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
138+
unsafe {
139+
let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
140+
&*slice_ptr
141+
}
142+
}
143+
144+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
145+
where
146+
Self: ToBytes,
147+
{
148+
unsafe {
149+
let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
150+
&mut *slice_ptr
151+
}
152+
}
153+
}
154+
155+
unsafe impl FromBytes for i8 {
156+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
157+
unsafe {
158+
let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
159+
&*slice_ptr
160+
}
161+
}
162+
163+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
164+
where
165+
Self: ToBytes,
166+
{
167+
unsafe {
168+
let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
169+
&mut *slice_ptr
170+
}
171+
}
172+
}
173+
174+
unsafe impl FromBytes for i16 {
175+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
176+
unsafe {
177+
let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
178+
&*slice_ptr
179+
}
180+
}
181+
182+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
183+
where
184+
Self: ToBytes,
185+
{
186+
unsafe {
187+
let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
188+
&mut *slice_ptr
189+
}
190+
}
191+
}
192+
193+
unsafe impl FromBytes for i32 {
194+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
195+
unsafe {
196+
let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
197+
&*slice_ptr
198+
}
199+
}
200+
201+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
202+
where
203+
Self: ToBytes,
204+
{
205+
unsafe {
206+
let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
207+
&mut *slice_ptr
208+
}
209+
}
210+
}
211+
212+
unsafe impl FromBytes for i64 {
213+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
214+
unsafe {
215+
let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
216+
&*slice_ptr
217+
}
218+
}
219+
220+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
221+
where
222+
Self: ToBytes,
223+
{
224+
unsafe {
225+
let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
226+
&mut *slice_ptr
227+
}
228+
}
229+
}
230+
231+
unsafe impl FromBytes for isize {
232+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
233+
unsafe {
234+
let slice_ptr = slice_of_bytes.as_ptr() as *const Self;
235+
&*slice_ptr
236+
}
237+
}
238+
239+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
240+
where
241+
Self: ToBytes,
242+
{
243+
unsafe {
244+
let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut Self;
245+
&mut *slice_ptr
246+
}
247+
}
248+
}
249+
// SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
250+
// patterns are also acceptable for arrays of that type.
251+
unsafe impl<T: FromBytes> FromBytes for [T] {
252+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
253+
unsafe {
254+
let slice_ptr = slice_of_bytes.as_ptr() as *const T;
255+
let slice_len = slice_of_bytes.len() / core::mem::size_of::<T>();
256+
core::slice::from_raw_parts(slice_ptr, slice_len)
257+
}
258+
}
259+
260+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
261+
where
262+
Self: ToBytes,
263+
{
264+
unsafe {
265+
let slice_ptr = slice_of_bytes.as_mut_ptr() as *mut T;
266+
let slice_len = slice_of_bytes.len() / core::mem::size_of::<T>();
267+
core::slice::from_raw_parts_mut(slice_ptr, slice_len)
268+
}
269+
}
270+
}
271+
272+
/// # Examples
273+
///```
274+
///let slice_of_bytes: &[u8] = &[
275+
/// 1, 0, 0, 0,
276+
/// 2, 0, 0, 0,
277+
/// 3, 0, 0, 0,
278+
/// 4, 0, 0, 0,
279+
/// 5, 0, 0, 0,
280+
/// 6, 0, 0, 0,
281+
/// 7, 0, 0, 0,
282+
/// 8, 0, 0, 0,
283+
///];
284+
///
285+
///let foo = <[u32; 8]>::from_bytes(slice_of_bytes);
286+
///let expected: [u32; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
287+
///
288+
///assert_eq!(*foo, expected);
289+
///```
290+
unsafe impl<T: FromBytes, const N: usize> FromBytes for [T; N] {
291+
unsafe fn from_bytes(slice_of_bytes: &[u8]) -> &Self {
292+
unsafe {
293+
let slice_ptr = slice_of_bytes.as_ptr() as *const T;
294+
&*(slice_ptr as *const [T; N])
295+
}
296+
}
28297

29-
// SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit
30-
// patterns are also acceptable for arrays of that type.
31-
{<T: FromBytes>} [T],
32-
{<T: FromBytes, const N: usize>} [T; N],
298+
unsafe fn from_bytes_mut(slice_of_bytes: &mut [u8]) -> &mut Self
299+
where
300+
Self: ToBytes,
301+
{
302+
unsafe {
303+
let slice_ptr = slice_of_bytes.as_ptr() as *mut T;
304+
&mut *(slice_ptr as *mut [T; N])
305+
}
306+
}
33307
}
34308

35309
/// Types that can be viewed as an immutable slice of initialized bytes.

0 commit comments

Comments
 (0)