starnix_syscalls/
syscall_arg.rs1use starnix_uapi::device_type::DeviceType;
6use starnix_uapi::file_mode::FileMode;
7use starnix_uapi::signals::UncheckedSignal;
8use starnix_uapi::user_address::{MappingMultiArchUserRef, MultiArchFrom, UserAddress, UserRef};
9use starnix_uapi::user_value::UserValue;
10
11#[derive(Debug, Default, Copy, Clone, Eq, PartialEq)]
12pub struct SyscallArg(u64);
13
14impl SyscallArg {
15 pub fn from_raw(raw: u64) -> Self {
16 Self(raw)
17 }
18
19 pub fn raw(&self) -> u64 {
20 self.0
21 }
22}
23
24impl From<UserAddress> for SyscallArg {
25 fn from(value: UserAddress) -> Self {
26 Self::from_raw(value.ptr() as u64)
27 }
28}
29
30impl From<u64> for SyscallArg {
31 fn from(value: u64) -> Self {
32 Self::from_raw(value)
33 }
34}
35
36impl From<usize> for SyscallArg {
37 fn from(value: usize) -> Self {
38 Self::from_raw(value as u64)
39 }
40}
41
42impl From<UserValue<u64>> for SyscallArg {
43 fn from(value: UserValue<u64>) -> Self {
44 Self::from_raw(value.raw())
45 }
46}
47
48impl From<UserValue<usize>> for SyscallArg {
49 fn from(value: UserValue<usize>) -> Self {
50 Self::from_raw(value.raw() as u64)
51 }
52}
53
54impl From<bool> for SyscallArg {
55 fn from(value: bool) -> Self {
56 Self::from_raw(if value { 1 } else { 0 })
57 }
58}
59
60impl std::fmt::LowerHex for SyscallArg {
61 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62 std::fmt::LowerHex::fmt(&self.0, f)
63 }
64}
65
66macro_rules! impl_from_syscall_arg {
67 { for $ty:ty: $arg:ident => $($body:tt)* } => {
68 impl From<SyscallArg> for $ty {
69 fn from($arg: SyscallArg) -> Self { $($body)* }
70 }
71 }
72}
73
74impl_from_syscall_arg! { for bool: arg => arg.raw() != 0 }
75impl_from_syscall_arg! { for i32: arg => arg.raw() as Self }
76impl_from_syscall_arg! { for i64: arg => arg.raw() as Self }
77impl_from_syscall_arg! { for u32: arg => arg.raw() as Self }
78impl_from_syscall_arg! { for usize: arg => arg.raw() as Self }
79impl_from_syscall_arg! { for u64: arg => arg.raw() as Self }
80impl_from_syscall_arg! { for UserValue<i32>: arg => Self::from_raw(arg.raw() as i32) }
81impl_from_syscall_arg! { for UserValue<i64>: arg => Self::from_raw(arg.raw() as i64) }
82impl_from_syscall_arg! { for UserValue<u32>: arg => Self::from_raw(arg.raw() as u32) }
83impl_from_syscall_arg! { for UserValue<usize>: arg => Self::from_raw(arg.raw() as usize) }
84impl_from_syscall_arg! { for UserValue<u64>: arg => Self::from_raw(arg.raw() as u64) }
85impl_from_syscall_arg! { for UserAddress: arg => Self::from(arg.raw()) }
86
87impl_from_syscall_arg! { for FileMode: arg => Self::from_bits(arg.raw() as u32) }
88impl_from_syscall_arg! { for DeviceType: arg => Self::from_bits(arg.raw()) }
89impl_from_syscall_arg! { for UncheckedSignal: arg => Self::new(arg.raw()) }
90
91impl<T> From<SyscallArg> for UserRef<T> {
92 fn from(arg: SyscallArg) -> UserRef<T> {
93 Self::new(arg.into())
94 }
95}
96
97impl<T, T64, T32> MultiArchFrom<SyscallArg> for MappingMultiArchUserRef<T, T64, T32> {
98 fn from_64(value: SyscallArg) -> Self {
99 Self::from(UserRef::<T64>::from(value))
100 }
101 fn from_32(value: SyscallArg) -> Self {
102 Self::from_32(UserRef::<T32>::from(value))
103 }
104}