Skip to content

Commit 6d3e93c

Browse files
committed
Refactor random number generation
1 parent b120e8b commit 6d3e93c

File tree

2 files changed

+39
-24
lines changed

2 files changed

+39
-24
lines changed

src/fn_call.rs

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -215,36 +215,22 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
215215
// figure out some way to actually process some of them.
216216
//
217217
// `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)`
218-
// is called if a `HashMap` is created the regular way.
218+
// is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
219219
match this.read_scalar(args[0])?.to_usize(this)? as i64 {
220220
// SYS_getrandom on x86_64 and x86 respectively
221221
318 | 355 => {
222-
match this.machine.rng.as_ref() {
223-
Some(rng) => {
224-
let ptr = this.read_scalar(args[1])?.to_ptr()?;
225-
let len = this.read_scalar(args[2])?.to_usize(this)?;
222+
let ptr = this.read_scalar(args[1])?.to_ptr()?;
223+
let len = this.read_scalar(args[2])?.to_usize(this)?;
226224

227-
// The only supported flags are GRND_RANDOM and GRND_NONBLOCK,
228-
// neither of which have any effect on our current PRNG
229-
let _flags = this.read_scalar(args[3])?.to_i32()?;
225+
// The only supported flags are GRND_RANDOM and GRND_NONBLOCK,
226+
// neither of which have any effect on our current PRNG
227+
let _flags = this.read_scalar(args[3])?.to_i32()?;
230228

231-
let mut data = vec![0; len as usize];
232-
rng.borrow_mut().fill_bytes(&mut data);
233-
234-
this.memory_mut().get_mut(ptr.alloc_id)?
229+
let data = gen_random(this, len as usize)?;
230+
this.memory_mut().get_mut(ptr.alloc_id)?
235231
.write_bytes(tcx, ptr, &data)?;
236232

237-
this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?;
238-
239-
},
240-
None => {
241-
return err!(Unimplemented(
242-
"miri does not support random number generators in deterministic mode!
243-
Use '-Zmiri-seed=<seed>' to enable random number generation".to_owned(),
244-
))
245-
}
246-
}
247-
233+
this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?;
248234
}
249235
id => {
250236
return err!(Unimplemented(
@@ -768,6 +754,17 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
768754
"GetCommandLineW" => {
769755
this.write_scalar(Scalar::Ptr(this.machine.cmd_line.unwrap()), dest)?;
770756
}
757+
// The actual name of 'RtlGenRandom'
758+
"SystemFunction036" => {
759+
let ptr = this.read_scalar(args[1])?.to_ptr()?;
760+
let len = this.read_scalar(args[2])?.to_usize(this)?;
761+
762+
let data = gen_random(this, len as usize)?;
763+
this.memory_mut().get_mut(ptr.alloc_id)?
764+
.write_bytes(tcx, ptr, &data)?;
765+
766+
this.write_scalar(Scalar::from_bool(true), dest)?;
767+
}
771768

772769
// We can't execute anything else.
773770
_ => {
@@ -786,3 +783,21 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
786783
self.eval_context_mut().write_scalar(Scalar::from_int(0, dest.layout.size), dest)
787784
}
788785
}
786+
787+
fn gen_random<'a, 'mir, 'tcx>(this: &mut MiriEvalContext<'a, 'mir, 'tcx>,
788+
len: usize) -> Result<Vec<u8>, EvalError<'tcx>> {
789+
790+
match this.machine.rng.as_ref() {
791+
Some(rng) => {
792+
let mut data = vec![0; len];
793+
rng.borrow_mut().fill_bytes(&mut data);
794+
Ok(data)
795+
}
796+
None => {
797+
err!(Unimplemented(
798+
"miri does not support random number generators in deterministic mode!
799+
Use '-Zmiri-seed=<seed>' to enable random number generation".to_owned(),
800+
))
801+
}
802+
}
803+
}

tests/compile-fail/getrandom.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ extern crate libc;
44
fn main() {
55
let mut buf = [0u8; 5];
66
unsafe {
7-
libc::syscall(libc::SYS_getrandom, buf.as_mut_ptr() as *mut libc::c_void, 5, 0);
7+
libc::syscall(libc::SYS_getrandom, buf.as_mut_ptr() as *mut libc::c_void, 5 as libc::size_t, 0 as libc::c_uint);
88
//~^ ERROR constant evaluation error: miri does not support random number generators in deterministic mode!
99
}
1010
}

0 commit comments

Comments
 (0)