123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- // Start code adapted from https://gitlab.redox-os.org/redox-os/relibc/blob/master/src/start.rs
- use c_str::CStr;
- use header::unistd;
- use platform::types::c_char;
- use super::linker::Linker;
- use crate::start::Stack;
- #[no_mangle]
- pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack) -> usize {
- if sp.argc < 2 {
- eprintln!("ld.so [executable] [arguments...]");
- unistd::_exit(1);
- loop {}
- }
- // Some variables that will be overridden by environment and auxiliary vectors
- let mut library_path = "/lib";
- //let mut page_size = 4096;
- // Pop the first argument (path to ld_so), and get the path of the program
- let path_c = unsafe {
- let mut argv = sp.argv() as *mut usize;
- // Move arguments
- loop {
- let next_argv = argv.add(1);
- let arg = *next_argv;
- *argv = arg;
- argv = next_argv;
- if arg == 0 {
- break;
- }
- if let Ok(arg_str) = CStr::from_ptr(arg as *const c_char).to_str() {
- println!(" arg: '{}'", arg_str);
- }
- }
- // Move environment
- loop {
- let next_argv = argv.add(1);
- let arg = *next_argv;
- *argv = arg;
- argv = next_argv;
- if arg == 0 {
- break;
- }
- if let Ok(arg_str) = CStr::from_ptr(arg as *const c_char).to_str() {
- println!(" env: '{}'", arg_str);
- let mut parts = arg_str.splitn(2, '=');
- if let Some(key) = parts.next() {
- if let Some(value) = parts.next() {
- if let "LD_LIBRARY_PATH" = key {
- library_path = value
- }
- }
- }
- }
- }
- // Move auxiliary vectors
- loop {
- let next_argv = argv.add(1);
- let kind = *next_argv;
- *argv = kind;
- argv = next_argv;
- let next_argv = argv.add(1);
- let value = *next_argv;
- *argv = value;
- argv = next_argv;
- if kind == 0 {
- break;
- }
- println!(" aux: {}={:#x}", kind, value);
- //match kind {
- // 6 => page_size = value,
- // _ => (),
- //}
- }
- sp.argc -= 1;
- CStr::from_ptr(sp.argv0)
- };
- let path = match path_c.to_str() {
- Ok(ok) => ok,
- Err(err) => {
- eprintln!("ld.so: failed to parse path: {}", err);
- unistd::_exit(1);
- loop {}
- }
- };
- let mut linker = Linker::new(library_path);
- match linker.load(&path, &path) {
- Ok(()) => (),
- Err(err) => {
- eprintln!("ld.so: failed to load '{}': {}", path, err);
- unistd::_exit(1);
- loop {}
- }
- }
- match linker.link(&path) {
- Ok(entry) => {
- eprintln!("ld.so: entry '{}': {:#x}", path, entry);
- //unistd::_exit(0);
- entry
- }
- Err(err) => {
- eprintln!("ld.so: failed to link '{}': {}", path, err);
- unistd::_exit(1);
- loop {}
- }
- }
- }
|