Move IO Initialization to .init_array section

Most shared object in linux have their initialization in a separate
.init_array section. but glibc does not have the same behavour. Instead
the initialization is part of crt0. which (as it seams to me) run after
.init_array section. As such, this patch move IO initialization to
separate function that is marked as .init_array member and then the crt0
call this function only if init_array was never invoked (as in
statically linked binaries).
This commit is contained in:
oddcoder
2020-04-19 12:07:41 +02:00
parent 6aeb2d6fa2
commit b717f6cf5a
+21 -5
View File
@@ -60,6 +60,24 @@ pub unsafe fn relibc_verify_host() {
intrinsics::abort();
}
}
#[link_section = ".init_array"]
#[used]
static INIT_ARRAY: [extern "C" fn(); 1] = [init_array];
static mut init_complete: bool = false;
extern "C" fn init_array() {
io_init();
unsafe { init_complete = true };
}
fn io_init() {
unsafe {
// Initialize stdin/stdout/stderr, see https://github.com/rust-lang/rust/issues/51718
stdio::stdin = stdio::default_stdin.get();
stdio::stdout = stdio::default_stdout.get();
stdio::stderr = stdio::default_stderr.get();
}
}
#[inline(never)]
#[no_mangle]
@@ -95,11 +113,9 @@ pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
platform::inner_environ = copy_string_array(envp, len);
platform::environ = platform::inner_environ.as_mut_ptr();
// Initialize stdin/stdout/stderr, see https://github.com/rust-lang/rust/issues/51718
stdio::stdin = stdio::default_stdin.get();
stdio::stdout = stdio::default_stdout.get();
stdio::stderr = stdio::default_stderr.get();
if !init_complete {
init_array();
}
pthread_init();
// Run preinit array