fn write()

in reverie-ptrace/src/trace/memory.rs [161:189]


    fn write(&mut self, addr: AddrMut<u8>, buf: &[u8]) -> Result<usize, Errno> {
        let size = buf.len();
        if size == 0 {
            return Ok(0);
        } else if size == mem::size_of::<u64>() {
            #[allow(clippy::cast_ptr_alignment)]
            let value = unsafe { *(buf.as_ptr() as *const u64) };
            self.write_u64(addr.cast::<u64>(), value)?;
            return Ok(size);
        }

        let mut addr_slice = unsafe { AddrSliceMut::from_raw_parts(addr, buf.len()) };

        // Since process_vm_writev partial transfers apply at the granularity of
        // the iovec elements, we need to know if the address range spans a page
        // boundary and split the remote write if it does. This helps ensure that
        // we get a write length >0 before we hit a protected page.
        if let Some((mut first, mut second)) = addr_slice.split_at_page_boundary() {
            let mut remote = unsafe { [first.as_ioslice_mut(), second.as_ioslice_mut()] };

            // The two remote writes come from a single local buffer.
            let local = [io::IoSlice::new(buf)];

            self.write_vectored(&local, &mut remote)
        } else {
            // The address range fits into one page. Nothing special to do.
            self.write_aligned(addr, buf)
        }
    }