Implement linux_execfn, exposing AT_EXECFN.

This commit is contained in:
Dan Gohman
2021-09-29 15:26:44 -07:00
parent 5a7b4cb6d5
commit dc4e93d469
7 changed files with 44 additions and 5 deletions
+2
View File
@@ -80,5 +80,7 @@ fn main() -> io::Result<()> {
target_os = "openbsd",
)))]
println!("Rttime Limit: {:?}", getrlimit(Resource::Rttime));
#[cfg(any(target_os = "android", target_os = "linux"))]
println!("Execfn: {:?}", linux_execfn());
Ok(())
}
+11
View File
@@ -1,3 +1,8 @@
#[cfg(any(target_os = "android", target_os = "linux"))]
use libc::c_char;
#[cfg(any(target_os = "android", target_os = "linux"))]
use std::ffi::CStr;
#[inline]
pub(crate) fn page_size() -> usize {
unsafe { libc::sysconf(libc::_SC_PAGESIZE) as usize }
@@ -12,3 +17,9 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
(hwcap, hwcap2)
}
}
#[cfg(any(target_os = "android", target_os = "linux"))]
#[inline]
pub(crate) fn linux_execfn() -> &'static CStr {
unsafe { CStr::from_ptr(libc::getauxval(libc::AT_EXECFN) as *const c_char) }
}
+2 -2
View File
@@ -1,9 +1,9 @@
mod auxv;
mod types;
#[cfg(any(target_os = "android", target_os = "linux"))]
pub(crate) use auxv::linux_hwcap;
pub(crate) use auxv::page_size;
#[cfg(any(target_os = "android", target_os = "linux"))]
pub(crate) use auxv::{linux_execfn, linux_hwcap};
#[cfg(not(any(target_os = "fuchsia", target_os = "redox", target_os = "wasi")))]
pub use types::Resource;
#[cfg(any(target_os = "android", target_os = "linux"))]
+10 -1
View File
@@ -6,13 +6,14 @@
#![allow(unsafe_code)]
use super::super::elf::Elf_Phdr;
use linux_raw_sys::general::{AT_HWCAP, AT_NULL, AT_PAGESZ, AT_PHDR, AT_PHENT, AT_PHNUM};
use linux_raw_sys::general::{AT_HWCAP, AT_NULL, AT_PAGESZ, AT_PHDR, AT_PHENT, AT_PHNUM, AT_EXECFN};
use linux_raw_sys::v5_4::general::{AT_HWCAP2, AT_SYSINFO_EHDR};
use std::mem::size_of;
use std::os::raw::c_char;
#[cfg(target_env = "gnu")]
use std::os::raw::c_int;
use std::slice;
use std::ffi::CStr;
#[inline]
pub(crate) fn page_size() -> usize {
@@ -25,6 +26,11 @@ pub(crate) fn linux_hwcap() -> (usize, usize) {
(auxv.hwcap, auxv.hwcap2)
}
#[inline]
pub(crate) fn linux_execfn() -> &'static CStr {
unsafe { CStr::from_ptr(auxv().execfn as *const c_char) }
}
#[inline]
pub(in super::super) fn exe_phdrs() -> &'static [Elf_Phdr] {
unsafe { slice::from_raw_parts(AUXV.phdr as *const Elf_Phdr, AUXV.phnum) }
@@ -50,6 +56,7 @@ struct Auxv {
sysinfo_ehdr: usize,
phdr: usize,
phnum: usize,
execfn: usize,
}
/// Data obtained from the kernel-provided auxv array. This is initialized at
@@ -61,6 +68,7 @@ static mut AUXV: Auxv = Auxv {
sysinfo_ehdr: 0,
phdr: 0,
phnum: 0,
execfn: 0,
};
/// GLIBC passes argc, argv, and envp to functions in .init_array, as a
@@ -121,6 +129,7 @@ unsafe fn init_from_auxp(mut auxp: *const Elf_auxv_t) {
AT_PHDR => AUXV.phdr = a_val,
AT_PHNUM => AUXV.phnum = a_val,
AT_PHENT => assert_eq!(a_val, size_of::<Elf_Phdr>()),
AT_EXECFN => AUXV.execfn = a_val,
AT_NULL => break,
_ => (),
}
+1 -1
View File
@@ -2,7 +2,7 @@ mod auxv;
mod types;
pub(super) use auxv::{exe_phdrs, sysinfo_ehdr};
pub(crate) use auxv::{linux_hwcap, page_size};
pub(crate) use auxv::{linux_hwcap, page_size, linux_execfn};
pub use types::{
MembarrierCommand, RawCpuid, RawGid, RawPid, RawUid, RawUname, Resource, EXIT_FAILURE,
EXIT_SIGNALED_SIGABRT, EXIT_SUCCESS,
+17
View File
@@ -1,4 +1,6 @@
use crate::imp;
#[cfg(any(linux_raw, all(libc, any(target_os = "android", target_os = "linux"))))]
use std::ffi::CStr;
/// `getpagesize()`—Returns the process' page size.
#[inline]
@@ -22,3 +24,18 @@ pub fn page_size() -> usize {
pub fn linux_hwcap() -> (usize, usize) {
imp::process::linux_hwcap()
}
/// `getauxval(AT_EXECFN)`—Returns the Linux "execfn" string.
///
/// Return the string that Linux has recorded as the filesystem path to the
/// executable.
///
/// # References
/// - [Linux]
///
/// [Linux]: https://man7.org/linux/man-pages/man3/getauxval.3.html
#[cfg(any(linux_raw, all(libc, any(target_os = "android", target_os = "linux"))))]
#[inline]
pub fn linux_execfn() -> &'static CStr {
imp::process::linux_execfn()
}
+1 -1
View File
@@ -19,7 +19,7 @@ mod sched;
mod uname;
#[cfg(any(linux_raw, all(libc, any(target_os = "android", target_os = "linux"))))]
pub use auxv::linux_hwcap;
pub use auxv::{linux_hwcap, linux_execfn};
pub use auxv::page_size;
#[cfg(not(target_os = "wasi"))]
pub use chdir::chdir;