@@ -30,12 +30,6 @@ use rustix_futex_sync::Mutex;
3030/// `mem` should point to the stack as provided by the operating system.
3131#[ cfg( any( feature = "origin-start" , feature = "external-start" ) ) ]
3232pub ( super ) unsafe extern "C" fn entry ( mem : * mut usize ) -> ! {
33- use linux_raw_sys:: ctypes:: c_uint;
34-
35- extern "C" {
36- fn main ( argc : c_int , argv : * mut * mut u8 , envp : * mut * mut u8 ) -> c_int ;
37- }
38-
3933 // Do some basic precondition checks, to ensure that our assembly code did
4034 // what we expect it to do. These are debug-only for now, to keep the
4135 // release-mode startup code simple to disassemble and inspect, while we're
@@ -75,6 +69,20 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! {
7569 }
7670
7771 // Compute `argc`, `argv`, and `envp`.
72+ let ( argc, argv, envp) = compute_args ( mem) ;
73+ init_runtime ( mem, envp) ;
74+
75+ let status = call_user_code ( argc, argv, envp) ;
76+
77+ // Run functions registered with `at_exit`, and exit with main's return
78+ // value.
79+ exit ( status)
80+ }
81+
82+ #[ cfg( any( feature = "origin-start" , feature = "external-start" ) ) ]
83+ unsafe fn compute_args ( mem : * mut usize ) -> ( i32 , * mut * mut u8 , * mut * mut u8 ) {
84+ use linux_raw_sys:: ctypes:: c_uint;
85+
7886 let argc = * mem as c_int ;
7987 let argv = mem. add ( 1 ) . cast :: < * mut u8 > ( ) ;
8088 let envp = argv. add ( argc as c_uint as usize + 1 ) ;
@@ -84,6 +92,12 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! {
8492 debug_assert_eq ! ( * mem, argc as _) ;
8593 debug_assert_eq ! ( * argv. add( argc as usize ) , core:: ptr:: null_mut( ) ) ;
8694
95+ ( argc, argv, envp)
96+ }
97+
98+ #[ cfg( any( feature = "origin-start" , feature = "external-start" ) ) ]
99+ #[ allow( unused_variables) ]
100+ unsafe fn init_runtime ( mem : * mut usize , envp : * mut * mut u8 ) {
87101 // Explicitly initialize `rustix` so that we can control the initialization
88102 // order.
89103 #[ cfg( feature = "param" ) ]
@@ -98,6 +112,14 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! {
98112 // Initialize the main thread.
99113 #[ cfg( feature = "origin-thread" ) ]
100114 initialize_main_thread ( mem. cast ( ) ) ;
115+ }
116+
117+ #[ cfg( any( feature = "origin-start" , feature = "external-start" ) ) ]
118+ #[ allow( unused_variables) ]
119+ unsafe fn call_user_code ( argc : c_int , argv : * mut * mut u8 , envp : * mut * mut u8 ) -> i32 {
120+ extern "C" {
121+ fn main ( argc : c_int , argv : * mut * mut u8 , envp : * mut * mut u8 ) -> c_int ;
122+ }
101123
102124 // Call the functions registered via `.init_array`.
103125 #[ cfg( feature = "init-fini-arrays" ) ]
@@ -112,9 +134,7 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! {
112134 #[ cfg( feature = "log" ) ]
113135 log:: trace!( "`main` returned `{:?}`" , status) ;
114136
115- // Run functions registered with `at_exit`, and exit with main's return
116- // value.
117- exit ( status)
137+ status
118138}
119139
120140/// Call the constructors in the `.init_array` section.
0 commit comments