From 41f8cfa30edc92c3c42a08059d0737d5ee4b87ac Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Wed, 14 Aug 2019 15:44:37 -0500 Subject: [PATCH] Move env shims to its own module --- src/eval.rs | 1 - src/lib.rs | 2 +- src/shims/env.rs | 92 ++++++++++++++++++++++++++++++++------ src/shims/foreign_items.rs | 60 ++----------------------- 4 files changed, 83 insertions(+), 72 deletions(-) diff --git a/src/eval.rs b/src/eval.rs index 0970edb2b75f..ae57bcf98b96 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -39,7 +39,6 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( Evaluator::new(config.communicate), MemoryExtra::new(StdRng::seed_from_u64(config.seed.unwrap_or(0)), config.validate), ); - // Complete initialization. EnvVars::init(&mut ecx, config.communicate); diff --git a/src/lib.rs b/src/lib.rs index 738419c2498b..cea99d86eaa8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,7 +33,7 @@ pub use crate::shims::foreign_items::EvalContextExt as ForeignItemsEvalContextEx pub use crate::shims::intrinsics::EvalContextExt as IntrinsicsEvalContextExt; pub use crate::shims::tls::{EvalContextExt as TlsEvalContextExt, TlsData}; pub use crate::shims::dlsym::{Dlsym, EvalContextExt as DlsymEvalContextExt}; -pub use crate::shims::env::EnvVars; +pub use crate::shims::env::{EnvVars, EvalContextExt as EnvEvalContextExt}; pub use crate::operator::EvalContextExt as OperatorEvalContextExt; pub use crate::range_map::RangeMap; pub use crate::helpers::{EvalContextExt as HelpersEvalContextExt}; diff --git a/src/shims/env.rs b/src/shims/env.rs index 05c5fbb04309..8362a02c7e80 100644 --- a/src/shims/env.rs +++ b/src/shims/env.rs @@ -22,21 +22,9 @@ impl EnvVars { } } } - - 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>( +fn alloc_env_value<'mir, 'tcx>( bytes: &[u8], memory: &mut Memory<'mir, 'tcx, Evaluator<'tcx>>, ) -> Pointer { @@ -58,3 +46,81 @@ pub(crate) fn alloc_env_value<'mir, 'tcx>( alloc.write_bytes(&tcx, trailing_zero_ptr, &[0]).unwrap(); ptr } + +impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} +pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> { + fn getenv( + &mut self, + name_op: OpTy<'tcx, Tag>, + dest: PlaceTy<'tcx, Tag> + ) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + + let result = { + let name_ptr = this.read_scalar(name_op)?.not_undef()?; + let name = this.memory().read_c_str(name_ptr)?; + match this.machine.env_vars.map.get(name) { + Some(&var) => Scalar::Ptr(var), + None => Scalar::ptr_null(&*this.tcx), + } + }; + this.write_scalar(result, dest)?; + Ok(()) + } + + fn setenv( + &mut self, + name_op: OpTy<'tcx, Tag>, + value_op: OpTy<'tcx, Tag>, + dest: PlaceTy<'tcx, Tag> + ) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + + let mut new = None; + let name_ptr = this.read_scalar(name_op)?.not_undef()?; + let value_ptr = this.read_scalar(value_op)?.not_undef()?; + let value = this.memory().read_c_str(value_ptr)?; + if !this.is_null(name_ptr)? { + let name = this.memory().read_c_str(name_ptr)?; + if !name.is_empty() && !name.contains(&b'=') { + new = Some((name.to_owned(), value.to_owned())); + } + } + if let Some((name, value)) = new { + let value_copy = alloc_env_value(&value, this.memory_mut()); + if let Some(var) = this.machine.env_vars.map.insert(name.to_owned(), value_copy) { + this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?; + } + this.write_null(dest)?; + } else { + this.write_scalar(Scalar::from_int(-1, dest.layout.size), dest)?; + } + Ok(()) + } + + fn unsetenv( + &mut self, + name_op: OpTy<'tcx, Tag>, + dest: PlaceTy<'tcx, Tag> + ) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + + let mut success = None; + let name_ptr = this.read_scalar(name_op)?.not_undef()?; + 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.map.remove(&name)); + } + } + if let Some(old) = success { + if let Some(var) = old { + this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?; + } + this.write_null(dest)?; + } else { + this.write_scalar(Scalar::from_int(-1, dest.layout.size), dest)?; + } + Ok(()) + } +} diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index 2d2b917eb275..34b54f329024 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -8,7 +8,6 @@ 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> { @@ -422,62 +421,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx } } - "getenv" => { - let result = { - let name_ptr = this.read_scalar(args[0])?.not_undef()?; - let name = this.memory().read_c_str(name_ptr)?; - match this.machine.env_vars.get(name) { - Some(&var) => Scalar::Ptr(var), - None => Scalar::ptr_null(&*this.tcx), - } - }; - this.write_scalar(result, dest)?; - } - - "unsetenv" => { - let mut success = None; - { - let name_ptr = this.read_scalar(args[0])?.not_undef()?; - 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.unset(&name)); - } - } - } - if let Some(old) = success { - if let Some(var) = old { - this.memory_mut().deallocate(var, None, MiriMemoryKind::Env.into())?; - } - this.write_null(dest)?; - } else { - this.write_scalar(Scalar::from_int(-1, dest.layout.size), dest)?; - } - } - - "setenv" => { - let mut new = None; - { - let name_ptr = this.read_scalar(args[0])?.not_undef()?; - let value_ptr = this.read_scalar(args[1])?.not_undef()?; - let value = this.memory().read_c_str(value_ptr)?; - if !this.is_null(name_ptr)? { - let name = this.memory().read_c_str(name_ptr)?; - if !name.is_empty() && !name.contains(&b'=') { - new = Some((name.to_owned(), value.to_owned())); - } - } - } - if let Some((name, value)) = new { - let value_copy = alloc_env_value(&value, this.memory_mut()); - 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)?; - } else { - this.write_scalar(Scalar::from_int(-1, dest.layout.size), dest)?; - } - } + "getenv" => this.getenv(args[0], dest)?, + "unsetenv" => this.unsetenv(args[0], dest)?, + "setenv" => this.setenv(args[0], args[1], dest)?, "write" => { let fd = this.read_scalar(args[0])?.to_i32()?;