twizzler_abi/syscall/
map.rs

1use core::mem::MaybeUninit;
2
3use bitflags::bitflags;
4use twizzler_rt_abi::Result;
5
6use super::{convert_codes_to_result, twzerr, Syscall};
7use crate::{
8    arch::syscall::raw_syscall,
9    object::{ObjID, Protections},
10};
11
12bitflags! {
13    /// Flags to pass to [sys_object_map].
14    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
15    pub struct MapFlags: u32 {
16        const STABLE = 1;
17        const NO_NULLPAGE = 2;
18    }
19}
20
21impl From<twizzler_rt_abi::object::MapFlags> for MapFlags {
22    fn from(of: twizzler_rt_abi::object::MapFlags) -> Self {
23        let mut this = Self::empty();
24        if of.contains(twizzler_rt_abi::object::MapFlags::INDIRECT) {
25            this.insert(MapFlags::STABLE);
26        }
27        if of.contains(twizzler_rt_abi::object::MapFlags::NO_NULLPAGE) {
28            this.insert(MapFlags::NO_NULLPAGE);
29        }
30        this
31    }
32}
33
34impl From<MapFlags> for twizzler_rt_abi::object::MapFlags {
35    fn from(mf: MapFlags) -> Self {
36        let mut this = Self::empty();
37        if mf.contains(MapFlags::STABLE) {
38            this.insert(twizzler_rt_abi::object::MapFlags::INDIRECT);
39        }
40        if mf.contains(MapFlags::NO_NULLPAGE) {
41            this.insert(twizzler_rt_abi::object::MapFlags::NO_NULLPAGE);
42        }
43        this
44    }
45}
46
47/// Map an object into the address space with the specified protections.
48pub fn sys_object_map(
49    handle: Option<ObjID>,
50    id: ObjID,
51    slot: usize,
52    prot: Protections,
53    flags: MapFlags,
54) -> Result<usize> {
55    let [hi, lo] = id.parts();
56    let args = [
57        hi,
58        lo,
59        slot as u64,
60        prot.bits() as u64,
61        flags.bits() as u64,
62        &handle as *const Option<ObjID> as usize as u64,
63    ];
64    let (code, val) = unsafe { raw_syscall(Syscall::ObjectMap, &args) };
65    convert_codes_to_result(code, val, |c, _| c != 0, |_, v| v as usize, twzerr)
66}
67
68bitflags! {
69    /// Flags to pass to [sys_object_unmap].
70    pub struct UnmapFlags: u32 {
71    }
72}
73
74/// Unmaps an object from the address space specified by `handle` (or the current address space if
75/// none is specified).
76pub fn sys_object_unmap(handle: Option<ObjID>, slot: usize, flags: UnmapFlags) -> Result<()> {
77    let [hi, lo] = handle.unwrap_or_else(|| ObjID::new(0)).parts();
78    let args = [hi, lo, slot as u64, flags.bits() as u64];
79    let (code, val) = unsafe { raw_syscall(Syscall::ObjectUnmap, &args) };
80    convert_codes_to_result(code, val, |c, _| c != 0, |_, _| (), twzerr)
81}
82
83/// Information about an object mapping.
84#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
85#[repr(C)]
86pub struct MapInfo {
87    /// The mapped object ID.
88    pub id: ObjID,
89    /// The protections of the mapping.
90    pub prot: Protections,
91    /// The slot.
92    pub slot: usize,
93    /// The mapping flags.
94    pub flags: MapFlags,
95}
96
97/// Reads the map information about a given slot in the address space specified by `handle` (or
98/// current address space if none is specified).
99pub fn sys_object_read_map(handle: Option<ObjID>, slot: usize) -> Result<MapInfo> {
100    let [hi, lo] = handle.unwrap_or_else(|| ObjID::new(0)).parts();
101    let mut map_info = MaybeUninit::<MapInfo>::uninit();
102    let args = [
103        hi,
104        lo,
105        slot as u64,
106        &mut map_info as *mut MaybeUninit<MapInfo> as usize as u64,
107    ];
108    let (code, val) = unsafe { raw_syscall(Syscall::ObjectReadMap, &args) };
109    convert_codes_to_result(
110        code,
111        val,
112        |c, _| c != 0,
113        |_, _| unsafe { map_info.assume_init() },
114        twzerr,
115    )
116}