Files
RedBear-OS/src/start.rs
T
Jeremy Soller ebffc977b2 Reduce warnings
2018-11-10 07:52:45 -07:00

95 lines
2.4 KiB
Rust

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!();
}