Auto merge of #808 - RalfJung:extra-fn, r=RalfJung
use Dlsym support to implement getentropy (and better thread spawn error) This is the Miri side of https://github.com/rust-lang/rust/pull/62245. Fixes https://github.com/rust-lang/miri/issues/789
This commit is contained in:
commit
226156f673
10 changed files with 186 additions and 124 deletions
|
|
@ -1 +1 @@
|
|||
481068a707679257e2a738b40987246e0420e787
|
||||
b820c761744db080ff7a4ba3ac88d259065cb836
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ use rustc::mir;
|
|||
|
||||
use crate::{
|
||||
InterpResult, InterpError, InterpCx, StackPopCleanup, struct_error,
|
||||
Scalar, Tag, Pointer,
|
||||
Scalar, Tag, Pointer, FnVal,
|
||||
MemoryExtra, MiriMemoryKind, Evaluator, TlsEvalContextExt,
|
||||
};
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>(
|
|||
let mut args = ecx.frame().body.args_iter();
|
||||
|
||||
// First argument: pointer to `main()`.
|
||||
let main_ptr = ecx.memory_mut().create_fn_alloc(main_instance);
|
||||
let main_ptr = ecx.memory_mut().create_fn_alloc(FnVal::Instance(main_instance));
|
||||
let dest = ecx.eval_place(&mir::Place::Base(mir::PlaceBase::Local(args.next().unwrap())))?;
|
||||
ecx.write_scalar(Scalar::Ptr(main_ptr), dest)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
use std::mem;
|
||||
|
||||
use rustc::ty::{self, layout::{self, Size}};
|
||||
use rustc::ty::{self, layout::{self, Size, Align}};
|
||||
use rustc::hir::def_id::{DefId, CRATE_DEF_INDEX};
|
||||
|
||||
use rand::RngCore;
|
||||
|
||||
use crate::*;
|
||||
|
||||
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
|
|
@ -65,6 +67,40 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
})
|
||||
}
|
||||
|
||||
/// Generate some random bytes, and write them to `dest`.
|
||||
fn gen_random(
|
||||
&mut self,
|
||||
len: usize,
|
||||
ptr: Scalar<Tag>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let ptr = match this.memory().check_ptr_access(ptr, Size::from_bytes(len as u64), Align::from_bytes(1).unwrap())? {
|
||||
Some(ptr) => ptr,
|
||||
None => return Ok(()), // zero-sized access
|
||||
};
|
||||
|
||||
let data = match &mut this.memory_mut().extra.rng {
|
||||
Some(rng) => {
|
||||
let mut rng = rng.borrow_mut();
|
||||
let mut data = vec![0; len];
|
||||
rng.fill_bytes(&mut data);
|
||||
data
|
||||
}
|
||||
None => {
|
||||
return err!(Unimplemented(
|
||||
"miri does not support gathering system entropy in deterministic mode!
|
||||
Use '-Zmiri-seed=<seed>' to enable random number generation.
|
||||
WARNING: Miri does *not* generate cryptographically secure entropy -
|
||||
do not use Miri to run any program that needs secure random number generation".to_owned(),
|
||||
));
|
||||
}
|
||||
};
|
||||
let tcx = &{this.tcx.tcx};
|
||||
this.memory_mut().get_mut(ptr.alloc_id)?
|
||||
.write_bytes(tcx, ptr, &data)
|
||||
}
|
||||
|
||||
/// Visits the memory covered by `place`, sensitive to freezing: the 3rd parameter
|
||||
/// will be true if this is frozen, false if this is in an `UnsafeCell`.
|
||||
fn visit_freeze_sensitive(
|
||||
|
|
|
|||
|
|
@ -31,13 +31,14 @@ pub use crate::shims::{EvalContextExt as ShimsEvalContextExt};
|
|||
pub use crate::shims::foreign_items::EvalContextExt as ForeignItemsEvalContextExt;
|
||||
pub use crate::shims::intrinsics::EvalContextExt as IntrinsicsEvalContextExt;
|
||||
pub use crate::shims::tls::{EvalContextExt as TlsEvalContextExt, TlsData};
|
||||
pub use crate::shims::dlsym::{Dlsym, EvalContextExt as DlsymEvalContextExt};
|
||||
pub use crate::operator::EvalContextExt as OperatorEvalContextExt;
|
||||
pub use crate::range_map::RangeMap;
|
||||
pub use crate::helpers::{EvalContextExt as HelpersEvalContextExt};
|
||||
pub use crate::mono_hash_map::MonoHashMap;
|
||||
pub use crate::stacked_borrows::{EvalContextExt as StackedBorEvalContextExt, Tag, Permission, Stack, Stacks, Item};
|
||||
pub use crate::machine::{
|
||||
PAGE_SIZE, STACK_ADDR, NUM_CPUS,
|
||||
PAGE_SIZE, STACK_ADDR, STACK_SIZE, NUM_CPUS,
|
||||
MemoryExtra, AllocExtra, MiriMemoryKind, Evaluator, MiriEvalContext, MiriEvalContextExt,
|
||||
};
|
||||
pub use crate::eval::{eval_main, create_ecx, MiriConfig};
|
||||
|
|
|
|||
|
|
@ -11,14 +11,15 @@ use rand::rngs::StdRng;
|
|||
use syntax::attr;
|
||||
use syntax::symbol::sym;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::ty::{self, layout::{Size, LayoutOf}, query::TyCtxtAt};
|
||||
use rustc::ty::{self, layout::{Size, LayoutOf}, TyCtxt};
|
||||
use rustc::mir;
|
||||
|
||||
use crate::*;
|
||||
|
||||
// Some global facts about the emulated machine.
|
||||
pub const PAGE_SIZE: u64 = 4*1024; // FIXME: adjust to target architecture
|
||||
pub const STACK_ADDR: u64 = 16*PAGE_SIZE; // not really about the "stack", but where we start assigning integer addresses to allocations
|
||||
pub const STACK_ADDR: u64 = 32*PAGE_SIZE; // not really about the "stack", but where we start assigning integer addresses to allocations
|
||||
pub const STACK_SIZE: u64 = 16*PAGE_SIZE; // whatever
|
||||
pub const NUM_CPUS: u64 = 1;
|
||||
|
||||
/// Extra memory kinds
|
||||
|
|
@ -135,6 +136,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
type MemoryExtra = MemoryExtra;
|
||||
type AllocExtra = AllocExtra;
|
||||
type PointerTag = Tag;
|
||||
type ExtraFnVal = Dlsym;
|
||||
|
||||
type MemoryMap = MonoHashMap<AllocId, (MemoryKind<MiriMemoryKind>, Allocation<Tag, Self::AllocExtra>)>;
|
||||
|
||||
|
|
@ -145,7 +147,6 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
ecx.memory().extra.validate
|
||||
}
|
||||
|
||||
/// Returns `Ok()` when the function was handled; fail otherwise.
|
||||
#[inline(always)]
|
||||
fn find_fn(
|
||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
|
|
@ -157,6 +158,17 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
ecx.find_fn(instance, args, dest, ret)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn call_extra_fn(
|
||||
ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
fn_val: Dlsym,
|
||||
args: &[OpTy<'tcx, Tag>],
|
||||
dest: Option<PlaceTy<'tcx, Tag>>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
ecx.call_dlsym(fn_val, args, dest, ret)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn call_intrinsic(
|
||||
ecx: &mut rustc_mir::interpret::InterpCx<'mir, 'tcx, Self>,
|
||||
|
|
@ -220,8 +232,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
}
|
||||
|
||||
fn find_foreign_static(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
tcx: TyCtxtAt<'tcx>,
|
||||
) -> InterpResult<'tcx, Cow<'tcx, Allocation>> {
|
||||
let attrs = tcx.get_attrs(def_id);
|
||||
let link_name = match attr::first_attr_value_str_by_name(&attrs, sym::link_name) {
|
||||
|
|
@ -251,20 +263,20 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
}
|
||||
|
||||
fn tag_allocation<'b>(
|
||||
memory_extra: &MemoryExtra,
|
||||
id: AllocId,
|
||||
alloc: Cow<'b, Allocation>,
|
||||
kind: Option<MemoryKind<Self::MemoryKinds>>,
|
||||
memory: &Memory<'mir, 'tcx, Self>,
|
||||
) -> (Cow<'b, Allocation<Self::PointerTag, Self::AllocExtra>>, Self::PointerTag) {
|
||||
let kind = kind.expect("we set our STATIC_KIND so this cannot be None");
|
||||
let alloc = alloc.into_owned();
|
||||
let (stacks, base_tag) = if !memory.extra.validate {
|
||||
let (stacks, base_tag) = if !memory_extra.validate {
|
||||
(None, Tag::Untagged)
|
||||
} else {
|
||||
let (stacks, base_tag) = Stacks::new_allocation(
|
||||
id,
|
||||
Size::from_bytes(alloc.bytes.len() as u64),
|
||||
Rc::clone(&memory.extra.stacked_borrows),
|
||||
Rc::clone(&memory_extra.stacked_borrows),
|
||||
kind,
|
||||
);
|
||||
(Some(stacks), base_tag)
|
||||
|
|
@ -273,7 +285,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
assert!(alloc.relocations.is_empty(), "Only statics can come initialized with inner pointers");
|
||||
// Now we can rely on the inner pointers being static, too.
|
||||
}
|
||||
let mut memory_extra = memory.extra.stacked_borrows.borrow_mut();
|
||||
let mut stacked_borrows = memory_extra.stacked_borrows.borrow_mut();
|
||||
let alloc: Allocation<Tag, Self::AllocExtra> = Allocation {
|
||||
bytes: alloc.bytes,
|
||||
relocations: Relocations::from_presorted(
|
||||
|
|
@ -281,10 +293,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
// The allocations in the relocations (pointers stored *inside* this allocation)
|
||||
// all get the base pointer tag.
|
||||
.map(|&(offset, ((), alloc))| {
|
||||
let tag = if !memory.extra.validate {
|
||||
let tag = if !memory_extra.validate {
|
||||
Tag::Untagged
|
||||
} else {
|
||||
memory_extra.static_base_ptr(alloc)
|
||||
stacked_borrows.static_base_ptr(alloc)
|
||||
};
|
||||
(offset, (tag, alloc))
|
||||
})
|
||||
|
|
@ -302,13 +314,13 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
|
||||
#[inline(always)]
|
||||
fn tag_static_base_pointer(
|
||||
memory_extra: &MemoryExtra,
|
||||
id: AllocId,
|
||||
memory: &Memory<'mir, 'tcx, Self>,
|
||||
) -> Self::PointerTag {
|
||||
if !memory.extra.validate {
|
||||
if !memory_extra.validate {
|
||||
Tag::Untagged
|
||||
} else {
|
||||
memory.extra.stacked_borrows.borrow_mut().static_base_ptr(id)
|
||||
memory_extra.stacked_borrows.borrow_mut().static_base_ptr(id)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -342,8 +354,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
}
|
||||
|
||||
fn int_to_ptr(
|
||||
int: u64,
|
||||
memory: &Memory<'mir, 'tcx, Self>,
|
||||
int: u64,
|
||||
) -> InterpResult<'tcx, Pointer<Self::PointerTag>> {
|
||||
if int == 0 {
|
||||
err!(InvalidNullPointerUsage)
|
||||
|
|
@ -355,8 +367,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'tcx> {
|
|||
}
|
||||
|
||||
fn ptr_to_int(
|
||||
ptr: Pointer<Self::PointerTag>,
|
||||
memory: &Memory<'mir, 'tcx, Self>,
|
||||
ptr: Pointer<Self::PointerTag>,
|
||||
) -> InterpResult<'tcx, u64> {
|
||||
if memory.extra.rng.is_none() {
|
||||
err!(ReadPointerAsBytes)
|
||||
|
|
|
|||
55
src/shims/dlsym.rs
Normal file
55
src/shims/dlsym.rs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
use rustc::mir;
|
||||
|
||||
use crate::*;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Dlsym {
|
||||
GetEntropy,
|
||||
}
|
||||
|
||||
impl Dlsym {
|
||||
// Returns an error for unsupported symbols, and None if this symbol
|
||||
// should become a NULL pointer (pretend it does not exist).
|
||||
pub fn from_str(name: &str) -> InterpResult<'static, Option<Dlsym>> {
|
||||
use self::Dlsym::*;
|
||||
Ok(match name {
|
||||
"getentropy" => Some(GetEntropy),
|
||||
"__pthread_get_minstack" => None,
|
||||
_ =>
|
||||
return err!(Unimplemented(format!(
|
||||
"Unsupported dlsym: {}", name
|
||||
))),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
|
||||
fn call_dlsym(
|
||||
&mut self,
|
||||
dlsym: Dlsym,
|
||||
args: &[OpTy<'tcx, Tag>],
|
||||
dest: Option<PlaceTy<'tcx, Tag>>,
|
||||
ret: Option<mir::BasicBlock>,
|
||||
) -> InterpResult<'tcx> {
|
||||
use self::Dlsym::*;
|
||||
|
||||
let this = self.eval_context_mut();
|
||||
|
||||
let dest = dest.expect("we don't support any diverging dlsym");
|
||||
let ret = ret.expect("dest is `Some` but ret is `None`");
|
||||
|
||||
match dlsym {
|
||||
GetEntropy => {
|
||||
let ptr = this.read_scalar(args[0])?.not_undef()?;
|
||||
let len = this.read_scalar(args[1])?.to_usize(this)?;
|
||||
this.gen_random(len as usize, ptr)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
}
|
||||
|
||||
this.goto_block(Some(ret))?;
|
||||
this.dump_place(*dest);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -4,8 +4,6 @@ use rustc::mir;
|
|||
use syntax::attr;
|
||||
use syntax::symbol::sym;
|
||||
|
||||
use rand::RngCore;
|
||||
|
||||
use crate::*;
|
||||
|
||||
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
|
||||
|
|
@ -307,7 +305,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
// neither of which have any effect on our current PRNG
|
||||
let _flags = this.read_scalar(args[3])?.to_i32()?;
|
||||
|
||||
gen_random(this, len as usize, ptr)?;
|
||||
this.gen_random(len as usize, ptr)?;
|
||||
this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?;
|
||||
}
|
||||
id => {
|
||||
|
|
@ -324,10 +322,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
let symbol_name = this.memory().get(symbol.alloc_id)?.read_c_str(tcx, symbol)?;
|
||||
let err = format!("bad c unicode symbol: {:?}", symbol_name);
|
||||
let symbol_name = ::std::str::from_utf8(symbol_name).unwrap_or(&err);
|
||||
return err!(Unimplemented(format!(
|
||||
"miri does not support dynamically loading libraries (requested symbol: {})",
|
||||
symbol_name
|
||||
)));
|
||||
if let Some(dlsym) = Dlsym::from_str(symbol_name)? {
|
||||
let ptr = this.memory_mut().create_fn_alloc(FnVal::Other(dlsym));
|
||||
this.write_scalar(Scalar::from(ptr), dest)?;
|
||||
} else {
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
}
|
||||
|
||||
"__rust_maybe_catch_panic" => {
|
||||
|
|
@ -338,9 +338,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
// vtable_ptr: *mut usize,
|
||||
// ) -> u32
|
||||
// We abort on panic, so not much is going on here, but we still have to call the closure.
|
||||
let f = this.read_scalar(args[0])?.to_ptr()?;
|
||||
let f = this.read_scalar(args[0])?.not_undef()?;
|
||||
let data = this.read_scalar(args[1])?.not_undef()?;
|
||||
let f_instance = this.memory().get_fn(f)?;
|
||||
let f_instance = this.memory().get_fn(f)?.as_instance()?;
|
||||
this.write_null(dest)?;
|
||||
trace!("__rust_maybe_catch_panic: {:?}", f_instance);
|
||||
|
||||
|
|
@ -659,7 +659,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
|
||||
// Extract the function type out of the signature (that seems easier than constructing it ourselves).
|
||||
let dtor = match this.test_null(this.read_scalar(args[1])?.not_undef()?)? {
|
||||
Some(dtor_ptr) => Some(this.memory().get_fn(dtor_ptr.to_ptr()?)?),
|
||||
Some(dtor_ptr) => Some(this.memory().get_fn(dtor_ptr)?.as_instance()?),
|
||||
None => None,
|
||||
};
|
||||
|
||||
|
|
@ -709,24 +709,31 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
// Determine stack base address.
|
||||
"pthread_attr_init" | "pthread_attr_destroy" | "pthread_attr_get_np" |
|
||||
"pthread_getattr_np" | "pthread_self" | "pthread_get_stacksize_np" => {
|
||||
// Stack size/address stuff.
|
||||
"pthread_attr_init" | "pthread_attr_destroy" | "pthread_self" |
|
||||
"pthread_attr_setstacksize" => {
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_attr_getstack" => {
|
||||
// Second argument is where we are supposed to write the stack size.
|
||||
let ptr = this.deref_operand(args[1])?;
|
||||
// Just any address.
|
||||
let stack_addr = Scalar::from_uint(STACK_ADDR, args[1].layout.size);
|
||||
this.write_scalar(stack_addr, ptr.into())?;
|
||||
let addr_place = this.deref_operand(args[1])?;
|
||||
let size_place = this.deref_operand(args[2])?;
|
||||
|
||||
this.write_scalar(
|
||||
Scalar::from_uint(STACK_ADDR, addr_place.layout.size),
|
||||
addr_place.into(),
|
||||
)?;
|
||||
this.write_scalar(
|
||||
Scalar::from_uint(STACK_SIZE, size_place.layout.size),
|
||||
size_place.into(),
|
||||
)?;
|
||||
|
||||
// Return success (`0`).
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_get_stackaddr_np" => {
|
||||
// Just any address.
|
||||
let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);
|
||||
this.write_scalar(stack_addr, dest)?;
|
||||
|
||||
// We don't support threading.
|
||||
"pthread_create" => {
|
||||
return err!(Unimplemented(format!("Miri does not support threading")));
|
||||
}
|
||||
|
||||
// Stub out calls for condvar, mutex and rwlock, to just return `0`.
|
||||
|
|
@ -754,6 +761,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
}
|
||||
|
||||
// macOS API stubs.
|
||||
"pthread_attr_get_np" | "pthread_getattr_np" => {
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_get_stackaddr_np" => {
|
||||
let stack_addr = Scalar::from_uint(STACK_ADDR, dest.layout.size);
|
||||
this.write_scalar(stack_addr, dest)?;
|
||||
}
|
||||
"pthread_get_stacksize_np" => {
|
||||
let stack_size = Scalar::from_uint(STACK_SIZE, dest.layout.size);
|
||||
this.write_scalar(stack_size, dest)?;
|
||||
}
|
||||
"_tlv_atexit" => {
|
||||
// FIXME: register the destructor.
|
||||
},
|
||||
|
|
@ -766,7 +784,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
"SecRandomCopyBytes" => {
|
||||
let len = this.read_scalar(args[1])?.to_usize(this)?;
|
||||
let ptr = this.read_scalar(args[2])?.not_undef()?;
|
||||
gen_random(this, len as usize, ptr)?;
|
||||
this.gen_random(len as usize, ptr)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
|
|
@ -934,7 +952,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
"SystemFunction036" => {
|
||||
let ptr = this.read_scalar(args[0])?.not_undef()?;
|
||||
let len = this.read_scalar(args[1])?.to_u32()?;
|
||||
gen_random(this, len as usize, ptr)?;
|
||||
this.gen_random(len as usize, ptr)?;
|
||||
this.write_scalar(Scalar::from_bool(true), dest)?;
|
||||
}
|
||||
|
||||
|
|
@ -966,36 +984,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
|
|||
}
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_random<'mir, 'tcx>(
|
||||
this: &mut MiriEvalContext<'mir, 'tcx>,
|
||||
len: usize,
|
||||
dest: Scalar<Tag>,
|
||||
) -> InterpResult<'tcx> {
|
||||
if len == 0 {
|
||||
// Nothing to do
|
||||
return Ok(());
|
||||
}
|
||||
let ptr = dest.to_ptr()?;
|
||||
|
||||
let data = match &mut this.memory_mut().extra.rng {
|
||||
Some(rng) => {
|
||||
let mut rng = rng.borrow_mut();
|
||||
let mut data = vec![0; len];
|
||||
rng.fill_bytes(&mut data);
|
||||
data
|
||||
}
|
||||
None => {
|
||||
return err!(Unimplemented(
|
||||
"miri does not support gathering system entropy in deterministic mode!
|
||||
Use '-Zmiri-seed=<seed>' to enable random number generation.
|
||||
WARNING: Miri does *not* generate cryptographically secure entropy -
|
||||
do not use Miri to run any program that needs secure random number generation".to_owned(),
|
||||
));
|
||||
}
|
||||
};
|
||||
let tcx = &{this.tcx.tcx};
|
||||
this.memory_mut().get_mut(ptr.alloc_id)?
|
||||
.write_bytes(tcx, ptr, &data)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
pub mod foreign_items;
|
||||
pub mod intrinsics;
|
||||
pub mod tls;
|
||||
pub mod dlsym;
|
||||
|
||||
use rustc::{ty, mir};
|
||||
|
||||
|
|
|
|||
58
test-cargo-miri/Cargo.lock
generated
58
test-cargo-miri/Cargo.lock
generated
|
|
@ -5,11 +5,6 @@ name = "autocfg"
|
|||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.2"
|
||||
|
|
@ -33,34 +28,22 @@ dependencies = [
|
|||
"rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.3"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
|
|
@ -85,7 +68,7 @@ name = "rand"
|
|||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"getrandom 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_chacha 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
@ -108,7 +91,7 @@ name = "rand_core"
|
|||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"getrandom 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
@ -129,32 +112,15 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
name = "spin"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf"
|
||||
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
|
||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
"checksum getrandom 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8d1dffef07351aafe6ef177e4dd2b8dcf503e6bc765dea3b0de9ed149a3db1ec"
|
||||
"checksum getrandom 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e65cce4e5084b14874c4e7097f38cab54f47ee554f9194673456ea379dcc4c55"
|
||||
"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14"
|
||||
"checksum libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319"
|
||||
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
|
||||
|
|
@ -164,6 +130,4 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum rand_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "615e683324e75af5d43d8f7a39ffe3ee4a9dc42c5c701167a71dc59c3a493aca"
|
||||
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
"checksum rand_pcg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e196346cbbc5c70c77e7b4926147ee8e383a38ee4d15d58a08098b169e492b6"
|
||||
"checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
"checksum spin 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44363f6f51401c34e7be73db0db371c04705d35efbe9f7d6082e03a921a32c55"
|
||||
|
|
|
|||
7
tests/compile-fail/thread-spawn.rs
Normal file
7
tests/compile-fail/thread-spawn.rs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
use std::thread;
|
||||
|
||||
// error-pattern: Miri does not support threading
|
||||
|
||||
fn main() {
|
||||
thread::spawn(|| {});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue