Struct stack::Stack

source ·
pub struct Stack { /* private fields */ }
Expand description

A range of mapped memory designated for use as a task’s stack.

There is an unmapped guard page beneath the stack, which is a standard approach to detect stack overflow.

A stack is backed by and auto-derefs into MappedPages.

Implementations§

Returns the address just beyond the top of this stack, which is necessary for some hardware registers to use.

This address is not dereferenceable, the one right below it is. To get the highest usable address in this Stack, call top_usable()

Returns the highest usable address of this Stack, which is top_unusable() - sizeof(VirtualAddress)

Returns the bottom of this stack, its lowest usable address.

Creates a stack from its constituent parts: a guard page and a series of mapped pages.

Conditions
  • The guard_page must be at least one page (which is unmapped) and must contiguously precede the stack_pages. In other words, the beginning of stack_pages must come right after the end of guard_page.
  • The stack_pages must be mapped as writable.

If the conditions are not met, an Err containing the given guard_page and stack_pages is returned.

Returns the guard page(s) for this stack.

Guard pages are virtual pages that are reserved/owned by this stack but are not mapped, causing any access to them to result in a page fault.

Methods from Deref<Target = MappedPages>§

Returns the flags that describe this MappedPages page table permissions.

Merges the given MappedPages object mp into this MappedPages object (self).

For example, if you have the following MappedPages objects:

  • this mapping, with a page range including one page at 0x2000
  • mp, with a page range including two pages at 0x3000 and 0x4000 Then this MappedPages object will be updated to cover three pages from [0x2000:0x4000] inclusive.

In addition, the MappedPages objects must have the same flags and page table root frame (i.e., they must have all been mapped using the same set of page tables).

If an error occurs, such as the mappings not being contiguous or having different flags, then a tuple including an error message and the original mp will be returned, which prevents the mp from being dropped.

Note

No remapping actions or page reallocations will occur on either a failure or a success.

Creates a deep copy of this MappedPages memory region, by duplicating not only the virtual memory mapping but also the underlying physical memory frames.

The caller can optionally specify new flags for the duplicated mapping, otherwise, the same flags as the existing MappedPages will be used. This is useful for when you want to modify contents in the new pages, since it avoids extra remap() operations.

Returns a new MappedPages object with the same in-memory contents as this object, but at a completely new memory region.

Change the mapping flags of this MappedPages’s page table entries.

Note that attempting to change certain “reserved” flags will have no effect. For example, the EXCLUSIVE flag cannot be changed beause arbitrarily setting it would violate safety.

Reinterprets this MappedPages’s underlying memory region as a struct of the given type T, i.e., overlays a struct on top of this mapped memory region.

Requirements

The type T must implement the FromBytes trait, which is similar to the requirements of a “plain old data” type, in that it cannot contain Rust references (& or &mut). This makes sense because there is no valid way to reinterpret a region of untyped memory as a Rust reference. In addition, if we did permit that, a Rust reference created from unchecked memory contents could never be valid, safe, or sound, as it could allow random memory access (just like with an arbitrary pointer dereference) that could break isolation.

To satisfy this condition, you can use #[derive(FromBytes)] on your struct type T, which will only compile correctly if the struct can be validly constructed from “untyped” memory, i.e., an array of bytes.

Arguments
  • byte_offset: the offset (in number of bytes) from the beginning of the memory region at which the struct is located (where it should start). This offset must be properly aligned with respect to the alignment requirements of type T, otherwise an error will be returned.

Returns a reference to the new struct (&T) that is formed from the underlying memory region, with a lifetime dependent upon the lifetime of this MappedPages object. This ensures safety by guaranteeing that the returned struct reference cannot be used after this MappedPages object is dropped and unmapped.

Same as [MappedPages::as_type()], but returns a mutable reference to the type T.

Thus, it also checks that the underlying mapping is writable.

Reinterprets this MappedPages’s underlying memory region as &[T], a length-element slice of type T.

It has similar requirements and behavior as [MappedPages::as_type()].

Arguments
  • byte_offset: the offset (in number of bytes) into the memory region at which the slice should start. This offset must be properly aligned with respect to the alignment requirements of type T, otherwise an error will be returned.
  • length: the length of the slice, i.e., the number of elements of type T in the slice. Thus, the slice’s address bounds will span the range from byte_offset (inclusive) to byte_offset + (size_of::<T>() * length) (exclusive).

Returns a reference to the new slice that is formed from the underlying memory region, with a lifetime dependent upon the lifetime of this MappedPages object. This ensures safety by guaranteeing that the returned slice cannot be used after this MappedPages object is dropped and unmapped.

Same as [MappedPages::as_slice()], but returns a mutable slice.

Thus, it checks that the underlying mapping is writable.

Methods from Deref<Target = PageRange>§

Returns the [VirtualAddress] of the starting [Page] in this PageRange.

Returns the number of [Page]s covered by this iterator.

Use this instead of Iterator::count() method. This is instant, because it doesn’t need to iterate over each entry, unlike normal iterators.

Returns the size of this range in number of bytes.

Returns true if this PageRange contains the given [VirtualAddress].

Returns the offset of the given [VirtualAddress] within this PageRange, i.e., addr - self.start_address().

If the given addr is not covered by this range of [Page]s, this returns None.

Examples

If the range covers addresses 0x2000 to 0x4000, then offset_of_address(0x3500) would return Some(0x1500).

Returns the [VirtualAddress] at the given offset into this PageRangewithin this PageRange, i.e., addr - self.start_address().

If the given offset is not within this range of [Page]s, this returns None.

Examples

If the range covers addresses 0x2000 to 0x4000, then address_at_offset(0x1500) would return Some(0x3500).

Returns a new separate PageRange that is extended to include the given [Page].

Returns an inclusive PageRange representing the [Page]s that overlap across this PageRange and the given other PageRange.

If there is no overlap between the two ranges, None is returned.

Methods from Deref<Target = RangeInclusive<Page>>§

Returns the lower bound of the range (inclusive).

When using an inclusive range for iteration, the values of start() and end() are unspecified after the iteration ended. To determine whether the inclusive range is empty, use the is_empty() method instead of comparing start() > end().

Note: the value returned by this method is unspecified after the range has been iterated to exhaustion.

Examples
assert_eq!((3..=5).start(), &3);

Returns the upper bound of the range (inclusive).

When using an inclusive range for iteration, the values of start() and end() are unspecified after the iteration ended. To determine whether the inclusive range is empty, use the is_empty() method instead of comparing start() > end().

Note: the value returned by this method is unspecified after the range has been iterated to exhaustion.

Examples
assert_eq!((3..=5).end(), &5);

Returns true if item is contained in the range.

Examples
assert!(!(3..=5).contains(&2));
assert!( (3..=5).contains(&3));
assert!( (3..=5).contains(&4));
assert!( (3..=5).contains(&5));
assert!(!(3..=5).contains(&6));

assert!( (3..=3).contains(&3));
assert!(!(3..=2).contains(&3));

assert!( (0.0..=1.0).contains(&1.0));
assert!(!(0.0..=1.0).contains(&f32::NAN));
assert!(!(0.0..=f32::NAN).contains(&0.0));
assert!(!(f32::NAN..=1.0).contains(&1.0));

This method always returns false after iteration has finished:

let mut r = 3..=5;
assert!(r.contains(&3) && r.contains(&5));
for _ in r.by_ref() {}
// Precise field values are unspecified here
assert!(!r.contains(&3) && !r.contains(&5));

Returns true if the range contains no items.

Examples
assert!(!(3..=5).is_empty());
assert!(!(3..=3).is_empty());
assert!( (3..=2).is_empty());

The range is empty if either side is incomparable:

assert!(!(3.0..=5.0).is_empty());
assert!( (3.0..=f32::NAN).is_empty());
assert!( (f32::NAN..=5.0).is_empty());

This method returns true after iteration has finished:

let mut r = 3..=5;
for _ in r.by_ref() {}
// Precise field values are unspecified here
assert!(r.is_empty());

Trait Implementations§

Formats the value using the given formatter. Read more
The resulting type after dereferencing.
Dereferences the value.
Mutably dereferences the value.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.