Move env shims to its own module

This commit is contained in:
Christian Poveda 2019-08-14 15:44:37 -05:00
parent 1f504ea7be
commit 41f8cfa30e
4 changed files with 83 additions and 72 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,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(())
}
}

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