1
1
//! Main evaluator loop and setting up the initial stack frame.
2
2
3
+ use std:: ffi:: OsStr ;
4
+
3
5
use rand:: rngs:: StdRng ;
4
6
use rand:: SeedableRng ;
5
7
@@ -75,26 +77,15 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
75
77
let argc = Scalar :: from_uint ( config. args . len ( ) as u128 , ecx. pointer_size ( ) ) ;
76
78
// Third argument (`argv`): created from `config.args`.
77
79
let argv = {
78
- // For Windows, construct a command string with all the aguments (before we take apart `config.args`) .
79
- let mut cmd = String :: new ( ) ;
80
+ // Put each argument in memory, collect pointers .
81
+ let mut argvs = Vec :: < Scalar < Tag > > :: new ( ) ;
80
82
for arg in config. args . iter ( ) {
81
- if !cmd. is_empty ( ) {
82
- cmd. push ( ' ' ) ;
83
- }
84
- cmd. push_str ( & * shell_escape:: windows:: escape ( arg. as_str ( ) . into ( ) ) ) ;
85
- }
86
- // Don't forget `0` terminator.
87
- cmd. push ( std:: char:: from_u32 ( 0 ) . unwrap ( ) ) ;
88
- // Collect the pointers to the individual strings.
89
- let mut argvs = Vec :: < Pointer < Tag > > :: new ( ) ;
90
- for arg in config. args {
91
- // Add `0` terminator.
92
- let mut arg = arg. into_bytes ( ) ;
93
- arg. push ( 0 ) ;
94
- argvs. push (
95
- ecx. memory
96
- . allocate_static_bytes ( arg. as_slice ( ) , MiriMemoryKind :: Env . into ( ) ) ,
97
- ) ;
83
+ // Make space for `0` terminator.
84
+ let size = arg. len ( ) as u64 + 1 ;
85
+ let arg_type = tcx. mk_array ( tcx. types . u8 , size) ;
86
+ let arg_place = ecx. allocate ( ecx. layout_of ( arg_type) ?, MiriMemoryKind :: Env . into ( ) ) ;
87
+ ecx. write_os_str_to_c_string ( OsStr :: new ( arg) , arg_place. ptr , size) ?;
88
+ argvs. push ( arg_place. ptr ) ;
98
89
}
99
90
// Make an array with all these pointers, in the Miri memory.
100
91
let argvs_layout = ecx. layout_of (
@@ -107,7 +98,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
107
98
}
108
99
ecx. memory
109
100
. mark_immutable ( argvs_place. ptr . assert_ptr ( ) . alloc_id ) ?;
110
- // A pointer to that place is the argument.
101
+ // A pointer to that place is the 3rd argument for main .
111
102
let argv = argvs_place. ptr ;
112
103
// Store `argc` and `argv` for macOS `_NSGetArg{c,v}`.
113
104
{
@@ -127,6 +118,17 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
127
118
}
128
119
// Store command line as UTF-16 for Windows `GetCommandLineW`.
129
120
{
121
+ // Construct a command string with all the aguments.
122
+ let mut cmd = String :: new ( ) ;
123
+ for arg in config. args . iter ( ) {
124
+ if !cmd. is_empty ( ) {
125
+ cmd. push ( ' ' ) ;
126
+ }
127
+ cmd. push_str ( & * shell_escape:: windows:: escape ( arg. as_str ( ) . into ( ) ) ) ;
128
+ }
129
+ // Don't forget `0` terminator.
130
+ cmd. push ( std:: char:: from_u32 ( 0 ) . unwrap ( ) ) ;
131
+
130
132
let cmd_utf16: Vec < u16 > = cmd. encode_utf16 ( ) . collect ( ) ;
131
133
let cmd_type = tcx. mk_array ( tcx. types . u16 , cmd_utf16. len ( ) as u64 ) ;
132
134
let cmd_place = ecx. allocate ( ecx. layout_of ( cmd_type) ?, MiriMemoryKind :: Env . into ( ) ) ;
0 commit comments