@@ -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,56 @@ 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" ;
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 ( )
154
+ . chain ( Some ( 0 ) ) // add 0-terminator
155
+ . collect ( ) ;
156
+ let cmd_ptr = ecx. memory_mut ( ) . allocate (
157
+ Size :: from_bytes ( cmd_utf16. len ( ) as u64 * 2 ) ,
158
+ Align :: from_bytes ( 2 ) . unwrap ( ) ,
159
+ MiriMemoryKind :: Env . into ( ) ,
160
+ ) ?. with_default_tag ( ) ;
161
+ ecx. machine . cmd_line = Some ( cmd_ptr) ;
162
+ // store the UTF-16 string
163
+ let char_size = Size :: from_bytes ( 2 ) ;
164
+ let cmd_alloc = ecx. memory_mut ( ) . get_mut ( cmd_ptr. alloc_id ) ?;
165
+ let mut cur_ptr = cmd_ptr;
166
+ for & c in cmd_utf16. iter ( ) {
167
+ cmd_alloc. write_scalar (
168
+ tcx,
169
+ cur_ptr,
170
+ Scalar :: from_uint ( c, char_size) . into ( ) ,
171
+ char_size,
172
+ ) ?;
173
+ cur_ptr = cur_ptr. offset ( char_size, tcx) ?;
174
+ }
175
+ }
144
176
145
177
assert ! ( args. next( ) . is_none( ) , "start lang item has more arguments than expected" ) ;
146
178
@@ -263,8 +295,13 @@ pub struct Evaluator<'tcx> {
263
295
264
296
/// Program arguments (`Option` because we can only initialize them after creating the ecx).
265
297
/// These are *pointers* to argc/argv because macOS.
298
+ /// We also need the full cmdline as one string because Window.
266
299
pub ( crate ) argc : Option < Pointer < Borrow > > ,
267
300
pub ( crate ) argv : Option < Pointer < Borrow > > ,
301
+ pub ( crate ) cmd_line : Option < Pointer < Borrow > > ,
302
+
303
+ /// Last OS error
304
+ pub ( crate ) last_error : u32 ,
268
305
269
306
/// TLS state
270
307
pub ( crate ) tls : TlsData < ' tcx > ,
@@ -282,6 +319,8 @@ impl<'tcx> Evaluator<'tcx> {
282
319
env_vars : HashMap :: default ( ) ,
283
320
argc : None ,
284
321
argv : None ,
322
+ cmd_line : None ,
323
+ last_error : 0 ,
285
324
tls : TlsData :: default ( ) ,
286
325
validate,
287
326
stacked_borrows : stacked_borrows:: State :: default ( ) ,
0 commit comments