libc: implement program_invocation_[short_]name

This commit is contained in:
Mark Poliakov 2025-03-09 14:42:38 +02:00
parent d963b3bac9
commit c5994dd390
5 changed files with 27 additions and 11 deletions

View File

@ -73,7 +73,7 @@ impl<'a> ArgPlacer<'a> {
}
}
pub fn build_argument(args: &[String], auxv: &[AuxValue]) -> Result<usize, Error> {
pub fn build_argument(args: &[String], binary: &str, auxv: &[AuxValue]) -> Result<usize, Error> {
let mut buffer = Mapping::new(0x1000, MappingFlags::WRITE)?;
let arg_base = buffer.as_ptr().addr();
let mut placer = ArgPlacer::new(&mut buffer[..]);
@ -93,12 +93,16 @@ pub fn build_argument(args: &[String], auxv: &[AuxValue]) -> Result<usize, Error
let argv = placer.put_ptr_array(&argv)? + arg_base;
let envp = placer.put_ptr_array(&envp)? + arg_base;
let auxv = placer.put_aux_array(auxv)? + arg_base;
let real_program = placer.put_str(binary)? + arg_base;
placer.align(size_of::<usize>())?;
let argument = placer.position + arg_base;
placer.put(&argv)?;
placer.put(&envp)?;
placer.put(&auxv)?;
placer.put(&real_program)?;
buffer.leak();

View File

@ -38,6 +38,7 @@ pub struct Args {
static mut OBJECTS: MaybeUninit<ObjectSet> = MaybeUninit::uninit();
fn run(binary: &Path, args: &Args) -> Result<!, Error> {
let binary_str = binary.to_str().unwrap();
let mut config = Config::load_or_default()?;
config.extend_from_env();
@ -128,7 +129,7 @@ fn run(binary: &Path, args: &Args) -> Result<!, Error> {
OBJECTS.write(objects)
};
let argument = env::build_argument(&args.args, &auxv)?;
let argument = env::build_argument(&args.args, binary_str, &auxv)?;
unsafe { enter(entry, argument) };
}

View File

@ -22,6 +22,11 @@ use crate::{
#[no_mangle]
pub static mut environ: *mut *mut c_char = null_mut();
#[no_mangle]
pub static mut program_invocation_short_name: *mut c_char = null_mut();
#[no_mangle]
pub static mut program_invocation_name: *mut c_char = null_mut();
static mut shadow: Vec<*mut c_char> = Vec::new();
unsafe fn get_key(var: NonNull<c_char>) -> Option<&'static [u8]> {
@ -224,6 +229,20 @@ pub fn handle_kernel_argument(arg: usize) -> Vec<CString> {
args.push(c_arg);
}
if let Some(arg0) = args.get(0) {
let invocation_name_str = arg0.to_str().unwrap();
let invocation_name = arg0.clone();
let invocation_name_short_str =
if let Some((_, basename)) = invocation_name_str.rsplit_once('/') {
basename.trim()
} else {
invocation_name_str
};
let invocation_name_short = CString::new(invocation_name_short_str).unwrap();
unsafe { program_invocation_name = invocation_name.into_raw() };
unsafe { program_invocation_short_name = invocation_name_short.into_raw() };
}
unsafe { setup_env(arg.envs()) };
// Setup TLS from argument

View File

@ -1,4 +1,4 @@
use core::{ffi::c_char, ptr::null_mut};
use core::ffi::c_char;
use super::{locale::locale_t, nl_types::nl_item};

View File

@ -1,7 +1,6 @@
use core::{
ffi::{c_char, c_int, c_void, CStr},
mem::MaybeUninit,
ptr::null_mut,
time::Duration,
};
@ -30,13 +29,6 @@ impl DsoDestructor {
}
}
#[allow(non_upper_case_globals)]
#[no_mangle]
static mut program_invocation_short_name: *mut c_char = null_mut();
#[allow(non_upper_case_globals)]
#[no_mangle]
static mut program_invocation_name: *mut c_char = null_mut();
static AT_EXIT: Mutex<Vec<extern "C" fn()>> = Mutex::new(Vec::new());
// TODO this will be in the linker instead
static AT_DSO_EXIT: Mutex<Vec<DsoDestructor>> = Mutex::new(Vec::new());