33use rand:: rngs:: StdRng ;
44use rand:: SeedableRng ;
55
6- use syntax:: source_map:: DUMMY_SP ;
7- use rustc:: ty:: { self , TyCtxt } ;
8- use rustc:: ty:: layout:: { LayoutOf , Size , Align } ;
96use rustc:: hir:: def_id:: DefId ;
7+ use rustc:: ty:: layout:: { Align , LayoutOf , Size } ;
8+ use rustc:: ty:: { self , TyCtxt } ;
9+ use syntax:: source_map:: DUMMY_SP ;
1010
1111use crate :: {
12- InterpResult , InterpError , InterpCx , StackPopCleanup , struct_error,
13- Scalar , Tag , Pointer , FnVal ,
14- MemoryExtra , MiriMemoryKind , Evaluator , TlsEvalContextExt , HelpersEvalContextExt ,
15- EnvVars ,
12+ struct_error, EnvVars , Evaluator , FnVal , HelpersEvalContextExt , InterpCx , InterpError ,
13+ InterpResult , MemoryExtra , MiriMemoryKind , Pointer , Scalar , StackPopCleanup , Tag ,
14+ TlsEvalContextExt ,
1615} ;
1716
1817/// Configuration needed to spawn a Miri instance.
@@ -40,7 +39,10 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
4039 tcx. at ( syntax:: source_map:: DUMMY_SP ) ,
4140 ty:: ParamEnv :: reveal_all ( ) ,
4241 Evaluator :: new ( config. communicate ) ,
43- MemoryExtra :: new ( StdRng :: seed_from_u64 ( config. seed . unwrap_or ( 0 ) ) , config. validate ) ,
42+ MemoryExtra :: new (
43+ StdRng :: seed_from_u64 ( config. seed . unwrap_or ( 0 ) ) ,
44+ config. validate ,
45+ ) ,
4446 ) ;
4547 // Complete initialization.
4648 EnvVars :: init ( & mut ecx, config. excluded_env_vars ) ;
@@ -50,9 +52,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
5052 let main_mir = ecx. load_mir ( main_instance. def , None ) ?;
5153
5254 if !main_mir. return_ty ( ) . is_unit ( ) || main_mir. arg_count != 0 {
53- throw_unsup_format ! (
54- "miri does not support main functions without `fn()` type signatures"
55- ) ;
55+ throw_unsup_format ! ( "miri does not support main functions without `fn()` type signatures" ) ;
5656 }
5757
5858 let start_id = tcx. lang_items ( ) . start_fn ( ) . unwrap ( ) ;
@@ -62,9 +62,10 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
6262 ecx. tcx . tcx ,
6363 ty:: ParamEnv :: reveal_all ( ) ,
6464 start_id,
65- ecx. tcx . mk_substs (
66- :: std:: iter:: once ( ty:: subst:: GenericArg :: from ( main_ret_ty) ) )
67- ) . unwrap ( ) ;
65+ ecx. tcx
66+ . mk_substs ( :: std:: iter:: once ( ty:: subst:: GenericArg :: from ( main_ret_ty) ) ) ,
67+ )
68+ . unwrap ( ) ;
6869 let start_mir = ecx. load_mir ( start_instance. def , None ) ?;
6970
7071 if start_mir. arg_count != 3 {
@@ -91,7 +92,9 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
9192 let mut args = ecx. frame ( ) . body . args_iter ( ) ;
9293
9394 // First argument: pointer to `main()`.
94- let main_ptr = ecx. memory_mut ( ) . create_fn_alloc ( FnVal :: Instance ( main_instance) ) ;
95+ let main_ptr = ecx
96+ . memory_mut ( )
97+ . create_fn_alloc ( FnVal :: Instance ( main_instance) ) ;
9598 let dest = ecx. local_place ( args. next ( ) . unwrap ( ) ) ?;
9699 ecx. write_scalar ( Scalar :: Ptr ( main_ptr) , dest) ?;
97100
@@ -124,16 +127,23 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
124127 // Add `0` terminator.
125128 let mut arg = arg. into_bytes ( ) ;
126129 arg. push ( 0 ) ;
127- argvs. push ( ecx. memory_mut ( ) . allocate_static_bytes ( arg. as_slice ( ) , MiriMemoryKind :: Static . into ( ) ) ) ;
130+ argvs. push (
131+ ecx. memory_mut ( )
132+ . allocate_static_bytes ( arg. as_slice ( ) , MiriMemoryKind :: Static . into ( ) ) ,
133+ ) ;
128134 }
129135 // Make an array with all these pointers, in the Miri memory.
130- let argvs_layout = ecx. layout_of ( ecx. tcx . mk_array ( ecx. tcx . mk_imm_ptr ( ecx. tcx . types . u8 ) , argvs. len ( ) as u64 ) ) ?;
136+ let argvs_layout = ecx. layout_of (
137+ ecx. tcx
138+ . mk_array ( ecx. tcx . mk_imm_ptr ( ecx. tcx . types . u8 ) , argvs. len ( ) as u64 ) ,
139+ ) ?;
131140 let argvs_place = ecx. allocate ( argvs_layout, MiriMemoryKind :: Env . into ( ) ) ;
132141 for ( idx, arg) in argvs. into_iter ( ) . enumerate ( ) {
133142 let place = ecx. mplace_field ( argvs_place, idx as u64 ) ?;
134143 ecx. write_scalar ( Scalar :: Ptr ( arg) , place. into ( ) ) ?;
135144 }
136- ecx. memory_mut ( ) . mark_immutable ( argvs_place. ptr . assert_ptr ( ) . alloc_id ) ?;
145+ ecx. memory_mut ( )
146+ . mark_immutable ( argvs_place. ptr . assert_ptr ( ) . alloc_id ) ?;
137147 // Write a pointer to that place as the argument.
138148 let argv = argvs_place. ptr ;
139149 ecx. write_scalar ( argv, dest) ?;
@@ -145,7 +155,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
145155 }
146156 // Store command line as UTF-16 for Windows `GetCommandLineW`.
147157 {
148- let tcx = & { ecx. tcx . tcx } ;
158+ let tcx = & { ecx. tcx . tcx } ;
149159 let cmd_utf16: Vec < u16 > = cmd. encode_utf16 ( ) . collect ( ) ;
150160 let cmd_ptr = ecx. memory_mut ( ) . allocate (
151161 Size :: from_bytes ( cmd_utf16. len ( ) as u64 * 2 ) ,
@@ -168,16 +178,22 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
168178 }
169179 }
170180
171- assert ! ( args. next( ) . is_none( ) , "start lang item has more arguments than expected" ) ;
181+ assert ! (
182+ args. next( ) . is_none( ) ,
183+ "start lang item has more arguments than expected"
184+ ) ;
185+
186+ // Set the last_error to 0
187+ let errno_layout = ecx. layout_of ( ecx. tcx . types . u32 ) ?;
188+ let errno_place = ecx. allocate ( errno_layout, MiriMemoryKind :: Static . into ( ) ) ;
189+ ecx. write_scalar ( Scalar :: from_u32 ( 0 ) , errno_place. into ( ) ) ?;
190+ let errno_ptr = ecx. check_mplace_access ( errno_place. into ( ) , Some ( Size :: from_bits ( 32 ) ) ) ?;
191+ ecx. machine . last_error = errno_ptr;
172192
173193 Ok ( ecx)
174194}
175195
176- pub fn eval_main < ' tcx > (
177- tcx : TyCtxt < ' tcx > ,
178- main_id : DefId ,
179- config : MiriConfig ,
180- ) {
196+ pub fn eval_main < ' tcx > ( tcx : TyCtxt < ' tcx > , main_id : DefId , config : MiriConfig ) {
181197 let mut ecx = match create_ecx ( tcx, main_id, config) {
182198 Ok ( ecx) => ecx,
183199 Err ( mut err) => {
@@ -228,8 +244,9 @@ pub fn eval_main<'tcx>(
228244 // We iterate with indices because we need to look at the next frame (the caller).
229245 for idx in 0 ..frames. len ( ) {
230246 let frame_info = & frames[ idx] ;
231- let call_site_is_local = frames. get ( idx+1 ) . map_or ( false ,
232- |caller_info| caller_info. instance . def_id ( ) . is_local ( ) ) ;
247+ let call_site_is_local = frames. get ( idx + 1 ) . map_or ( false , |caller_info| {
248+ caller_info. instance . def_id ( ) . is_local ( )
249+ } ) ;
233250 if call_site_is_local {
234251 err. span_note ( frame_info. call_site , & frame_info. to_string ( ) ) ;
235252 } else {
0 commit comments