From 666cd22fa64ee318edc3b6292efa507442eb2554 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Tue, 13 Aug 2019 11:34:43 -0500 Subject: [PATCH] Wrap hashmap for env vars in its own type --- src/eval.rs | 11 ++++------- src/machine.rs | 6 +++--- src/shims/env.rs | 35 +++++++++++++++++++++++++++++++++-- src/shims/foreign_items.rs | 4 ++-- 4 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/eval.rs b/src/eval.rs index b171b38a6cbd..5e6c8129fb31 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -13,17 +13,17 @@ use crate::{ Scalar, Tag, Pointer, FnVal, MemoryExtra, MiriMemoryKind, Evaluator, TlsEvalContextExt, HelpersEvalContextExt, }; -use crate::shims::env::alloc_env_value; +use crate::shims::env::EnvVars; /// Configuration needed to spawn a Miri instance. #[derive(Clone)] pub struct MiriConfig { + /// Determine if validity checking and Stacked Borrows are enabled. pub validate: bool, /// Determines if communication with the host environment is enabled. pub communicate: bool, pub args: Vec, - - /// The seed to use when non-determinism is required (e.g. getrandom()) + /// The seed to use when non-determinism or randomness are required (e.g. ptr-to-int cast, `getrandom()`). pub seed: Option, } @@ -165,10 +165,7 @@ 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); - } + EnvVars::init(&mut ecx, &tcx); } Ok(ecx) diff --git a/src/machine.rs b/src/machine.rs index ed9a8a1c4634..cc0c85d6603d 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -3,7 +3,6 @@ use std::rc::Rc; use std::borrow::Cow; -use std::collections::HashMap; use std::cell::RefCell; use rand::rngs::StdRng; @@ -15,6 +14,7 @@ use rustc::ty::{self, layout::{Size, LayoutOf}, TyCtxt}; use rustc::mir; use crate::*; +use crate::shims::env::EnvVars; // Some global facts about the emulated machine. pub const PAGE_SIZE: u64 = 4*1024; // FIXME: adjust to target architecture @@ -79,7 +79,7 @@ impl MemoryExtra { pub struct Evaluator<'tcx> { /// Environment variables set by `setenv`. /// Miri does not expose env vars from the host to the emulated program. - pub(crate) env_vars: HashMap, Pointer>, + pub(crate) env_vars: EnvVars, /// Program arguments (`Option` because we can only initialize them after creating the ecx). /// These are *pointers* to argc/argv because macOS. @@ -101,7 +101,7 @@ pub struct Evaluator<'tcx> { impl<'tcx> Evaluator<'tcx> { pub(crate) fn new(communicate: bool) -> Self { Evaluator { - env_vars: HashMap::default(), + env_vars: EnvVars::default(), argc: None, argv: None, cmd_line: None, diff --git a/src/shims/env.rs b/src/shims/env.rs index 56d2bd4b3d3e..09d87d27ebc2 100644 --- a/src/shims/env.rs +++ b/src/shims/env.rs @@ -1,8 +1,39 @@ -use rustc::ty::{layout::{Size, Align}, TyCtxt}; -use rustc_mir::interpret::Memory; +use std::collections::HashMap; +use rustc::ty::{layout::{Size, Align}, TyCtxt}; +use rustc_mir::interpret::{Pointer, Memory}; +use crate::stacked_borrows::Tag; use crate::*; +#[derive(Default)] +pub struct EnvVars { + map: HashMap, Pointer>, +} + +impl EnvVars { + pub(crate) fn init<'mir, 'tcx>( + ecx: &mut InterpCx<'mir, 'tcx, Evaluator<'tcx>>, + tcx: &TyCtxt<'tcx>, + ) { + for (name, value) in std::env::vars() { + let value = alloc_env_value(value.as_bytes(), ecx.memory_mut(), tcx); + ecx.machine.env_vars.map.insert(name.into_bytes(), value); + } + } + + pub(crate) fn get(&self, name: &[u8]) -> Option<&Pointer> { + self.map.get(name) + } + + pub(crate) fn unset(&mut self, name: &[u8]) -> Option> { + self.map.remove(name) + } + + pub(crate) fn set(&mut self, name: Vec, ptr: Pointer) -> Option>{ + self.map.insert(name, ptr) + } +} + pub(crate) fn alloc_env_value<'mir, 'tcx>( bytes: &[u8], memory: &mut Memory<'mir, 'tcx, Evaluator<'tcx>>, diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index b1554395b692..6705183da47f 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -438,7 +438,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx if !this.is_null(name_ptr)? { let name = this.memory().read_c_str(name_ptr)?.to_owned(); if !name.is_empty() && !name.contains(&b'=') { - success = Some(this.machine.env_vars.remove(&name)); + success = Some(this.machine.env_vars.unset(&name)); } } } @@ -467,7 +467,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } if let Some((name, value)) = new { 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) { + if let Some(var) = this.machine.env_vars.set(name.to_owned(), value_copy) { this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?; } this.write_null(dest)?;