Auto merge of #907 - christianpoveda:env-vars-shim, r=RalfJung

Move env shims to its own module

r? @RalfJung
This commit is contained in:
bors 2019-08-15 08:47:20 +00:00
commit 868da2a139
4 changed files with 76 additions and 63 deletions

View file

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

View file

@ -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};

View file

@ -22,21 +22,9 @@ impl EnvVars {
}
}
}
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>(
fn alloc_env_value<'mir, 'tcx>(
bytes: &[u8],
memory: &mut Memory<'mir, 'tcx, Evaluator<'tcx>>,
) -> Pointer<Tag> {
@ -58,3 +46,72 @@ 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>,
) -> InterpResult<'tcx, Scalar<Tag>> {
let this = self.eval_context_mut();
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
let name = this.memory().read_c_str(name_ptr)?;
Ok(match this.machine.env_vars.map.get(name) {
Some(&var) => Scalar::Ptr(var),
None => Scalar::ptr_null(&*this.tcx),
})
}
fn setenv(
&mut self,
name_op: OpTy<'tcx, Tag>,
value_op: OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
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)?;
let mut new = None;
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())?;
}
Ok(0)
} else {
Ok(-1)
}
}
fn unsetenv(
&mut self,
name_op: OpTy<'tcx, Tag>,
) -> InterpResult<'tcx, i32> {
let this = self.eval_context_mut();
let name_ptr = this.read_scalar(name_op)?.not_undef()?;
let mut success = None;
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())?;
}
Ok(0)
} else {
Ok(-1)
}
}
}

View file

@ -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> {
@ -423,60 +422,18 @@ 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),
}
};
let result = this.getenv(args[0])?;
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)?;
}
let result = this.unsetenv(args[0])?;
this.write_scalar(Scalar::from_int(result, 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)?;
}
let result = this.setenv(args[0], args[1])?;
this.write_scalar(Scalar::from_int(result, dest.layout.size), dest)?;
}
"write" => {