Trait memflow::mem::virt_translate::VirtualTranslate
source · 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§
sourcefn virt_to_phys_list(
&mut self,
addrs: &[VtopRange],
out: VirtualTranslationCallback<'_>,
out_fail: VirtualTranslationFailCallback<'_>
)
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§
sourcefn virt_to_phys_range(
&mut self,
start: Address,
end: Address,
out: VirtualTranslationCallback<'_>
)
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);
}
sourcefn virt_translation_map_range(
&mut self,
start: Address,
end: Address,
out: VirtualTranslationCallback<'_>
)
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());
sourcefn virt_page_map_range(
&mut self,
gap_size: imem,
start: Address,
end: Address,
out: MemoryRangeCallback<'_>
)
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());
sourcefn virt_to_phys(&mut self, address: Address) -> Result<PhysicalAddress>
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());
}
sourcefn virt_page_info(&mut self, addr: Address) -> Result<Page>
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);
}
sourcefn virt_page_map_range_vec(
&mut self,
gap_size: imem,
start: Address,
end: Address
) -> Vec<MemoryRange>
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);
}
sourcefn virt_translation_map(&mut self, out: VirtualTranslationCallback<'_>)
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());
sourcefn virt_translation_map_vec(&mut self) -> Vec<VirtualTranslation>
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());
sourcefn phys_to_virt(&mut self, phys: Address) -> Option<Address>
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));
}
sourcefn phys_to_virt_vec(&mut self, phys: Address) -> Vec<Address>
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]);
}
sourcefn virt_page_map(&mut self, gap_size: imem, out: MemoryRangeCallback<'_>)
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());
sourcefn virt_page_map_vec(&mut self, gap_size: imem) -> Vec<MemoryRange>
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);
};