Skip to content

Commit 6f72de5

Browse files
authored
Add ELF aux vector AT_MINSIGSTKSZ (bytecodealliance#1041)
1 parent 7077238 commit 6f72de5

File tree

6 files changed

+102
-4
lines changed

6 files changed

+102
-4
lines changed

src/backend/libc/param/auxv.rs

+15
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
4040
}
4141
}
4242

43+
#[cfg(any(
44+
all(target_os = "android", target_pointer_width = "64"),
45+
target_os = "linux",
46+
))]
47+
#[inline]
48+
pub(crate) fn linux_minsigstksz() -> usize {
49+
// FIXME: reuse const from libc when available?
50+
const AT_MINSIGSTKSZ: c::c_ulong = 51;
51+
if let Some(libc_getauxval) = getauxval.get() {
52+
unsafe { libc_getauxval(AT_MINSIGSTKSZ) as usize }
53+
} else {
54+
0
55+
}
56+
}
57+
4358
#[cfg(any(
4459
all(target_os = "android", target_pointer_width = "64"),
4560
target_os = "linux",

src/backend/linux_raw/param/auxv.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use core::sync::atomic::Ordering::Relaxed;
2222
use core::sync::atomic::{AtomicPtr, AtomicUsize};
2323
use linux_raw_sys::elf::*;
2424
use linux_raw_sys::general::{
25-
AT_BASE, AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR,
25+
AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_MINSIGSTKSZ, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR,
2626
};
2727
#[cfg(feature = "runtime")]
2828
use linux_raw_sys::general::{
@@ -72,6 +72,19 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
7272
(hwcap, hwcap2)
7373
}
7474

75+
#[cfg(feature = "param")]
76+
#[inline]
77+
pub(crate) fn linux_minsigstksz() -> usize {
78+
let mut minsigstksz = MINSIGSTKSZ.load(Relaxed);
79+
80+
if minsigstksz == 0 {
81+
init_auxv();
82+
minsigstksz = MINSIGSTKSZ.load(Relaxed);
83+
}
84+
85+
minsigstksz
86+
}
87+
7588
#[cfg(feature = "param")]
7689
#[inline]
7790
pub(crate) fn linux_execfn() -> &'static CStr {
@@ -172,6 +185,7 @@ static PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);
172185
static CLOCK_TICKS_PER_SECOND: AtomicUsize = AtomicUsize::new(0);
173186
static HWCAP: AtomicUsize = AtomicUsize::new(0);
174187
static HWCAP2: AtomicUsize = AtomicUsize::new(0);
188+
static MINSIGSTKSZ: AtomicUsize = AtomicUsize::new(0);
175189
static EXECFN: AtomicPtr<c::c_char> = AtomicPtr::new(null_mut());
176190
static SYSINFO_EHDR: AtomicPtr<Elf_Ehdr> = AtomicPtr::new(null_mut());
177191
#[cfg(feature = "runtime")]
@@ -351,6 +365,7 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
351365
let mut clktck = 0;
352366
let mut hwcap = 0;
353367
let mut hwcap2 = 0;
368+
let mut minsigstksz = 0;
354369
let mut execfn = null_mut();
355370
let mut sysinfo_ehdr = null_mut();
356371
#[cfg(feature = "runtime")]
@@ -380,6 +395,7 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
380395
AT_CLKTCK => clktck = a_val as usize,
381396
AT_HWCAP => hwcap = a_val as usize,
382397
AT_HWCAP2 => hwcap2 = a_val as usize,
398+
AT_MINSIGSTKSZ => minsigstksz = a_val as usize,
383399
AT_EXECFN => execfn = check_raw_pointer::<c::c_char>(a_val as *mut _)?.as_ptr(),
384400
AT_SYSINFO_EHDR => sysinfo_ehdr = check_elf_base(a_val as *mut _)?.as_ptr(),
385401

@@ -434,6 +450,7 @@ unsafe fn init_from_aux_iter(aux_iter: impl Iterator<Item = Elf_auxv_t>) -> Opti
434450
CLOCK_TICKS_PER_SECOND.store(clktck, Relaxed);
435451
HWCAP.store(hwcap, Relaxed);
436452
HWCAP2.store(hwcap2, Relaxed);
453+
MINSIGSTKSZ.store(minsigstksz, Relaxed);
437454
EXECFN.store(execfn, Relaxed);
438455
SYSINFO_EHDR.store(sysinfo_ehdr, Relaxed);
439456
#[cfg(feature = "runtime")]

src/backend/linux_raw/param/init.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use core::sync::atomic::AtomicBool;
1515
use core::sync::atomic::{AtomicPtr, AtomicUsize, Ordering};
1616
use linux_raw_sys::elf::*;
1717
use linux_raw_sys::general::{
18-
AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR,
18+
AT_CLKTCK, AT_EXECFN, AT_HWCAP, AT_HWCAP2, AT_MINSIGSTKSZ, AT_NULL, AT_PAGESZ, AT_SYSINFO_EHDR,
1919
};
2020
#[cfg(feature = "runtime")]
2121
use linux_raw_sys::general::{AT_ENTRY, AT_PHDR, AT_PHENT, AT_PHNUM, AT_RANDOM, AT_SECURE};
@@ -43,6 +43,12 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
4343
}
4444
}
4545

46+
#[cfg(feature = "param")]
47+
#[inline]
48+
pub(crate) fn linux_minsigstksz() -> usize {
49+
unsafe { MINSIGSTKSZ.load(Ordering::Relaxed) }
50+
}
51+
4652
#[cfg(feature = "param")]
4753
#[inline]
4854
pub(crate) fn linux_execfn() -> &'static CStr {
@@ -94,6 +100,7 @@ static mut PAGE_SIZE: AtomicUsize = AtomicUsize::new(0);
94100
static mut CLOCK_TICKS_PER_SECOND: AtomicUsize = AtomicUsize::new(0);
95101
static mut HWCAP: AtomicUsize = AtomicUsize::new(0);
96102
static mut HWCAP2: AtomicUsize = AtomicUsize::new(0);
103+
static mut MINSIGSTKSZ: AtomicUsize = AtomicUsize::new(0);
97104
static mut SYSINFO_EHDR: AtomicPtr<Elf_Ehdr> = AtomicPtr::new(null_mut());
98105
// Initialize `EXECFN` to a valid `CStr` pointer so that we don't need to check
99106
// for null on every `execfn` call.
@@ -147,6 +154,7 @@ unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) {
147154
AT_CLKTCK => CLOCK_TICKS_PER_SECOND.store(a_val as usize, Ordering::Relaxed),
148155
AT_HWCAP => HWCAP.store(a_val as usize, Ordering::Relaxed),
149156
AT_HWCAP2 => HWCAP2.store(a_val as usize, Ordering::Relaxed),
157+
AT_MINSIGSTKSZ => MINSIGSTKSZ.store(a_val as usize, Ordering::Relaxed),
150158
AT_EXECFN => EXECFN.store(a_val.cast::<c::c_char>(), Ordering::Relaxed),
151159
AT_SYSINFO_EHDR => SYSINFO_EHDR.store(a_val.cast::<Elf_Ehdr>(), Ordering::Relaxed),
152160

src/backend/linux_raw/param/libc_auxv.rs

+19
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,25 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
108108
}
109109
}
110110

111+
#[cfg(feature = "param")]
112+
#[inline]
113+
pub(crate) fn linux_minsigstksz() -> usize {
114+
// FIXME: reuse const from libc when available?
115+
const AT_MINSIGSTKSZ: c::c_ulong = 51;
116+
117+
#[cfg(not(feature = "runtime"))]
118+
if let Some(libc_getauxval) = getauxval.get() {
119+
unsafe { libc_getauxval(AT_MINSIGSTKSZ) as usize }
120+
} else {
121+
0
122+
}
123+
124+
#[cfg(feature = "runtime")]
125+
unsafe {
126+
getauxval(AT_MINSIGSTKSZ) as usize
127+
}
128+
}
129+
111130
#[cfg(feature = "param")]
112131
#[inline]
113132
pub(crate) fn linux_execfn() -> &'static CStr {

src/param/auxv.rs

+21
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,27 @@ pub fn linux_hwcap() -> (usize, usize) {
6565
backend::param::auxv::linux_hwcap()
6666
}
6767

68+
/// `getauxval(AT_MINSIGSTKSZ)`—Returns the Linux "minsigstksz" data.
69+
///
70+
/// Return the Linux `AT_MINSIGSTKSZ` value passed to the current process.
71+
/// Returns 0 if it is not available.
72+
///
73+
/// # References
74+
/// - [Linux]
75+
///
76+
/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html
77+
#[cfg(any(
78+
linux_raw,
79+
any(
80+
all(target_os = "android", target_pointer_width = "64"),
81+
target_os = "linux",
82+
)
83+
))]
84+
#[inline]
85+
pub fn linux_minsigstksz() -> usize {
86+
backend::param::auxv::linux_minsigstksz()
87+
}
88+
6889
/// `getauxval(AT_EXECFN)`—Returns the Linux "execfn" string.
6990
///
7091
/// Return the string that Linux has recorded as the filesystem path to the

tests/param/auxv.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1+
use rustix::param::{clock_ticks_per_second, page_size};
12
#[cfg(any(
23
all(target_os = "android", target_pointer_width = "64"),
34
target_os = "linux",
45
))]
5-
use rustix::param::linux_hwcap;
6-
use rustix::param::{clock_ticks_per_second, page_size};
6+
use rustix::param::{linux_hwcap, linux_minsigstksz};
77

88
#[test]
99
fn test_page_size() {
@@ -39,3 +39,21 @@ fn test_linux_hwcap() {
3939
assert_eq!(hwcap2, unsafe { libc_getauxval(libc::AT_HWCAP2) } as usize);
4040
}
4141
}
42+
43+
#[cfg(any(
44+
all(target_os = "android", target_pointer_width = "64"),
45+
target_os = "linux",
46+
))]
47+
#[test]
48+
fn test_linux_minsigstksz() {
49+
weak!(fn getauxval(libc::c_ulong) -> libc::c_ulong);
50+
51+
if let Some(libc_getauxval) = getauxval.get() {
52+
// FIXME: reuse const from libc when available?
53+
const AT_MINSIGSTKSZ: libc::c_ulong = 51;
54+
assert_eq!(
55+
linux_minsigstksz(),
56+
unsafe { libc_getauxval(AT_MINSIGSTKSZ) } as usize
57+
);
58+
}
59+
}

0 commit comments

Comments
 (0)