update the environ shim when environment changes
This commit is contained in:
parent
d13fe01f82
commit
4f5fdc5810
3 changed files with 38 additions and 24 deletions
|
|
@ -77,8 +77,8 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
|||
),
|
||||
);
|
||||
// Complete initialization.
|
||||
EnvVars::init(&mut ecx, config.excluded_env_vars);
|
||||
MemoryExtra::init_extern_statics(&mut ecx)?;
|
||||
EnvVars::init(&mut ecx, config.excluded_env_vars);
|
||||
|
||||
// Setup first stack-frame
|
||||
let main_instance = ty::Instance::mono(tcx, main_id);
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ pub struct AllocExtra {
|
|||
|
||||
/// Extra global memory data
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct MemoryExtra {
|
||||
pub struct MemoryExtra<'tcx> {
|
||||
pub stacked_borrows: Option<stacked_borrows::MemoryExtra>,
|
||||
pub intptrcast: intptrcast::MemoryExtra,
|
||||
|
||||
|
|
@ -85,11 +85,11 @@ pub struct MemoryExtra {
|
|||
/// (helps for debugging memory leaks).
|
||||
tracked_alloc_id: Option<AllocId>,
|
||||
|
||||
/// The `AllocId` for the `environ` static.
|
||||
pub(crate) environ: Option<Scalar<Tag>>,
|
||||
/// Place where the `environ` static is stored.
|
||||
pub(crate) environ: Option<MPlaceTy<'tcx, Tag>>,
|
||||
}
|
||||
|
||||
impl MemoryExtra {
|
||||
impl<'tcx> MemoryExtra<'tcx> {
|
||||
pub fn new(rng: StdRng, stacked_borrows: bool, tracked_pointer_tag: Option<PtrId>, tracked_alloc_id: Option<AllocId>) -> Self {
|
||||
let stacked_borrows = if stacked_borrows {
|
||||
Some(Rc::new(RefCell::new(stacked_borrows::GlobalState::new(tracked_pointer_tag))))
|
||||
|
|
@ -107,7 +107,7 @@ impl MemoryExtra {
|
|||
}
|
||||
|
||||
/// Sets up the "extern statics" for this machine.
|
||||
pub fn init_extern_statics<'mir, 'tcx>(
|
||||
pub fn init_extern_statics<'mir>(
|
||||
this: &mut MiriEvalContext<'mir, 'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
match this.tcx.sess.target.target.target_os.as_str() {
|
||||
|
|
@ -126,12 +126,13 @@ impl MemoryExtra {
|
|||
// "environ"
|
||||
let layout = this.layout_of(this.tcx.types.usize)?;
|
||||
let place = this.allocate(layout, MiriMemoryKind::Machine.into());
|
||||
this.write_scalar(this.memory.extra.environ.unwrap(), place.into())?;
|
||||
this.write_scalar(Scalar::from_machine_usize(0, &*this.tcx), place.into())?;
|
||||
this.memory
|
||||
.extra
|
||||
.extern_statics
|
||||
.insert(Symbol::intern("environ"), place.ptr.assert_ptr().alloc_id)
|
||||
.unwrap_none();
|
||||
this.memory.extra.environ = Some(place);
|
||||
}
|
||||
_ => {} // No "extern statics" supported on this platform
|
||||
}
|
||||
|
|
@ -217,7 +218,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
type MemoryKinds = MiriMemoryKind;
|
||||
|
||||
type FrameExtra = FrameData<'tcx>;
|
||||
type MemoryExtra = MemoryExtra;
|
||||
type MemoryExtra = MemoryExtra<'tcx>;
|
||||
type AllocExtra = AllocExtra;
|
||||
type PointerTag = Tag;
|
||||
type ExtraFnVal = Dlsym;
|
||||
|
|
@ -343,7 +344,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
}
|
||||
|
||||
fn init_allocation_extra<'b>(
|
||||
memory_extra: &MemoryExtra,
|
||||
memory_extra: &MemoryExtra<'tcx>,
|
||||
id: AllocId,
|
||||
alloc: Cow<'b, Allocation>,
|
||||
kind: Option<MemoryKind<Self::MemoryKinds>>,
|
||||
|
|
@ -380,7 +381,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn tag_static_base_pointer(memory_extra: &MemoryExtra, id: AllocId) -> Self::PointerTag {
|
||||
fn tag_static_base_pointer(memory_extra: &MemoryExtra<'tcx>, id: AllocId) -> Self::PointerTag {
|
||||
if let Some(stacked_borrows) = memory_extra.stacked_borrows.as_ref() {
|
||||
stacked_borrows.borrow_mut().static_base_ptr(id)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -21,29 +21,16 @@ impl EnvVars {
|
|||
ecx: &mut InterpCx<'mir, 'tcx, Evaluator<'tcx>>,
|
||||
excluded_env_vars: Vec<String>,
|
||||
) {
|
||||
let mut vars = Vec::new();
|
||||
if ecx.machine.communicate {
|
||||
for (name, value) in env::vars() {
|
||||
if !excluded_env_vars.contains(&name) {
|
||||
let var_ptr =
|
||||
alloc_env_var_as_c_str(name.as_ref(), value.as_ref(), ecx);
|
||||
ecx.machine.env_vars.map.insert(OsString::from(name), var_ptr);
|
||||
vars.push(var_ptr.into());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add the trailing null pointer
|
||||
vars.push(Scalar::from_int(0, ecx.pointer_size()));
|
||||
// Make an array with all these pointers inside Miri.
|
||||
let tcx = ecx.tcx;
|
||||
let environ_layout =
|
||||
ecx.layout_of(tcx.mk_array(tcx.mk_imm_ptr(tcx.types.u8), vars.len() as u64)).unwrap();
|
||||
let environ_place = ecx.allocate(environ_layout, MiriMemoryKind::Machine.into());
|
||||
for (idx, var) in vars.into_iter().enumerate() {
|
||||
let place = ecx.mplace_field(environ_place, idx as u64).unwrap();
|
||||
ecx.write_scalar(var, place.into()).unwrap();
|
||||
}
|
||||
ecx.memory.extra.environ = Some(environ_place.ptr.into());
|
||||
ecx.update_environ().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,6 +81,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
if let Some((name, value)) = new {
|
||||
let var_ptr = alloc_env_var_as_c_str(&name, &value, &mut this);
|
||||
if let Some(var) = this.machine.env_vars.map.insert(name.to_owned(), var_ptr) {
|
||||
this.update_environ()?;
|
||||
this.memory
|
||||
.deallocate(var, None, MiriMemoryKind::Machine.into())?;
|
||||
}
|
||||
|
|
@ -112,6 +100,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
let name = this.read_os_str_from_c_str(name_ptr)?.to_owned();
|
||||
if !name.is_empty() && !name.to_string_lossy().contains('=') {
|
||||
success = Some(this.machine.env_vars.map.remove(&name));
|
||||
this.update_environ()?;
|
||||
}
|
||||
}
|
||||
if let Some(old) = success {
|
||||
|
|
@ -165,4 +154,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn update_environ(&mut self) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
// Collect all the pointers to each variable in a vector.
|
||||
let mut vars: Vec<Scalar<Tag>> = this.machine.env_vars.map.values().map(|&ptr| ptr.into()).collect();
|
||||
// Add the trailing null pointer.
|
||||
vars.push(Scalar::from_int(0, this.pointer_size()));
|
||||
// Make an array with all these pointers inside Miri.
|
||||
let tcx = this.tcx;
|
||||
let vars_layout =
|
||||
this.layout_of(tcx.mk_array(tcx.types.usize, vars.len() as u64))?;
|
||||
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Machine.into());
|
||||
for (idx, var) in vars.into_iter().enumerate() {
|
||||
let place = this.mplace_field(vars_place, idx as u64)?;
|
||||
this.write_scalar(var, place.into())?;
|
||||
}
|
||||
|
||||
this.write_scalar(
|
||||
vars_place.ptr,
|
||||
this.memory.extra.environ.unwrap().into(),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue