Skip to main content

syscall/
data.rs

1use core::{
2    mem,
3    ops::{Deref, DerefMut},
4    slice,
5};
6
7use crate::{
8    flag::{EventFlags, MapFlags, PtraceFlags, StdFsCallKind},
9    Error, EINVAL,
10};
11
12#[derive(Copy, Clone, Debug, Default)]
13#[repr(C)]
14pub struct Event {
15    pub id: usize,
16    pub flags: EventFlags,
17    pub data: usize,
18}
19
20impl Deref for Event {
21    type Target = [u8];
22    fn deref(&self) -> &[u8] {
23        unsafe { slice::from_raw_parts(self as *const Event as *const u8, mem::size_of::<Event>()) }
24    }
25}
26
27impl DerefMut for Event {
28    fn deref_mut(&mut self) -> &mut [u8] {
29        unsafe { slice::from_raw_parts_mut(self as *mut Event as *mut u8, mem::size_of::<Event>()) }
30    }
31}
32
33#[derive(Copy, Clone, Debug, Default)]
34#[repr(C)]
35pub struct ITimerSpec {
36    pub it_interval: TimeSpec,
37    pub it_value: TimeSpec,
38}
39
40impl Deref for ITimerSpec {
41    type Target = [u8];
42    fn deref(&self) -> &[u8] {
43        unsafe {
44            slice::from_raw_parts(
45                self as *const ITimerSpec as *const u8,
46                mem::size_of::<ITimerSpec>(),
47            )
48        }
49    }
50}
51
52impl DerefMut for ITimerSpec {
53    fn deref_mut(&mut self) -> &mut [u8] {
54        unsafe {
55            slice::from_raw_parts_mut(
56                self as *mut ITimerSpec as *mut u8,
57                mem::size_of::<ITimerSpec>(),
58            )
59        }
60    }
61}
62
63#[derive(Copy, Clone, Debug, Default)]
64#[repr(C)]
65pub struct OldMap {
66    pub offset: usize,
67    pub size: usize,
68    pub flags: MapFlags,
69}
70
71impl Deref for OldMap {
72    type Target = [u8];
73    fn deref(&self) -> &[u8] {
74        unsafe {
75            slice::from_raw_parts(self as *const OldMap as *const u8, mem::size_of::<OldMap>())
76        }
77    }
78}
79
80impl DerefMut for OldMap {
81    fn deref_mut(&mut self) -> &mut [u8] {
82        unsafe {
83            slice::from_raw_parts_mut(self as *mut OldMap as *mut u8, mem::size_of::<OldMap>())
84        }
85    }
86}
87#[derive(Copy, Clone, Debug, Default)]
88#[repr(C)]
89pub struct Map {
90    /// The offset inside the file that is being mapped.
91    pub offset: usize,
92
93    /// The size of the memory map.
94    pub size: usize,
95
96    /// Contains both prot and map flags.
97    pub flags: MapFlags,
98
99    /// Functions as a hint to where in the virtual address space of the running process, to place
100    /// the memory map. If [`MapFlags::MAP_FIXED`] is set, then this address must be the address to
101    /// map to.
102    pub address: usize,
103}
104
105impl Deref for Map {
106    type Target = [u8];
107    fn deref(&self) -> &[u8] {
108        unsafe { slice::from_raw_parts(self as *const Map as *const u8, mem::size_of::<Map>()) }
109    }
110}
111
112impl DerefMut for Map {
113    fn deref_mut(&mut self) -> &mut [u8] {
114        unsafe { slice::from_raw_parts_mut(self as *mut Map as *mut u8, mem::size_of::<Map>()) }
115    }
116}
117
118#[derive(Copy, Clone, Debug, Default, PartialEq)]
119#[repr(C)]
120pub struct Stat {
121    pub st_dev: u64,
122    pub st_ino: u64,
123    pub st_mode: u16,
124    pub st_nlink: u32,
125    pub st_uid: u32,
126    pub st_gid: u32,
127    pub st_size: u64,
128    pub st_blksize: u32,
129    pub st_blocks: u64,
130    pub st_mtime: u64,
131    pub st_mtime_nsec: u32,
132    pub st_atime: u64,
133    pub st_atime_nsec: u32,
134    pub st_ctime: u64,
135    pub st_ctime_nsec: u32,
136}
137
138impl Deref for Stat {
139    type Target = [u8];
140    fn deref(&self) -> &[u8] {
141        unsafe { slice::from_raw_parts(self as *const Stat as *const u8, mem::size_of::<Stat>()) }
142    }
143}
144
145impl DerefMut for Stat {
146    fn deref_mut(&mut self) -> &mut [u8] {
147        unsafe { slice::from_raw_parts_mut(self as *mut Stat as *mut u8, mem::size_of::<Stat>()) }
148    }
149}
150
151#[derive(Copy, Clone, Debug, Default, PartialEq)]
152#[repr(C)]
153pub struct StatVfs {
154    pub f_bsize: u32,
155    pub f_blocks: u64,
156    pub f_bfree: u64,
157    pub f_bavail: u64,
158}
159
160impl Deref for StatVfs {
161    type Target = [u8];
162    fn deref(&self) -> &[u8] {
163        unsafe {
164            slice::from_raw_parts(
165                self as *const StatVfs as *const u8,
166                mem::size_of::<StatVfs>(),
167            )
168        }
169    }
170}
171
172impl DerefMut for StatVfs {
173    fn deref_mut(&mut self) -> &mut [u8] {
174        unsafe {
175            slice::from_raw_parts_mut(self as *mut StatVfs as *mut u8, mem::size_of::<StatVfs>())
176        }
177    }
178}
179
180#[derive(Copy, Clone, Debug, Default, PartialEq)]
181#[repr(C, packed)]
182pub struct StdFsCallMeta {
183    pub kind: u8, // enum StdFsCallKind
184    _rsvd: [u8; 7],
185    pub arg1: u64,
186    pub arg2: u64,
187}
188
189impl StdFsCallMeta {
190    pub fn new(kind: StdFsCallKind, arg1: u64, arg2: u64) -> Self {
191        Self {
192            kind: kind as u8,
193            _rsvd: [0; 7],
194            arg1,
195            arg2,
196        }
197    }
198}
199
200impl Deref for StdFsCallMeta {
201    type Target = [u64];
202    fn deref(&self) -> &[u64] {
203        unsafe {
204            slice::from_raw_parts(
205                self as *const StdFsCallMeta as *const u64,
206                mem::size_of::<StdFsCallMeta>() / mem::size_of::<u64>(),
207            )
208        }
209    }
210}
211
212impl DerefMut for StdFsCallMeta {
213    fn deref_mut(&mut self) -> &mut [u64] {
214        unsafe {
215            slice::from_raw_parts_mut(
216                self as *mut StdFsCallMeta as *mut u64,
217                mem::size_of::<StdFsCallMeta>() / mem::size_of::<u64>(),
218            )
219        }
220    }
221}
222
223#[derive(Copy, Clone, Debug, Default, PartialEq)]
224#[repr(C)]
225pub struct TimeSpec {
226    pub tv_sec: i64,
227    pub tv_nsec: i32,
228}
229
230const NANOS_PER_SEC: u128 = 1_000_000_000;
231
232impl TimeSpec {
233    pub fn from_nanos(nanos: u128) -> Self {
234        Self {
235            tv_sec: i64::try_from(nanos / NANOS_PER_SEC).unwrap_or(i64::MAX),
236            tv_nsec: (nanos % NANOS_PER_SEC) as i32, // guaranteed to never overflow
237        }
238    }
239    pub fn to_nanos(&self) -> u128 {
240        self.tv_sec as u128 * NANOS_PER_SEC + self.tv_nsec as u128
241    }
242}
243
244impl Deref for TimeSpec {
245    type Target = [u8];
246    fn deref(&self) -> &[u8] {
247        unsafe {
248            slice::from_raw_parts(
249                self as *const TimeSpec as *const u8,
250                mem::size_of::<TimeSpec>(),
251            )
252        }
253    }
254}
255
256impl DerefMut for TimeSpec {
257    fn deref_mut(&mut self) -> &mut [u8] {
258        unsafe {
259            slice::from_raw_parts_mut(self as *mut TimeSpec as *mut u8, mem::size_of::<TimeSpec>())
260        }
261    }
262}
263
264#[derive(Clone, Copy, Debug, Default)]
265#[repr(C)]
266pub struct PtraceEvent {
267    pub cause: PtraceFlags,
268    pub a: usize,
269    pub b: usize,
270    pub c: usize,
271    pub d: usize,
272    pub e: usize,
273    pub f: usize,
274}
275
276impl Deref for PtraceEvent {
277    type Target = [u8];
278    fn deref(&self) -> &[u8] {
279        unsafe {
280            slice::from_raw_parts(
281                self as *const PtraceEvent as *const u8,
282                mem::size_of::<PtraceEvent>(),
283            )
284        }
285    }
286}
287
288impl DerefMut for PtraceEvent {
289    fn deref_mut(&mut self) -> &mut [u8] {
290        unsafe {
291            slice::from_raw_parts_mut(
292                self as *mut PtraceEvent as *mut u8,
293                mem::size_of::<PtraceEvent>(),
294            )
295        }
296    }
297}
298
299#[macro_export]
300macro_rules! ptrace_event {
301    ($cause:expr $(, $a:expr $(, $b:expr $(, $c:expr)?)?)?) => {
302        $crate::data::PtraceEvent {
303            cause: $cause,
304            $(a: $a,
305              $(b: $b,
306                $(c: $c,)?
307              )?
308            )?
309            ..Default::default()
310        }
311    }
312}
313
314bitflags::bitflags! {
315    #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy, Default)]
316    pub struct GrantFlags: usize {
317        const GRANT_READ = 0x0000_0001;
318        const GRANT_WRITE = 0x0000_0002;
319        const GRANT_EXEC = 0x0000_0004;
320
321        const GRANT_SHARED = 0x0000_0008;
322        const GRANT_LAZY = 0x0000_0010;
323        const GRANT_SCHEME = 0x0000_0020;
324        const GRANT_PHYS = 0x0000_0040;
325        const GRANT_PINNED = 0x0000_0080;
326        const GRANT_PHYS_CONTIGUOUS = 0x0000_0100;
327    }
328}
329
330impl GrantFlags {
331    #[deprecated = "use the safe `from_bits_retain` method instead"]
332    pub unsafe fn from_bits_unchecked(bits: usize) -> Self {
333        Self::from_bits_retain(bits)
334    }
335}
336
337#[derive(Clone, Copy, Debug, Default)]
338#[repr(C)]
339pub struct GrantDesc {
340    pub base: usize,
341    pub size: usize,
342    pub flags: GrantFlags,
343    pub offset: u64,
344}
345
346impl Deref for GrantDesc {
347    type Target = [u8];
348    fn deref(&self) -> &[u8] {
349        unsafe {
350            slice::from_raw_parts(
351                self as *const GrantDesc as *const u8,
352                mem::size_of::<GrantDesc>(),
353            )
354        }
355    }
356}
357
358impl DerefMut for GrantDesc {
359    fn deref_mut(&mut self) -> &mut [u8] {
360        unsafe {
361            slice::from_raw_parts_mut(
362                self as *mut GrantDesc as *mut u8,
363                mem::size_of::<GrantDesc>(),
364            )
365        }
366    }
367}
368
369#[derive(Clone, Copy, Debug, Default)]
370#[repr(C)]
371pub struct SetSighandlerData {
372    pub user_handler: usize,
373    pub excp_handler: usize,
374    pub thread_control_addr: usize,
375    pub proc_control_addr: usize,
376}
377
378impl Deref for SetSighandlerData {
379    type Target = [u8];
380    fn deref(&self) -> &[u8] {
381        unsafe { slice::from_raw_parts(self as *const Self as *const u8, mem::size_of::<Self>()) }
382    }
383}
384
385impl DerefMut for SetSighandlerData {
386    fn deref_mut(&mut self) -> &mut [u8] {
387        unsafe { slice::from_raw_parts_mut(self as *mut Self as *mut u8, mem::size_of::<Self>()) }
388    }
389}
390pub use crate::sigabi::*;
391
392/// UNSTABLE
393#[derive(Copy, Clone, Debug, Default, PartialEq)]
394#[repr(C)]
395pub struct ProcSchemeAttrs {
396    pub pid: u32,
397    pub euid: u32,
398    pub egid: u32,
399    pub prio: u32,
400    pub debug_name: [u8; 32],
401}
402impl Deref for ProcSchemeAttrs {
403    type Target = [u8];
404    fn deref(&self) -> &[u8] {
405        unsafe { slice::from_raw_parts(self as *const Self as *const u8, mem::size_of::<Self>()) }
406    }
407}
408impl DerefMut for ProcSchemeAttrs {
409    fn deref_mut(&mut self) -> &mut [u8] {
410        unsafe {
411            slice::from_raw_parts_mut(
412                self as *mut ProcSchemeAttrs as *mut u8,
413                mem::size_of::<ProcSchemeAttrs>(),
414            )
415        }
416    }
417}
418#[derive(Copy, Clone, Debug, Default)]
419#[repr(C)]
420pub struct CtxtStsBuf {
421    pub status: usize,
422    pub excp: crate::Exception,
423}
424impl Deref for CtxtStsBuf {
425    type Target = [u8];
426    fn deref(&self) -> &[u8] {
427        unsafe { slice::from_raw_parts(self as *const Self as *const u8, mem::size_of::<Self>()) }
428    }
429}
430impl DerefMut for CtxtStsBuf {
431    fn deref_mut(&mut self) -> &mut [u8] {
432        unsafe {
433            slice::from_raw_parts_mut(
434                self as *mut CtxtStsBuf as *mut u8,
435                mem::size_of::<CtxtStsBuf>(),
436            )
437        }
438    }
439}
440
441#[derive(Copy, Clone, Debug, Default)]
442#[repr(C)]
443pub struct NewFdParams {
444    pub offset: u64,
445    pub number: usize,
446    pub flags: usize,
447    pub internal_flags: u8,
448}
449
450#[repr(u8)]
451#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
452pub enum GlobalSchemes {
453    Debug = 1,
454    Event = 2,
455    Memory = 3,
456    Pipe = 4,
457    Serio = 5,
458    Irq = 6,
459    Time = 7,
460    Sys = 8,
461    Proc = 9,
462    Acpi = 10,
463    Dtb = 11,
464}
465impl GlobalSchemes {
466    pub fn try_from_raw(raw: u8) -> Option<Self> {
467        match raw {
468            1 => Some(Self::Debug),
469            2 => Some(Self::Event),
470            3 => Some(Self::Memory),
471            4 => Some(Self::Pipe),
472            5 => Some(Self::Serio),
473            6 => Some(Self::Irq),
474            7 => Some(Self::Time),
475            8 => Some(Self::Sys),
476            9 => Some(Self::Proc),
477            10 => Some(Self::Acpi),
478            11 => Some(Self::Dtb),
479            _ => None,
480        }
481    }
482    pub fn as_str(&self) -> &'static str {
483        match self {
484            Self::Debug => "debug",
485            Self::Event => "event",
486            Self::Memory => "memory",
487            Self::Pipe => "pipe",
488            Self::Serio => "serio",
489            Self::Irq => "irq",
490            Self::Time => "time",
491            Self::Sys => "sys",
492            Self::Proc => "kernel.proc",
493            Self::Acpi => "kernel.acpi",
494            Self::Dtb => "kernel.dtb",
495        }
496    }
497}
498
499#[repr(C)]
500#[derive(Debug, Clone, Copy, Default)]
501pub struct KernelSchemeInfo {
502    pub scheme_id: u8,
503    pub fd: usize,
504}
505
506#[repr(C)]
507#[derive(Debug, Clone, Copy)]
508pub enum NumaMemoryPolicy {
509    /// Allocates from local node; fails if no memory is available in local node
510    NodeLocalStrict = 1,
511
512    /// Allocates from local node; falls back to allocating from other nodes in the increasing order of distance from the current node
513    NodeLocalLeniant = 2,
514}
515
516impl TryFrom<u64> for NumaMemoryPolicy {
517    type Error = Error;
518
519    fn try_from(value: u64) -> Result<Self, Self::Error> {
520        match value {
521            1 => Ok(NumaMemoryPolicy::NodeLocalStrict),
522            2 => Ok(NumaMemoryPolicy::NodeLocalLeniant),
523            _ => Err(Error::new(EINVAL)),
524        }
525    }
526}