start.rs 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. use alloc::vec::Vec;
  2. use core::ptr;
  3. use header::{stdio, stdlib};
  4. use platform;
  5. use platform::types::*;
  6. #[repr(C)]
  7. pub struct Stack {
  8. argc: isize,
  9. argv0: *const c_char,
  10. }
  11. impl Stack {
  12. fn argc(&self) -> isize {
  13. self.argc
  14. }
  15. fn argv(&self) -> *const *const c_char {
  16. &self.argv0 as *const _
  17. }
  18. fn envp(&self) -> *const *const c_char {
  19. unsafe { self.argv().offset(self.argc() + 1) }
  20. }
  21. }
  22. #[inline(never)]
  23. #[no_mangle]
  24. pub unsafe extern "C" fn relibc_start(sp: &'static Stack) -> ! {
  25. extern "C" {
  26. static __preinit_array_start: extern "C" fn();
  27. static __preinit_array_end: extern "C" fn();
  28. static __init_array_start: extern "C" fn();
  29. static __init_array_end: extern "C" fn();
  30. fn _init();
  31. fn main(argc: isize, argv: *const *const c_char, envp: *const *const c_char) -> c_int;
  32. }
  33. let argc = sp.argc();
  34. let argv = sp.argv();
  35. let envp = sp.envp();
  36. let mut len = 0;
  37. while *envp.offset(len) != ptr::null() {
  38. len += 1;
  39. }
  40. platform::inner_environ = Vec::with_capacity(len as usize + 1);
  41. for i in 0..len {
  42. let mut item = *envp.offset(i);
  43. let mut len = 0;
  44. while *item.offset(len) != 0 {
  45. len += 1;
  46. }
  47. let buf = platform::alloc(len as usize + 1) as *mut c_char;
  48. for i in 0..=len {
  49. *buf.offset(i) = *item.offset(i);
  50. }
  51. platform::inner_environ.push(buf);
  52. }
  53. platform::inner_environ.push(ptr::null_mut());
  54. platform::environ = platform::inner_environ.as_mut_ptr();
  55. // Initialize stdin/stdout/stderr, see https://github.com/rust-lang/rust/issues/51718
  56. stdio::stdin = stdio::default_stdin.get();
  57. stdio::stdout = stdio::default_stdout.get();
  58. stdio::stderr = stdio::default_stderr.get();
  59. _init();
  60. // Look for the neighbor functions in memory until the end
  61. let mut f = &__preinit_array_start as *const _;
  62. while f < &__preinit_array_end {
  63. (*f)();
  64. f = f.offset(1);
  65. }
  66. f = &__init_array_start as *const _;
  67. while f < &__init_array_end {
  68. (*f)();
  69. f = f.offset(1);
  70. }
  71. stdlib::exit(main(
  72. argc,
  73. argv,
  74. // not envp, because programs like bash try to modify this *const*
  75. // pointer :|
  76. platform::environ as *const *const c_char,
  77. ));
  78. unreachable!();
  79. }