rustix/backend/linux_raw/param/
libc_auxv.rs
1#![allow(unsafe_code)]
7
8use crate::backend::c;
9#[cfg(feature = "param")]
10use crate::ffi::CStr;
11#[cfg(not(feature = "runtime"))]
12use core::ptr::null;
13use linux_raw_sys::elf::*;
14
15#[cfg(not(feature = "runtime"))]
18weak!(fn getauxval(c::c_ulong) -> *mut c::c_void);
19
20#[cfg(feature = "runtime")]
23extern "C" {
24 fn getauxval(type_: c::c_ulong) -> *mut c::c_void;
25}
26
27#[cfg(feature = "runtime")]
28const AT_PHDR: c::c_ulong = 3;
29#[cfg(feature = "runtime")]
30const AT_PHENT: c::c_ulong = 4;
31#[cfg(feature = "runtime")]
32const AT_PHNUM: c::c_ulong = 5;
33#[cfg(feature = "runtime")]
34const AT_ENTRY: c::c_ulong = 9;
35const AT_HWCAP: c::c_ulong = 16;
36#[cfg(feature = "runtime")]
37const AT_RANDOM: c::c_ulong = 25;
38const AT_HWCAP2: c::c_ulong = 26;
39const AT_SECURE: c::c_ulong = 23;
40const AT_EXECFN: c::c_ulong = 31;
41const AT_SYSINFO_EHDR: c::c_ulong = 33;
42const AT_MINSIGSTKSZ: c::c_ulong = 51;
43
44extern "C" {
47 fn sysconf(name: c::c_int) -> c::c_long;
48}
49
50#[cfg(target_os = "android")]
51const _SC_PAGESIZE: c::c_int = 39;
52#[cfg(target_os = "linux")]
53const _SC_PAGESIZE: c::c_int = 30;
54#[cfg(target_os = "android")]
55const _SC_CLK_TCK: c::c_int = 6;
56#[cfg(target_os = "linux")]
57const _SC_CLK_TCK: c::c_int = 2;
58
59#[test]
60fn test_abi() {
61 const_assert_eq!(self::_SC_PAGESIZE, ::libc::_SC_PAGESIZE);
62 const_assert_eq!(self::_SC_CLK_TCK, ::libc::_SC_CLK_TCK);
63 const_assert_eq!(self::AT_HWCAP, ::libc::AT_HWCAP);
64 const_assert_eq!(self::AT_HWCAP2, ::libc::AT_HWCAP2);
65 const_assert_eq!(self::AT_EXECFN, ::libc::AT_EXECFN);
66 const_assert_eq!(self::AT_SECURE, ::libc::AT_SECURE);
67 const_assert_eq!(self::AT_SYSINFO_EHDR, ::libc::AT_SYSINFO_EHDR);
68 const_assert_eq!(self::AT_MINSIGSTKSZ, ::libc::AT_MINSIGSTKSZ);
69 #[cfg(feature = "runtime")]
70 const_assert_eq!(self::AT_PHDR, ::libc::AT_PHDR);
71 #[cfg(feature = "runtime")]
72 const_assert_eq!(self::AT_PHNUM, ::libc::AT_PHNUM);
73 #[cfg(feature = "runtime")]
74 const_assert_eq!(self::AT_ENTRY, ::libc::AT_ENTRY);
75 #[cfg(feature = "runtime")]
76 const_assert_eq!(self::AT_RANDOM, ::libc::AT_RANDOM);
77}
78
79#[cfg(feature = "param")]
80#[inline]
81pub(crate) fn page_size() -> usize {
82 unsafe { sysconf(_SC_PAGESIZE) as usize }
83}
84
85#[cfg(feature = "param")]
86#[inline]
87pub(crate) fn clock_ticks_per_second() -> u64 {
88 unsafe { sysconf(_SC_CLK_TCK) as u64 }
89}
90
91#[cfg(feature = "param")]
92#[inline]
93pub(crate) fn linux_hwcap() -> (usize, usize) {
94 #[cfg(not(feature = "runtime"))]
95 unsafe {
96 if let Some(libc_getauxval) = getauxval.get() {
97 let hwcap = libc_getauxval(AT_HWCAP) as usize;
98 let hwcap2 = libc_getauxval(AT_HWCAP2) as usize;
99 (hwcap, hwcap2)
100 } else {
101 (0, 0)
102 }
103 }
104
105 #[cfg(feature = "runtime")]
106 unsafe {
107 let hwcap = getauxval(AT_HWCAP) as usize;
108 let hwcap2 = getauxval(AT_HWCAP2) as usize;
109 (hwcap, hwcap2)
110 }
111}
112
113#[cfg(feature = "param")]
114#[inline]
115pub(crate) fn linux_minsigstksz() -> usize {
116 #[cfg(not(feature = "runtime"))]
117 if let Some(libc_getauxval) = getauxval.get() {
118 unsafe { libc_getauxval(AT_MINSIGSTKSZ) as usize }
119 } else {
120 0
121 }
122
123 #[cfg(feature = "runtime")]
124 unsafe {
125 getauxval(AT_MINSIGSTKSZ) as usize
126 }
127}
128
129#[cfg(feature = "param")]
130#[inline]
131pub(crate) fn linux_execfn() -> &'static CStr {
132 #[cfg(not(feature = "runtime"))]
133 unsafe {
134 if let Some(libc_getauxval) = getauxval.get() {
135 CStr::from_ptr(libc_getauxval(AT_EXECFN).cast())
136 } else {
137 cstr!("")
138 }
139 }
140
141 #[cfg(feature = "runtime")]
142 unsafe {
143 CStr::from_ptr(getauxval(AT_EXECFN).cast())
144 }
145}
146
147#[cfg(feature = "runtime")]
148#[inline]
149pub(crate) fn linux_secure() -> bool {
150 unsafe { getauxval(AT_SECURE) as usize != 0 }
151}
152
153#[cfg(feature = "runtime")]
154#[inline]
155pub(crate) fn exe_phdrs() -> (*const c::c_void, usize, usize) {
156 unsafe {
157 let phdr = getauxval(AT_PHDR) as *const c::c_void;
158 let phent = getauxval(AT_PHENT) as usize;
159 let phnum = getauxval(AT_PHNUM) as usize;
160 (phdr, phent, phnum)
161 }
162}
163
164#[inline]
167pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr {
168 #[cfg(not(feature = "runtime"))]
169 unsafe {
170 if let Some(libc_getauxval) = getauxval.get() {
171 libc_getauxval(AT_SYSINFO_EHDR) as *const Elf_Ehdr
172 } else {
173 null()
174 }
175 }
176
177 #[cfg(feature = "runtime")]
178 unsafe {
179 getauxval(AT_SYSINFO_EHDR) as *const Elf_Ehdr
180 }
181}
182
183#[cfg(feature = "runtime")]
184#[inline]
185pub(crate) fn entry() -> usize {
186 unsafe { getauxval(AT_ENTRY) as usize }
187}
188
189#[cfg(feature = "runtime")]
190#[inline]
191pub(crate) fn random() -> *const [u8; 16] {
192 unsafe { getauxval(AT_RANDOM) as *const [u8; 16] }
193}