xref: /aosp_15_r20/external/crosvm/base/src/iobuf.rs (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2023 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker //! Cross platform [`IoBuf`] and [`IoBufMut`] types wrapping `iovec`/`WSABUF`.
6*bb4ee6a4SAndroid Build Coastguard Worker 
7*bb4ee6a4SAndroid Build Coastguard Worker use std::fmt;
8*bb4ee6a4SAndroid Build Coastguard Worker use std::fmt::Debug;
9*bb4ee6a4SAndroid Build Coastguard Worker use std::marker::PhantomData;
10*bb4ee6a4SAndroid Build Coastguard Worker use std::slice;
11*bb4ee6a4SAndroid Build Coastguard Worker 
12*bb4ee6a4SAndroid Build Coastguard Worker pub use crate::IoBuf;
13*bb4ee6a4SAndroid Build Coastguard Worker 
14*bb4ee6a4SAndroid Build Coastguard Worker pub(crate) trait PlatformIoBuf {
new(ptr: *mut u8, len: usize) -> Self15*bb4ee6a4SAndroid Build Coastguard Worker     fn new(ptr: *mut u8, len: usize) -> Self;
len(&self) -> usize16*bb4ee6a4SAndroid Build Coastguard Worker     fn len(&self) -> usize;
ptr(&self) -> *mut u817*bb4ee6a4SAndroid Build Coastguard Worker     fn ptr(&self) -> *mut u8;
set_len(&mut self, len: usize)18*bb4ee6a4SAndroid Build Coastguard Worker     fn set_len(&mut self, len: usize);
set_ptr(&mut self, ptr: *mut u8)19*bb4ee6a4SAndroid Build Coastguard Worker     fn set_ptr(&mut self, ptr: *mut u8);
20*bb4ee6a4SAndroid Build Coastguard Worker }
21*bb4ee6a4SAndroid Build Coastguard Worker 
22*bb4ee6a4SAndroid Build Coastguard Worker /// Cross-platform mutable buffer.
23*bb4ee6a4SAndroid Build Coastguard Worker ///
24*bb4ee6a4SAndroid Build Coastguard Worker /// This type is essentialy `std::io::IoSliceMut`, and guaranteed to be ABI-compatible with
25*bb4ee6a4SAndroid Build Coastguard Worker /// `libc::iovec` on Linux/`WSABUF` on Windows; however, it does NOT automatically deref to `&mut
26*bb4ee6a4SAndroid Build Coastguard Worker /// [u8]`, which is critical because it can point to guest memory. (Guest memory is implicitly
27*bb4ee6a4SAndroid Build Coastguard Worker /// mutably borrowed by the guest, so another mutable borrow would violate Rust assumptions about
28*bb4ee6a4SAndroid Build Coastguard Worker /// references.)
29*bb4ee6a4SAndroid Build Coastguard Worker #[derive(Copy, Clone)]
30*bb4ee6a4SAndroid Build Coastguard Worker #[repr(transparent)]
31*bb4ee6a4SAndroid Build Coastguard Worker pub struct IoBufMut<'a> {
32*bb4ee6a4SAndroid Build Coastguard Worker     iobuf: IoBuf,
33*bb4ee6a4SAndroid Build Coastguard Worker     phantom: PhantomData<&'a mut [u8]>,
34*bb4ee6a4SAndroid Build Coastguard Worker }
35*bb4ee6a4SAndroid Build Coastguard Worker 
36*bb4ee6a4SAndroid Build Coastguard Worker impl<'a> IoBufMut<'a> {
new(buf: &mut [u8]) -> IoBufMut<'a>37*bb4ee6a4SAndroid Build Coastguard Worker     pub fn new(buf: &mut [u8]) -> IoBufMut<'a> {
38*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
39*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because buf's memory is of the supplied length, and
40*bb4ee6a4SAndroid Build Coastguard Worker         // guaranteed to exist for the lifetime of the returned value.
41*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { Self::from_raw_parts(buf.as_mut_ptr(), buf.len()) }
42*bb4ee6a4SAndroid Build Coastguard Worker     }
43*bb4ee6a4SAndroid Build Coastguard Worker 
44*bb4ee6a4SAndroid Build Coastguard Worker     /// Creates a `IoBufMut` from a pointer and a length.
45*bb4ee6a4SAndroid Build Coastguard Worker     ///
46*bb4ee6a4SAndroid Build Coastguard Worker     /// # Safety
47*bb4ee6a4SAndroid Build Coastguard Worker     ///
48*bb4ee6a4SAndroid Build Coastguard Worker     /// In order to use this method safely, `addr` must be valid for reads and writes of `len` bytes
49*bb4ee6a4SAndroid Build Coastguard Worker     /// and should live for the entire duration of lifetime `'a`.
from_raw_parts(addr: *mut u8, len: usize) -> IoBufMut<'a>50*bb4ee6a4SAndroid Build Coastguard Worker     pub unsafe fn from_raw_parts(addr: *mut u8, len: usize) -> IoBufMut<'a> {
51*bb4ee6a4SAndroid Build Coastguard Worker         IoBufMut {
52*bb4ee6a4SAndroid Build Coastguard Worker             iobuf: IoBuf::new(addr, len),
53*bb4ee6a4SAndroid Build Coastguard Worker             phantom: PhantomData,
54*bb4ee6a4SAndroid Build Coastguard Worker         }
55*bb4ee6a4SAndroid Build Coastguard Worker     }
56*bb4ee6a4SAndroid Build Coastguard Worker 
57*bb4ee6a4SAndroid Build Coastguard Worker     /// Creates a `IoBufMut` from an IoBuf.
58*bb4ee6a4SAndroid Build Coastguard Worker     ///
59*bb4ee6a4SAndroid Build Coastguard Worker     /// # Safety
60*bb4ee6a4SAndroid Build Coastguard Worker     ///
61*bb4ee6a4SAndroid Build Coastguard Worker     /// In order to use this method safely, `iobuf` must be valid for reads and writes through its
62*bb4ee6a4SAndroid Build Coastguard Worker     /// length and should live for the entire duration of lifetime `'a`.
from_iobuf(iobuf: IoBuf) -> IoBufMut<'a>63*bb4ee6a4SAndroid Build Coastguard Worker     pub unsafe fn from_iobuf(iobuf: IoBuf) -> IoBufMut<'a> {
64*bb4ee6a4SAndroid Build Coastguard Worker         IoBufMut {
65*bb4ee6a4SAndroid Build Coastguard Worker             iobuf,
66*bb4ee6a4SAndroid Build Coastguard Worker             phantom: PhantomData,
67*bb4ee6a4SAndroid Build Coastguard Worker         }
68*bb4ee6a4SAndroid Build Coastguard Worker     }
69*bb4ee6a4SAndroid Build Coastguard Worker 
70*bb4ee6a4SAndroid Build Coastguard Worker     /// Advance the internal position of the buffer.
71*bb4ee6a4SAndroid Build Coastguard Worker     ///
72*bb4ee6a4SAndroid Build Coastguard Worker     /// Panics if `count > self.len()`.
advance(&mut self, count: usize)73*bb4ee6a4SAndroid Build Coastguard Worker     pub fn advance(&mut self, count: usize) {
74*bb4ee6a4SAndroid Build Coastguard Worker         assert!(count <= self.len());
75*bb4ee6a4SAndroid Build Coastguard Worker 
76*bb4ee6a4SAndroid Build Coastguard Worker         self.iobuf.set_len(self.len() - count);
77*bb4ee6a4SAndroid Build Coastguard Worker 
78*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
79*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because we've checked that `count <= self.len()` so both the starting and resulting
80*bb4ee6a4SAndroid Build Coastguard Worker         // pointer are within the bounds of the allocation.
81*bb4ee6a4SAndroid Build Coastguard Worker         self.iobuf.set_ptr(unsafe { self.as_mut_ptr().add(count) });
82*bb4ee6a4SAndroid Build Coastguard Worker     }
83*bb4ee6a4SAndroid Build Coastguard Worker 
84*bb4ee6a4SAndroid Build Coastguard Worker     /// Shorten the length of the buffer.
85*bb4ee6a4SAndroid Build Coastguard Worker     ///
86*bb4ee6a4SAndroid Build Coastguard Worker     /// Has no effect if `len > self.len()`.
truncate(&mut self, len: usize)87*bb4ee6a4SAndroid Build Coastguard Worker     pub fn truncate(&mut self, len: usize) {
88*bb4ee6a4SAndroid Build Coastguard Worker         if len < self.len() {
89*bb4ee6a4SAndroid Build Coastguard Worker             self.iobuf.set_len(len);
90*bb4ee6a4SAndroid Build Coastguard Worker         }
91*bb4ee6a4SAndroid Build Coastguard Worker     }
92*bb4ee6a4SAndroid Build Coastguard Worker 
93*bb4ee6a4SAndroid Build Coastguard Worker     #[inline]
len(&self) -> usize94*bb4ee6a4SAndroid Build Coastguard Worker     pub fn len(&self) -> usize {
95*bb4ee6a4SAndroid Build Coastguard Worker         self.iobuf.len()
96*bb4ee6a4SAndroid Build Coastguard Worker     }
97*bb4ee6a4SAndroid Build Coastguard Worker 
98*bb4ee6a4SAndroid Build Coastguard Worker     #[inline]
is_empty(&self) -> bool99*bb4ee6a4SAndroid Build Coastguard Worker     pub fn is_empty(&self) -> bool {
100*bb4ee6a4SAndroid Build Coastguard Worker         self.len() == 0
101*bb4ee6a4SAndroid Build Coastguard Worker     }
102*bb4ee6a4SAndroid Build Coastguard Worker 
103*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets a const pointer to this slice's memory.
104*bb4ee6a4SAndroid Build Coastguard Worker     #[inline]
as_ptr(&self) -> *const u8105*bb4ee6a4SAndroid Build Coastguard Worker     pub fn as_ptr(&self) -> *const u8 {
106*bb4ee6a4SAndroid Build Coastguard Worker         self.iobuf.ptr() as *const u8
107*bb4ee6a4SAndroid Build Coastguard Worker     }
108*bb4ee6a4SAndroid Build Coastguard Worker 
109*bb4ee6a4SAndroid Build Coastguard Worker     /// Gets a mutable pointer to this slice's memory.
110*bb4ee6a4SAndroid Build Coastguard Worker     #[inline]
as_mut_ptr(&self) -> *mut u8111*bb4ee6a4SAndroid Build Coastguard Worker     pub fn as_mut_ptr(&self) -> *mut u8 {
112*bb4ee6a4SAndroid Build Coastguard Worker         self.iobuf.ptr()
113*bb4ee6a4SAndroid Build Coastguard Worker     }
114*bb4ee6a4SAndroid Build Coastguard Worker 
115*bb4ee6a4SAndroid Build Coastguard Worker     /// Converts a slice of `IoBufMut`s into a slice of `IoBuf`s.
116*bb4ee6a4SAndroid Build Coastguard Worker     #[allow(clippy::wrong_self_convention)]
117*bb4ee6a4SAndroid Build Coastguard Worker     #[inline]
as_iobufs<'slice>(iovs: &'slice [IoBufMut<'_>]) -> &'slice [IoBuf]118*bb4ee6a4SAndroid Build Coastguard Worker     pub fn as_iobufs<'slice>(iovs: &'slice [IoBufMut<'_>]) -> &'slice [IoBuf] {
119*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
120*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because `IoBufMut` is ABI-compatible with `IoBuf`.
121*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { slice::from_raw_parts(iovs.as_ptr() as *const IoBuf, iovs.len()) }
122*bb4ee6a4SAndroid Build Coastguard Worker     }
123*bb4ee6a4SAndroid Build Coastguard Worker 
124*bb4ee6a4SAndroid Build Coastguard Worker     /// Converts a mutable slice of `IoBufMut`s into a mutable slice of `IoBuf`s.
125*bb4ee6a4SAndroid Build Coastguard Worker     #[inline]
as_iobufs_mut<'slice>(iovs: &'slice mut [IoBufMut<'_>]) -> &'slice mut [IoBuf]126*bb4ee6a4SAndroid Build Coastguard Worker     pub fn as_iobufs_mut<'slice>(iovs: &'slice mut [IoBufMut<'_>]) -> &'slice mut [IoBuf] {
127*bb4ee6a4SAndroid Build Coastguard Worker         // SAFETY:
128*bb4ee6a4SAndroid Build Coastguard Worker         // Safe because `IoBufMut` is ABI-compatible with `IoBuf`.
129*bb4ee6a4SAndroid Build Coastguard Worker         unsafe { slice::from_raw_parts_mut(iovs.as_mut_ptr() as *mut IoBuf, iovs.len()) }
130*bb4ee6a4SAndroid Build Coastguard Worker     }
131*bb4ee6a4SAndroid Build Coastguard Worker }
132*bb4ee6a4SAndroid Build Coastguard Worker 
133*bb4ee6a4SAndroid Build Coastguard Worker impl<'a> AsRef<IoBuf> for IoBufMut<'a> {
as_ref(&self) -> &IoBuf134*bb4ee6a4SAndroid Build Coastguard Worker     fn as_ref(&self) -> &IoBuf {
135*bb4ee6a4SAndroid Build Coastguard Worker         &self.iobuf
136*bb4ee6a4SAndroid Build Coastguard Worker     }
137*bb4ee6a4SAndroid Build Coastguard Worker }
138*bb4ee6a4SAndroid Build Coastguard Worker 
139*bb4ee6a4SAndroid Build Coastguard Worker impl<'a> AsMut<IoBuf> for IoBufMut<'a> {
as_mut(&mut self) -> &mut IoBuf140*bb4ee6a4SAndroid Build Coastguard Worker     fn as_mut(&mut self) -> &mut IoBuf {
141*bb4ee6a4SAndroid Build Coastguard Worker         &mut self.iobuf
142*bb4ee6a4SAndroid Build Coastguard Worker     }
143*bb4ee6a4SAndroid Build Coastguard Worker }
144*bb4ee6a4SAndroid Build Coastguard Worker 
145*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY:
146*bb4ee6a4SAndroid Build Coastguard Worker // It's safe to implement Send + Sync for this type for the same reason that `std::io::IoSliceMut`
147*bb4ee6a4SAndroid Build Coastguard Worker // is Send + Sync. Internally, it contains a pointer and a length. The integer length is safely Send
148*bb4ee6a4SAndroid Build Coastguard Worker // + Sync.  There's nothing wrong with sending a pointer between threads and de-referencing the
149*bb4ee6a4SAndroid Build Coastguard Worker // pointer requires an unsafe block anyway. See also https://github.com/rust-lang/rust/pull/70342.
150*bb4ee6a4SAndroid Build Coastguard Worker unsafe impl<'a> Send for IoBufMut<'a> {}
151*bb4ee6a4SAndroid Build Coastguard Worker // SAFETY: See comments for impl Send
152*bb4ee6a4SAndroid Build Coastguard Worker unsafe impl<'a> Sync for IoBufMut<'a> {}
153*bb4ee6a4SAndroid Build Coastguard Worker 
154*bb4ee6a4SAndroid Build Coastguard Worker impl<'a> Debug for IoBufMut<'a> {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result155*bb4ee6a4SAndroid Build Coastguard Worker     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
156*bb4ee6a4SAndroid Build Coastguard Worker         f.debug_struct("IoBufMut")
157*bb4ee6a4SAndroid Build Coastguard Worker             .field("ptr", &self.iobuf.ptr())
158*bb4ee6a4SAndroid Build Coastguard Worker             .field("len", &self.iobuf.len())
159*bb4ee6a4SAndroid Build Coastguard Worker             .finish()
160*bb4ee6a4SAndroid Build Coastguard Worker     }
161*bb4ee6a4SAndroid Build Coastguard Worker }
162