Trait Bytes
pub trait Bytes<A> {
type E;
// Required methods
fn write(&self, buf: &[u8], addr: A) -> Result<usize, Self::E>;
fn read(&self, buf: &mut [u8], addr: A) -> Result<usize, Self::E>;
fn write_slice(&self, buf: &[u8], addr: A) -> Result<(), Self::E>;
fn read_slice(&self, buf: &mut [u8], addr: A) -> Result<(), Self::E>;
fn read_volatile_from<F>(
&self,
addr: A,
src: &mut F,
count: usize,
) -> Result<usize, Self::E>
where F: ReadVolatile;
fn read_exact_volatile_from<F>(
&self,
addr: A,
src: &mut F,
count: usize,
) -> Result<(), Self::E>
where F: ReadVolatile;
fn write_volatile_to<F>(
&self,
addr: A,
dst: &mut F,
count: usize,
) -> Result<usize, Self::E>
where F: WriteVolatile;
fn write_all_volatile_to<F>(
&self,
addr: A,
dst: &mut F,
count: usize,
) -> Result<(), Self::E>
where F: WriteVolatile;
fn store<T>(&self, val: T, addr: A, order: Ordering) -> Result<(), Self::E>
where T: AtomicAccess;
fn load<T>(&self, addr: A, order: Ordering) -> Result<T, Self::E>
where T: AtomicAccess;
// Provided methods
fn write_obj<T>(&self, val: T, addr: A) -> Result<(), Self::E>
where T: ByteValued { ... }
fn read_obj<T>(&self, addr: A) -> Result<T, Self::E>
where T: ByteValued { ... }
}Expand description
A container to host a range of bytes and access its content.
Candidates which may implement this trait include:
- anonymous memory areas
- mmapped memory areas
- data files
- a proxy to access memory on remote
Required Associated Types§
type E
type E
Associated error codes
Required Methods§
fn write(&self, buf: &[u8], addr: A) -> Result<usize, Self::E>
fn write(&self, buf: &[u8], addr: A) -> Result<usize, Self::E>
Writes a slice into the container at addr.
Returns the number of bytes written. The number of bytes written can be less than the length of the slice if there isn’t enough room in the container.
If the given slice is empty (e.g. has length 0), always returns Ok(0), even if addr
is otherwise out of bounds. However, if the container is empty, it will
return an error (unless the slice is also empty, in which case the above takes precedence).
let mut arr = [1, 2, 3, 4, 5];
let slice = VolatileSlice::from(arr.as_mut_slice());
assert_eq!(slice.write(&[1, 2, 3], 0).unwrap(), 3);
assert_eq!(slice.write(&[1, 2, 3], 3).unwrap(), 2);
assert_matches!(
slice.write(&[1, 2, 3], 5).unwrap_err(),
VolatileMemoryError::OutOfBounds { addr: 5 }
);
assert_eq!(slice.write(&[], 5).unwrap(), 0);fn read(&self, buf: &mut [u8], addr: A) -> Result<usize, Self::E>
fn read(&self, buf: &mut [u8], addr: A) -> Result<usize, Self::E>
Reads data from the container at addr into a slice.
Returns the number of bytes read. The number of bytes read can be less than the length of the slice if there isn’t enough data within the container.
If the given slice is empty (e.g. has length 0), always returns Ok(0), even if addr
is otherwise out of bounds. However, if the container is empty, it will
return an error (unless the slice is also empty, in which case the above takes precedence).
fn write_slice(&self, buf: &[u8], addr: A) -> Result<(), Self::E>
fn write_slice(&self, buf: &[u8], addr: A) -> Result<(), Self::E>
Writes the entire content of a slice into the container at addr.
If the given slice is empty (e.g. has length 0), always returns Ok(0), even if addr
is otherwise out of bounds.
§Errors
Returns an error if there isn’t enough space within the container to write the entire slice. Part of the data may have been copied nevertheless.
fn read_slice(&self, buf: &mut [u8], addr: A) -> Result<(), Self::E>
fn read_slice(&self, buf: &mut [u8], addr: A) -> Result<(), Self::E>
Reads data from the container at addr to fill an entire slice.
If the given slice is empty (e.g. has length 0), always returns Ok(0), even if addr
is otherwise out of bounds.
§Errors
Returns an error if there isn’t enough data within the container to fill the entire slice. Part of the data may have been copied nevertheless.
fn read_volatile_from<F>(
&self,
addr: A,
src: &mut F,
count: usize,
) -> Result<usize, Self::E>where
F: ReadVolatile,
fn read_volatile_from<F>(
&self,
addr: A,
src: &mut F,
count: usize,
) -> Result<usize, Self::E>where
F: ReadVolatile,
Reads up to count bytes from src and writes them into the container at addr.
Unlike VolatileRead::read_volatile, this function retries on EINTR being returned from
the underlying I/O read operation.
Returns the number of bytes written into the container.
§Arguments
addr- Begin writing at this address.src- Copy fromsrcinto the container.count- Copycountbytes fromsrcinto the container.
§Examples
- Read bytes from /dev/urandom (uses the
backend-mmapfeature)
let mut file = File::open(Path::new("/dev/urandom")).expect("Could not open /dev/urandom");
gm.read_volatile_from(addr, &mut file, 128)
.expect("Could not read from /dev/urandom into guest memory");
let read_addr = addr.checked_add(8).expect("Could not compute read address");
let rand_val: u32 = gm
.read_obj(read_addr)
.expect("Could not read u32 val from /dev/urandom");fn read_exact_volatile_from<F>(
&self,
addr: A,
src: &mut F,
count: usize,
) -> Result<(), Self::E>where
F: ReadVolatile,
fn read_exact_volatile_from<F>(
&self,
addr: A,
src: &mut F,
count: usize,
) -> Result<(), Self::E>where
F: ReadVolatile,
Reads exactly count bytes from an object and writes them into the container at addr.
§Errors
Returns an error if count bytes couldn’t have been copied from src to the container.
Part of the data may have been copied nevertheless.
§Arguments
addr- Begin writing at this address.src- Copy fromsrcinto the container.count- Copy exactlycountbytes fromsrcinto the container.
fn write_volatile_to<F>(
&self,
addr: A,
dst: &mut F,
count: usize,
) -> Result<usize, Self::E>where
F: WriteVolatile,
fn write_volatile_to<F>(
&self,
addr: A,
dst: &mut F,
count: usize,
) -> Result<usize, Self::E>where
F: WriteVolatile,
Reads up to count bytes from the container at addr and writes them into dst.
Unlike VolatileWrite::write_volatile, this function retries on EINTR being returned by
the underlying I/O write operation.
Returns the number of bytes written into the object.
§Arguments
addr- Begin reading from this address.dst- Copy from the container todst.count- Copycountbytes from the container todst.
fn write_all_volatile_to<F>(
&self,
addr: A,
dst: &mut F,
count: usize,
) -> Result<(), Self::E>where
F: WriteVolatile,
fn write_all_volatile_to<F>(
&self,
addr: A,
dst: &mut F,
count: usize,
) -> Result<(), Self::E>where
F: WriteVolatile,
Reads exactly count bytes from the container at addr and writes them into an object.
§Errors
Returns an error if count bytes couldn’t have been copied from the container to dst.
Part of the data may have been copied nevertheless.
§Arguments
addr- Begin reading from this address.dst- Copy from the container todst.count- Copy exactlycountbytes from the container todst.
Provided Methods§
fn write_obj<T>(&self, val: T, addr: A) -> Result<(), Self::E>where
T: ByteValued,
fn write_obj<T>(&self, val: T, addr: A) -> Result<(), Self::E>where
T: ByteValued,
Writes an object into the container at addr.
§Errors
Returns an error if the object doesn’t fit inside the container.
fn read_obj<T>(&self, addr: A) -> Result<T, Self::E>where
T: ByteValued,
fn read_obj<T>(&self, addr: A) -> Result<T, Self::E>where
T: ByteValued,
Reads an object from the container at addr.
Reading from a volatile area isn’t strictly safe as it could change mid-read. However, as long as the type T is plain old data and can handle random initialization, everything will be OK.
§Errors
Returns an error if there’s not enough data inside the container.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.