linux_syscalls/env/aux/
mod.rs1use core::ffi::c_void;
2
3#[cfg_attr(
4 any(target_arch = "powerpc", target_arch = "powerpc64"),
5 path = "powerpc.rs"
6)]
7#[cfg_attr(any(target_arch = "x86", target_arch = "x86_64"), path = "x86.rs")]
8#[cfg_attr(target_arch = "arm", path = "arm.rs")]
9#[cfg_attr(target_arch = "aarch64", path = "aarch64.rs")]
10#[cfg_attr(target_arch = "loongarch64", path = "loongarch64.rs")]
11#[cfg_attr(target_arch = "s390x", path = "s390x.rs")]
12#[cfg_attr(any(target_arch = "mips", target_arch = "mips64"), path = "mips.rs")]
13#[cfg_attr(
14 any(target_arch = "riscv32", target_arch = "riscv64"),
15 path = "riscv.rs"
16)]
17mod arch;
18
19pub use arch::{Features, Features2};
20
21#[cfg(target_pointer_width = "32")]
22#[allow(non_camel_case_types)]
23type aux_t = u32;
24#[cfg(target_pointer_width = "64")]
25#[allow(non_camel_case_types)]
26type aux_t = u64;
27
28#[repr(C)]
29struct AuxvPair {
30 pub a_type: aux_t,
31 pub a_un: aux_t,
32}
33
34mod __sealed {
35 pub trait Sealed {}
36}
37use __sealed::Sealed;
38
39#[doc(hidden)]
40pub trait AuxValue: Sealed {
41 fn from(value: aux_t) -> Self;
42}
43
44pub trait VdsoKey: Sealed {
46 const ID: aux_t;
47 const N: usize;
48 type Item: AuxValue;
49}
50
51impl Sealed for i32 {}
52impl AuxValue for i32 {
53 #[inline]
54 fn from(value: aux_t) -> Self {
55 value as Self
56 }
57}
58
59impl Sealed for *const c_void {}
60impl AuxValue for *const c_void {
61 #[inline]
62 fn from(value: aux_t) -> Self {
63 value as Self
64 }
65}
66
67impl Sealed for *const u8 {}
68impl AuxValue for *const u8 {
69 #[inline]
70 fn from(value: aux_t) -> Self {
71 value as Self
72 }
73}
74
75impl Sealed for *const [u8; 16] {}
76impl AuxValue for *const [u8; 16] {
77 #[inline]
78 fn from(value: aux_t) -> Self {
79 value as Self
80 }
81}
82
83impl Sealed for usize {}
84impl AuxValue for usize {
85 #[inline]
86 fn from(value: aux_t) -> Self {
87 value as usize
88 }
89}
90
91impl Sealed for bool {}
92impl AuxValue for bool {
93 #[inline]
94 fn from(value: aux_t) -> Self {
95 value != 0
96 }
97}
98
99impl Sealed for u32 {}
100impl AuxValue for u32 {
101 #[inline]
102 #[allow(clippy::unnecessary_cast)]
103 fn from(value: aux_t) -> Self {
104 value as u32
105 }
106}
107
108macro_rules! def_keys {
109 (__internal_def ($no:expr) $(#[$meta:meta])* $name:ident($n:literal) -> $ty:ty $(,)?) => {
110 def_keys!(__decl_def ($no) $(#[$meta])* $name($n) -> $ty);
111 const KEYS_LEN: usize = $no+1;
112 };
113 (__internal_def ($no:expr) $(#[$meta:meta])* $name:ident($n:literal) -> $ty:ty, $($rest:tt)+) => {
114 def_keys!(__decl_def ($no) $(#[$meta])* $name($n) -> $ty);
115 def_keys!(__internal_def ($no+1) $($rest)+);
116 };
117 (__decl_def ($no:expr) $(#[$meta:meta])* $name:ident($n:literal) -> $ty:ty) => {
118 $(#[$meta])*
119 #[non_exhaustive]
120 pub struct $name;
121 impl Sealed for $name {}
122 impl VdsoKey for $name {
123 const ID: aux_t = $n;
124 const N: usize = $no;
125 type Item = $ty;
126 }
127 };
128 (__internal_match $($(#[$meta:meta])* $name:ident($n:literal) -> $ty:ty),+ $(,)?) => {
129 #[inline]
130 pub(crate) unsafe fn init(ptr: *const ()) {
131 let mut ptr = ptr as *mut AuxvPair;
132
133 while (*ptr).a_type != 0 {
134 #[deny(unreachable_patterns)]
135 match (*ptr).a_type {
136 $(
137 $name::ID => {
138 *AUXV.get_unchecked_mut($name::N) = Some((*ptr).a_un);
139 }
140 )+
141 _ => (),
142 }
143 ptr = ptr.add(1);
144 }
145 }
146 };
147 ($($rest:tt)+) => {
148 def_keys!(__internal_def (0) $($rest)+);
149 def_keys!(__internal_match $($rest)+);
150 }
151}
152
153def_keys! {
154 ExecFd(2) -> i32,
156 ProgramHeader(3) -> *const c_void,
158 ProgramHeaderSize(4) -> usize,
160 ProgramHeadersNumber(5) -> usize,
162 PageSize(6) -> usize,
164 BaseAddress(7) -> *const c_void,
166 Flags(8) -> usize,
168 EntryPoint(9) -> *const c_void,
170 NotElf(10) -> bool,
172 Uid(11) -> u32,
174 Euid(12) -> u32,
176 Gid(13) -> u32,
178 Egid(14) -> u32,
180 Platform(15) -> *const u8,
182 HardwareCapabilities(16) -> Features,
184 ClockFrequency(17) -> usize,
186 DCacheBSize(19) -> usize,
188 ICacheBSize(20) -> usize,
190 UCacheBSize(21) -> usize,
192 Secure(23) -> bool,
194 BasePlatform(24) -> *const u8,
196 Random(25) -> *const [u8; 16],
198 HardwareCapabilities2(26) -> Features2,
200 RSeqFeatureSize(27) -> usize,
202 RSeqAlign(28) -> usize,
204 Filename(31) -> *const u8,
206 SysInfo(32) -> *const c_void,
210 SysInfoHeader(33) -> *const c_void,
214 L1ICacheSize(40) -> usize,
216 L1ICacheGeometry(41) -> usize,
219 L1DCacheSize(42) -> usize,
221 L1DCacheGeometry(43) -> usize,
226 L2CacheSize(44) -> usize,
228 L2CacheGeometry(45) -> usize,
230 L3CacheSize(46) -> usize,
232 L3CacheGeometry(47) -> usize,
234 ADIBlockSize(48) -> usize,
236 ADINBits(49) -> usize,
238 ADIUEOnADI(50) -> usize,
240 MinimalSignalStackSize(51) -> usize,
242}
243
244pub(crate) static mut AUXV: [Option<aux_t>; KEYS_LEN] = [None; KEYS_LEN];
245
246#[inline]
247pub(crate) unsafe fn get<T: VdsoKey>() -> Option<T::Item> {
248 AUXV.get_unchecked(T::N).map(<T::Item as AuxValue>::from)
249}