1 //! Linux auxv support, using libc.
2 //!
3 //! # Safety
4 //!
5 //! This uses raw pointers to locate and read the kernel-provided auxv array.
6 #![allow(unsafe_code)]
7
8 #[cfg(any(feature = "param", feature = "runtime"))]
9 use super::super::c;
10 use super::super::elf::*;
11 #[cfg(feature = "param")]
12 use crate::ffi::CStr;
13 #[cfg(feature = "runtime")]
14 use core::slice;
15
16 #[cfg(feature = "param")]
17 #[inline]
page_size() -> usize18 pub(crate) fn page_size() -> usize {
19 unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }
20 }
21
22 #[cfg(feature = "param")]
23 #[inline]
clock_ticks_per_second() -> u6424 pub(crate) fn clock_ticks_per_second() -> u64 {
25 unsafe { libc::getauxval(libc::AT_CLKTCK) as u64 }
26 }
27
28 #[cfg(feature = "param")]
29 #[inline]
linux_hwcap() -> (usize, usize)30 pub(crate) fn linux_hwcap() -> (usize, usize) {
31 unsafe {
32 (
33 libc::getauxval(libc::AT_HWCAP) as usize,
34 libc::getauxval(libc::AT_HWCAP2) as usize,
35 )
36 }
37 }
38
39 #[cfg(feature = "param")]
40 #[inline]
linux_execfn() -> &'static CStr41 pub(crate) fn linux_execfn() -> &'static CStr {
42 unsafe {
43 let execfn = libc::getauxval(libc::AT_EXECFN) as *const c::c_char;
44 CStr::from_ptr(execfn.cast())
45 }
46 }
47
48 #[cfg(feature = "runtime")]
49 #[inline]
exe_phdrs() -> (*const c::c_void, usize)50 pub(crate) fn exe_phdrs() -> (*const c::c_void, usize) {
51 unsafe {
52 (
53 libc::getauxval(libc::AT_PHDR) as *const c::c_void,
54 libc::getauxval(libc::AT_PHNUM) as usize,
55 )
56 }
57 }
58
59 #[cfg(feature = "runtime")]
60 #[inline]
exe_phdrs_slice() -> &'static [Elf_Phdr]61 pub(in super::super) fn exe_phdrs_slice() -> &'static [Elf_Phdr] {
62 let (phdr, phnum) = exe_phdrs();
63
64 // Safety: We assume the `AT_PHDR` and `AT_PHNUM` values provided by the
65 // kernel form a valid slice.
66 unsafe { slice::from_raw_parts(phdr.cast(), phnum) }
67 }
68
69 /// `AT_SYSINFO_EHDR` isn't present on all platforms in all configurations,
70 /// so if we don't see it, this function returns a null pointer.
71 #[inline]
sysinfo_ehdr() -> *const Elf_Ehdr72 pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr {
73 unsafe { libc::getauxval(linux_raw_sys::general::AT_SYSINFO_EHDR.into()) as *const Elf_Ehdr }
74 }
75