Skip to content
Snippets Groups Projects
Verified Commit 4e5ccbff authored by Jacob Lorentzon's avatar Jacob Lorentzon
Browse files

Allow constructors to access env vars.

parent 049a5156
No related branches found
No related tags found
No related merge requests found
......@@ -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 {
......
......@@ -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();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment