Allow constructors to access env vars.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user