Allow constructors to access env vars.

This commit is contained in:
4lDO2
2022-07-23 16:24:02 +02:00
parent 049a5156d7
commit 4e5ccbffd1
3 changed files with 49 additions and 8 deletions
+8
View File
@@ -472,7 +472,15 @@ impl Linker {
}
fn run_init(&self, objects: &Vec<DSO>) {
use crate::platform::{self, types::*};
for obj in objects.iter().rev() {
if let Some((symbol, true)) = obj.get_sym("__relibc_init_environ") {
unsafe {
symbol.as_ptr().cast::<*mut *mut c_char>().write(platform::environ);
}
}
obj.run_init();
}
}
+16
View File
@@ -167,6 +167,22 @@ pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack, ld_entry: usize) ->
(argv, envs, auxv)
};
unsafe {
crate::platform::OUR_ENVIRON = envs.iter().map(|(k, v)| {
let mut var = Vec::with_capacity(k.len() + v.len() + 2);
var.extend(k.as_bytes());
var.push(b'=');
var.extend(v.as_bytes());
var.push(b'\0');
let mut var = var.into_boxed_slice();
let ptr = var.as_mut_ptr();
core::mem::forget(var);
ptr.cast()
}).chain(core::iter::once(core::ptr::null_mut())).collect::<Vec<_>>();
crate::platform::environ = crate::platform::OUR_ENVIRON.as_mut_ptr();
}
let is_manual = if let Some(img_entry) = auxv.get(&AT_ENTRY) {
*img_entry == ld_entry
} else {
+25 -8
View File
@@ -67,7 +67,16 @@ static INIT_ARRAY: [extern "C" fn(); 1] = [init_array];
static mut init_complete: bool = false;
#[used]
#[no_mangle]
static mut __relibc_init_environ: *mut *mut c_char = ptr::null_mut();
fn alloc_init() {
unsafe {
if init_complete {
return;
}
}
unsafe {
if let Some(tcb) = ld_so::tcb::Tcb::current() {
if tcb.mspace != 0 {
@@ -96,6 +105,10 @@ extern "C" fn init_array() {
alloc_init();
io_init();
unsafe {
platform::environ = __relibc_init_environ;
}
extern "C" {
fn pthread_init();
}
@@ -155,15 +168,19 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
platform::program_invocation_name = *arg;
platform::program_invocation_short_name = libgen::basename(*arg);
}
// Set up envp
let envp = sp.envp();
let mut len = 0;
while !(*envp.add(len)).is_null() {
len += 1;
// We check for NULL here since ld.so might already have initialized it for us, and we don't
// want to overwrite it if constructors in .init_array of dependency libraries have called
// setenv.
if platform::environ.is_null() {
// Set up envp
let envp = sp.envp();
let mut len = 0;
while !(*envp.add(len)).is_null() {
len += 1;
}
platform::OUR_ENVIRON = copy_string_array(envp, len);
platform::environ = platform::OUR_ENVIRON.as_mut_ptr();
}
platform::OUR_ENVIRON = copy_string_array(envp, len);
platform::environ = platform::OUR_ENVIRON.as_mut_ptr();
// Setup signal stack, otherwise we cannot handle any signals besides SIG_IGN/SIG_DFL behavior.
setup_sigstack();