Skip to content

Commit b731a6a

Browse files
committed
Add support for env communication
1 parent 0df7a72 commit b731a6a

File tree

5 files changed

+41
-20
lines changed

5 files changed

+41
-20
lines changed

src/eval.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::{
1313
Scalar, Tag, Pointer, FnVal,
1414
MemoryExtra, MiriMemoryKind, Evaluator, TlsEvalContextExt, HelpersEvalContextExt,
1515
};
16+
use crate::shims::env::alloc_env_value;
1617

1718
/// Configuration needed to spawn a Miri instance.
1819
#[derive(Clone)]
@@ -163,6 +164,13 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
163164

164165
assert!(args.next().is_none(), "start lang item has more arguments than expected");
165166

167+
if config.communicate {
168+
for (name, value) in std::env::vars() {
169+
let value = alloc_env_value(value.as_bytes(), ecx.memory_mut(), &tcx);
170+
ecx.machine.env_vars.insert(name.into_bytes(), value);
171+
}
172+
}
173+
166174
Ok(ecx)
167175
}
168176

src/shims/env.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use rustc::ty::{layout::{Size, Align}, TyCtxt};
2+
use rustc_mir::interpret::Memory;
3+
4+
use crate::*;
5+
6+
pub(crate) fn alloc_env_value<'mir, 'tcx>(bytes: &[u8], memory: &mut Memory<'mir, 'tcx, Evaluator<'tcx>>, tcx: &TyCtxt<'tcx>) -> Pointer<Tag> {
7+
let length = bytes.len() as u64;
8+
// `+1` for the null terminator.
9+
let ptr = memory.allocate(
10+
Size::from_bytes(length + 1),
11+
Align::from_bytes(1).unwrap(),
12+
MiriMemoryKind::Env.into(),
13+
);
14+
// We just allocated these, so the write cannot fail.
15+
let alloc = memory.get_mut(ptr.alloc_id).unwrap();
16+
alloc.write_bytes(tcx, ptr, &bytes).unwrap();
17+
let trailing_zero_ptr = ptr.offset(
18+
Size::from_bytes(length),
19+
tcx,
20+
).unwrap();
21+
alloc.write_bytes(tcx, trailing_zero_ptr, &[0]).unwrap();
22+
ptr
23+
}

src/shims/foreign_items.rs

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use syntax::attr;
55
use syntax::symbol::sym;
66

77
use crate::*;
8+
use crate::shims::env::alloc_env_value;
89

910
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
1011
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
@@ -465,26 +466,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
465466
}
466467
}
467468
if let Some((name, value)) = new {
468-
// `+1` for the null terminator.
469-
let value_copy = this.memory_mut().allocate(
470-
Size::from_bytes((value.len() + 1) as u64),
471-
Align::from_bytes(1).unwrap(),
472-
MiriMemoryKind::Env.into(),
473-
);
474-
// We just allocated these, so the write cannot fail.
475-
let alloc = this.memory_mut().get_mut(value_copy.alloc_id).unwrap();
476-
alloc.write_bytes(tcx, value_copy, &value).unwrap();
477-
let trailing_zero_ptr = value_copy.offset(
478-
Size::from_bytes(value.len() as u64),
479-
tcx,
480-
).unwrap();
481-
alloc.write_bytes(tcx, trailing_zero_ptr, &[0]).unwrap();
482-
483-
if let Some(var) = this.machine.env_vars.insert(
484-
name.to_owned(),
485-
value_copy,
486-
)
487-
{
469+
let value_copy = alloc_env_value(&value, this.memory_mut(), tcx);
470+
if let Some(var) = this.machine.env_vars.insert(name.to_owned(), value_copy) {
488471
this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?;
489472
}
490473
this.write_null(dest)?;

src/shims/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ pub mod foreign_items;
22
pub mod intrinsics;
33
pub mod tls;
44
pub mod dlsym;
5+
pub mod env;
56

67
use rustc::{ty, mir};
78

tests/run-pass/communication.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// ignore-windows: TODO env var emulation stubbed out on Windows
2+
// compile-flags: -Zmiri-enable-communication
3+
4+
fn main() {
5+
assert!(std::env::var("PWD").is_ok());
6+
}

0 commit comments

Comments
 (0)