3
3
use rand:: rngs:: StdRng ;
4
4
use rand:: SeedableRng ;
5
5
6
- use syntax:: source_map:: DUMMY_SP ;
7
- use rustc:: ty:: { self , TyCtxt } ;
8
- use rustc:: ty:: layout:: { LayoutOf , Size , Align } ;
9
6
use 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 ;
10
10
11
11
use 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 ,
16
15
} ;
17
16
18
17
/// Configuration needed to spawn a Miri instance.
@@ -40,7 +39,10 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
40
39
tcx. at ( syntax:: source_map:: DUMMY_SP ) ,
41
40
ty:: ParamEnv :: reveal_all ( ) ,
42
41
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
+ ) ,
44
46
) ;
45
47
// Complete initialization.
46
48
EnvVars :: init ( & mut ecx, config. excluded_env_vars ) ;
@@ -50,9 +52,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
50
52
let main_mir = ecx. load_mir ( main_instance. def , None ) ?;
51
53
52
54
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" ) ;
56
56
}
57
57
58
58
let start_id = tcx. lang_items ( ) . start_fn ( ) . unwrap ( ) ;
@@ -62,9 +62,10 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
62
62
ecx. tcx . tcx ,
63
63
ty:: ParamEnv :: reveal_all ( ) ,
64
64
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 ( ) ;
68
69
let start_mir = ecx. load_mir ( start_instance. def , None ) ?;
69
70
70
71
if start_mir. arg_count != 3 {
@@ -91,7 +92,9 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
91
92
let mut args = ecx. frame ( ) . body . args_iter ( ) ;
92
93
93
94
// 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) ) ;
95
98
let dest = ecx. local_place ( args. next ( ) . unwrap ( ) ) ?;
96
99
ecx. write_scalar ( Scalar :: Ptr ( main_ptr) , dest) ?;
97
100
@@ -124,16 +127,23 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
124
127
// Add `0` terminator.
125
128
let mut arg = arg. into_bytes ( ) ;
126
129
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
+ ) ;
128
134
}
129
135
// 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
+ ) ?;
131
140
let argvs_place = ecx. allocate ( argvs_layout, MiriMemoryKind :: Env . into ( ) ) ;
132
141
for ( idx, arg) in argvs. into_iter ( ) . enumerate ( ) {
133
142
let place = ecx. mplace_field ( argvs_place, idx as u64 ) ?;
134
143
ecx. write_scalar ( Scalar :: Ptr ( arg) , place. into ( ) ) ?;
135
144
}
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 ) ?;
137
147
// Write a pointer to that place as the argument.
138
148
let argv = argvs_place. ptr ;
139
149
ecx. write_scalar ( argv, dest) ?;
@@ -145,7 +155,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
145
155
}
146
156
// Store command line as UTF-16 for Windows `GetCommandLineW`.
147
157
{
148
- let tcx = & { ecx. tcx . tcx } ;
158
+ let tcx = & { ecx. tcx . tcx } ;
149
159
let cmd_utf16: Vec < u16 > = cmd. encode_utf16 ( ) . collect ( ) ;
150
160
let cmd_ptr = ecx. memory_mut ( ) . allocate (
151
161
Size :: from_bytes ( cmd_utf16. len ( ) as u64 * 2 ) ,
@@ -168,16 +178,22 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
168
178
}
169
179
}
170
180
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;
172
192
173
193
Ok ( ecx)
174
194
}
175
195
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 ) {
181
197
let mut ecx = match create_ecx ( tcx, main_id, config) {
182
198
Ok ( ecx) => ecx,
183
199
Err ( mut err) => {
@@ -228,8 +244,9 @@ pub fn eval_main<'tcx>(
228
244
// We iterate with indices because we need to look at the next frame (the caller).
229
245
for idx in 0 ..frames. len ( ) {
230
246
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
+ } ) ;
233
250
if call_site_is_local {
234
251
err. span_note ( frame_info. call_site , & frame_info. to_string ( ) ) ;
235
252
} else {
0 commit comments