pub struct VmReader<'a, Fallibility = Fallible> { /* private fields */ }
Expand description
VmReader
is a reader for reading data from a contiguous range of memory.
The memory range read by VmReader
can be in either kernel space or user space.
When the operating range is in kernel space, the memory within that range
is guaranteed to be valid, and the corresponding memory reads are infallible.
When the operating range is in user space, it is ensured that the page table of
the process creating the VmReader
is active for the duration of 'a
,
and the corresponding memory reads are considered fallible.
When perform reading with a VmWriter
, if one of them represents typed memory,
it can ensure that the reading range in this reader and writing range in the
writer are not overlapped.
NOTE: The overlap mentioned above is at both the virtual address level
and physical address level. There is not guarantee for the operation results
of VmReader
and VmWriter
in overlapping untyped addresses, and it is
the user’s responsibility to handle this situation.
Implementations§
Source§impl<'a> VmReader<'a, Infallible>
impl<'a> VmReader<'a, Infallible>
Sourcepub unsafe fn from_kernel_space(ptr: *const u8, len: usize) -> Self
pub unsafe fn from_kernel_space(ptr: *const u8, len: usize) -> Self
Sourcepub fn read(&mut self, writer: &mut VmWriter<'_, Infallible>) -> usize
pub fn read(&mut self, writer: &mut VmWriter<'_, Infallible>) -> usize
Reads all data into the writer until one of the two conditions is met:
- The reader has no remaining data.
- The writer has no available space.
Returns the number of bytes read.
Sourcepub fn read_val<T: Pod>(&mut self) -> Result<T>
pub fn read_val<T: Pod>(&mut self) -> Result<T>
Reads a value of Pod
type.
If the length of the Pod
type exceeds self.remain()
,
this method will return Err
.
Sourcepub fn read_once<T: PodOnce>(&mut self) -> Result<T>
pub fn read_once<T: PodOnce>(&mut self) -> Result<T>
Reads a value of the PodOnce
type using one non-tearing memory load.
If the length of the PodOnce
type exceeds self.remain()
, this method will return Err
.
This method will not compile if the Pod
type is too large for the current architecture
and the operation must be tear into multiple memory loads.
§Panics
This method will panic if the current position of the reader does not meet the alignment
requirements of type T
.
Sourcepub fn to_fallible(self) -> VmReader<'a, Fallible>
pub fn to_fallible(self) -> VmReader<'a, Fallible>
Converts to a fallible reader.
Source§impl VmReader<'_, Fallible>
impl VmReader<'_, Fallible>
Sourcepub unsafe fn from_user_space(ptr: *const u8, len: usize) -> Self
pub unsafe fn from_user_space(ptr: *const u8, len: usize) -> Self
Constructs a VmReader
from a pointer and a length, which represents
a memory range in user space.
§Safety
The virtual address range ptr..ptr + len
must be in user space.
Sourcepub fn read_val<T: Pod>(&mut self) -> Result<T>
pub fn read_val<T: Pod>(&mut self) -> Result<T>
Reads a value of Pod
type.
If the length of the Pod
type exceeds self.remain()
,
or the value can not be read completely,
this method will return Err
.
If the memory read failed, this method will return Err
and the current reader’s cursor remains pointing to
the original starting position.
Sourcepub fn atomic_load<T: PodAtomic>(&self) -> Result<T>
pub fn atomic_load<T: PodAtomic>(&self) -> Result<T>
Atomically loads a PodAtomic
value.
Regardless of whether it is successful, the cursor of the reader will not move.
This method only guarantees the atomicity of the specific operation. There are no synchronization constraints on other memory accesses. This aligns with the Relaxed ordering specified in the C++11 memory model.
This method will fail with errors if
- the remaining space of the reader is less than
size_of::<T>()
bytes, or - the memory operation fails due to an unresolvable page fault.
§Panics
This method will panic if the memory location is not aligned on an align_of::<T>()
-byte
boundary.
Source§impl<Fallibility> VmReader<'_, Fallibility>
impl<Fallibility> VmReader<'_, Fallibility>
Sourcepub fn cursor(&self) -> *const u8
pub fn cursor(&self) -> *const u8
Returns the cursor pointer, which refers to the address of the next byte to read.
Sourcepub fn has_remain(&self) -> bool
pub fn has_remain(&self) -> bool
Returns if it has remaining data to read.
Trait Implementations§
Source§impl<'a> FallibleVmRead<Fallible> for VmReader<'a, Infallible>
impl<'a> FallibleVmRead<Fallible> for VmReader<'a, Infallible>
Source§impl<'a> FallibleVmRead<Infallible> for VmReader<'a, Fallible>
impl<'a> FallibleVmRead<Infallible> for VmReader<'a, Fallible>
Source§fn read_fallible(
&mut self,
writer: &mut VmWriter<'_, Infallible>,
) -> Result<usize, (Error, usize)>
fn read_fallible( &mut self, writer: &mut VmWriter<'_, Infallible>, ) -> Result<usize, (Error, usize)>
Auto Trait Implementations§
impl<'a, Fallibility> Freeze for VmReader<'a, Fallibility>
impl<'a, Fallibility> RefUnwindSafe for VmReader<'a, Fallibility>where
Fallibility: RefUnwindSafe,
impl<'a, Fallibility = Fallible> !Send for VmReader<'a, Fallibility>
impl<'a, Fallibility = Fallible> !Sync for VmReader<'a, Fallibility>
impl<'a, Fallibility> Unpin for VmReader<'a, Fallibility>where
Fallibility: Unpin,
impl<'a, Fallibility> UnwindSafe for VmReader<'a, Fallibility>where
Fallibility: UnwindSafe,
Blanket Implementations§
§impl<T> Any for Twhere
T: 'static + ?Sized,
impl<T> Any for Twhere
T: 'static + ?Sized,
§impl<T> Borrow<T> for Twhere
T: ?Sized,
impl<T> Borrow<T> for Twhere
T: ?Sized,
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§unsafe fn clone_to_uninit(&self, dst: *mut u8)
unsafe fn clone_to_uninit(&self, dst: *mut u8)
clone_to_uninit
)Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§impl<T, U> Into<U> for Twhere
U: From<T>,
impl<T, U> Into<U> for Twhere
U: From<T>,
Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere
Self: Borrow<B>,
B: 'a + ?Sized,
R: 'a,
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> Rwhere
Self: BorrowMut<B>,
B: 'a + ?Sized,
R: 'a,
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere
Self: AsRef<U>,
U: 'a + ?Sized,
R: 'a,
self
, then passes self.as_ref()
into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere
Self: AsMut<U>,
U: 'a + ?Sized,
R: 'a,
self
, then passes self.as_mut()
into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere
Self: Deref<Target = T>,
T: 'a + ?Sized,
R: 'a,
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere
Self: Deref<Target = T>,
T: 'a + ?Sized,
R: 'a,
self
, then passes self.deref()
into the pipe function.Source§fn pipe_deref_mut<'a, T, R>(
&'a mut self,
func: impl FnOnce(&'a mut T) -> R,
) -> Rwhere
Self: DerefMut<Target = T> + Deref,
T: 'a + ?Sized,
R: 'a,
fn pipe_deref_mut<'a, T, R>(
&'a mut self,
func: impl FnOnce(&'a mut T) -> R,
) -> Rwhere
Self: DerefMut<Target = T> + Deref,
T: 'a + ?Sized,
R: 'a,
self
, then passes self.deref_mut()
into the pipe
function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
Borrow<B>
of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
BorrowMut<B>
of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
AsRef<R>
view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
AsMut<R>
view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
Deref::Target
of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
Deref::Target
of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere
Self: Borrow<B>,
B: ?Sized,
.tap_borrow()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere
Self: BorrowMut<B>,
B: ?Sized,
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere
Self: AsRef<R>,
R: ?Sized,
.tap_ref()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere
Self: AsMut<R>,
R: ?Sized,
.tap_ref_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere
Self: Deref<Target = T>,
T: ?Sized,
.tap_deref()
only in debug builds, and is erased in release
builds.Source§fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere
Self: DerefMut<Target = T> + Deref,
T: ?Sized,
.tap_deref_mut()
only in debug builds, and is erased in release
builds.