diff options
author | Stephen Barber <smbarber@chromium.org> | 2017-08-07 16:01:53 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-08-09 11:47:55 -0700 |
commit | 2fb1969902f8b81466c21df02dfc283732998bbf (patch) | |
tree | afd4e1256949b0ccc671b602e417cd8ce989e256 /sys_util/src/mmap.rs | |
parent | 09a95f5e74c47d43a1f6962fca108466d8cc31e5 (diff) | |
download | crosvm-2fb1969902f8b81466c21df02dfc283732998bbf.tar crosvm-2fb1969902f8b81466c21df02dfc283732998bbf.tar.gz crosvm-2fb1969902f8b81466c21df02dfc283732998bbf.tar.bz2 crosvm-2fb1969902f8b81466c21df02dfc283732998bbf.tar.lz crosvm-2fb1969902f8b81466c21df02dfc283732998bbf.tar.xz crosvm-2fb1969902f8b81466c21df02dfc283732998bbf.tar.zst crosvm-2fb1969902f8b81466c21df02dfc283732998bbf.zip |
sys_util: add read_slice_at_addr to GuestMemory
BUG=none TEST=cargo test Change-Id: Ifeda91de37bf83a2e5a00f5e308db786fa5d49d5 Signed-off-by: Stephen Barber <smbarber@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/604934 Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'sys_util/src/mmap.rs')
-rw-r--r-- | sys_util/src/mmap.rs | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/sys_util/src/mmap.rs b/sys_util/src/mmap.rs index 732c4f0..78f533d 100644 --- a/sys_util/src/mmap.rs +++ b/sys_util/src/mmap.rs @@ -25,8 +25,10 @@ pub enum Error { ReadFromSource, /// `mmap` returned the given error. SystemCallFailed(errno::Error), - /// Wrting to memory failed + /// Writing to memory failed WriteToMemory(std::io::Error), + /// Reading from memory failed + ReadFromMemory(std::io::Error), } pub type Result<T> = std::result::Result<T, Error>; @@ -115,7 +117,7 @@ impl MemoryMapping { /// ``` /// # use sys_util::MemoryMapping; /// # let mut mem_map = MemoryMapping::new(1024).unwrap(); - /// let res = mem_map.write_slice(&[1,2,3,4,5], 0); + /// let res = mem_map.write_slice(&[1,2,3,4,5], 256); /// assert!(res.is_ok()); /// assert_eq!(res.unwrap(), 5); /// ``` @@ -132,6 +134,35 @@ impl MemoryMapping { } } + /// Reads to a slice from the memory region at the specified offset. + /// 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 room in the + /// memory region. + /// + /// # Examples + /// * Read a slice of size 16 at offset 256. + /// + /// ``` + /// # use sys_util::MemoryMapping; + /// # let mut mem_map = MemoryMapping::new(1024).unwrap(); + /// let buf = &mut [0u8; 16]; + /// let res = mem_map.read_slice(buf, 256); + /// assert!(res.is_ok()); + /// assert_eq!(res.unwrap(), 16); + /// ``` + pub fn read_slice(&self, mut buf: &mut [u8], offset: usize) -> Result<usize> { + if offset >= self.size { + return Err(Error::InvalidAddress); + } + unsafe { + // Guest memory can't strictly be modeled as a slice because it is + // volatile. Writing to it with what compiles down to a memcpy + // won't hurt anything as long as we get the bounds checks right. + let slice: &[u8] = &self.as_slice()[offset..]; + Ok(buf.write(slice).map_err(Error::ReadFromMemory)?) + } + } + /// Writes an object to the memory region at the specified offset. /// Returns Ok(()) if the object fits, or Err if it extends past the end. /// |