start.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. // Start code adapted from https://gitlab.redox-os.org/redox-os/relibc/blob/master/src/start.rs
  2. use c_str::CStr;
  3. use header::unistd;
  4. use platform::types::c_char;
  5. use super::linker::Linker;
  6. use crate::start::Stack;
  7. #[no_mangle]
  8. pub extern "C" fn relibc_ld_so_start(sp: &'static mut Stack) -> usize {
  9. if sp.argc < 2 {
  10. eprintln!("ld.so [executable] [arguments...]");
  11. unistd::_exit(1);
  12. loop {}
  13. }
  14. // Some variables that will be overridden by environment and auxiliary vectors
  15. let mut library_path = "/lib";
  16. //let mut page_size = 4096;
  17. // Pop the first argument (path to ld_so), and get the path of the program
  18. let path_c = unsafe {
  19. let mut argv = sp.argv() as *mut usize;
  20. // Move arguments
  21. loop {
  22. let next_argv = argv.add(1);
  23. let arg = *next_argv;
  24. *argv = arg;
  25. argv = next_argv;
  26. if arg == 0 {
  27. break;
  28. }
  29. if let Ok(arg_str) = CStr::from_ptr(arg as *const c_char).to_str() {
  30. println!(" arg: '{}'", arg_str);
  31. }
  32. }
  33. // Move environment
  34. loop {
  35. let next_argv = argv.add(1);
  36. let arg = *next_argv;
  37. *argv = arg;
  38. argv = next_argv;
  39. if arg == 0 {
  40. break;
  41. }
  42. if let Ok(arg_str) = CStr::from_ptr(arg as *const c_char).to_str() {
  43. println!(" env: '{}'", arg_str);
  44. let mut parts = arg_str.splitn(2, '=');
  45. if let Some(key) = parts.next() {
  46. if let Some(value) = parts.next() {
  47. if let "LD_LIBRARY_PATH" = key {
  48. library_path = value
  49. }
  50. }
  51. }
  52. }
  53. }
  54. // Move auxiliary vectors
  55. loop {
  56. let next_argv = argv.add(1);
  57. let kind = *next_argv;
  58. *argv = kind;
  59. argv = next_argv;
  60. let next_argv = argv.add(1);
  61. let value = *next_argv;
  62. *argv = value;
  63. argv = next_argv;
  64. if kind == 0 {
  65. break;
  66. }
  67. println!(" aux: {}={:#x}", kind, value);
  68. //match kind {
  69. // 6 => page_size = value,
  70. // _ => (),
  71. //}
  72. }
  73. sp.argc -= 1;
  74. CStr::from_ptr(sp.argv0)
  75. };
  76. let path = match path_c.to_str() {
  77. Ok(ok) => ok,
  78. Err(err) => {
  79. eprintln!("ld.so: failed to parse path: {}", err);
  80. unistd::_exit(1);
  81. loop {}
  82. }
  83. };
  84. let mut linker = Linker::new(library_path);
  85. match linker.load(&path, &path) {
  86. Ok(()) => (),
  87. Err(err) => {
  88. eprintln!("ld.so: failed to load '{}': {}", path, err);
  89. unistd::_exit(1);
  90. loop {}
  91. }
  92. }
  93. match linker.link(&path) {
  94. Ok(entry) => {
  95. eprintln!("ld.so: entry '{}': {:#x}", path, entry);
  96. //unistd::_exit(0);
  97. entry
  98. }
  99. Err(err) => {
  100. eprintln!("ld.so: failed to link '{}': {}", path, err);
  101. unistd::_exit(1);
  102. loop {}
  103. }
  104. }
  105. }