@@ -30,12 +30,6 @@ use rustix_futex_sync::Mutex;
30
30
/// `mem` should point to the stack as provided by the operating system.
31
31
#[ cfg( any( feature = "origin-start" , feature = "external-start" ) ) ]
32
32
pub ( 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
-
39
33
// Do some basic precondition checks, to ensure that our assembly code did
40
34
// what we expect it to do. These are debug-only for now, to keep the
41
35
// 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) -> ! {
75
69
}
76
70
77
71
// 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
+
78
86
let argc = * mem as c_int ;
79
87
let argv = mem. add ( 1 ) . cast :: < * mut u8 > ( ) ;
80
88
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) -> ! {
84
92
debug_assert_eq ! ( * mem, argc as _) ;
85
93
debug_assert_eq ! ( * argv. add( argc as usize ) , core:: ptr:: null_mut( ) ) ;
86
94
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 ) {
87
101
// Explicitly initialize `rustix` so that we can control the initialization
88
102
// order.
89
103
#[ cfg( feature = "param" ) ]
@@ -98,6 +112,14 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! {
98
112
// Initialize the main thread.
99
113
#[ cfg( feature = "origin-thread" ) ]
100
114
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
+ }
101
123
102
124
// Call the functions registered via `.init_array`.
103
125
#[ cfg( feature = "init-fini-arrays" ) ]
@@ -112,9 +134,7 @@ pub(super) unsafe extern "C" fn entry(mem: *mut usize) -> ! {
112
134
#[ cfg( feature = "log" ) ]
113
135
log:: trace!( "`main` returned `{:?}`" , status) ;
114
136
115
- // Run functions registered with `at_exit`, and exit with main's return
116
- // value.
117
- exit ( status)
137
+ status
118
138
}
119
139
120
140
/// Call the constructors in the `.init_array` section.
0 commit comments