]> git.lizzy.rs Git - rust.git/commitdiff
Add support for env communication
authorChristian Poveda <christianpoveda@protonmail.com>
Tue, 6 Aug 2019 22:40:07 +0000 (17:40 -0500)
committerChristian Poveda <christianpoveda@protonmail.com>
Tue, 6 Aug 2019 22:40:07 +0000 (17:40 -0500)
src/eval.rs
src/shims/env.rs [new file with mode: 0644]
src/shims/foreign_items.rs
src/shims/mod.rs
tests/run-pass/communication.rs [new file with mode: 0644]

index e80162ec1796dc40a20f9b4aa12398df2c2be85a..b171b38a6cbd5a4ad2fdf7d6cf8ca22bf08f6f66 100644 (file)
@@ -13,6 +13,7 @@
     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)
 }
 
diff --git a/src/shims/env.rs b/src/shims/env.rs
new file mode 100644 (file)
index 0000000..0cb8c9c
--- /dev/null
@@ -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
+}
index 37e5fe42c3de7829f71c77d48f87700ba12d3972..b1554395b692b543b58f31d7f1f4a9da3bc556e7 100644 (file)
@@ -5,6 +5,7 @@
 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 @@ fn emulate_foreign_item(
                     }
                 }
                 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)?;
index c06373005ff9919155009afa5b2f1964f37da7e4..96a1f34152b329d0d51ace78e08146d1b23c73fc 100644 (file)
@@ -2,6 +2,7 @@
 pub mod intrinsics;
 pub mod tls;
 pub mod dlsym;
+pub mod env;
 
 use rustc::{ty, mir};
 
diff --git a/tests/run-pass/communication.rs b/tests/run-pass/communication.rs
new file mode 100644 (file)
index 0000000..08c6bd8
--- /dev/null
@@ -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());
+}