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] 18 pub(crate) fn page_size() -> usize { 19 unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize } 20 } 21 22 #[cfg(feature = "param")] 23 #[inline] 24 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] 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] 41 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] 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] 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] 72 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