Add support for env communication
This commit is contained in:
parent
0df7a728c6
commit
b731a6a15f
5 changed files with 41 additions and 20 deletions
|
|
@ -13,6 +13,7 @@ use crate::{
|
|||
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)]
|
||||
|
|
@ -163,6 +164,13 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
|||
|
||||
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)
|
||||
}
|
||||
|
||||
|
|
|
|||
23
src/shims/env.rs
Normal file
23
src/shims/env.rs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
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
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ use syntax::attr;
|
|||
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> {
|
||||
|
|
@ -465,26 +466,8 @@ 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)?;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ pub mod foreign_items;
|
|||
pub mod intrinsics;
|
||||
pub mod tls;
|
||||
pub mod dlsym;
|
||||
pub mod env;
|
||||
|
||||
use rustc::{ty, mir};
|
||||
|
||||
|
|
|
|||
6
tests/run-pass/communication.rs
Normal file
6
tests/run-pass/communication.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
// ignore-windows: TODO env var emulation stubbed out on Windows
|
||||
// compile-flags: -Zmiri-enable-communication
|
||||
|
||||
fn main() {
|
||||
assert!(std::env::var("PWD").is_ok());
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue