12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- use alloc::vec::Vec;
- use core::ptr;
- use header::{stdio, stdlib};
- use platform;
- use platform::types::*;
- #[repr(C)]
- pub struct Stack {
- argc: isize,
- argv0: *const c_char,
- }
- impl Stack {
- fn argc(&self) -> isize {
- self.argc
- }
- fn argv(&self) -> *const *const c_char {
- &self.argv0 as *const _
- }
- fn envp(&self) -> *const *const c_char {
- unsafe { self.argv().offset(self.argc() + 1) }
- }
- }
- #[inline(never)]
- #[no_mangle]
- pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
- extern "C" {
- static __preinit_array_start: extern "C" fn();
- static __preinit_array_end: extern "C" fn();
- static __init_array_start: extern "C" fn();
- static __init_array_end: extern "C" fn();
- fn _init();
- fn main(argc: isize, argv: *const *const c_char, envp: *const *const c_char) -> c_int;
- }
- let argc = sp.argc();
- let argv = sp.argv();
- let envp = sp.envp();
- let mut len = 0;
- while *envp.offset(len) != ptr::null() {
- len += 1;
- }
- platform::inner_environ = Vec::with_capacity(len as usize + 1);
- for i in 0..len {
- let mut item = *envp.offset(i);
- let mut len = 0;
- while *item.offset(len) != 0 {
- len += 1;
- }
- let buf = platform::alloc(len as usize + 1) as *mut c_char;
- for i in 0..=len {
- *buf.offset(i) = *item.offset(i);
- }
- platform::inner_environ.push(buf);
- }
- platform::inner_environ.push(ptr::null_mut());
- 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();
- _init();
- // Look for the neighbor functions in memory until the end
- let mut f = &__preinit_array_start as *const _;
- while f < &__preinit_array_end {
- (*f)();
- f = f.offset(1);
- }
- f = &__init_array_start as *const _;
- while f < &__init_array_end {
- (*f)();
- f = f.offset(1);
- }
- stdlib::exit(main(
- argc,
- argv,
- // not envp, because programs like bash try to modify this *const*
- // pointer :|
- platform::environ as *const *const c_char,
- ));
- unreachable!();
- }
|