Wrap hashmap for env vars in its own type

This commit is contained in:
Christian Poveda 2019-08-13 11:34:43 -05:00
parent 253af9692a
commit 666cd22fa6
4 changed files with 42 additions and 14 deletions

View File

@ -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<String>,
/// 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<u64>,
}
@ -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)

View File

@ -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<Vec<u8>, Pointer<Tag>>,
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,

View File

@ -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<Vec<u8>, Pointer<Tag>>,
}
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<Tag>> {
self.map.get(name)
}
pub(crate) fn unset(&mut self, name: &[u8]) -> Option<Pointer<Tag>> {
self.map.remove(name)
}
pub(crate) fn set(&mut self, name: Vec<u8>, ptr: Pointer<Tag>) -> Option<Pointer<Tag>>{
self.map.insert(name, ptr)
}
}
pub(crate) fn alloc_env_value<'mir, 'tcx>(
bytes: &[u8],
memory: &mut Memory<'mir, 'tcx, Evaluator<'tcx>>,

View File

@ -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)?;