• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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