pub trait VirtualTranslate: Send {
Show 13 methods // Required method fn virt_to_phys_list( &mut self, addrs: &[VtopRange], out: VirtualTranslationCallback<'_>, out_fail: VirtualTranslationFailCallback<'_> ); // Provided methods fn virt_to_phys_range( &mut self, start: Address, end: Address, out: VirtualTranslationCallback<'_> ) { ... } fn virt_translation_map_range( &mut self, start: Address, end: Address, out: VirtualTranslationCallback<'_> ) { ... } fn virt_page_map_range( &mut self, gap_size: imem, start: Address, end: Address, out: MemoryRangeCallback<'_> ) { ... } fn virt_to_phys(&mut self, address: Address) -> Result<PhysicalAddress> { ... } fn virt_page_info(&mut self, addr: Address) -> Result<Page> { ... } fn virt_page_map_range_vec( &mut self, gap_size: imem, start: Address, end: Address ) -> Vec<MemoryRange> { ... } fn virt_translation_map(&mut self, out: VirtualTranslationCallback<'_>) { ... } fn virt_translation_map_vec(&mut self) -> Vec<VirtualTranslation> { ... } fn phys_to_virt(&mut self, phys: Address) -> Option<Address> { ... } fn phys_to_virt_vec(&mut self, phys: Address) -> Vec<Address> { ... } fn virt_page_map(&mut self, gap_size: imem, out: MemoryRangeCallback<'_>) { ... } fn virt_page_map_vec(&mut self, gap_size: imem) -> Vec<MemoryRange> { ... }
}
Expand description

Translates virtual addresses into physical ones.

This is a simple user-facing trait to perform virtual address translations. Implementor needs to implement only 1 function - virt_to_phys_list. Other functions are provided as helpers built on top of the base function.

For overview how this trait relates to other virtual translation traits, check out documentation of this module.

Required Methods§

source

fn virt_to_phys_list( &mut self, addrs: &[VtopRange], out: VirtualTranslationCallback<'_>, out_fail: VirtualTranslationFailCallback<'_> )

Translate a list of address ranges into physical address space.

This function will take addresses in addrs and produce translation of them into out. Any unsuccessful ranges will be sent to out_fail.

Remarks

Note that the number of outputs may not match the number of inputs - virtual address space does not usually map linearly to the physical one, thus the input may need to be split into smaller parts, which may not be combined back together.

Example:
use memflow::prelude::v1::*;

// Virtual translation test
fn vtop(mem: &mut impl VirtualTranslate, addr: Address) {
    let mut cnt = 0;
    mem.virt_to_phys_list(
        &[CTup2(addr, 0x2000)],
        // Successfully translated
        (&mut |_| { cnt += 1; true }).into(),
        // Failed to translate
        (&mut |v| panic!("Failed to translate: {:?}", v)).into()
    );
    // We attempt to translate 2 pages, thus there are 2 outputs.
    assert_eq!(2, cnt);
}

Provided Methods§

source

fn virt_to_phys_range( &mut self, start: Address, end: Address, out: VirtualTranslationCallback<'_> )

Translate a single virtual address range into physical address space.

This function is a helper for virt_to_phys_list that translates just a single range, and has no failure output. It is otherwise identical.

Example:
use memflow::prelude::v1::*;

// Virtual translation test
fn vtop(mem: &mut impl VirtualTranslate, addr: Address) {
    let mut cnt = 0;
    mem.virt_to_phys_range(
        addr, addr + 0x2000,
        // Successfully translated
        (&mut |_| { cnt += 1; true }).into(),
    );
    // We attempt to translate 2 pages, thus there are 2 outputs.
    assert_eq!(2, cnt);
}
source

fn virt_translation_map_range( &mut self, start: Address, end: Address, out: VirtualTranslationCallback<'_> )

Translate a single virtual address range into physical address space and coalesce nearby regions.

This function is nearly identical to virt_to_phys_range, however, it performs additional post-processing of the output to combine consecutive ranges, and output them in sorted order (by input virtual address).

Example:
use memflow::prelude::v1::*;
use memflow::dummy::{DummyOs, DummyMemory};

// Create a dummy OS
let mem = DummyMemory::new(size::mb(1));
let mut os = DummyOs::new(mem);

// Create a process with 1+10 randomly placed regions
let pid = os.alloc_process(size::kb(4), &[]);
let proc = os.process_by_pid(pid).unwrap().proc;
os.process_alloc_random_mem(&proc, 10, 1);
let mut mem = os.process_by_pid(pid).unwrap().mem;

// Translate entire address space
let mut output = vec![];

mem.virt_translation_map_range(
    Address::null(),
    Address::invalid(),
    (&mut output).into()
);

// There should be 11 memory ranges.
assert_eq!(11, output.len());
source

fn virt_page_map_range( &mut self, gap_size: imem, start: Address, end: Address, out: MemoryRangeCallback<'_> )

Retrieves mapped virtual pages in the specified range.

In case a range from Address::null(), Address::invalid() is specified this function will return all mappings.

Given negative gap size, they will not be removed.

Example:
use memflow::prelude::v1::*;
println!("{:>16} {:>12} {:<}", "ADDR", "SIZE", "TYPE");

let callback = &mut |CTup3(addr, size, pagety)| {
    println!("{:>16x} {:>12x} {:<?}", addr, size, pagety);
    true
};

// display all mappings with a gap size of 0
virt_mem.virt_page_map_range(0, Address::null(), Address::invalid(), callback.into());
source

fn virt_to_phys(&mut self, address: Address) -> Result<PhysicalAddress>

Translate a single virtual address into a single physical address.

This is the simplest translation function that performs single address translation.

Example:
use memflow::prelude::v1::*;

// Virtual translation test
fn vtop(mem: &mut impl VirtualTranslate, addr: Address) {
    assert!(mem.virt_to_phys(addr).is_ok());
}
source

fn virt_page_info(&mut self, addr: Address) -> Result<Page>

Retrieve page information at virtual address.

This function is equivalent to calling containing_page on virt_to_phys result.

Example:
use memflow::prelude::v1::*;

// Virtual translation test
fn vtop(mem: &mut impl VirtualTranslate, addr: Address) {
    let page = mem.virt_page_info(addr).unwrap();
    assert_eq!(page.page_size, mem::kb(4));
    assert_eq!(page.page_type, PageType::WRITEABLE);
}
source

fn virt_page_map_range_vec( &mut self, gap_size: imem, start: Address, end: Address ) -> Vec<MemoryRange>

Retrieve a vector of physical pages within given range.

This is equivalent to calling virt_page_map_range with a vector output argument.

Example:
use memflow::prelude::v1::*;
println!("{:>16} {:>12} {:<}", "ADDR", "SIZE", "TYPE");

// display all mappings with a gap size of 0
let out = virt_mem.virt_page_map_range_vec(0, Address::null(), Address::invalid());

assert!(out.len() > 0);

for CTup3(addr, size, pagety) in out {
    println!("{:>16x} {:>12x} {:<?}", addr, size, pagety);
}
source

fn virt_translation_map(&mut self, out: VirtualTranslationCallback<'_>)

Get virtual translation map over entire address space.

This is equivalent to virt_translation_map_range with a range from null to highest address.

Example:
use memflow::prelude::v1::*;
use memflow::dummy::{DummyOs, DummyMemory};

// Create a dummy OS
let mem = DummyMemory::new(size::mb(1));
let mut os = DummyOs::new(mem);

// Create a process with 1+10 randomly placed regions
let pid = os.alloc_process(size::kb(4), &[]);
let proc = os.process_by_pid(pid).unwrap().proc;
os.process_alloc_random_mem(&proc, 10, 1);
let mut mem = os.process_by_pid(pid).unwrap().mem;

// Translate entire address space
let mut output = vec![];

mem.virt_translation_map((&mut output).into());

// There should be 11 memory ranges.
assert_eq!(11, output.len());
source

fn virt_translation_map_vec(&mut self) -> Vec<VirtualTranslation>

Get virtual translation map over entire address space and return it as a vector.

This is a virt_translation_map helper that stores results into a vector that gets returned.

Example:
use memflow::prelude::v1::*;
use memflow::dummy::{DummyOs, DummyMemory};

// Create a dummy OS
let mem = DummyMemory::new(size::mb(1));
let mut os = DummyOs::new(mem);

// Create a process with 1+10 randomly placed regions
let pid = os.alloc_process(size::kb(4), &[]);
let proc = os.process_by_pid(pid).unwrap().proc;
os.process_alloc_random_mem(&proc, 10, 1);
let mut mem = os.process_by_pid(pid).unwrap().mem;

// Translate entire address space
let output = mem.virt_translation_map_vec();

// There should be 11 memory ranges.
assert_eq!(11, output.len());
source

fn phys_to_virt(&mut self, phys: Address) -> Option<Address>

Attempt to translate a physical address into a virtual one.

This function is the reverse of virt_to_phys. Note, that there could could be multiple virtual addresses for one physical address. If all candidates are needed, use phys_to_virt_vec function.

Example:
use memflow::prelude::v1::*;

// Virtual translation and reversal test
fn vtop_ptov(mem: &mut impl VirtualTranslate, addr: Address) {
    let paddr = mem.virt_to_phys(addr).unwrap();
    let vaddr = mem.phys_to_virt(paddr.address());
    assert_eq!(vaddr, Some(addr));
}
source

fn phys_to_virt_vec(&mut self, phys: Address) -> Vec<Address>

Retrieve all virtual address that map into a given physical address.

This function is the reverse of virt_to_phys, and it retrieves all physical addresses that map to this virtual address.

Example:
use memflow::prelude::v1::*;

// Virtual translation and reversal test
fn vtop_ptov(mem: &mut impl VirtualTranslate, addr: Address) {
    let paddr = mem.virt_to_phys(addr).unwrap();
    let vaddrs = mem.phys_to_virt_vec(paddr.address());
    assert_eq!(&vaddrs, &[addr]);
}
source

fn virt_page_map(&mut self, gap_size: imem, out: MemoryRangeCallback<'_>)

Retrieves all mapped virtual pages.

The virt_page_map function is a convenience wrapper for calling virt_page_map_range(gap_size, Address::null(), Address::invalid(), out).

Example:
use memflow::prelude::v1::*;
println!("{:>16} {:>12} {:<}", "ADDR", "SIZE", "TYPE");

let callback = &mut |CTup3(addr, size, pagety)| {
    println!("{:>16x} {:>12x} {:<?}", addr, size, pagety);
    true
};

// display all mappings with a gap size of 0
virt_mem.virt_page_map(0, callback.into());
source

fn virt_page_map_vec(&mut self, gap_size: imem) -> Vec<MemoryRange>

Returns a Vec of all mapped virtual pages.

The virt_page_map function is a convenience wrapper for calling virt_page_map_range(gap_size, Address::null(), Address::invalid(), out).

Remarks:

This function has to allocate all MemoryRanges when they are put into a Vec. If the additional allocations are undesired please use the provided virt_page_map with an appropiate callback.

Example:
use memflow::prelude::v1::*;
// acquire all mappings with a gap size of 0
let maps = virt_mem.virt_page_map_vec(0);

println!("{:>16} {:>12} {:<}", "ADDR", "SIZE", "TYPE");
for CTup3(addr, size, pagety) in maps.iter() {
    println!("{:>16x} {:>12x} {:<?}", addr, size, pagety);
};

Implementors§