Skip to content

Commit

Permalink
Add ELF aux vector AT_MINSIGSTKSZ (#1041)
Browse files Browse the repository at this point in the history
  • Loading branch information
ur4t committed Apr 1, 2024
1 parent 7077238 commit 6f72de5
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 4 deletions.
15 changes: 15 additions & 0 deletions src/backend/libc/param/auxv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,21 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
}
}

#[cfg(any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux",
))]
#[inline]
pub(crate) fn linux_minsigstksz() -> usize {
// FIXME: reuse const from libc when available?
const AT_MINSIGSTKSZ: c::c_ulong = 51;
if let Some(libc_getauxval) = getauxval.get() {
unsafe { libc_getauxval(AT_MINSIGSTKSZ) as usize }
} else {
0
}
}

#[cfg(any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux",
Expand Down
19 changes: 18 additions & 1 deletion src/backend/linux_raw/param/auxv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use core::sync::atomic::Ordering::Relaxed;
use core::sync::atomic::{AtomicPtr, AtomicUsize};
use linux_raw_sys::elf::*;
use linux_raw_sys::general::{
AT_BASE, AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR,
AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_MINSIGSTKSZ, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR,
};
#[cfg(feature = "runtime")]
use linux_raw_sys::general::{
Expand Down Expand Up @@ -72,6 +72,19 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
(hwcap, hwcap2)
}

#[cfg(feature = "param")]
#[inline]
pub(crate) fn linux_minsigstksz() -> usize {
let mut minsigstksz = MINSIGSTKSZ.load(Relaxed);

if minsigstksz == 0 {
init_auxv();
minsigstksz = MINSIGSTKSZ.load(Relaxed);
}

minsigstksz
}

#[cfg(feature = "param")]
#[inline]
pub(crate) fn linux_execfn() -> &'static CStr {
Expand Down Expand Up @@ -172,6 +185,7 @@ static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);
static CLOCK_TICKS_PER_SECOND: AtomicUsize = AtomicUsize::new(0);
static HWCAP: AtomicUsize = AtomicUsize::new(0);
static HWCAP2: AtomicUsize = AtomicUsize::new(0);
static MINSIGSTKSZ: AtomicUsize = AtomicUsize::new(0);
static EXECFN: AtomicPtr<c::c_char> = AtomicPtr::new(null_mut());
static SYSINFO_EHDR: AtomicPtr<Elf_Ehdr> = AtomicPtr::new(null_mut());
#[cfg(feature = "runtime")]
Expand Down Expand Up @@ -351,6 +365,7 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
let mut clktck = 0;
let mut hwcap = 0;
let mut hwcap2 = 0;
let mut minsigstksz = 0;
let mut execfn = null_mut();
let mut sysinfo_ehdr = null_mut();
#[cfg(feature = "runtime")]
Expand Down Expand Up @@ -380,6 +395,7 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
AT_CLKTCK => clktck = a_val as usize,
AT_HWCAP => hwcap = a_val as usize,
AT_HWCAP2 => hwcap2 = a_val as usize,
AT_MINSIGSTKSZ => minsigstksz = a_val as usize,
AT_EXECFN => execfn = check_raw_pointer::<c::c_char>(a_val as *mut _)?.as_ptr(),
AT_SYSINFO_EHDR => sysinfo_ehdr = check_elf_base(a_val as *mut _)?.as_ptr(),

Expand Down Expand Up @@ -434,6 +450,7 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
CLOCK_TICKS_PER_SECOND.store(clktck, Relaxed);
HWCAP.store(hwcap, Relaxed);
HWCAP2.store(hwcap2, Relaxed);
MINSIGSTKSZ.store(minsigstksz, Relaxed);
EXECFN.store(execfn, Relaxed);
SYSINFO_EHDR.store(sysinfo_ehdr, Relaxed);
#[cfg(feature = "runtime")]
Expand Down
10 changes: 9 additions & 1 deletion src/backend/linux_raw/param/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use core::sync::atomic::AtomicBool;
use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
use linux_raw_sys::elf::*;
use linux_raw_sys::general::{
AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR,
AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_MINSIGSTKSZ, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR,
};
#[cfg(feature = "runtime")]
use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM, AT_RANDOM, AT_SECURE};
Expand Down Expand Up @@ -43,6 +43,12 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
}
}

#[cfg(feature = "param")]
#[inline]
pub(crate) fn linux_minsigstksz() -> usize {
unsafe { MINSIGSTKSZ.load(Ordering::Relaxed) }
}

#[cfg(feature = "param")]
#[inline]
pub(crate) fn linux_execfn() -> &'static CStr {
Expand Down Expand Up @@ -94,6 +100,7 @@ static mut PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);
static mut CLOCK_TICKS_PER_SECOND: AtomicUsize = AtomicUsize::new(0);
static mut HWCAP: AtomicUsize = AtomicUsize::new(0);
static mut HWCAP2: AtomicUsize = AtomicUsize::new(0);
static mut MINSIGSTKSZ: AtomicUsize = AtomicUsize::new(0);
static mut SYSINFO_EHDR: AtomicPtr<Elf_Ehdr> = AtomicPtr::new(null_mut());
// Initialize `EXECFN` to a valid `CStr` pointer so that we don't need to check
// for null on every `execfn` call.
Expand Down Expand Up @@ -147,6 +154,7 @@ unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) {
AT_CLKTCK => CLOCK_TICKS_PER_SECOND.store(a_val as usize, Ordering::Relaxed),
AT_HWCAP => HWCAP.store(a_val as usize, Ordering::Relaxed),
AT_HWCAP2 => HWCAP2.store(a_val as usize, Ordering::Relaxed),
AT_MINSIGSTKSZ => MINSIGSTKSZ.store(a_val as usize, Ordering::Relaxed),
AT_EXECFN => EXECFN.store(a_val.cast::<c::c_char>(), Ordering::Relaxed),
AT_SYSINFO_EHDR => SYSINFO_EHDR.store(a_val.cast::<Elf_Ehdr>(), Ordering::Relaxed),

Expand Down
19 changes: 19 additions & 0 deletions src/backend/linux_raw/param/libc_auxv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,25 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
}
}

#[cfg(feature = "param")]
#[inline]
pub(crate) fn linux_minsigstksz() -> usize {
// FIXME: reuse const from libc when available?
const AT_MINSIGSTKSZ: c::c_ulong = 51;

#[cfg(not(feature = "runtime"))]
if let Some(libc_getauxval) = getauxval.get() {
unsafe { libc_getauxval(AT_MINSIGSTKSZ) as usize }
} else {
0
}

#[cfg(feature = "runtime")]
unsafe {
getauxval(AT_MINSIGSTKSZ) as usize
}
}

#[cfg(feature = "param")]
#[inline]
pub(crate) fn linux_execfn() -> &'static CStr {
Expand Down
21 changes: 21 additions & 0 deletions src/param/auxv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,27 @@ pub fn linux_hwcap() -> (usize, usize) {
backend::param::auxv::linux_hwcap()
}

/// `getauxval(AT_MINSIGSTKSZ)`—Returns the Linux "minsigstksz" data.
///
/// Return the Linux `AT_MINSIGSTKSZ` value passed to the current process.
/// Returns 0 if it is not available.
///
/// # References
/// - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html
#[cfg(any(
linux_raw,
any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux",
)
))]
#[inline]
pub fn linux_minsigstksz() -> usize {
backend::param::auxv::linux_minsigstksz()
}

/// `getauxval(AT_EXECFN)`—Returns the Linux "execfn" string.
///
/// Return the string that Linux has recorded as the filesystem path to the
Expand Down
22 changes: 20 additions & 2 deletions tests/param/auxv.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use rustix::param::{clock_ticks_per_second, page_size};
#[cfg(any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux",
))]
use rustix::param::linux_hwcap;
use rustix::param::{clock_ticks_per_second, page_size};
use rustix::param::{linux_hwcap, linux_minsigstksz};

#[test]
fn test_page_size() {
Expand Down Expand Up @@ -39,3 +39,21 @@ fn test_linux_hwcap() {
assert_eq!(hwcap2, unsafe { libc_getauxval(libc::AT_HWCAP2) } as usize);
}
}

#[cfg(any(
all(target_os = "android", target_pointer_width = "64"),
target_os = "linux",
))]
#[test]
fn test_linux_minsigstksz() {
weak!(fn getauxval(libc::c_ulong) -> libc::c_ulong);

if let Some(libc_getauxval) = getauxval.get() {
// FIXME: reuse const from libc when available?
const AT_MINSIGSTKSZ: libc::c_ulong = 51;
assert_eq!(
linux_minsigstksz(),
unsafe { libc_getauxval(AT_MINSIGSTKSZ) } as usize
);
}
}

0 comments on commit 6f72de5

Please sign in to comment.