vm-info 0.1.0

Inspect Linux virtual memory structure
Documentation
extern crate vm_info;

use std::env;

/// If no arguments are provided, the process will dump its own memory.
///
/// If running as an unprivileged user, page frame numbers will usually not be available. Run as
/// root to see physical memory info.
fn main() {
    let pid = env::args()
        .skip(1)
        .next()
        .map(|n| vm_info::ProcessId::Num(n.parse().expect("argument must be a number")))
        .unwrap_or(vm_info::ProcessId::SelfPid);

    let page_size = vm_info::page_size().unwrap();
    println!("Page size {}", page_size);

    for region in vm_info::mapped_region::iter_mappings(pid)
        .unwrap()
        .map(|r| r.unwrap())
        // vsyscall emulation leads to a vm mapping that has no actual page entry, so skip it
        .filter(|r| r.pathname != Some(String::from("[vsyscall]")))
    {
        println!(
            "Region starting at 0x{:x}\t{:?}\t{}",
            region.start_address,
            region.permissions,
            region
                .pathname
                .map(|p| format!("{}", p))
                .unwrap_or(String::from(""))
        );

        let page = vm_info::page_map::read_page_map(pid, region.start_address / page_size).unwrap();

        println!(
            "\tPage frame number: {}",
            page.page_frame()
                .map(|n| format!("{:#x} = {}", n, n))
                .unwrap_or(String::from("None"))
        );
        println!("\tPresent: {}", page.is_present());
        println!("\tSwapped: {}", page.is_swapped());
        println!("\tFile / shared anon: {}", page.is_file_page_shared_anon());
    }
}