@@ -18,7 +18,7 @@ use std::borrow::Cow;
18
18
use std:: env;
19
19
20
20
use rustc:: ty:: { self , TyCtxt , query:: TyCtxtAt } ;
21
- use rustc:: ty:: layout:: { TyLayout , LayoutOf , Size } ;
21
+ use rustc:: ty:: layout:: { TyLayout , LayoutOf , Size , Align } ;
22
22
use rustc:: hir:: { self , def_id:: DefId } ;
23
23
use rustc:: mir;
24
24
@@ -123,24 +123,54 @@ pub fn create_ecx<'a, 'mir: 'a, 'tcx: 'mir>(
123
123
let dest = ecx. eval_place ( & mir:: Place :: Local ( args. next ( ) . unwrap ( ) ) ) ?;
124
124
let argc = Scalar :: from_int ( 1 , dest. layout . size ) ;
125
125
ecx. write_scalar ( argc, dest) ?;
126
- let argc_place = ecx. allocate ( dest. layout , MiriMemoryKind :: Env . into ( ) ) ?;
127
- ecx. write_scalar ( argc, argc_place. into ( ) ) ?;
128
- ecx. machine . argc = Some ( argc_place. ptr . to_ptr ( ) ?) ;
126
+ // Store argc for macOS _NSGetArgc
127
+ {
128
+ let argc_place = ecx. allocate ( dest. layout , MiriMemoryKind :: Env . into ( ) ) ?;
129
+ ecx. write_scalar ( argc, argc_place. into ( ) ) ?;
130
+ ecx. machine . argc = Some ( argc_place. ptr . to_ptr ( ) ?) ;
131
+ }
129
132
130
133
// FIXME: extract main source file path
131
134
// Third argument (argv): &[b"foo"]
135
+ const CMD : & str = "running-in-miri\0 " ;
132
136
let dest = ecx. eval_place ( & mir:: Place :: Local ( args. next ( ) . unwrap ( ) ) ) ?;
133
- let foo = ecx. memory_mut ( ) . allocate_static_bytes ( b"foo\0 " ) . with_default_tag ( ) ;
134
- let foo_ty = ecx. tcx . mk_imm_ptr ( ecx. tcx . types . u8 ) ;
135
- let foo_layout = ecx. layout_of ( foo_ty) ?;
136
- let foo_place = ecx. allocate ( foo_layout, MiriMemoryKind :: Env . into ( ) ) ?;
137
- ecx. write_scalar ( Scalar :: Ptr ( foo) , foo_place. into ( ) ) ?;
138
- ecx. memory_mut ( ) . mark_immutable ( foo_place. to_ptr ( ) ?. alloc_id ) ?;
139
- let argv = foo_place. ptr ;
140
- ecx. write_scalar ( argv, dest) ?;
141
- let argv_place = ecx. allocate ( dest. layout , MiriMemoryKind :: Env . into ( ) ) ?;
142
- ecx. write_scalar ( argv, argv_place. into ( ) ) ?;
143
- ecx. machine . argv = Some ( argv_place. ptr . to_ptr ( ) ?) ;
137
+ let cmd = ecx. memory_mut ( ) . allocate_static_bytes ( CMD . as_bytes ( ) ) . with_default_tag ( ) ;
138
+ let raw_str_layout = ecx. layout_of ( ecx. tcx . mk_imm_ptr ( ecx. tcx . types . u8 ) ) ?;
139
+ let cmd_place = ecx. allocate ( raw_str_layout, MiriMemoryKind :: Env . into ( ) ) ?;
140
+ ecx. write_scalar ( Scalar :: Ptr ( cmd) , cmd_place. into ( ) ) ?;
141
+ ecx. memory_mut ( ) . mark_immutable ( cmd_place. to_ptr ( ) ?. alloc_id ) ?;
142
+ // Store argv for macOS _NSGetArgv
143
+ {
144
+ let argv = cmd_place. ptr ;
145
+ ecx. write_scalar ( argv, dest) ?;
146
+ let argv_place = ecx. allocate ( dest. layout , MiriMemoryKind :: Env . into ( ) ) ?;
147
+ ecx. write_scalar ( argv, argv_place. into ( ) ) ?;
148
+ ecx. machine . argv = Some ( argv_place. ptr . to_ptr ( ) ?) ;
149
+ }
150
+ // Store cmdline as UTF-16 for Windows GetCommandLineW
151
+ {
152
+ let tcx = & { ecx. tcx . tcx } ;
153
+ let cmd_utf16: Vec < u16 > = CMD . encode_utf16 ( ) . collect ( ) ;
154
+ let cmd_ptr = ecx. memory_mut ( ) . allocate (
155
+ Size :: from_bytes ( cmd_utf16. len ( ) as u64 * 2 ) ,
156
+ Align :: from_bytes ( 2 ) . unwrap ( ) ,
157
+ MiriMemoryKind :: Env . into ( ) ,
158
+ ) ?. with_default_tag ( ) ;
159
+ ecx. machine . cmd_line = Some ( cmd_ptr) ;
160
+ // store the UTF-16 string
161
+ let char_size = Size :: from_bytes ( 2 ) ;
162
+ let cmd_alloc = ecx. memory_mut ( ) . get_mut ( cmd_ptr. alloc_id ) ?;
163
+ let mut cur_ptr = cmd_ptr;
164
+ for & c in cmd_utf16. iter ( ) {
165
+ cmd_alloc. write_scalar (
166
+ tcx,
167
+ cur_ptr,
168
+ Scalar :: from_uint ( c, char_size) . into ( ) ,
169
+ char_size,
170
+ ) ?;
171
+ cur_ptr = cur_ptr. offset ( char_size, tcx) ?;
172
+ }
173
+ }
144
174
145
175
assert ! ( args. next( ) . is_none( ) , "start lang item has more arguments than expected" ) ;
146
176
@@ -263,8 +293,13 @@ pub struct Evaluator<'tcx> {
263
293
264
294
/// Program arguments (`Option` because we can only initialize them after creating the ecx).
265
295
/// These are *pointers* to argc/argv because macOS.
296
+ /// We also need the full cmdline as one string because Window.
266
297
pub ( crate ) argc : Option < Pointer < Borrow > > ,
267
298
pub ( crate ) argv : Option < Pointer < Borrow > > ,
299
+ pub ( crate ) cmd_line : Option < Pointer < Borrow > > ,
300
+
301
+ /// Last OS error
302
+ pub ( crate ) last_error : u32 ,
268
303
269
304
/// TLS state
270
305
pub ( crate ) tls : TlsData < ' tcx > ,
@@ -282,6 +317,8 @@ impl<'tcx> Evaluator<'tcx> {
282
317
env_vars : HashMap :: default ( ) ,
283
318
argc : None ,
284
319
argv : None ,
320
+ cmd_line : None ,
321
+ last_error : 0 ,
285
322
tls : TlsData :: default ( ) ,
286
323
validate,
287
324
stacked_borrows : stacked_borrows:: State :: default ( ) ,
0 commit comments