Skip to content

Commit c6e0d09

Browse files
committed
Retrieve SYS_getrandom from libc using const-eval
1 parent ae8e7f6 commit c6e0d09

File tree

1 file changed

+27
-16
lines changed

1 file changed

+27
-16
lines changed

src/fn_call.rs

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,14 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
211211
}
212212

213213
"syscall" => {
214-
// TODO: read `syscall` IDs like `sysconf` IDs and
215-
// figure out some way to actually process some of them.
216-
//
214+
let sys_getrandom = this.eval_path_scalar(&["libc", "SYS_getrandom"])?
215+
.expect("Failed to get libc::SYS_getrandom")
216+
.to_usize(this)? as i64;
217+
217218
// `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)`
218219
// is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
219-
match (this.read_scalar(args[0])?.to_usize(this)? as i64, tcx.data_layout.pointer_size.bits()) {
220-
// SYS_getrandom on x86_64 and x86 respectively
221-
(318, 64) | (355, 32) => {
220+
match this.read_scalar(args[0])?.to_usize(this)? as i64 {
221+
id if id == sys_getrandom => {
222222
let ptr = this.read_scalar(args[1])?.to_ptr()?;
223223
let len = this.read_scalar(args[2])?.to_usize(this)?;
224224

@@ -232,7 +232,7 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
232232

233233
this.write_scalar(Scalar::from_uint(len, dest.layout.size), dest)?;
234234
}
235-
(id, _size) => {
235+
id => {
236236
return err!(Unimplemented(
237237
format!("miri does not support syscall ID {}", id),
238238
))
@@ -496,18 +496,13 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
496496
];
497497
let mut result = None;
498498
for &(path, path_value) in paths {
499-
if let Ok(instance) = this.resolve_path(path) {
500-
let cid = GlobalId {
501-
instance,
502-
promoted: None,
503-
};
504-
let const_val = this.const_eval_raw(cid)?;
505-
let const_val = this.read_scalar(const_val.into())?;
506-
let value = const_val.to_i32()?;
507-
if value == name {
499+
if let Some(val) = this.eval_path_scalar(path)? {
500+
let val = val.to_i32()?;
501+
if val == name {
508502
result = Some(path_value);
509503
break;
510504
}
505+
511506
}
512507
}
513508
if let Some(result) = result {
@@ -782,6 +777,22 @@ pub trait EvalContextExt<'a, 'mir, 'tcx: 'a + 'mir>: crate::MiriEvalContextExt<'
782777
fn write_null(&mut self, dest: PlaceTy<'tcx, Borrow>) -> EvalResult<'tcx> {
783778
self.eval_context_mut().write_scalar(Scalar::from_int(0, dest.layout.size), dest)
784779
}
780+
781+
/// Evaluates the scalar at the specified path. Returns Some(val)
782+
/// if the path could be resolved, and None otherwise
783+
fn eval_path_scalar(&mut self, path: &[&str]) -> EvalResult<'tcx, Option<ScalarMaybeUndef<stacked_borrows::Borrow>>> {
784+
let this = self.eval_context_mut();
785+
if let Ok(instance) = this.resolve_path(path) {
786+
let cid = GlobalId {
787+
instance,
788+
promoted: None,
789+
};
790+
let const_val = this.const_eval_raw(cid)?;
791+
let const_val = this.read_scalar(const_val.into())?;
792+
return Ok(Some(const_val));
793+
}
794+
return Ok(None);
795+
}
785796
}
786797

787798
fn gen_random<'a, 'mir, 'tcx>(this: &mut MiriEvalContext<'a, 'mir, 'tcx>,

0 commit comments

Comments
 (0)