Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
pvdrz committed Aug 29, 2019
1 parent b82e7a3 commit 529af9b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 9 deletions.
16 changes: 12 additions & 4 deletions src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub struct MemoryExtra {
pub stacked_borrows: stacked_borrows::MemoryExtra,
pub intptrcast: intptrcast::MemoryExtra,

pub(crate) env_alloc: Option<Allocation<Tag, AllocExtra>>,
/// The random number generator used for resolving non-determinism.
pub(crate) rng: RefCell<StdRng>,

Expand All @@ -68,6 +69,7 @@ impl MemoryExtra {
MemoryExtra {
stacked_borrows: Default::default(),
intptrcast: Default::default(),
env_alloc: Default::default(),
rng: RefCell::new(rng),
validate,
}
Expand Down Expand Up @@ -239,10 +241,11 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
}

fn find_foreign_static(
_memory_extra: &MemoryExtra,
memory_extra: &MemoryExtra,
tcx: TyCtxt<'tcx>,
def_id: DefId,
) -> InterpResult<'tcx, Cow<'tcx, Allocation>> {
id: AllocId,
) -> InterpResult<'tcx, Cow<'tcx, Allocation<Self::PointerTag, Self::AllocExtra>>> {
let attrs = tcx.get_attrs(def_id);
let link_name = match attr::first_attr_value_str_by_name(&attrs, sym::link_name) {
Some(name) => name.as_str(),
Expand All @@ -254,11 +257,16 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
// This should be all-zero, pointer-sized.
let size = tcx.data_layout.pointer_size;
let data = vec![0; size.bytes() as usize];
Allocation::from_bytes(&data, tcx.data_layout.pointer_align.abi)
let alloc = Allocation::from_bytes(&data, tcx.data_layout.pointer_align.abi);
Self::tag_allocation(memory_extra, id, Cow::Owned(alloc), Self::STATIC_KIND.map(MemoryKind::Machine)).0
}
"environ" => {
Cow::Owned(memory_extra.env_alloc.as_ref().unwrap().clone())
}
_ => throw_unsup_format!("can't access foreign static: {}", link_name),
};
Ok(Cow::Owned(alloc))

Ok(alloc)
}

#[inline(always)]
Expand Down
40 changes: 38 additions & 2 deletions src/shims/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,54 @@ pub struct EnvVars {
/// Stores pointers to the environment variables. These variables must be stored as
/// null-terminated C strings with the `"{name}={value}"` format.
map: HashMap<Vec<u8>, Pointer<Tag>>,
env_ptr: Option<Pointer<Tag>>,
}

impl EnvVars {
pub(crate) fn init<'mir, 'tcx>(
ecx: &mut InterpCx<'mir, 'tcx, Evaluator<'tcx>>,
) {
) {
use crate::rustc_target::abi::LayoutOf;

// Vector to store `*u8`s
let mut pointers = Vec::new();
if ecx.machine.communicate {
for (name, value) in std::env::vars() {
let var_ptr = alloc_env_var(name.as_bytes(), value.as_bytes(), ecx.memory_mut());
let mut bytes = [name.as_bytes(), b"=", value.as_bytes()].concat();
// String is null terminated
bytes.push(0);
// Allocate the `u8`s and retrieve the pointer to the allocation
let var_ptr = ecx.memory_mut().allocate_static_bytes(bytes.as_slice(), MiriMemoryKind::Env.into());
ecx.machine.env_vars.map.insert(name.into_bytes(), var_ptr);
// Add the `*u8` to the vector
pointers.push(Scalar::Ptr(var_ptr));
}
}
// Array of pointers is null terminated
pointers.push(Scalar::from_int(0, ecx.pointer_size()));
// Layout of a `[*u8; N]` (`environ` is a `**char`)
let pointers_layout = ecx.layout_of(ecx.tcx.mk_array(ecx.tcx.mk_imm_ptr(ecx.tcx.types.u8), pointers.len() as u64)).unwrap();
// Allocate place for the `**u8`
let pointers_place = ecx.allocate(pointers_layout, MiriMemoryKind::Env.into());
for (idx, ptr) in pointers.into_iter().enumerate() {
// `idx`-th field of the `[*u8; N]` array
let place = ecx.mplace_field(pointers_place, idx as u64).unwrap();
// write the `*u8` to that field
ecx.write_scalar(ptr, place.into()).unwrap();
}
ecx.memory_mut().mark_immutable(pointers_place.ptr.assert_ptr().alloc_id).unwrap();
// pointer to our `[*u8; N]`
let ptr = pointers_place.ptr.assert_ptr();
// layout of a `*[*u8; N]`
let ptr_layout = ecx.layout_of(ecx.tcx.mk_imm_ptr(pointers_layout.ty.clone())).unwrap();
// Allocate place for the `*[*u8; N]`
let ptr_place = ecx.allocate(ptr_layout, MiriMemoryKind::Env.into());
// Write the `*[*u8; N]` to that place
ecx.write_scalar(Scalar::Ptr(ptr), ptr_place.into()).unwrap();
// Pointer to the `*[*u8; N]`
let env_ptr = ptr_place.ptr.assert_ptr();
// Get the `*[*u8; N]` allocation
ecx.memory_mut().extra.env_alloc = Some(ecx.memory_mut().get(env_ptr.alloc_id).unwrap().clone());
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/stacked_borrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,6 @@ impl<'tcx> Stack {
global: &GlobalState,
) -> InterpResult<'tcx> {
// Two main steps: Find granting item, remove incompatible items above.

// Step 1: Find granting item.
let granting_idx = self.find_granting(access, tag)
.ok_or_else(|| err_ub!(UbExperimental(format!(
Expand Down Expand Up @@ -435,7 +434,7 @@ impl<'tcx> Stacks {

Stacks {
stacks: RefCell::new(RangeMap::new(size, stack)),
global: extra,
global: extra,
}
}

Expand All @@ -460,7 +459,7 @@ impl Stacks {
pub fn new_allocation(
id: AllocId,
size: Size,
extra: MemoryExtra,
extra: MemoryExtra,
kind: MemoryKind<MiriMemoryKind>,
) -> (Self, Tag) {
let (tag, perm) = match kind {
Expand Down

0 comments on commit 529af9b

Please sign in to comment.