Skip to content

Commit 4f5fdc5

Browse files
committed
update the environ shim when environment changes
1 parent d13fe01 commit 4f5fdc5

File tree

3 files changed

+38
-24
lines changed

3 files changed

+38
-24
lines changed

src/eval.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
7777
),
7878
);
7979
// Complete initialization.
80-
EnvVars::init(&mut ecx, config.excluded_env_vars);
8180
MemoryExtra::init_extern_statics(&mut ecx)?;
81+
EnvVars::init(&mut ecx, config.excluded_env_vars);
8282

8383
// Setup first stack-frame
8484
let main_instance = ty::Instance::mono(tcx, main_id);

src/machine.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ pub struct AllocExtra {
7070

7171
/// Extra global memory data
7272
#[derive(Clone, Debug)]
73-
pub struct MemoryExtra {
73+
pub struct MemoryExtra<'tcx> {
7474
pub stacked_borrows: Option<stacked_borrows::MemoryExtra>,
7575
pub intptrcast: intptrcast::MemoryExtra,
7676

@@ -85,11 +85,11 @@ pub struct MemoryExtra {
8585
/// (helps for debugging memory leaks).
8686
tracked_alloc_id: Option<AllocId>,
8787

88-
/// The `AllocId` for the `environ` static.
89-
pub(crate) environ: Option<Scalar<Tag>>,
88+
/// Place where the `environ` static is stored.
89+
pub(crate) environ: Option<MPlaceTy<'tcx, Tag>>,
9090
}
9191

92-
impl MemoryExtra {
92+
impl<'tcx> MemoryExtra<'tcx> {
9393
pub fn new(rng: StdRng, stacked_borrows: bool, tracked_pointer_tag: Option<PtrId>, tracked_alloc_id: Option<AllocId>) -> Self {
9494
let stacked_borrows = if stacked_borrows {
9595
Some(Rc::new(RefCell::new(stacked_borrows::GlobalState::new(tracked_pointer_tag))))
@@ -107,7 +107,7 @@ impl MemoryExtra {
107107
}
108108

109109
/// Sets up the "extern statics" for this machine.
110-
pub fn init_extern_statics<'mir, 'tcx>(
110+
pub fn init_extern_statics<'mir>(
111111
this: &mut MiriEvalContext<'mir, 'tcx>,
112112
) -> InterpResult<'tcx> {
113113
match this.tcx.sess.target.target.target_os.as_str() {
@@ -126,12 +126,13 @@ impl MemoryExtra {
126126
// "environ"
127127
let layout = this.layout_of(this.tcx.types.usize)?;
128128
let place = this.allocate(layout, MiriMemoryKind::Machine.into());
129-
this.write_scalar(this.memory.extra.environ.unwrap(), place.into())?;
129+
this.write_scalar(Scalar::from_machine_usize(0, &*this.tcx), place.into())?;
130130
this.memory
131131
.extra
132132
.extern_statics
133133
.insert(Symbol::intern("environ"), place.ptr.assert_ptr().alloc_id)
134134
.unwrap_none();
135+
this.memory.extra.environ = Some(place);
135136
}
136137
_ => {} // No "extern statics" supported on this platform
137138
}
@@ -217,7 +218,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
217218
type MemoryKinds = MiriMemoryKind;
218219

219220
type FrameExtra = FrameData<'tcx>;
220-
type MemoryExtra = MemoryExtra;
221+
type MemoryExtra = MemoryExtra<'tcx>;
221222
type AllocExtra = AllocExtra;
222223
type PointerTag = Tag;
223224
type ExtraFnVal = Dlsym;
@@ -343,7 +344,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
343344
}
344345

345346
fn init_allocation_extra<'b>(
346-
memory_extra: &MemoryExtra,
347+
memory_extra: &MemoryExtra<'tcx>,
347348
id: AllocId,
348349
alloc: Cow<'b, Allocation>,
349350
kind: Option<MemoryKind<Self::MemoryKinds>>,
@@ -380,7 +381,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
380381
}
381382

382383
#[inline(always)]
383-
fn tag_static_base_pointer(memory_extra: &MemoryExtra, id: AllocId) -> Self::PointerTag {
384+
fn tag_static_base_pointer(memory_extra: &MemoryExtra<'tcx>, id: AllocId) -> Self::PointerTag {
384385
if let Some(stacked_borrows) = memory_extra.stacked_borrows.as_ref() {
385386
stacked_borrows.borrow_mut().static_base_ptr(id)
386387
} else {

src/shims/env.rs

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,29 +21,16 @@ impl EnvVars {
2121
ecx: &mut InterpCx<'mir, 'tcx, Evaluator<'tcx>>,
2222
excluded_env_vars: Vec<String>,
2323
) {
24-
let mut vars = Vec::new();
2524
if ecx.machine.communicate {
2625
for (name, value) in env::vars() {
2726
if !excluded_env_vars.contains(&name) {
2827
let var_ptr =
2928
alloc_env_var_as_c_str(name.as_ref(), value.as_ref(), ecx);
3029
ecx.machine.env_vars.map.insert(OsString::from(name), var_ptr);
31-
vars.push(var_ptr.into());
3230
}
3331
}
3432
}
35-
// Add the trailing null pointer
36-
vars.push(Scalar::from_int(0, ecx.pointer_size()));
37-
// Make an array with all these pointers inside Miri.
38-
let tcx = ecx.tcx;
39-
let environ_layout =
40-
ecx.layout_of(tcx.mk_array(tcx.mk_imm_ptr(tcx.types.u8), vars.len() as u64)).unwrap();
41-
let environ_place = ecx.allocate(environ_layout, MiriMemoryKind::Machine.into());
42-
for (idx, var) in vars.into_iter().enumerate() {
43-
let place = ecx.mplace_field(environ_place, idx as u64).unwrap();
44-
ecx.write_scalar(var, place.into()).unwrap();
45-
}
46-
ecx.memory.extra.environ = Some(environ_place.ptr.into());
33+
ecx.update_environ().unwrap();
4734
}
4835
}
4936

@@ -94,6 +81,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9481
if let Some((name, value)) = new {
9582
let var_ptr = alloc_env_var_as_c_str(&name, &value, &mut this);
9683
if let Some(var) = this.machine.env_vars.map.insert(name.to_owned(), var_ptr) {
84+
this.update_environ()?;
9785
this.memory
9886
.deallocate(var, None, MiriMemoryKind::Machine.into())?;
9987
}
@@ -112,6 +100,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
112100
let name = this.read_os_str_from_c_str(name_ptr)?.to_owned();
113101
if !name.is_empty() && !name.to_string_lossy().contains('=') {
114102
success = Some(this.machine.env_vars.map.remove(&name));
103+
this.update_environ()?;
115104
}
116105
}
117106
if let Some(old) = success {
@@ -165,4 +154,28 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
165154
}
166155
}
167156
}
157+
158+
fn update_environ(&mut self) -> InterpResult<'tcx> {
159+
let this = self.eval_context_mut();
160+
// Collect all the pointers to each variable in a vector.
161+
let mut vars: Vec<Scalar<Tag>> = this.machine.env_vars.map.values().map(|&ptr| ptr.into()).collect();
162+
// Add the trailing null pointer.
163+
vars.push(Scalar::from_int(0, this.pointer_size()));
164+
// Make an array with all these pointers inside Miri.
165+
let tcx = this.tcx;
166+
let vars_layout =
167+
this.layout_of(tcx.mk_array(tcx.types.usize, vars.len() as u64))?;
168+
let vars_place = this.allocate(vars_layout, MiriMemoryKind::Machine.into());
169+
for (idx, var) in vars.into_iter().enumerate() {
170+
let place = this.mplace_field(vars_place, idx as u64)?;
171+
this.write_scalar(var, place.into())?;
172+
}
173+
174+
this.write_scalar(
175+
vars_place.ptr,
176+
this.memory.extra.environ.unwrap().into(),
177+
)?;
178+
179+
Ok(())
180+
}
168181
}

0 commit comments

Comments
 (0)