/rust/registry/src/index.crates.io-6f17d22bba15001f/procfs-0.17.0/src/process/pagemap.rs
Line | Count | Source (jump to first uncovered line) |
1 | | use crate::{FileWrapper, ProcResult}; |
2 | | use procfs_core::process::PageInfo; |
3 | | use std::{ |
4 | | io::{BufReader, Read, Seek, SeekFrom}, |
5 | | mem::size_of, |
6 | | ops::{Bound, RangeBounds}, |
7 | | }; |
8 | | |
9 | | impl super::Process { |
10 | | /// Returns a struct that can be used to access information in the `/proc/pid/pagemap` file. |
11 | 0 | pub fn pagemap(&self) -> ProcResult<PageMap> { |
12 | 0 | let path = self.root.join("pagemap"); |
13 | 0 | let file = FileWrapper::open(&path)?; |
14 | 0 | Ok(PageMap::from_file_wrapper(file)) |
15 | 0 | } |
16 | | } |
17 | | |
18 | | /// Parses page table entries accessing `/proc/<pid>/pagemap`. |
19 | | pub struct PageMap { |
20 | | reader: BufReader<FileWrapper>, |
21 | | } |
22 | | |
23 | | impl PageMap { |
24 | 0 | pub(crate) fn from_file_wrapper(file: FileWrapper) -> Self { |
25 | 0 | Self { |
26 | 0 | reader: BufReader::new(file), |
27 | 0 | } |
28 | 0 | } |
29 | | |
30 | | /// Retrieves information in the page table entry for the page at index `page_index`. |
31 | | /// |
32 | | /// Some mappings are not accessible, and will return an Err: `vsyscall` |
33 | 0 | pub fn get_info(&mut self, page_index: usize) -> ProcResult<PageInfo> { |
34 | 0 | self.get_range_info(page_index..page_index + 1) |
35 | 0 | .map(|mut vec| vec.pop().unwrap()) |
36 | 0 | } |
37 | | |
38 | | /// Retrieves information in the page table entry for the pages with index in range `page_range`. |
39 | 0 | pub fn get_range_info(&mut self, page_range: impl RangeBounds<usize>) -> ProcResult<Vec<PageInfo>> { |
40 | | // `start` is always included |
41 | 0 | let start = match page_range.start_bound() { |
42 | 0 | Bound::Included(v) => *v, |
43 | 0 | Bound::Excluded(v) => *v + 1, |
44 | 0 | Bound::Unbounded => 0, |
45 | | }; |
46 | | |
47 | | // `end` is always excluded |
48 | 0 | let end = match page_range.end_bound() { |
49 | 0 | Bound::Included(v) => *v + 1, |
50 | 0 | Bound::Excluded(v) => *v, |
51 | 0 | Bound::Unbounded => std::usize::MAX / crate::page_size() as usize, |
52 | | }; |
53 | | |
54 | 0 | let start_position = (start * size_of::<u64>()) as u64; |
55 | 0 | self.reader.seek(SeekFrom::Start(start_position))?; |
56 | | |
57 | 0 | let mut page_infos = Vec::with_capacity((end - start) as usize); |
58 | 0 | for _ in start..end { |
59 | 0 | let mut info_bytes = [0; size_of::<u64>()]; |
60 | 0 | self.reader.read_exact(&mut info_bytes)?; |
61 | 0 | page_infos.push(PageInfo::parse_info(u64::from_ne_bytes(info_bytes))); |
62 | | } |
63 | | |
64 | 0 | Ok(page_infos) |
65 | 0 | } |
66 | | } |