From 2861ceb2fa1acc2c642abd4f2efb96c713a47e29 Mon Sep 17 00:00:00 2001 From: Christian Poveda Date: Mon, 24 Jun 2019 10:03:16 -0500 Subject: [PATCH] Rename new fields and move rng to MemoryExtra --- src/fn_call.rs | 2 +- src/intptrcast.rs | 10 +++++---- src/lib.rs | 55 ++++++++++++++++++++--------------------------- src/memory.rs | 9 +++++--- src/operator.rs | 2 +- 5 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/fn_call.rs b/src/fn_call.rs index eca1d9144ec..e47e2169121 100644 --- a/src/fn_call.rs +++ b/src/fn_call.rs @@ -979,7 +979,7 @@ fn gen_random<'mir, 'tcx>( } let ptr = dest.to_ptr()?; - let data = match &mut this.machine.rng { + let data = match &mut this.memory_mut().extra.rng { Some(rng) => { let mut data = vec![0; len]; rng.fill_bytes(&mut data); diff --git a/src/intptrcast.rs b/src/intptrcast.rs index 3e07f54fbd3..f95cf0fda46 100644 --- a/src/intptrcast.rs +++ b/src/intptrcast.rs @@ -6,15 +6,17 @@ #[derive(Clone, Debug)] pub struct GlobalState { - pub vec: Vec<(u64, AllocId)>, - pub addr: u64, + /// This field is used as a map between the address of each allocation and its `AllocId` + pub int_to_ptr_map: Vec<(u64, AllocId)>, + pub next_base_addr: u64, } impl Default for GlobalState { + // FIXME: Query the page size in the future fn default() -> Self { GlobalState { - vec: Vec::default(), - addr: 2u64.pow(16) + int_to_ptr_map: Vec::default(), + next_base_addr: 2u64.pow(16) } } } diff --git a/src/lib.rs b/src/lib.rs index 17b20d003e9..5288537f20e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -25,7 +25,7 @@ use std::collections::HashMap; use std::borrow::Cow; -use std::cell::RefCell; +use std::cell::Cell; use std::rc::Rc; use rand::rngs::StdRng; @@ -83,9 +83,11 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( let mut ecx = InterpretCx::new( tcx.at(syntax::source_map::DUMMY_SP), ty::ParamEnv::reveal_all(), - Evaluator::new(config.validate, config.seed), + Evaluator::new(config.validate), ); + ecx.memory_mut().extra.rng = config.seed.map(StdRng::seed_from_u64); + let main_instance = ty::Instance::mono(ecx.tcx.tcx, main_id); let main_mir = ecx.load_mir(main_instance.def)?; @@ -209,9 +211,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( cur_ptr = cur_ptr.offset(char_size, tcx)?; } } - - ecx.memory_mut().extra.seed = config.seed.clone(); - + assert!(args.next().is_none(), "start lang item has more arguments than expected"); Ok(ecx) @@ -347,14 +347,10 @@ pub struct Evaluator<'tcx> { /// Whether to enforce the validity invariant. pub(crate) validate: bool, - - /// The random number generator to use if Miri - /// is running in non-deterministic mode - pub(crate) rng: Option } impl<'tcx> Evaluator<'tcx> { - fn new(validate: bool, seed: Option) -> Self { + fn new(validate: bool) -> Self { Evaluator { env_vars: HashMap::default(), argc: None, @@ -363,7 +359,6 @@ fn new(validate: bool, seed: Option) -> Self { last_error: 0, tls: TlsData::default(), validate, - rng: seed.map(|s| StdRng::seed_from_u64(s)) } } } @@ -543,7 +538,7 @@ fn tag_allocation<'b>( mutability: alloc.mutability, extra: AllocExtra { stacks: extra, - base_addr: RefCell::new(None), + base_addr: Cell::new(None), }, }; (Cow::Owned(alloc), base_tag) @@ -598,20 +593,20 @@ fn int_to_ptr( return err!(InvalidNullPointerUsage); } - if memory.extra.seed.is_none() { + if memory.extra.rng.is_none() { return err!(ReadBytesAsPointer); } let extra = memory.extra.intptrcast.borrow(); - match extra.vec.binary_search_by_key(&int, |(int, _)| *int) { + match extra.int_to_ptr_map.binary_search_by_key(&int, |(int, _)| *int) { Ok(pos) => { - let (_, alloc_id) = extra.vec[pos]; + let (_, alloc_id) = extra.int_to_ptr_map[pos]; Ok(Pointer::new_with_tag(alloc_id, Size::from_bytes(0), Tag::Untagged)) } Err(pos) => { if pos > 0 { - let (glb, alloc_id) = extra.vec[pos - 1]; + let (glb, alloc_id) = extra.int_to_ptr_map[pos - 1]; let offset = int - glb; if offset <= memory.get(alloc_id)?.bytes.len() as u64 { Ok(Pointer::new_with_tag(alloc_id, Size::from_bytes(offset), Tag::Untagged)) @@ -629,7 +624,7 @@ fn ptr_to_int( ptr: Pointer, memory: &Memory<'mir, 'tcx, Self>, ) -> InterpResult<'tcx, u64> { - if memory.extra.seed.is_none() { + if memory.extra.rng.is_none() { return err!(ReadPointerAsBytes); } @@ -637,28 +632,24 @@ fn ptr_to_int( let alloc = memory.get(ptr.alloc_id)?; - let mut base_addr = alloc.extra.base_addr.borrow_mut(); - - let addr = match *base_addr { - Some(addr) => addr, + let base_addr = match alloc.extra.base_addr.get() { + Some(base_addr) => base_addr, None => { - let addr = extra.addr; - extra.addr += alloc.bytes.len() as u64; + let base_addr = extra.next_base_addr; + extra.next_base_addr += alloc.bytes.len() as u64; - *base_addr = Some(addr); + alloc.extra.base_addr.set(Some(base_addr)); - let elem = (addr, ptr.alloc_id); + let elem = (base_addr, ptr.alloc_id); - if let Err(pos) = extra.vec.binary_search(&elem) { - extra.vec.insert(pos, elem); - } else { - return err!(Unreachable); - } + // Given that `next_base_addr` increases in each allocation, pushing the + // corresponding tuple keeps `int_to_ptr_map` sorted + extra.int_to_ptr_map.push(elem); - addr + base_addr } }; - Ok(addr + ptr.offset.bytes()) + Ok(base_addr + ptr.offset.bytes()) } } diff --git a/src/memory.rs b/src/memory.rs index 13ffd859ade..fafa9272bac 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -1,4 +1,5 @@ -use std::cell::RefCell; +use std::cell::Cell; +use rand::rngs::StdRng; use rustc_mir::interpret::{Pointer, Allocation, AllocationExtra, InterpResult}; use rustc_target::abi::Size; @@ -10,13 +11,15 @@ pub struct MemoryState { pub stacked: stacked_borrows::MemoryState, pub intptrcast: intptrcast::MemoryState, - pub seed: Option, + /// The random number generator to use if Miri + /// is running in non-deterministic mode + pub(crate) rng: Option } #[derive(Debug, Clone,)] pub struct AllocExtra { pub stacks: stacked_borrows::Stacks, - pub base_addr: RefCell>, + pub base_addr: Cell>, } impl AllocationExtra for AllocExtra { diff --git a/src/operator.rs b/src/operator.rs index 7dd3b3526cd..0ebb1e71610 100644 --- a/src/operator.rs +++ b/src/operator.rs @@ -44,7 +44,7 @@ fn ptr_op( trace!("ptr_op: {:?} {:?} {:?}", *left, bin_op, *right); - if self.memory().extra.seed.is_some() && bin_op != Offset { + if self.memory().extra.rng.is_some() && bin_op != Offset { let l_bits = self.force_bits(left.imm.to_scalar()?, left.layout.size)?; let r_bits = self.force_bits(right.imm.to_scalar()?, right.layout.size)?;