Expand description
A guest pointer into host memory.
This type represents a pointer from the guest that points into host memory.
Internally a GuestPtr
contains a handle to its original GuestMemory
as
well as the offset into the memory that the pointer is pointing at.
Presence of a GuestPtr
does not imply any form of validity. Pointers can
be out-of-bounds, misaligned, etc. It is safe to construct a GuestPtr
with
any offset at any time. Consider a GuestPtr<T>
roughly equivalent to *mut T
, although there are a few more safety guarantees around this type.
Slices and Strings
Note that the type parameter does not need to implement the Sized
trait,
so you can implement types such as this:
GuestPtr<'_, str>
- a pointer to a guest string. Has the methodsGuestPtr::as_str_mut
, which gives a dynamically borrow-checkedGuestStrMut<'_>
, whichDerefMut
s to a&mut str
, andGuestPtr::as_str
, which is the shareable version of same.GuestPtr<'_, [T]>
- a pointer to a guest array. Has methodsGuestPtr::as_slice_mut
, which gives a dynamically borrow-checkedGuestSliceMut<'_, T>
, whichDerefMut
s to a&mut [T]
andGuestPtr::as_slice
, which is the shareable version of same.
Unsized types such as this may have extra methods and won’t have methods
like GuestPtr::read
or GuestPtr::write
.
Type parameter and pointee
The T
type parameter is largely intended for more static safety in Rust as
well as having a better handle on what we’re pointing to. A GuestPtr<T>
,
however, does not necessarily literally imply a guest pointer pointing to
type T
. Instead the GuestType
trait is a layer of abstraction where
GuestPtr<T>
may actually be a pointer to U
in guest memory, but you can
construct a T
from a U
.
For example GuestPtr<GuestPtr<T>>
is a valid type, but this is actually
more equivalent to GuestPtr<u32>
because guest pointers are always
32-bits. That being said you can create a GuestPtr<T>
from a u32
.
Additionally GuestPtr<MyEnum>
will actually delegate, typically, to and
implementation which loads the underlying data as GuestPtr<u8>
(or
similar) and then the bytes loaded are validated to fit within the
definition of MyEnum
before MyEnum
is returned.
For more information see the GuestPtr::read
and GuestPtr::write
methods. In general though be extremely careful about writing unsafe
code
when working with a GuestPtr
if you’re not using one of the
already-attached helper methods.
Implementations
sourceimpl<'a, T: ?Sized + Pointee> GuestPtr<'a, T>
impl<'a, T: ?Sized + Pointee> GuestPtr<'a, T>
sourcepub fn new(
mem: &'a (dyn GuestMemory + 'a),
pointer: T::Pointer
) -> GuestPtr<'a, T>
pub fn new(
mem: &'a (dyn GuestMemory + 'a),
pointer: T::Pointer
) -> GuestPtr<'a, T>
Creates a new GuestPtr
from the given mem
and pointer
values.
Note that for sized types like u32
, GuestPtr<T>
, etc, the pointer
value is a u32
offset into guest memory. For slices and strings,
pointer
is a (u32, u32)
offset/length pair.
sourcepub fn offset(&self) -> T::Pointer
pub fn offset(&self) -> T::Pointer
Returns the offset of this pointer in guest memory.
Note that for sized types this returns a u32
, but for slices and
strings it returns a (u32, u32)
pointer/length pair.
sourcepub fn mem(&self) -> &'a (dyn GuestMemory + 'a)
pub fn mem(&self) -> &'a (dyn GuestMemory + 'a)
Returns the guest memory that this pointer is coming from.
sourcepub fn cast<U>(&self) -> GuestPtr<'a, U> where
T: Pointee<Pointer = u32>,
pub fn cast<U>(&self) -> GuestPtr<'a, U> where
T: Pointee<Pointer = u32>,
Casts this GuestPtr
type to a different type.
This is a safe method which is useful for simply reinterpreting the type
parameter on this GuestPtr
. Note that this is a safe method, where
again there’s no guarantees about alignment, validity, in-bounds-ness,
etc of the returned pointer.
sourcepub fn read(&self) -> Result<T, GuestError> where
T: GuestType<'a>,
pub fn read(&self) -> Result<T, GuestError> where
T: GuestType<'a>,
Safely read a value from this pointer.
This is a fun method, and is one of the lynchpins of this
implementation. The highlight here is that this is a safe operation,
not an unsafe one like *mut T
. This works for a few reasons:
-
The
unsafe
contract of theGuestMemory
trait means that there’s always at least some backing memory for thisGuestPtr<T>
. -
This does not use Rust-intrinsics to read the type
T
, but rather it delegates toT
’s implementation ofGuestType
to actually read the underlying data. This again is a safe method, so any unsafety, if any, must be internally documented. -
Eventually what typically happens it that this bottoms out in the read implementations for primitives types (like
i32
) which can safely be read at any time, and then it’s up to the runtime to determine what to do with the bytes it read in a safe manner.
Naturally lots of things can still go wrong, such as out-of-bounds
checks, alignment checks, validity checks (e.g. for enums), etc. All of
these check failures, however, are returned as a GuestError
in the
Result
here, and Ok
is only returned if all the checks passed.
sourcepub fn write(&self, val: T) -> Result<(), GuestError> where
T: GuestType<'a>,
pub fn write(&self, val: T) -> Result<(), GuestError> where
T: GuestType<'a>,
Safely write a value to this pointer.
This method, like GuestPtr::read
, is pretty crucial for the safe
operation of this crate. All the same reasons apply though for why this
method is safe, even eventually bottoming out in primitives like writing
an i32
which is safe to write bit patterns into memory at any time due
to the guarantees of GuestMemory
.
Like read
, write
can fail due to any manner of pointer checks, but
any failure is returned as a GuestError
.
sourcepub fn add(&self, amt: u32) -> Result<GuestPtr<'a, T>, GuestError> where
T: GuestType<'a> + Pointee<Pointer = u32>,
pub fn add(&self, amt: u32) -> Result<GuestPtr<'a, T>, GuestError> where
T: GuestType<'a> + Pointee<Pointer = u32>,
Performs pointer arithmetic on this pointer, moving the pointer forward
amt
slots.
This will either return the resulting pointer or Err
if the pointer
arithmetic calculation would overflow around the end of the address
space.
sourceimpl<'a, T> GuestPtr<'a, [T]>
impl<'a, T> GuestPtr<'a, [T]>
sourcepub fn offset_base(&self) -> u32
pub fn offset_base(&self) -> u32
For slices, specifically returns the relative pointer to the base of the array.
This is similar to <[T]>::as_ptr()
sourcepub fn iter<'b>(
&'b self
) -> impl ExactSizeIterator<Item = Result<GuestPtr<'a, T>, GuestError>> + 'b where
T: GuestType<'a>,
pub fn iter<'b>(
&'b self
) -> impl ExactSizeIterator<Item = Result<GuestPtr<'a, T>, GuestError>> + 'b where
T: GuestType<'a>,
Returns an iterator over interior pointers.
Each item is a Result
indicating whether it overflowed past the end of
the address space or not.
sourcepub fn as_slice(&self) -> Result<GuestSlice<'a, T>, GuestError> where
T: GuestTypeTransparent<'a>,
pub fn as_slice(&self) -> Result<GuestSlice<'a, T>, GuestError> where
T: GuestTypeTransparent<'a>,
Attempts to create a [GuestSlice<'_, T>
] from this pointer, performing
bounds checks and type validation. The GuestSlice
is a smart pointer
that can be used as a &[T]
via the Deref
trait.
The region of memory backing the slice will be marked as shareably
borrowed by the GuestMemory
until the GuestSlice
is dropped.
Multiple shareable borrows of the same memory are permitted, but only
one mutable borrow.
This function will return a GuestSlice
into host memory if all checks
succeed (valid utf-8, valid pointers, memory is not borrowed, etc). If
any checks fail then GuestError
will be returned.
sourcepub fn as_slice_mut(&self) -> Result<GuestSliceMut<'a, T>, GuestError> where
T: GuestTypeTransparent<'a>,
pub fn as_slice_mut(&self) -> Result<GuestSliceMut<'a, T>, GuestError> where
T: GuestTypeTransparent<'a>,
Attempts to create a [GuestSliceMut<'_, T>
] from this pointer, performing
bounds checks and type validation. The GuestSliceMut
is a smart pointer
that can be used as a &[T]
or a &mut [T]
via the Deref
and DerefMut
traits. The region of memory backing the slice will be marked as borrowed
by the GuestMemory
until the GuestSlice
is dropped.
This function will return a GuestSliceMut
into host memory if all checks
succeed (valid utf-8, valid pointers, memory is not borrowed, etc). If
any checks fail then GuestError
will be returned.
sourcepub fn copy_from_slice(&self, slice: &[T]) -> Result<(), GuestError> where
T: GuestTypeTransparent<'a> + Copy + 'a,
pub fn copy_from_slice(&self, slice: &[T]) -> Result<(), GuestError> where
T: GuestTypeTransparent<'a> + Copy + 'a,
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.
sourcepub fn as_ptr(&self) -> GuestPtr<'a, T>
pub fn as_ptr(&self) -> GuestPtr<'a, T>
Returns a GuestPtr
pointing to the base of the array for the interior
type T
.
pub fn get(&self, index: u32) -> Option<GuestPtr<'a, T>> where
T: GuestType<'a>,
pub fn get_range(&self, r: Range<u32>) -> Option<GuestPtr<'a, [T]>> where
T: GuestType<'a>,
sourceimpl<'a> GuestPtr<'a, str>
impl<'a> GuestPtr<'a, str>
sourcepub fn offset_base(&self) -> u32
pub fn offset_base(&self) -> u32
For strings, returns the relative pointer to the base of the string allocation.
sourcepub fn as_bytes(&self) -> GuestPtr<'a, [u8]>
pub fn as_bytes(&self) -> GuestPtr<'a, [u8]>
Returns a raw pointer for the underlying slice of bytes that this pointer points to.
sourcepub fn as_byte_ptr(&self) -> GuestPtr<'a, [u8]>
pub fn as_byte_ptr(&self) -> GuestPtr<'a, [u8]>
Returns a pointer for the underlying slice of bytes that this pointer points to.
sourcepub fn as_str(&self) -> Result<GuestStr<'a>, GuestError>
pub fn as_str(&self) -> Result<GuestStr<'a>, GuestError>
Attempts to create a [GuestStr<'_>
] from this pointer, performing
bounds checks and utf-8 checks. The resulting GuestStr
can be used
as a &str
via the Deref
trait. The region of memory backing the
str
will be marked as shareably borrowed by the GuestMemory
until the GuestStr
is dropped.
This function will return GuestStr
into host memory if all checks
succeed (valid utf-8, valid pointers, etc). If any checks fail then
GuestError
will be returned.
sourcepub fn as_str_mut(&self) -> Result<GuestStrMut<'a>, GuestError>
pub fn as_str_mut(&self) -> Result<GuestStrMut<'a>, GuestError>
Attempts to create a [GuestStrMut<'_>
] from this pointer, performing
bounds checks and utf-8 checks. The resulting GuestStrMut
can be used
as a &str
or &mut str
via the Deref
and DerefMut
traits. The
region of memory backing the str
will be marked as borrowed by the
GuestMemory
until the GuestStrMut
is dropped.
This function will return GuestStrMut
into host memory if all checks
succeed (valid utf-8, valid pointers, etc). If any checks fail then
GuestError
will be returned.
Trait Implementations
sourceimpl<'a, T> GuestType<'a> for GuestPtr<'a, T>
impl<'a, T> GuestType<'a> for GuestPtr<'a, T>
sourcefn guest_size() -> u32
fn guest_size() -> u32
Returns the size, in bytes, of this type in the guest memory.
sourcefn guest_align() -> usize
fn guest_align() -> usize
Returns the required alignment of this type, in bytes, for both guest and host memory. Read more
sourceimpl<'a, T> GuestType<'a> for GuestPtr<'a, [T]> where
T: GuestType<'a>,
impl<'a, T> GuestType<'a> for GuestPtr<'a, [T]> where
T: GuestType<'a>,
sourcefn guest_size() -> u32
fn guest_size() -> u32
Returns the size, in bytes, of this type in the guest memory.
sourcefn guest_align() -> usize
fn guest_align() -> usize
Returns the required alignment of this type, in bytes, for both guest and host memory. Read more
impl<T: ?Sized + Pointee> Copy for GuestPtr<'_, T>
Auto Trait Implementations
impl<'a, T> !RefUnwindSafe for GuestPtr<'a, T>
impl<'a, T: ?Sized> Send for GuestPtr<'a, T> where
<T as Pointee>::Pointer: Send,
impl<'a, T: ?Sized> Sync for GuestPtr<'a, T> where
<T as Pointee>::Pointer: Sync,
impl<'a, T: ?Sized> Unpin for GuestPtr<'a, T> where
<T as Pointee>::Pointer: Unpin,
impl<'a, T> !UnwindSafe for GuestPtr<'a, T>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
sourceimpl<T> Instrument for T
impl<T> Instrument for T
sourcefn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
sourcefn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
sourceimpl<T> Pointable for T
impl<T> Pointable for T
sourceimpl<T> ToOwned for T where
T: Clone,
impl<T> ToOwned for T where
T: Clone,
type Owned = T
type Owned = T
The resulting type after obtaining ownership.
sourcefn clone_into(&self, target: &mut T)
fn clone_into(&self, target: &mut T)
toowned_clone_into
)Uses borrowed data to replace owned data, usually by cloning. Read more
sourceimpl<T> WithSubscriber for T
impl<T> WithSubscriber for T
sourcefn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> where
S: Into<Dispatch>,
fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> where
S: Into<Dispatch>,
Attaches the provided Subscriber
to this type, returning a
WithDispatch
wrapper. Read more
sourcefn with_current_subscriber(self) -> WithDispatch<Self>
fn with_current_subscriber(self) -> WithDispatch<Self>
Attaches the current default Subscriber
to this type, returning a
WithDispatch
wrapper. Read more