summaryrefslogtreecommitdiffstats
path: root/vendor/rustix/src/backend/linux_raw/param/auxv.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/rustix/src/backend/linux_raw/param/auxv.rs')
-rw-r--r--vendor/rustix/src/backend/linux_raw/param/auxv.rs81
1 files changed, 56 insertions, 25 deletions
diff --git a/vendor/rustix/src/backend/linux_raw/param/auxv.rs b/vendor/rustix/src/backend/linux_raw/param/auxv.rs
index 741a0564f..bf8935a0d 100644
--- a/vendor/rustix/src/backend/linux_raw/param/auxv.rs
+++ b/vendor/rustix/src/backend/linux_raw/param/auxv.rs
@@ -5,12 +5,11 @@
//! This uses raw pointers to locate and read the kernel-provided auxv array.
#![allow(unsafe_code)]
-use super::super::c;
-use super::super::elf::*;
+use crate::backend::c;
+use crate::backend::elf::*;
use crate::fd::OwnedFd;
#[cfg(feature = "param")]
use crate::ffi::CStr;
-#[cfg(not(target_vendor = "mustang"))]
use crate::fs::{Mode, OFlags};
use crate::utils::{as_ptr, check_raw_pointer};
use alloc::vec::Vec;
@@ -32,7 +31,7 @@ pub(crate) fn page_size() -> usize {
let mut page_size = PAGE_SIZE.load(Relaxed);
if page_size == 0 {
- init_from_proc_self_auxv();
+ init_auxv();
page_size = PAGE_SIZE.load(Relaxed);
}
@@ -45,7 +44,7 @@ pub(crate) fn clock_ticks_per_second() -> u64 {
let mut ticks = CLOCK_TICKS_PER_SECOND.load(Relaxed);
if ticks == 0 {
- init_from_proc_self_auxv();
+ init_auxv();
ticks = CLOCK_TICKS_PER_SECOND.load(Relaxed);
}
@@ -59,7 +58,7 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
let mut hwcap2 = HWCAP2.load(Relaxed);
if hwcap == 0 || hwcap2 == 0 {
- init_from_proc_self_auxv();
+ init_auxv();
hwcap = HWCAP.load(Relaxed);
hwcap2 = HWCAP2.load(Relaxed);
}
@@ -73,7 +72,7 @@ pub(crate) fn linux_execfn() -> &'static CStr {
let mut execfn = EXECFN.load(Relaxed);
if execfn.is_null() {
- init_from_proc_self_auxv();
+ init_auxv();
execfn = EXECFN.load(Relaxed);
}
@@ -89,7 +88,7 @@ pub(crate) fn exe_phdrs() -> (*const c::c_void, usize) {
let mut phnum = PHNUM.load(Relaxed);
if phdr.is_null() || phnum == 0 {
- init_from_proc_self_auxv();
+ init_auxv();
phdr = PHDR.load(Relaxed);
phnum = PHNUM.load(Relaxed);
}
@@ -114,7 +113,7 @@ pub(in super::super) fn sysinfo_ehdr() -> *const Elf_Ehdr {
let mut ehdr = SYSINFO_EHDR.load(Relaxed);
if ehdr.is_null() {
- init_from_proc_self_auxv();
+ init_auxv();
ehdr = SYSINFO_EHDR.load(Relaxed);
}
@@ -130,29 +129,61 @@ static PHDR: AtomicPtr<Elf_Phdr> = AtomicPtr::new(null_mut());
static PHNUM: AtomicUsize = AtomicUsize::new(0);
static EXECFN: AtomicPtr<c::c_char> = AtomicPtr::new(null_mut());
-/// On non-Mustang platforms, we read the aux vector from /proc/self/auxv.
-#[cfg(not(target_vendor = "mustang"))]
-fn init_from_proc_self_auxv() {
+fn pr_get_auxv() -> crate::io::Result<Vec<u8>> {
+ use super::super::conv::{c_int, pass_usize, ret_usize};
+ const PR_GET_AUXV: c::c_int = 0x41555856;
+ let mut buffer = alloc::vec![0u8; 512];
+ let len = unsafe {
+ ret_usize(syscall_always_asm!(
+ __NR_prctl,
+ c_int(PR_GET_AUXV),
+ buffer.as_ptr(),
+ pass_usize(buffer.len())
+ ))?
+ };
+ if len <= buffer.len() {
+ buffer.truncate(len);
+ return Ok(buffer);
+ }
+ buffer.resize(len, 0);
+ let len = unsafe {
+ ret_usize(syscall_always_asm!(
+ __NR_prctl,
+ c_int(PR_GET_AUXV),
+ buffer.as_ptr(),
+ pass_usize(buffer.len())
+ ))?
+ };
+ assert_eq!(len, buffer.len());
+ return Ok(buffer);
+}
+
+/// On non-Mustang platforms, we read the aux vector via the `prctl`
+/// `PR_GET_AUXV`, with a fallback to /proc/self/auxv for kernels that don't
+/// support `PR_GET_AUXV`.
+fn init_auxv() {
+ match pr_get_auxv() {
+ Ok(buffer) => {
+ // SAFETY: We assume the kernel returns a valid auxv.
+ unsafe {
+ init_from_auxp(buffer.as_ptr().cast());
+ }
+ return;
+ }
+ Err(_) => {
+ // Fall back to /proc/self/auxv on error.
+ }
+ }
+
// Open "/proc/self/auxv", either because we trust "/proc", or because
// we're running inside QEMU and `proc_self_auxv`'s extra checking foils
// QEMU's emulation so we need to do a plain open to get the right
// auxv records.
- let file = crate::fs::openat(
- crate::fs::cwd(),
- "/proc/self/auxv",
- OFlags::empty(),
- Mode::empty(),
- )
- .unwrap();
+ let file = crate::fs::open("/proc/self/auxv", OFlags::RDONLY, Mode::empty()).unwrap();
let _ = init_from_auxv_file(file);
}
-#[cfg(target_vendor = "mustang")]
-fn init_from_proc_self_auxv() {
- panic!("mustang should have initialized the auxv values");
-}
-
/// Process auxv entries from the open file `auxv`.
fn init_from_auxv_file(auxv: OwnedFd) -> Option<()> {
let mut buffer = Vec::<u8>::with_capacity(512);
@@ -276,7 +307,7 @@ unsafe fn check_vdso_base(base: *const Elf_Ehdr) -> Option<NonNull<Elf_Ehdr>> {
// as an arbitrary system call which writes to a buffer and fails with
// `EFAULT` if the buffer is not writable.
{
- use super::super::conv::{c_uint, ret};
+ use crate::backend::conv::{c_uint, ret};
if ret(syscall!(
__NR_clock_getres,
c_uint(linux_raw_sys::general::CLOCK_MONOTONIC),