add working shim for environ

This commit is contained in:
Christian Poveda 2020-03-04 12:15:14 -05:00
parent c72af45b1c
commit d13fe01f82
No known key found for this signature in database
GPG Key ID: 27525EF5E7420A50
3 changed files with 30 additions and 1 deletions

View File

@ -77,8 +77,8 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
),
);
// Complete initialization.
MemoryExtra::init_extern_statics(&mut ecx)?;
EnvVars::init(&mut ecx, config.excluded_env_vars);
MemoryExtra::init_extern_statics(&mut ecx)?;
// Setup first stack-frame
let main_instance = ty::Instance::mono(tcx, main_id);

View File

@ -84,6 +84,9 @@ pub struct MemoryExtra {
/// An allocation ID to report when it is being allocated
/// (helps for debugging memory leaks).
tracked_alloc_id: Option<AllocId>,
/// The `AllocId` for the `environ` static.
pub(crate) environ: Option<Scalar<Tag>>,
}
impl MemoryExtra {
@ -99,6 +102,7 @@ impl MemoryExtra {
extern_statics: FxHashMap::default(),
rng: RefCell::new(rng),
tracked_alloc_id,
environ: None,
}
}
@ -118,6 +122,16 @@ impl MemoryExtra {
.extern_statics
.insert(Symbol::intern("__cxa_thread_atexit_impl"), place.ptr.assert_ptr().alloc_id)
.unwrap_none();
// "environ"
let layout = this.layout_of(this.tcx.types.usize)?;
let place = this.allocate(layout, MiriMemoryKind::Machine.into());
this.write_scalar(this.memory.extra.environ.unwrap(), place.into())?;
this.memory
.extra
.extern_statics
.insert(Symbol::intern("environ"), place.ptr.assert_ptr().alloc_id)
.unwrap_none();
}
_ => {} // No "extern statics" supported on this platform
}

View File

@ -2,6 +2,7 @@ use std::ffi::{OsString, OsStr};
use std::env;
use crate::stacked_borrows::Tag;
use crate::rustc_target::abi::LayoutOf;
use crate::*;
use rustc_data_structures::fx::FxHashMap;
@ -20,15 +21,29 @@ impl EnvVars {
ecx: &mut InterpCx<'mir, 'tcx, Evaluator<'tcx>>,
excluded_env_vars: Vec<String>,
) {
let mut vars = Vec::new();
if ecx.machine.communicate {
for (name, value) in env::vars() {
if !excluded_env_vars.contains(&name) {
let var_ptr =
alloc_env_var_as_c_str(name.as_ref(), value.as_ref(), ecx);
ecx.machine.env_vars.map.insert(OsString::from(name), var_ptr);
vars.push(var_ptr.into());
}
}
}
// Add the trailing null pointer
vars.push(Scalar::from_int(0, ecx.pointer_size()));
// Make an array with all these pointers inside Miri.
let tcx = ecx.tcx;
let environ_layout =
ecx.layout_of(tcx.mk_array(tcx.mk_imm_ptr(tcx.types.u8), vars.len() as u64)).unwrap();
let environ_place = ecx.allocate(environ_layout, MiriMemoryKind::Machine.into());
for (idx, var) in vars.into_iter().enumerate() {
let place = ecx.mplace_field(environ_place, idx as u64).unwrap();
ecx.write_scalar(var, place.into()).unwrap();
}
ecx.memory.extra.environ = Some(environ_place.ptr.into());
}
}