Skip to content

Commit 3b718a3

Browse files
committed
try to update the environ shim when environment changes
1 parent 06703ba commit 3b718a3

File tree

3 files changed

+40
-24
lines changed

3 files changed

+40
-24
lines changed

src/eval.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
5858
),
5959
);
6060
// Complete initialization.
61-
EnvVars::init(&mut ecx, config.excluded_env_vars);
6261
MemoryExtra::init_extern_statics(&mut ecx)?;
62+
EnvVars::init(&mut ecx, config.excluded_env_vars);
6363

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

src/machine.rs

+10-9
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

@@ -80,11 +80,11 @@ pub struct MemoryExtra {
8080
/// The random number generator used for resolving non-determinism.
8181
/// Needs to be queried by ptr_to_int, hence needs interior mutability.
8282
pub(crate) rng: RefCell<StdRng>,
83-
/// The `AllocId` for the `environ` static.
84-
pub(crate) environ: Option<Scalar<Tag>>,
83+
/// Place where the `environ` static is stored.
84+
pub(crate) environ: Option<MPlaceTy<'tcx, Tag>>,
8585
}
8686

87-
impl MemoryExtra {
87+
impl<'tcx> MemoryExtra<'tcx> {
8888
pub fn new(rng: StdRng, stacked_borrows: bool, tracked_pointer_tag: Option<PtrId>) -> Self {
8989
let stacked_borrows = if stacked_borrows {
9090
Some(Rc::new(RefCell::new(stacked_borrows::GlobalState::new(tracked_pointer_tag))))
@@ -101,7 +101,7 @@ impl MemoryExtra {
101101
}
102102

103103
/// Sets up the "extern statics" for this machine.
104-
pub fn init_extern_statics<'mir, 'tcx>(
104+
pub fn init_extern_statics<'mir>(
105105
this: &mut MiriEvalContext<'mir, 'tcx>,
106106
) -> InterpResult<'tcx> {
107107
match this.tcx.sess.target.target.target_os.as_str() {
@@ -120,12 +120,13 @@ impl MemoryExtra {
120120
// "environ"
121121
let layout = this.layout_of(this.tcx.types.usize)?;
122122
let place = this.allocate(layout, MiriMemoryKind::Machine.into());
123-
this.write_scalar(this.memory.extra.environ.unwrap(), place.into())?;
123+
this.write_scalar(Scalar::from_machine_usize(0, &*this.tcx), place.into())?;
124124
this.memory
125125
.extra
126126
.extern_statics
127127
.insert("environ", place.ptr.assert_ptr().alloc_id)
128128
.unwrap_none();
129+
this.memory.extra.environ = Some(place);
129130
}
130131
_ => {} // No "extern statics" supported on this platform
131132
}
@@ -211,7 +212,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
211212
type MemoryKinds = MiriMemoryKind;
212213

213214
type FrameExtra = FrameData<'tcx>;
214-
type MemoryExtra = MemoryExtra;
215+
type MemoryExtra = MemoryExtra<'tcx>;
215216
type AllocExtra = AllocExtra;
216217
type PointerTag = Tag;
217218
type ExtraFnVal = Dlsym;
@@ -337,7 +338,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
337338
}
338339

339340
fn init_allocation_extra<'b>(
340-
memory_extra: &MemoryExtra,
341+
memory_extra: &MemoryExtra<'tcx>,
341342
id: AllocId,
342343
alloc: Cow<'b, Allocation>,
343344
kind: Option<MemoryKind<Self::MemoryKinds>>,
@@ -370,7 +371,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
370371
}
371372

372373
#[inline(always)]
373-
fn tag_static_base_pointer(memory_extra: &MemoryExtra, id: AllocId) -> Self::PointerTag {
374+
fn tag_static_base_pointer(memory_extra: &MemoryExtra<'tcx>, id: AllocId) -> Self::PointerTag {
374375
if let Some(stacked_borrows) = memory_extra.stacked_borrows.as_ref() {
375376
stacked_borrows.borrow_mut().static_base_ptr(id)
376377
} else {

src/shims/env.rs

+29-14
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,30 @@ 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 environ_layout =
167+
this.layout_of(tcx.mk_array(tcx.mk_imm_ptr(tcx.types.u8), vars.len() as u64))?;
168+
let environ_place = this.allocate(environ_layout, MiriMemoryKind::Machine.into());
169+
for (idx, var) in vars.into_iter().enumerate() {
170+
let place = this.mplace_field(environ_place, idx as u64)?;
171+
this.write_scalar(var, place.into())?;
172+
}
173+
174+
let scalar: Scalar<Tag> = environ_place.ptr.into();
175+
176+
this.write_scalar(
177+
scalar,
178+
this.memory.extra.environ.unwrap().into()
179+
)?;
180+
181+
Ok(())
182+
}
168183
}

0 commit comments

Comments
 (0)