1use alloc::string::String;
4use alloc::vec::Vec;
5use bitflags::bitflags;
6use core::fmt;
7use core::ops::Range;
8
9#[derive(Clone)]
10pub struct VMMan {
11 pub vmas: Vec<VMArea>,
12}
13
14impl VMMan {
15 pub fn new() -> Self { Self { vmas: Vec::<VMArea>::new() } }
16}
17
18bitflags! {
19 #[derive(Clone)]
20 pub struct VMPerms: u8 {
21 const NONE = 0;
22 const R = 1 << 0;
23 const W = 1 << 1;
24 const X = 1 << 2;
25 }
26}
27
28impl fmt::Debug for VMPerms {
29 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
30 write!(
31 f,
32 "{}{}{}",
33 if self.contains(Self::R) { "R" } else { "-" },
34 if self.contains(Self::W) { "W" } else { "-" },
35 if self.contains(Self::X) { "X" } else { "-" }
36 )
37 }
38}
39
40#[derive(Clone)]
44pub struct VMArea {
45 pub vm_range: Range<u64>,
46 pub tag: String,
47 pub user_perms: VMPerms,
48 pub backing: VMType,
49}
50
51impl VMArea {
52 pub fn bss_range(&self) -> Option<Range<u64>> {
54 if let VMType::FILE(f) = self.backing {
55 assert!(
56 self.vm_range.end - self.vm_range.start >= f.len() as u64,
57 "ill-formed VMA"
58 );
59 Some((self.vm_range.start + f.len() as u64)..self.vm_range.end)
60 } else {
61 None
62 }
63 }
64}
65
66impl fmt::Debug for VMArea {
67 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
68 write!(
69 f,
70 "{:016X}-{:016X} {:?} - {:?} - {}",
71 self.vm_range.start,
72 self.vm_range.end,
73 self.user_perms,
74 self.backing,
75 self.tag
76 )
77 }
78}
79
80#[derive(Clone)]
81pub enum VMType {
82 ANOM,
83 FILE(&'static [u8]),
84 NONE,
86}
87
88impl fmt::Debug for VMType {
89 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
90 write!(
91 f,
92 "{}",
93 match self {
94 Self::ANOM => "ANOM",
95 Self::FILE(_) => "FILE",
96 Self::NONE => "DEV",
97 },
98 )
99 }
100}