Fix `use-libc-auxv` to use a weak dependency on `getauxval`. (#535) · bytecodealliance/rustix@04c1ef2 · GitHub
Skip to content

Commit 04c1ef2

Browse files
committed
Fix use-libc-auxv to use a weak dependency on getauxval. (#535)
* Fix `use-libc-auxv` to use a weak dependency on `getauxval`. glibc <= 2.15 lacks `getauxval`, so avoid a strong dependency on it in the `use-libc-auxv` implementation.
1 parent 1200c6b commit 04c1ef2

3 files changed

Lines changed: 256 additions & 14 deletions

File tree

‎src/backend/linux_raw/mod.rs‎

Lines changed: 5 additions & 0 deletions

‎src/backend/linux_raw/param/libc_auxv.rs‎

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
//! This uses raw pointers to locate and read the kernel-provided auxv array.
66
#![allow(unsafe_code)]
77

8-
#[cfg(any(feature = "param", feature = "runtime"))]
9-
use super::super::c;
108
use super::super::elf::*;
119
#[cfg(feature = "param")]
1210
use crate::ffi::CStr;
1311
#[cfg(feature = "runtime")]
1412
use core::slice;
1513

14+
// `getauxval` wasn't supported in glibc until 2.16.
15+
weak!(fn getauxval(libc::c_ulong) -> *mut libc::c_void);
16+
1617
#[cfg(feature = "param")]
1718
#[inline]
1819
pub(crate) fn page_size() -> usize {
@@ -22,35 +23,39 @@ pub(crate) fn page_size() -> usize {
2223
#[cfg(feature = "param")]
2324
#[inline]
2425
pub(crate) fn clock_ticks_per_second() -> u64 {
25-
unsafe { libc::getauxval(libc::AT_CLKTCK) as u64 }
26+
unsafe { libc::sysconf(libc::_SC_CLK_TCK) as u64 }
2627
}
2728

2829
#[cfg(feature = "param")]
2930
#[inline]
3031
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-
)
32+
if let Some(libc_getauxval) = getauxval.get() {
33+
unsafe {
34+
let hwcap = libc_getauxval(libc::AT_HWCAP) as usize;
35+
let hwcap2 = libc_getauxval(libc::AT_HWCAP2) as usize;
36+
(hwcap, hwcap2)
37+
}
38+
} else {
39+
(0, 0)
3640
}
3741
}
3842

3943
#[cfg(feature = "param")]
4044
#[inline]
4145
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())
46+
if let Some(libc_getauxval) = getauxval.get() {
47+
unsafe { CStr::from_ptr(libc_getauxval(libc::AT_EXECFN).cast()) }
48+
} else {
49+
cstr!("")
4550
}
4651
}
4752

4853
#[cfg(feature = "runtime")]
4954
#[inline]
50-
pub(crate) fn exe_phdrs() -> (*const c::c_void, usize) {
55+
pub(crate) fn exe_phdrs() -> (*const libc::c_void, usize) {
5156
unsafe {
5257
(
53-
libc::getauxval(libc::AT_PHDR) as *const c::c_void,
58+
libc::getauxval(libc::AT_PHDR) as *const libc::c_void,
5459
libc::getauxval(libc::AT_PHNUM) as usize,
5560
)
5661
}
@@ -70,5 +75,9 @@ pub(in super::super) fn exe_phdrs_slice() -> &'static [Elf_Phdr] {
7075
/// so if we don't see it, this function returns a null pointer.
7176
#[inline]
7277
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 }
78+
if let Some(libc_getauxval) = getauxval.get() {
79+
unsafe { libc_getauxval(linux_raw_sys::general::AT_SYSINFO_EHDR.into()) as *const Elf_Ehdr }
80+
} else {
81+
core::ptr::null()
82+
}
7483
}

‎src/backend/linux_raw/weak.rs‎

Lines changed: 228 additions & 0 deletions

0 commit comments

Comments
 (0)