@@ -11,7 +11,7 @@ use syntax::source_map::DUMMY_SP;
1111use crate :: {
1212 EnvVars , Evaluator , FnVal , HelpersEvalContextExt , InterpCx , InterpError ,
1313 InterpResult , MemoryExtra , MiriMemoryKind , Pointer , Scalar , StackPopCleanup , Tag ,
14- TlsEvalContextExt ,
14+ TlsEvalContextExt , MPlaceTy
1515} ;
1616
1717/// Configuration needed to spawn a Miri instance.
@@ -34,7 +34,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
3434 tcx : TyCtxt < ' tcx > ,
3535 main_id : DefId ,
3636 config : MiriConfig ,
37- ) -> InterpResult < ' tcx , InterpCx < ' mir , ' tcx , Evaluator < ' tcx > > > {
37+ ) -> InterpResult < ' tcx , ( InterpCx < ' mir , ' tcx , Evaluator < ' tcx > > , MPlaceTy < ' tcx , Tag > ) > {
3838 let mut ecx = InterpCx :: new (
3939 tcx. at ( syntax:: source_map:: DUMMY_SP ) ,
4040 ty:: ParamEnv :: reveal_all ( ) ,
@@ -170,27 +170,31 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
170170 ecx. write_scalar ( Scalar :: from_u32 ( 0 ) , errno_place. into ( ) ) ?;
171171 ecx. machine . last_error = Some ( errno_place) ;
172172
173- Ok ( ecx)
173+ Ok ( ( ecx, ret_ptr ) )
174174}
175175
176176pub fn eval_main < ' tcx > ( tcx : TyCtxt < ' tcx > , main_id : DefId , config : MiriConfig ) {
177- let mut ecx = match create_ecx ( tcx, main_id, config) {
178- Ok ( ecx ) => ecx ,
177+ let ( mut ecx, ret_ptr ) = match create_ecx ( tcx, main_id, config) {
178+ Ok ( v ) => v ,
179179 Err ( mut err) => {
180180 err. print_backtrace ( ) ;
181181 panic ! ( "Miri initialziation error: {}" , err. kind)
182182 }
183183 } ;
184184
185185 // Perform the main execution.
186- let res: InterpResult < ' _ > = ( || {
186+ let res: InterpResult < ' _ , i64 > = ( || {
187187 ecx. run ( ) ?;
188- ecx. run_tls_dtors ( )
188+ // Read the return code pointer *before* we run TLS destructors, to assert
189+ // that it was written to by the time that `start` lang item returned.
190+ let return_code = ecx. read_scalar ( ret_ptr. into ( ) ) ?. not_undef ( ) ?. to_machine_isize ( & ecx) ?;
191+ ecx. run_tls_dtors ( ) ?;
192+ Ok ( return_code)
189193 } ) ( ) ;
190194
191195 // Process the result.
192196 match res {
193- Ok ( ( ) ) => {
197+ Ok ( return_code ) => {
194198 let leaks = ecx. memory . leak_report ( ) ;
195199 // Disable the leak test on some platforms where we do not
196200 // correctly implement TLS destructors.
@@ -199,6 +203,7 @@ pub fn eval_main<'tcx>(tcx: TyCtxt<'tcx>, main_id: DefId, config: MiriConfig) {
199203 if !ignore_leaks && leaks != 0 {
200204 tcx. sess . err ( "the evaluated program leaked memory" ) ;
201205 }
206+ std:: process:: exit ( return_code as i32 ) ;
202207 }
203208 Err ( mut e) => {
204209 // Special treatment for some error kinds
0 commit comments