Scalar, Tag, Pointer, FnVal,
MemoryExtra, MiriMemoryKind, Evaluator, TlsEvalContextExt, HelpersEvalContextExt,
};
+use crate::shims::env::alloc_env_value;
/// Configuration needed to spawn a Miri instance.
#[derive(Clone)]
assert!(args.next().is_none(), "start lang item has more arguments than expected");
+ if config.communicate {
+ for (name, value) in std::env::vars() {
+ let value = alloc_env_value(value.as_bytes(), ecx.memory_mut(), &tcx);
+ ecx.machine.env_vars.insert(name.into_bytes(), value);
+ }
+ }
+
Ok(ecx)
}
--- /dev/null
+use rustc::ty::{layout::{Size, Align}, TyCtxt};
+use rustc_mir::interpret::Memory;
+
+use crate::*;
+
+pub(crate) fn alloc_env_value<'mir, 'tcx>(bytes: &[u8], memory: &mut Memory<'mir, 'tcx, Evaluator<'tcx>>, tcx: &TyCtxt<'tcx>) -> Pointer<Tag> {
+ let length = bytes.len() as u64;
+ // `+1` for the null terminator.
+ let ptr = memory.allocate(
+ Size::from_bytes(length + 1),
+ Align::from_bytes(1).unwrap(),
+ MiriMemoryKind::Env.into(),
+ );
+ // We just allocated these, so the write cannot fail.
+ let alloc = memory.get_mut(ptr.alloc_id).unwrap();
+ alloc.write_bytes(tcx, ptr, &bytes).unwrap();
+ let trailing_zero_ptr = ptr.offset(
+ Size::from_bytes(length),
+ tcx,
+ ).unwrap();
+ alloc.write_bytes(tcx, trailing_zero_ptr, &[0]).unwrap();
+ ptr
+}
use syntax::symbol::sym;
use crate::*;
+use crate::shims::env::alloc_env_value;
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
}
}
if let Some((name, value)) = new {
- // `+1` for the null terminator.
- let value_copy = this.memory_mut().allocate(
- Size::from_bytes((value.len() + 1) as u64),
- Align::from_bytes(1).unwrap(),
- MiriMemoryKind::Env.into(),
- );
- // We just allocated these, so the write cannot fail.
- let alloc = this.memory_mut().get_mut(value_copy.alloc_id).unwrap();
- alloc.write_bytes(tcx, value_copy, &value).unwrap();
- let trailing_zero_ptr = value_copy.offset(
- Size::from_bytes(value.len() as u64),
- tcx,
- ).unwrap();
- alloc.write_bytes(tcx, trailing_zero_ptr, &[0]).unwrap();
-
- if let Some(var) = this.machine.env_vars.insert(
- name.to_owned(),
- value_copy,
- )
- {
+ let value_copy = alloc_env_value(&value, this.memory_mut(), tcx);
+ if let Some(var) = this.machine.env_vars.insert(name.to_owned(), value_copy) {
this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?;
}
this.write_null(dest)?;
pub mod intrinsics;
pub mod tls;
pub mod dlsym;
+pub mod env;
use rustc::{ty, mir};
--- /dev/null
+// ignore-windows: TODO env var emulation stubbed out on Windows
+// compile-flags: -Zmiri-enable-communication
+
+fn main() {
+ assert!(std::env::var("PWD").is_ok());
+}