Add a safe method GuestPtr::copy_from_slice (#1367)

This commit adds a safe method to wiggle pointers to copy slices of data
from the host to the guest.
This commit is contained in:
Alex Crichton
2020-03-20 10:37:29 -05:00
committed by GitHub
parent fe0dc508ac
commit 0a30fdf85f
2 changed files with 31 additions and 0 deletions

View File

@@ -15,6 +15,8 @@ pub enum GuestError {
PtrNotAligned(Region, u32), PtrNotAligned(Region, u32),
#[error("Pointer already borrowed: {0:?}")] #[error("Pointer already borrowed: {0:?}")]
PtrBorrowed(Region), PtrBorrowed(Region),
#[error("Slice length mismatch")]
SliceLengthsDiffer,
#[error("In func {funcname}:{location}:")] #[error("In func {funcname}:{location}:")]
InFunc { InFunc {
funcname: &'static str, funcname: &'static str,

View File

@@ -429,6 +429,35 @@ impl<'a, T> GuestPtr<'a, [T]> {
} }
} }
/// Copies the data pointed to by `slice` into this guest region.
///
/// This method is a *safe* method to copy data from the host to the guest.
/// This requires that `self` and `slice` have the same length. The pointee
/// type `T` requires the [`GuestTypeTransparent`] trait which is an
/// assertion that the representation on the host and on the guest is the
/// same.
///
/// # Errors
///
/// Returns an error if this guest pointer is out of bounds or if the length
/// of this guest pointer is not equal to the length of the slice provided.
pub fn copy_from_slice(&self, slice: &[T]) -> Result<(), GuestError>
where
T: GuestTypeTransparent<'a> + Copy,
{
// bounds check ...
let raw = self.as_raw(&mut GuestBorrows::new())?;
unsafe {
// ... length check ...
if (*raw).len() != slice.len() {
return Err(GuestError::SliceLengthsDiffer);
}
// ... and copy!
(*raw).copy_from_slice(slice);
Ok(())
}
}
/// Returns a `GuestPtr` pointing to the base of the array for the interior /// Returns a `GuestPtr` pointing to the base of the array for the interior
/// type `T`. /// type `T`.
pub fn as_ptr(&self) -> GuestPtr<'a, T> { pub fn as_ptr(&self) -> GuestPtr<'a, T> {