Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add helper alloc_os_str_as_c_str and use it in env_var emulation #1098

Closed
wants to merge 12 commits into from
5 changes: 3 additions & 2 deletions src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,15 +483,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx

fn alloc_os_str_as_c_str(
&mut self,
os_str : &OsStr
os_str: &OsStr,
memkind: MemoryKind<MiriMemoryKind>
) -> Pointer<Tag> {
let bytes = os_str_to_bytes(os_str).unwrap();
let size = bytes.len() as u64 + 1; // Make space for `0` terminator.

let this = self.eval_context_mut();

let arg_type = this.tcx.mk_array(this.tcx.types.u8, size);
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), MiriMemoryKind::Env.into());
let arg_place = this.allocate(this.layout_of(arg_type).unwrap(), memkind);
self.write_os_str_to_c_str(os_str, arg_place.ptr, size).unwrap();
arg_place.ptr.assert_ptr()
}
Expand Down
22 changes: 11 additions & 11 deletions src/shims/env.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::collections::HashMap;
use std::ffi::OsString;
use std::ffi::{OsString, OsStr};
use std::env;

use crate::stacked_borrows::Tag;
use crate::*;
use crate::helpers::{ os_str_to_bytes, bytes_to_os_str};
use crate::helpers::os_str_to_bytes;

use rustc::ty::layout::Size;
use rustc_mir::interpret::Pointer;
Expand All @@ -28,7 +28,7 @@ impl EnvVars {
for (name, value) in env::vars() {
if !excluded_env_vars.contains(&name) {
let var_ptr =
alloc_env_var_as_c_str(name.as_bytes(), value.as_bytes(), ecx);
alloc_env_var_as_c_str(name.as_ref(), value.as_ref(), ecx);
RalfJung marked this conversation as resolved.
Show resolved Hide resolved
ecx.machine.env_vars.map.insert(OsString::from(name), var_ptr);
}
}
Expand All @@ -37,15 +37,15 @@ impl EnvVars {
}

fn alloc_env_var_as_c_str<'mir, 'tcx>(
name: &[u8],
value: &[u8],
name: &OsStr,
value: &OsStr,
ecx: &mut InterpCx<'mir, 'tcx, Evaluator<'tcx>>
) -> Pointer<Tag> {
let mut bytes = name.to_vec();
bytes.push(b'=');
bytes.extend_from_slice(value);
bytes.push(0);
ecx.alloc_os_str_as_c_str(bytes_to_os_str(bytes.as_slice()).unwrap())
let mut name_osstring = name.to_os_string();
name_osstring.push("=");
name_osstring.push(value);
name_osstring.push("\u{0000}");
ecx.alloc_os_str_as_c_str(name_osstring.as_os_str(), MiriMemoryKind::Env.into())
JOE1994 marked this conversation as resolved.
Show resolved Hide resolved
}

impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
Expand Down Expand Up @@ -82,7 +82,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
}
}
if let Some((name, value)) = new {
let var_ptr = alloc_env_var_as_c_str(os_str_to_bytes(&name).unwrap(), os_str_to_bytes(&value).unwrap(), &mut this);
let var_ptr = alloc_env_var_as_c_str(name.as_os_str(), value.as_os_str(), &mut this);
JOE1994 marked this conversation as resolved.
Show resolved Hide resolved
if let Some(var) = this.machine.env_vars.map.insert(name.to_owned(), var_ptr) {
this.memory
.deallocate(var, None, MiriMemoryKind::Env.into())?;
Expand Down
2 changes: 1 addition & 1 deletion src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -926,7 +926,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
// args[0] : LPCWSTR lpName (32-bit ptr to a const string of 16-bit Unicode chars)
// args[1] : LPCWSTR lpValue (32-bit ptr to a const string of 16-bit Unicode chars)
// Return nonzero if success, else return 0.

throw_unsup_format!("can't call foreign function: {}", link_name);
JOE1994 marked this conversation as resolved.
Show resolved Hide resolved
}
"GetCommandLineW" => {
this.write_scalar(this.machine.cmd_line.expect("machine must be initialized"), dest)?;
Expand Down