Struct memflow::mem::phys_mem::middleware::cache::CachedPhysicalMemoryBuilder
source · pub struct CachedPhysicalMemoryBuilder<T, Q> { /* private fields */ }
Expand description
The builder interface for constructing a CachedPhysicalMemory
object.
Implementations§
source§impl<T: PhysicalMemory> CachedPhysicalMemoryBuilder<T, DefaultCacheValidator>
impl<T: PhysicalMemory> CachedPhysicalMemoryBuilder<T, DefaultCacheValidator>
sourcepub fn new(mem: T) -> Self
pub fn new(mem: T) -> Self
Creates a new CachedPhysicalMemory
builder.
The memory object is mandatory as the CachedPhysicalMemory
struct wraps around it.
This type of cache also is required to know the exact page size of the target system.
This can either be set directly via the page_size()
method or via the arch()
method.
If no page size has been set this builder will fail to build the CachedPhysicalMemory
.
Without further adjustments this function creates a cache that is 2 megabytes in size and caches pages that contain pagetable entries as well as read-only pages.
It is also possible to either let the [
CachedPhysicalMemory]
object own or just borrow the underlying memory object.
Examples
Moves ownership of a mem object and retrieves it back:
use memflow::architecture::x86::x64;
use memflow::mem::{PhysicalMemory, CachedPhysicalMemory, MemoryView};
fn build<T: PhysicalMemory>(mem: T) {
let mut cache = CachedPhysicalMemory::builder(mem)
.arch(x64::ARCH)
.cache_size(size::mb(1))
.build()
.unwrap();
cache.phys_write(0.into(), &MAGIC_VALUE);
let mut mem = cache.into_inner();
let value: u64 = mem.phys_view().read(0.into()).unwrap();
assert_eq!(value, MAGIC_VALUE);
}
Borrowing a mem object:
use memflow::architecture::x86::x64;
use memflow::mem::{PhysicalMemory, CachedPhysicalMemory, MemoryView};
use memflow::cglue::{Fwd, ForwardMut};
fn build<T: PhysicalMemory>(mem: Fwd<&mut T>)
-> impl PhysicalMemory + '_ {
CachedPhysicalMemory::builder(mem)
.arch(x64::ARCH)
.build()
.unwrap()
}
let mut cache = build(mem.forward_mut());
let value: u64 = cache.phys_view().read(0.into()).unwrap();
assert_eq!(value, MAGIC_VALUE);
cache.phys_write(0.into(), &0u64).unwrap();
// We drop the cache and are able to use mem again
std::mem::drop(cache);
let value: u64 = mem.phys_view().read(0.into()).unwrap();
assert_ne!(value, MAGIC_VALUE);
source§impl<T: PhysicalMemory, Q: CacheValidator> CachedPhysicalMemoryBuilder<T, Q>
impl<T: PhysicalMemory, Q: CacheValidator> CachedPhysicalMemoryBuilder<T, Q>
sourcepub fn build<'a>(self) -> Result<CachedPhysicalMemory<'a, T, Q>>
pub fn build<'a>(self) -> Result<CachedPhysicalMemory<'a, T, Q>>
Builds the CachedPhysicalMemory
object or returns an error if the page size is not set.
sourcepub fn validator<QN: CacheValidator>(
self,
validator: QN
) -> CachedPhysicalMemoryBuilder<T, QN>
pub fn validator<QN: CacheValidator>( self, validator: QN ) -> CachedPhysicalMemoryBuilder<T, QN>
Sets a custom validator for the cache.
If this function is not called it will default to a DefaultCacheValidator
.
The default validator for std builds is the [TimedCacheValidator
].
The default validator for no_std builds is the [CountCacheValidator
].
The default setting is DefaultCacheValidator::default()
.
Examples:
use std::time::Duration;
use memflow::architecture::x86::x64;
use memflow::mem::{PhysicalMemory, CachedPhysicalMemory};
use memflow::types::DefaultCacheValidator;
fn build<T: PhysicalMemory>(mem: T) {
let cache = CachedPhysicalMemory::builder(mem)
.arch(x64::ARCH)
.validator(DefaultCacheValidator::new(Duration::from_millis(2000).into()))
.build()
.unwrap();
}
sourcepub fn page_size(self, page_size: usize) -> Self
pub fn page_size(self, page_size: usize) -> Self
Changes the page size of the cache.
The cache has to know the exact page size of the target system internally to give reasonable performance.
The page size can be either set directly via this function or it can be fetched from the Architecture
via the arch()
method of the builder.
If the page size is not set the builder will fail.
Examples
use memflow::types::size;
use memflow::mem::{PhysicalMemory, CachedPhysicalMemory};
fn build<T: PhysicalMemory>(mem: T) {
let cache = CachedPhysicalMemory::builder(mem)
.page_size(size::kb(4))
.build()
.unwrap();
}
sourcepub fn arch(self, arch: impl Into<ArchitectureObj>) -> Self
pub fn arch(self, arch: impl Into<ArchitectureObj>) -> Self
Retrieves the page size for this cache from the given [Architecture
].
The cache has to know the exact page size of the target system internally to give reasonable performance.
The page size can be either fetched from the [Architecture
] via this method or it can be set directly
via the page_size()
method of the builder.
If the page size is not set the builder will fail.
Examples
use memflow::architecture::x86::x64;
use memflow::mem::{PhysicalMemory, CachedPhysicalMemory};
fn build<T: PhysicalMemory>(mem: T) {
let cache = CachedPhysicalMemory::builder(mem)
.arch(x64::ARCH)
.build()
.unwrap();
}
sourcepub fn cache_size(self, cache_size: usize) -> Self
pub fn cache_size(self, cache_size: usize) -> Self
Sets the total amount of cache to be used.
This is the total amount of cache (in bytes) this page cache will allocate. Ideally you’d want to keep this value low enough so that most of the cache stays in the lower level caches of your cpu.
The default setting is 2 megabytes.
This setting can drastically impact the performance of the cache.
Examples:
use memflow::types::size;
use memflow::architecture::x86::x64;
use memflow::mem::{PhysicalMemory, CachedPhysicalMemory};
fn build<T: PhysicalMemory>(mem: T) {
let cache = CachedPhysicalMemory::builder(mem)
.arch(x64::ARCH)
.cache_size(size::mb(2))
.build()
.unwrap();
}
sourcepub fn page_type_mask(self, page_type_mask: PageType) -> Self
pub fn page_type_mask(self, page_type_mask: PageType) -> Self
Adjusts the type of pages that the cache will hold in it’s cache.
The page type can be a bitmask that contains one or multiple page types. All page types matching this bitmask will be kept in the cache. All pages that are not matching the bitmask will be re-read/re-written on every request.
The default setting is PageType::PAGE_TABLE | PageType::READ_ONLY
.
This setting can drastically impact the performance of the cache.
Examples:
use memflow::types::PageType;
use memflow::architecture::x86::x32;
use memflow::mem::{PhysicalMemory, CachedPhysicalMemory};
fn build<T: PhysicalMemory>(mem: T) {
let cache = CachedPhysicalMemory::builder(mem)
.arch(x32::ARCH)
.page_type_mask(PageType::PAGE_TABLE | PageType::READ_ONLY)
.build()
.unwrap();
}
Auto Trait Implementations§
impl<T, Q> RefUnwindSafe for CachedPhysicalMemoryBuilder<T, Q>where
Q: RefUnwindSafe,
T: RefUnwindSafe,
impl<T, Q> Send for CachedPhysicalMemoryBuilder<T, Q>
impl<T, Q> Sync for CachedPhysicalMemoryBuilder<T, Q>
impl<T, Q> Unpin for CachedPhysicalMemoryBuilder<T, Q>
impl<T, Q> UnwindSafe for CachedPhysicalMemoryBuilder<T, Q>where
Q: UnwindSafe,
T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> GetWithMetadata for T
impl<T> GetWithMetadata for T
§type ForSelf = WithMetadata_<T, T>
type ForSelf = WithMetadata_<T, T>
WithMetadata_<Self, Self>
§impl<S> ROExtAcc for S
impl<S> ROExtAcc for S
§fn f_get<F>(&self, offset: FieldOffset<S, F, Aligned>) -> &F
fn f_get<F>(&self, offset: FieldOffset<S, F, Aligned>) -> &F
offset
. Read more§fn f_get_mut<F>(&mut self, offset: FieldOffset<S, F, Aligned>) -> &mut F
fn f_get_mut<F>(&mut self, offset: FieldOffset<S, F, Aligned>) -> &mut F
offset
. Read more§fn f_get_ptr<F, A>(&self, offset: FieldOffset<S, F, A>) -> *const F
fn f_get_ptr<F, A>(&self, offset: FieldOffset<S, F, A>) -> *const F
offset
. Read more§fn f_get_mut_ptr<F, A>(&mut self, offset: FieldOffset<S, F, A>) -> *mut F
fn f_get_mut_ptr<F, A>(&mut self, offset: FieldOffset<S, F, A>) -> *mut F
offset
. Read more§impl<S> ROExtOps<Aligned> for S
impl<S> ROExtOps<Aligned> for S
§fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Aligned>, value: F) -> F
fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Aligned>, value: F) -> F
offset
) with value
,
returning the previous value of the field. Read more§fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Aligned>) -> Fwhere
F: Copy,
fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Aligned>) -> Fwhere
F: Copy,
§impl<S> ROExtOps<Unaligned> for S
impl<S> ROExtOps<Unaligned> for S
§fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Unaligned>, value: F) -> F
fn f_replace<F>(&mut self, offset: FieldOffset<S, F, Unaligned>, value: F) -> F
offset
) with value
,
returning the previous value of the field. Read more§fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Unaligned>) -> Fwhere
F: Copy,
fn f_get_copy<F>(&self, offset: FieldOffset<S, F, Unaligned>) -> Fwhere
F: Copy,
§impl<T> SelfOps for Twhere
T: ?Sized,
impl<T> SelfOps for Twhere
T: ?Sized,
§fn piped<F, U>(self, f: F) -> U
fn piped<F, U>(self, f: F) -> U
§fn piped_ref<'a, F, U>(&'a self, f: F) -> U
fn piped_ref<'a, F, U>(&'a self, f: F) -> U
piped
except that the function takes &Self
Useful for functions that take &Self
instead of Self
. Read more§fn piped_mut<'a, F, U>(&'a mut self, f: F) -> Uwhere
F: FnOnce(&'a mut Self) -> U,
fn piped_mut<'a, F, U>(&'a mut self, f: F) -> Uwhere
F: FnOnce(&'a mut Self) -> U,
piped
, except that the function takes &mut Self
.
Useful for functions that take &mut Self
instead of Self
.§fn mutated<F>(self, f: F) -> Self
fn mutated<F>(self, f: F) -> Self
§fn observe<F>(self, f: F) -> Self
fn observe<F>(self, f: F) -> Self
§fn as_ref_<T>(&self) -> &T
fn as_ref_<T>(&self) -> &T
AsRef
,
using the turbofish .as_ref_::<_>()
syntax. Read more