1 // Copyright 2017 The Chromium OS Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::io; 6 use std::mem::{align_of, size_of}; 7 use std::slice::{from_raw_parts, from_raw_parts_mut}; 8 9 /// Types for which it is safe to initialize from raw data. 10 /// 11 /// 12 /// Implementing this trait guarantees that it is safe to instantiate the struct with random data. 13 /// 14 /// # Safety 15 /// A type `T` is `DataInit` if it can be initialized by reading its contents from a byte array. 16 /// This is generally true for all plain-old-data structs. It is notably not true for any type 17 /// that includes a reference. 18 /// 19 /// It is unsafe for `T` to be `DataInit` if `T` contains implicit padding. (LLVM considers access 20 /// to implicit padding to be undefined behavior, which can cause UB when working with `T`. 21 /// For details on structure padding in Rust, see 22 /// https://doc.rust-lang.org/reference/type-layout.html#the-c-representation 23 pub unsafe trait DataInit: Copy + Send + Sync { 24 /// Converts a slice of raw data into a reference of `Self`. 25 /// 26 /// The value of `data` is not copied. Instead a reference is made from the given slice. The 27 /// value of `Self` will depend on the representation of the type in memory, and may change in 28 /// an unstable fashion. 29 /// 30 /// This will return `None` if the length of data does not match the size of `Self`, or if the 31 /// data is not aligned for the type of `Self`. from_slice(data: &[u8]) -> Option<&Self>32 fn from_slice(data: &[u8]) -> Option<&Self> { 33 // Early out to avoid an unneeded `align_to` call. 34 if data.len() != size_of::<Self>() { 35 return None; 36 } 37 38 // Safe because the DataInit trait asserts any data is valid for this type, and we ensured 39 // the size of the pointer's buffer is the correct size. The `align_to` method ensures that 40 // we don't have any unaligned references. This aliases a pointer, but because the pointer 41 // is from a const slice reference, there are no mutable aliases. Finally, the reference 42 // returned can not outlive data because they have equal implicit lifetime constraints. 43 match unsafe { data.align_to::<Self>() } { 44 ([], [mid], []) => Some(mid), 45 _ => None, 46 } 47 } 48 49 /// Converts a mutable slice of raw data into a mutable reference of `Self`. 50 /// 51 /// Because `Self` is made from a reference to the mutable slice`, mutations to the returned 52 /// reference are immediately reflected in `data`. The value of the returned `Self` will depend 53 /// on the representation of the type in memory, and may change in an unstable fashion. 54 /// 55 /// This will return `None` if the length of data does not match the size of `Self`, or if the 56 /// data is not aligned for the type of `Self`. from_mut_slice(data: &mut [u8]) -> Option<&mut Self>57 fn from_mut_slice(data: &mut [u8]) -> Option<&mut Self> { 58 // Early out to avoid an unneeded `align_to_mut` call. 59 if data.len() != size_of::<Self>() { 60 return None; 61 } 62 63 // Safe because the DataInit trait asserts any data is valid for this type, and we ensured 64 // the size of the pointer's buffer is the correct size. The `align_to` method ensures that 65 // we don't have any unaligned references. This aliases a pointer, but because the pointer 66 // is from a mut slice reference, we borrow the passed in mutable reference. Finally, the 67 // reference returned can not outlive data because they have equal implicit lifetime 68 // constraints. 69 match unsafe { data.align_to_mut::<Self>() } { 70 ([], [mid], []) => Some(mid), 71 _ => None, 72 } 73 } 74 75 /// Creates an instance of `Self` by copying raw data from an io::Read stream. from_reader<R: io::Read>(mut read: R) -> io::Result<Self>76 fn from_reader<R: io::Read>(mut read: R) -> io::Result<Self> { 77 // Allocate a Vec<u8> with enough extra space for the worst-case alignment offset. 78 let mut data = vec![0u8; size_of::<Self>() + align_of::<Self>()]; 79 80 // Get a u8 slice within data with sufficient alignment for Self. 81 let align_offset = data.as_ptr().align_offset(align_of::<Self>()); 82 let mut aligned_data = &mut data[align_offset..align_offset + size_of::<Self>()]; 83 84 read.read_exact(&mut aligned_data)?; 85 match Self::from_slice(&aligned_data) { 86 Some(obj) => Ok(*obj), 87 None => Err(io::Error::new( 88 io::ErrorKind::InvalidData, 89 "from_slice failed", 90 )), 91 } 92 } 93 94 /// Converts a reference to `self` into a slice of bytes. 95 /// 96 /// The value of `self` is not copied. Instead, the slice is made from a reference to `self`. 97 /// The value of bytes in the returned slice will depend on the representation of the type in 98 /// memory, and may change in an unstable fashion. as_slice(&self) -> &[u8]99 fn as_slice(&self) -> &[u8] { 100 // Safe because the entire size of self is accessible as bytes because the trait guarantees 101 // it. The lifetime of the returned slice is the same as the passed reference, so that no 102 // dangling pointers will result from this pointer alias. 103 unsafe { from_raw_parts(self as *const Self as *const u8, size_of::<Self>()) } 104 } 105 106 /// Converts a mutable reference to `self` into a mutable slice of bytes. 107 /// 108 /// Because the slice is made from a reference to `self`, mutations to the returned slice are 109 /// immediately reflected in `self`. The value of bytes in the returned slice will depend on 110 /// the representation of the type in memory, and may change in an unstable fashion. as_mut_slice(&mut self) -> &mut [u8]111 fn as_mut_slice(&mut self) -> &mut [u8] { 112 // Safe because the entire size of self is accessible as bytes because the trait guarantees 113 // it. The trait also guarantees that any combination of bytes is valid for this type, so 114 // modifying them in the form of a byte slice is valid. The lifetime of the returned slice 115 // is the same as the passed reference, so that no dangling pointers will result from this 116 // pointer alias. Although this does alias a mutable pointer, we do so by exclusively 117 // borrowing the given mutable reference. 118 unsafe { from_raw_parts_mut(self as *mut Self as *mut u8, size_of::<Self>()) } 119 } 120 } 121 122 // All intrinsic types and arays of intrinsic types are DataInit. They are just numbers. 123 macro_rules! array_data_init { 124 ($T:ty, $($N:expr)+) => { 125 $( 126 unsafe impl DataInit for [$T; $N] {} 127 )+ 128 } 129 } 130 macro_rules! data_init_type { 131 ($($T:ident),*) => { 132 $( 133 unsafe impl DataInit for $T {} 134 array_data_init! { 135 $T, 136 0 1 2 3 4 5 6 7 8 9 137 10 11 12 13 14 15 16 17 18 19 138 20 21 22 23 24 25 26 27 28 29 139 30 31 32 140 } 141 )* 142 #[cfg(test)] 143 mod data_init_tests { 144 use std::mem::{size_of, align_of}; 145 use crate::DataInit; 146 147 #[test] 148 fn from_slice_alignment() { 149 let mut v = [0u8; 32]; 150 $( 151 let (pre, _, _) = unsafe { v.align_to::<$T>() }; 152 let pre_len = pre.len(); 153 154 let aligned_v = &mut v[pre_len..pre_len + size_of::<$T>()]; 155 156 let from_aligned = $T::from_slice(aligned_v); 157 assert_eq!(from_aligned, Some(&0)); 158 159 let from_aligned_mut = $T::from_mut_slice(aligned_v); 160 assert_eq!(from_aligned_mut, Some(&mut 0)); 161 162 for i in 1..size_of::<$T>() { 163 let begin = pre_len + i; 164 let end = begin + size_of::<$T>(); 165 let unaligned_v = &mut v[begin..end]; 166 167 let from_unaligned = $T::from_slice(unaligned_v); 168 if align_of::<$T>() != 1 { 169 assert_eq!(from_unaligned, None); 170 } 171 172 let from_unaligned_mut = $T::from_mut_slice(unaligned_v); 173 if align_of::<$T>() != 1 { 174 assert_eq!(from_unaligned_mut, None); 175 } 176 } 177 )* 178 179 } 180 } 181 }; 182 } 183 data_init_type!(u8, u16, u32, u64, usize, i8, i16, i32, i64, isize); 184 185 pub mod endian; 186 pub use crate::endian::*; 187 188 pub mod volatile_memory; 189 pub use crate::volatile_memory::*; 190 191 mod flexible_array; 192 pub use flexible_array::{vec_with_array_field, FlexibleArray, FlexibleArrayWrapper}; 193 194 mod sys; 195 pub use sys::IoBufMut; 196