linux_api/
prctl.rs

1use linux_syscall::Result64;
2use linux_syscall::syscall;
3
4use crate::errno::Errno;
5use crate::{bindings, const_conversions};
6
7/// Options for `man 2 prctl`.
8// We want to allow unknown values since newer kernel versions may add new options, and we may want
9// to gracefully handle these options (for example to pass them on to the kernel). Linux also uses
10// the same namespace ("PR_") for both options and argument flags (for example the `option`
11// `PR_SET_FP_MODE` and the bitflag arguments `PR_FP_MODE_FR` and `PR_FP_MODE_FRE` in `arg2`). We
12// don't want bitflags in this struct, so when adding new "PR_" entries, make sure they correspond
13// with prctl "options" and not "arguments".
14#[derive(PartialEq, Eq)]
15pub struct PrctlOp(i32);
16
17impl PrctlOp {
18    pub const PR_SET_PDEATHSIG: Self = Self::from_u32(bindings::LINUX_PR_SET_PDEATHSIG);
19    pub const PR_GET_PDEATHSIG: Self = Self::from_u32(bindings::LINUX_PR_GET_PDEATHSIG);
20    pub const PR_GET_DUMPABLE: Self = Self::from_u32(bindings::LINUX_PR_GET_DUMPABLE);
21    pub const PR_SET_DUMPABLE: Self = Self::from_u32(bindings::LINUX_PR_SET_DUMPABLE);
22    pub const PR_GET_UNALIGN: Self = Self::from_u32(bindings::LINUX_PR_GET_UNALIGN);
23    pub const PR_SET_UNALIGN: Self = Self::from_u32(bindings::LINUX_PR_SET_UNALIGN);
24    pub const PR_GET_KEEPCAPS: Self = Self::from_u32(bindings::LINUX_PR_GET_KEEPCAPS);
25    pub const PR_SET_KEEPCAPS: Self = Self::from_u32(bindings::LINUX_PR_SET_KEEPCAPS);
26    pub const PR_GET_FPEMU: Self = Self::from_u32(bindings::LINUX_PR_GET_FPEMU);
27    pub const PR_SET_FPEMU: Self = Self::from_u32(bindings::LINUX_PR_SET_FPEMU);
28    pub const PR_GET_FPEXC: Self = Self::from_u32(bindings::LINUX_PR_GET_FPEXC);
29    pub const PR_SET_FPEXC: Self = Self::from_u32(bindings::LINUX_PR_SET_FPEXC);
30    pub const PR_GET_TIMING: Self = Self::from_u32(bindings::LINUX_PR_GET_TIMING);
31    pub const PR_SET_TIMING: Self = Self::from_u32(bindings::LINUX_PR_SET_TIMING);
32    pub const PR_SET_NAME: Self = Self::from_u32(bindings::LINUX_PR_SET_NAME);
33    pub const PR_GET_NAME: Self = Self::from_u32(bindings::LINUX_PR_GET_NAME);
34    pub const PR_GET_ENDIAN: Self = Self::from_u32(bindings::LINUX_PR_GET_ENDIAN);
35    pub const PR_SET_ENDIAN: Self = Self::from_u32(bindings::LINUX_PR_SET_ENDIAN);
36    pub const PR_GET_SECCOMP: Self = Self::from_u32(bindings::LINUX_PR_GET_SECCOMP);
37    pub const PR_SET_SECCOMP: Self = Self::from_u32(bindings::LINUX_PR_SET_SECCOMP);
38    pub const PR_CAPBSET_READ: Self = Self::from_u32(bindings::LINUX_PR_CAPBSET_READ);
39    pub const PR_CAPBSET_DROP: Self = Self::from_u32(bindings::LINUX_PR_CAPBSET_DROP);
40    pub const PR_GET_TSC: Self = Self::from_u32(bindings::LINUX_PR_GET_TSC);
41    pub const PR_SET_TSC: Self = Self::from_u32(bindings::LINUX_PR_SET_TSC);
42    pub const PR_GET_SECUREBITS: Self = Self::from_u32(bindings::LINUX_PR_GET_SECUREBITS);
43    pub const PR_SET_SECUREBITS: Self = Self::from_u32(bindings::LINUX_PR_SET_SECUREBITS);
44    pub const PR_SET_TIMERSLACK: Self = Self::from_u32(bindings::LINUX_PR_SET_TIMERSLACK);
45    pub const PR_GET_TIMERSLACK: Self = Self::from_u32(bindings::LINUX_PR_GET_TIMERSLACK);
46    pub const PR_TASK_PERF_EVENTS_DISABLE: Self =
47        Self::from_u32(bindings::LINUX_PR_TASK_PERF_EVENTS_DISABLE);
48    pub const PR_TASK_PERF_EVENTS_ENABLE: Self =
49        Self::from_u32(bindings::LINUX_PR_TASK_PERF_EVENTS_ENABLE);
50    pub const PR_MCE_KILL: Self = Self::from_u32(bindings::LINUX_PR_MCE_KILL);
51    pub const PR_SET_MM: Self = Self::from_u32(bindings::LINUX_PR_SET_MM);
52    pub const PR_MCE_KILL_GET: Self = Self::from_u32(bindings::LINUX_PR_MCE_KILL_GET);
53    pub const PR_SET_PTRACER: Self = Self::from_u32(bindings::LINUX_PR_SET_PTRACER);
54    pub const PR_SET_CHILD_SUBREAPER: Self = Self::from_u32(bindings::LINUX_PR_SET_CHILD_SUBREAPER);
55    pub const PR_GET_CHILD_SUBREAPER: Self = Self::from_u32(bindings::LINUX_PR_GET_CHILD_SUBREAPER);
56    pub const PR_SET_NO_NEW_PRIVS: Self = Self::from_u32(bindings::LINUX_PR_SET_NO_NEW_PRIVS);
57    pub const PR_GET_NO_NEW_PRIVS: Self = Self::from_u32(bindings::LINUX_PR_GET_NO_NEW_PRIVS);
58    pub const PR_GET_TID_ADDRESS: Self = Self::from_u32(bindings::LINUX_PR_GET_TID_ADDRESS);
59    pub const PR_SET_THP_DISABLE: Self = Self::from_u32(bindings::LINUX_PR_SET_THP_DISABLE);
60    pub const PR_GET_THP_DISABLE: Self = Self::from_u32(bindings::LINUX_PR_GET_THP_DISABLE);
61    pub const PR_MPX_ENABLE_MANAGEMENT: Self =
62        Self::from_u32(bindings::LINUX_PR_MPX_ENABLE_MANAGEMENT);
63    pub const PR_MPX_DISABLE_MANAGEMENT: Self =
64        Self::from_u32(bindings::LINUX_PR_MPX_DISABLE_MANAGEMENT);
65    pub const PR_SET_FP_MODE: Self = Self::from_u32(bindings::LINUX_PR_SET_FP_MODE);
66    pub const PR_GET_FP_MODE: Self = Self::from_u32(bindings::LINUX_PR_GET_FP_MODE);
67    pub const PR_CAP_AMBIENT: Self = Self::from_u32(bindings::LINUX_PR_CAP_AMBIENT);
68    pub const PR_SVE_SET_VL: Self = Self::from_u32(bindings::LINUX_PR_SVE_SET_VL);
69    pub const PR_SVE_GET_VL: Self = Self::from_u32(bindings::LINUX_PR_SVE_GET_VL);
70    pub const PR_GET_SPECULATION_CTRL: Self =
71        Self::from_u32(bindings::LINUX_PR_GET_SPECULATION_CTRL);
72    pub const PR_SET_SPECULATION_CTRL: Self =
73        Self::from_u32(bindings::LINUX_PR_SET_SPECULATION_CTRL);
74    pub const PR_PAC_RESET_KEYS: Self = Self::from_u32(bindings::LINUX_PR_PAC_RESET_KEYS);
75    pub const PR_SET_TAGGED_ADDR_CTRL: Self =
76        Self::from_u32(bindings::LINUX_PR_SET_TAGGED_ADDR_CTRL);
77    pub const PR_GET_TAGGED_ADDR_CTRL: Self =
78        Self::from_u32(bindings::LINUX_PR_GET_TAGGED_ADDR_CTRL);
79    pub const PR_SET_IO_FLUSHER: Self = Self::from_u32(bindings::LINUX_PR_SET_IO_FLUSHER);
80    pub const PR_GET_IO_FLUSHER: Self = Self::from_u32(bindings::LINUX_PR_GET_IO_FLUSHER);
81    pub const PR_SET_SYSCALL_USER_DISPATCH: Self =
82        Self::from_u32(bindings::LINUX_PR_SET_SYSCALL_USER_DISPATCH);
83    pub const PR_PAC_SET_ENABLED_KEYS: Self =
84        Self::from_u32(bindings::LINUX_PR_PAC_SET_ENABLED_KEYS);
85    pub const PR_PAC_GET_ENABLED_KEYS: Self =
86        Self::from_u32(bindings::LINUX_PR_PAC_GET_ENABLED_KEYS);
87    pub const PR_SCHED_CORE: Self = Self::from_u32(bindings::LINUX_PR_SCHED_CORE);
88    pub const PR_SME_SET_VL: Self = Self::from_u32(bindings::LINUX_PR_SME_SET_VL);
89    pub const PR_SME_GET_VL: Self = Self::from_u32(bindings::LINUX_PR_SME_GET_VL);
90    pub const PR_SET_MDWE: Self = Self::from_u32(bindings::LINUX_PR_SET_MDWE);
91    pub const PR_GET_MDWE: Self = Self::from_u32(bindings::LINUX_PR_GET_MDWE);
92    pub const PR_SET_VMA: Self = Self::from_u32(bindings::LINUX_PR_SET_VMA);
93    pub const PR_GET_AUXV: Self = Self::from_u32(bindings::LINUX_PR_GET_AUXV);
94    pub const PR_SET_MEMORY_MERGE: Self = Self::from_u32(bindings::LINUX_PR_SET_MEMORY_MERGE);
95    pub const PR_GET_MEMORY_MERGE: Self = Self::from_u32(bindings::LINUX_PR_GET_MEMORY_MERGE);
96    pub const PR_RISCV_V_SET_CONTROL: Self = Self::from_u32(bindings::LINUX_PR_RISCV_V_SET_CONTROL);
97    pub const PR_RISCV_V_GET_CONTROL: Self = Self::from_u32(bindings::LINUX_PR_RISCV_V_GET_CONTROL);
98    pub const PR_RISCV_SET_ICACHE_FLUSH_CTX: Self =
99        Self::from_u32(bindings::LINUX_PR_RISCV_SET_ICACHE_FLUSH_CTX);
100    pub const PR_PPC_GET_DEXCR: Self = Self::from_u32(bindings::LINUX_PR_PPC_GET_DEXCR);
101    pub const PR_PPC_SET_DEXCR: Self = Self::from_u32(bindings::LINUX_PR_PPC_SET_DEXCR);
102    // NOTE: only add prctl options here (not prctl args), and add new entries to `to_str` below
103
104    pub const fn new(val: i32) -> Self {
105        Self(val)
106    }
107
108    pub const fn val(&self) -> i32 {
109        self.0
110    }
111
112    const fn from_u32(val: u32) -> Self {
113        Self::new(const_conversions::i32_from_u32(val))
114    }
115
116    pub const fn to_str(&self) -> Option<&'static str> {
117        match *self {
118            Self::PR_SET_PDEATHSIG => Some("PR_SET_PDEATHSIG"),
119            Self::PR_GET_PDEATHSIG => Some("PR_GET_PDEATHSIG"),
120            Self::PR_GET_DUMPABLE => Some("PR_GET_DUMPABLE"),
121            Self::PR_SET_DUMPABLE => Some("PR_SET_DUMPABLE"),
122            Self::PR_GET_UNALIGN => Some("PR_GET_UNALIGN"),
123            Self::PR_SET_UNALIGN => Some("PR_SET_UNALIGN"),
124            Self::PR_GET_KEEPCAPS => Some("PR_GET_KEEPCAPS"),
125            Self::PR_SET_KEEPCAPS => Some("PR_SET_KEEPCAPS"),
126            Self::PR_GET_FPEMU => Some("PR_GET_FPEMU"),
127            Self::PR_SET_FPEMU => Some("PR_SET_FPEMU"),
128            Self::PR_GET_FPEXC => Some("PR_GET_FPEXC"),
129            Self::PR_SET_FPEXC => Some("PR_SET_FPEXC"),
130            Self::PR_GET_TIMING => Some("PR_GET_TIMING"),
131            Self::PR_SET_TIMING => Some("PR_SET_TIMING"),
132            Self::PR_SET_NAME => Some("PR_SET_NAME"),
133            Self::PR_GET_NAME => Some("PR_GET_NAME"),
134            Self::PR_GET_ENDIAN => Some("PR_GET_ENDIAN"),
135            Self::PR_SET_ENDIAN => Some("PR_SET_ENDIAN"),
136            Self::PR_GET_SECCOMP => Some("PR_GET_SECCOMP"),
137            Self::PR_SET_SECCOMP => Some("PR_SET_SECCOMP"),
138            Self::PR_CAPBSET_READ => Some("PR_CAPBSET_READ"),
139            Self::PR_CAPBSET_DROP => Some("PR_CAPBSET_DROP"),
140            Self::PR_GET_TSC => Some("PR_GET_TSC"),
141            Self::PR_SET_TSC => Some("PR_SET_TSC"),
142            Self::PR_GET_SECUREBITS => Some("PR_GET_SECUREBITS"),
143            Self::PR_SET_SECUREBITS => Some("PR_SET_SECUREBITS"),
144            Self::PR_SET_TIMERSLACK => Some("PR_SET_TIMERSLACK"),
145            Self::PR_GET_TIMERSLACK => Some("PR_GET_TIMERSLACK"),
146            Self::PR_TASK_PERF_EVENTS_DISABLE => Some("PR_TASK_PERF_EVENTS_DISABLE"),
147            Self::PR_TASK_PERF_EVENTS_ENABLE => Some("PR_TASK_PERF_EVENTS_ENABLE"),
148            Self::PR_MCE_KILL => Some("PR_MCE_KILL"),
149            Self::PR_SET_MM => Some("PR_SET_MM"),
150            Self::PR_SET_PTRACER => Some("PR_SET_PTRACER"),
151            Self::PR_SET_CHILD_SUBREAPER => Some("PR_SET_CHILD_SUBREAPER"),
152            Self::PR_GET_CHILD_SUBREAPER => Some("PR_GET_CHILD_SUBREAPER"),
153            Self::PR_SET_NO_NEW_PRIVS => Some("PR_SET_NO_NEW_PRIVS"),
154            Self::PR_GET_NO_NEW_PRIVS => Some("PR_GET_NO_NEW_PRIVS"),
155            Self::PR_GET_TID_ADDRESS => Some("PR_GET_TID_ADDRESS"),
156            Self::PR_SET_THP_DISABLE => Some("PR_SET_THP_DISABLE"),
157            Self::PR_GET_THP_DISABLE => Some("PR_GET_THP_DISABLE"),
158            Self::PR_MPX_ENABLE_MANAGEMENT => Some("PR_MPX_ENABLE_MANAGEMENT"),
159            Self::PR_MPX_DISABLE_MANAGEMENT => Some("PR_MPX_DISABLE_MANAGEMENT"),
160            Self::PR_SET_FP_MODE => Some("PR_SET_FP_MODE"),
161            Self::PR_GET_FP_MODE => Some("PR_GET_FP_MODE"),
162            Self::PR_CAP_AMBIENT => Some("PR_CAP_AMBIENT"),
163            Self::PR_SVE_SET_VL => Some("PR_SVE_SET_VL"),
164            Self::PR_SVE_GET_VL => Some("PR_SVE_GET_VL"),
165            Self::PR_GET_SPECULATION_CTRL => Some("PR_GET_SPECULATION_CTRL"),
166            Self::PR_SET_SPECULATION_CTRL => Some("PR_SET_SPECULATION_CTRL"),
167            Self::PR_PAC_RESET_KEYS => Some("PR_PAC_RESET_KEYS"),
168            Self::PR_SET_TAGGED_ADDR_CTRL => Some("PR_SET_TAGGED_ADDR_CTRL"),
169            Self::PR_GET_TAGGED_ADDR_CTRL => Some("PR_GET_TAGGED_ADDR_CTRL"),
170            Self::PR_SET_IO_FLUSHER => Some("PR_SET_IO_FLUSHER"),
171            Self::PR_GET_IO_FLUSHER => Some("PR_GET_IO_FLUSHER"),
172            Self::PR_SET_SYSCALL_USER_DISPATCH => Some("PR_SET_SYSCALL_USER_DISPATCH"),
173            Self::PR_PAC_SET_ENABLED_KEYS => Some("PR_PAC_SET_ENABLED_KEYS"),
174            Self::PR_PAC_GET_ENABLED_KEYS => Some("PR_PAC_GET_ENABLED_KEYS"),
175            Self::PR_SCHED_CORE => Some("PR_SCHED_CORE"),
176            Self::PR_SME_SET_VL => Some("PR_SME_SET_VL"),
177            Self::PR_SME_GET_VL => Some("PR_SME_GET_VL"),
178            Self::PR_SET_MDWE => Some("PR_SET_MDWE"),
179            Self::PR_GET_MDWE => Some("PR_GET_MDWE"),
180            Self::PR_SET_VMA => Some("PR_SET_VMA"),
181            Self::PR_GET_AUXV => Some("PR_GET_AUXV"),
182            Self::PR_SET_MEMORY_MERGE => Some("PR_SET_MEMORY_MERGE"),
183            Self::PR_GET_MEMORY_MERGE => Some("PR_GET_MEMORY_MERGE"),
184            Self::PR_RISCV_V_SET_CONTROL => Some("PR_RISCV_V_SET_CONTROL"),
185            Self::PR_RISCV_V_GET_CONTROL => Some("PR_RISCV_V_GET_CONTROL"),
186            Self::PR_RISCV_SET_ICACHE_FLUSH_CTX => Some("PR_RISCV_SET_ICACHE_FLUSH_CTX"),
187            Self::PR_PPC_GET_DEXCR => Some("PR_PPC_GET_DEXCR"),
188            Self::PR_PPC_SET_DEXCR => Some("PR_PPC_SET_DEXCR"),
189            _ => None,
190        }
191    }
192}
193
194impl core::fmt::Display for PrctlOp {
195    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
196        match self.to_str() {
197            Some(s) => formatter.write_str(s),
198            None => write!(formatter, "(unknown prctl option {})", self.0),
199        }
200    }
201}
202
203impl core::fmt::Debug for PrctlOp {
204    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
205        match self.to_str() {
206            Some(s) => write!(formatter, "PrctlOp::{s}"),
207            None => write!(formatter, "PrctlOp::<{}>", self.0),
208        }
209    }
210}
211
212impl From<PrctlOp> for i32 {
213    #[inline]
214    fn from(val: PrctlOp) -> Self {
215        val.0
216    }
217}
218
219impl From<i32> for PrctlOp {
220    #[inline]
221    fn from(val: i32) -> Self {
222        Self::new(val)
223    }
224}
225
226#[derive(PartialEq, Eq)]
227pub struct ArchPrctlOp(i32);
228
229impl ArchPrctlOp {
230    pub const ARCH_SET_CPUID: Self = Self::from_u32(bindings::LINUX_ARCH_SET_CPUID);
231    pub const ARCH_GET_CPUID: Self = Self::from_u32(bindings::LINUX_ARCH_GET_CPUID);
232    pub const ARCH_SET_FS: Self = Self::from_u32(bindings::LINUX_ARCH_SET_FS);
233    pub const ARCH_GET_FS: Self = Self::from_u32(bindings::LINUX_ARCH_GET_FS);
234    pub const ARCH_SET_GS: Self = Self::from_u32(bindings::LINUX_ARCH_SET_GS);
235    pub const ARCH_GET_GS: Self = Self::from_u32(bindings::LINUX_ARCH_GET_GS);
236    pub const ARCH_GET_XCOMP_SUPP: Self = Self::from_u32(bindings::LINUX_ARCH_GET_XCOMP_SUPP);
237    pub const ARCH_GET_XCOMP_PERM: Self = Self::from_u32(bindings::LINUX_ARCH_GET_XCOMP_PERM);
238    pub const ARCH_REQ_XCOMP_PERM: Self = Self::from_u32(bindings::LINUX_ARCH_REQ_XCOMP_PERM);
239    pub const ARCH_GET_XCOMP_GUEST_PERM: Self =
240        Self::from_u32(bindings::LINUX_ARCH_GET_XCOMP_GUEST_PERM);
241    pub const ARCH_REQ_XCOMP_GUEST_PERM: Self =
242        Self::from_u32(bindings::LINUX_ARCH_REQ_XCOMP_GUEST_PERM);
243    pub const ARCH_XCOMP_TILECFG: Self = Self::from_u32(bindings::LINUX_ARCH_XCOMP_TILECFG);
244    pub const ARCH_XCOMP_TILEDATA: Self = Self::from_u32(bindings::LINUX_ARCH_XCOMP_TILEDATA);
245    pub const ARCH_MAP_VDSO_X32: Self = Self::from_u32(bindings::LINUX_ARCH_MAP_VDSO_X32);
246    pub const ARCH_MAP_VDSO_32: Self = Self::from_u32(bindings::LINUX_ARCH_MAP_VDSO_32);
247    pub const ARCH_MAP_VDSO_64: Self = Self::from_u32(bindings::LINUX_ARCH_MAP_VDSO_64);
248    pub const ARCH_GET_UNTAG_MASK: Self = Self::from_u32(bindings::LINUX_ARCH_GET_UNTAG_MASK);
249    pub const ARCH_ENABLE_TAGGED_ADDR: Self =
250        Self::from_u32(bindings::LINUX_ARCH_ENABLE_TAGGED_ADDR);
251    pub const ARCH_GET_MAX_TAG_BITS: Self = Self::from_u32(bindings::LINUX_ARCH_GET_MAX_TAG_BITS);
252    pub const ARCH_FORCE_TAGGED_SVA: Self = Self::from_u32(bindings::LINUX_ARCH_FORCE_TAGGED_SVA);
253    pub const ARCH_SHSTK_ENABLE: Self = Self::from_u32(bindings::LINUX_ARCH_SHSTK_ENABLE);
254    pub const ARCH_SHSTK_DISABLE: Self = Self::from_u32(bindings::LINUX_ARCH_SHSTK_DISABLE);
255    pub const ARCH_SHSTK_LOCK: Self = Self::from_u32(bindings::LINUX_ARCH_SHSTK_LOCK);
256    pub const ARCH_SHSTK_UNLOCK: Self = Self::from_u32(bindings::LINUX_ARCH_SHSTK_UNLOCK);
257    pub const ARCH_SHSTK_STATUS: Self = Self::from_u32(bindings::LINUX_ARCH_SHSTK_STATUS);
258    pub const ARCH_SHSTK_SHSTK: Self = Self::from_u32(bindings::LINUX_ARCH_SHSTK_SHSTK);
259    pub const ARCH_SHSTK_WRSS: Self = Self::from_u32(bindings::LINUX_ARCH_SHSTK_WRSS);
260
261    pub const fn new(val: i32) -> Self {
262        Self(val)
263    }
264
265    const fn from_u32(val: u32) -> Self {
266        Self::new(const_conversions::i32_from_u32(val))
267    }
268
269    pub const fn to_str(&self) -> Option<&'static str> {
270        match *self {
271            Self::ARCH_SET_CPUID => Some("ARCH_SET_CPUID"),
272            Self::ARCH_GET_CPUID => Some("ARCH_GET_CPUID"),
273            Self::ARCH_GET_FS => Some("ARCH_GET_FS"),
274            Self::ARCH_SET_FS => Some("ARCH_SET_FS"),
275            Self::ARCH_GET_GS => Some("ARCH_GET_GS"),
276            Self::ARCH_SET_GS => Some("ARCH_SET_GS"),
277            Self::ARCH_GET_XCOMP_SUPP => Some("ARCH_GET_XCOMP_SUPP"),
278            Self::ARCH_GET_XCOMP_PERM => Some("ARCH_GET_XCOMP_PERM"),
279            Self::ARCH_REQ_XCOMP_PERM => Some("ARCH_REQ_XCOMP_PERM"),
280            Self::ARCH_GET_XCOMP_GUEST_PERM => Some("ARCH_GET_XCOMP_GUEST_PERM"),
281            Self::ARCH_REQ_XCOMP_GUEST_PERM => Some("ARCH_REQ_XCOMP_GUEST_PERM"),
282            Self::ARCH_XCOMP_TILECFG => Some("ARCH_XCOMP_TILECFG"),
283            Self::ARCH_XCOMP_TILEDATA => Some("ARCH_XCOMP_TILEDATA"),
284            Self::ARCH_MAP_VDSO_X32 => Some("ARCH_MAP_VDSO_X32"),
285            Self::ARCH_MAP_VDSO_32 => Some("ARCH_MAP_VDSO_32"),
286            Self::ARCH_MAP_VDSO_64 => Some("ARCH_MAP_VDSO_64"),
287            Self::ARCH_GET_UNTAG_MASK => Some("ARCH_GET_UNTAG_MASK"),
288            Self::ARCH_ENABLE_TAGGED_ADDR => Some("ARCH_ENABLE_TAGGED_ADDR"),
289            Self::ARCH_GET_MAX_TAG_BITS => Some("ARCH_GET_MAX_TAG_BITS"),
290            Self::ARCH_FORCE_TAGGED_SVA => Some("ARCH_FORCE_TAGGED_SVA"),
291            Self::ARCH_SHSTK_ENABLE => Some("ARCH_SHSTK_ENABLE"),
292            Self::ARCH_SHSTK_DISABLE => Some("ARCH_SHSTK_DISABLE"),
293            Self::ARCH_SHSTK_LOCK => Some("ARCH_SHSTK_LOCK"),
294            Self::ARCH_SHSTK_UNLOCK => Some("ARCH_SHSTK_UNLOCK"),
295            Self::ARCH_SHSTK_STATUS => Some("ARCH_SHSTK_STATUS"),
296            Self::ARCH_SHSTK_SHSTK => Some("ARCH_SHSTK_SHSTK"),
297            Self::ARCH_SHSTK_WRSS => Some("ARCH_SHSTK_WRSS"),
298            _ => None,
299        }
300    }
301}
302
303impl From<ArchPrctlOp> for core::ffi::c_int {
304    fn from(value: ArchPrctlOp) -> Self {
305        value.0
306    }
307}
308
309impl core::fmt::Display for ArchPrctlOp {
310    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
311        match self.to_str() {
312            Some(s) => formatter.write_str(s),
313            None => write!(formatter, "(unknown arch_prctl option {})", self.0),
314        }
315    }
316}
317
318impl core::fmt::Debug for ArchPrctlOp {
319    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
320        match self.to_str() {
321            Some(s) => write!(formatter, "ArchPrctlOp::{s}"),
322            None => write!(formatter, "ArchPrctlOp::<{}>", self.0),
323        }
324    }
325}
326
327/// Execute the `arch_prctl` syscall.
328///
329/// # Safety
330///
331/// Some operations may change OS behavior in a way that violates assumptions
332/// that other code relies on.
333pub unsafe fn arch_prctl_raw(
334    option: core::ffi::c_int,
335    arg2: core::ffi::c_ulong,
336) -> Result<i64, Errno> {
337    unsafe { syscall!(linux_syscall::SYS_arch_prctl, option, arg2) }
338        .try_i64()
339        .map_err(Errno::from)
340}
341
342/// Execute the `arch_prctl` syscall.
343///
344/// # Safety
345///
346/// Some operations may change OS behavior in a way that violates assumptions
347/// that other code relies on.
348pub unsafe fn arch_prctl(option: ArchPrctlOp, arg2: u64) -> Result<i64, Errno> {
349    unsafe { arch_prctl_raw(option.into(), arg2) }
350}