Skip to content

Commit 808ac8f

Browse files
committed
use write_os_str_to_c_string for unix arg passing
1 parent 6e49f4a commit 808ac8f

File tree

1 file changed

+22
-20
lines changed

1 file changed

+22
-20
lines changed

src/eval.rs

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Main evaluator loop and setting up the initial stack frame.
22
3+
use std::ffi::OsStr;
4+
35
use rand::rngs::StdRng;
46
use rand::SeedableRng;
57

@@ -75,26 +77,15 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
7577
let argc = Scalar::from_uint(config.args.len() as u128, ecx.pointer_size());
7678
// Third argument (`argv`): created from `config.args`.
7779
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();
8082
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);
9889
}
9990
// Make an array with all these pointers, in the Miri memory.
10091
let argvs_layout = ecx.layout_of(
@@ -107,7 +98,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
10798
}
10899
ecx.memory
109100
.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.
111102
let argv = argvs_place.ptr;
112103
// Store `argc` and `argv` for macOS `_NSGetArg{c,v}`.
113104
{
@@ -127,6 +118,17 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
127118
}
128119
// Store command line as UTF-16 for Windows `GetCommandLineW`.
129120
{
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+
130132
let cmd_utf16: Vec<u16> = cmd.encode_utf16().collect();
131133
let cmd_type = tcx.mk_array(tcx.types.u16, cmd_utf16.len() as u64);
132134
let cmd_place = ecx.allocate(ecx.layout_of(cmd_type)?, MiriMemoryKind::Env.into());

0 commit comments

Comments
 (0)