Skip to content

Commit 681819c

Browse files
committed
getting a path should never fail
we basically treat them as lang items
1 parent 77cc0cd commit 681819c

File tree

6 files changed

+60
-74
lines changed

6 files changed

+60
-74
lines changed

src/helpers.rs

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::*;
1818
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
1919

2020
/// Gets an instance for a path.
21-
fn resolve_did<'mir, 'tcx>(tcx: TyCtxt<'tcx>, path: &[&str]) -> InterpResult<'tcx, DefId> {
21+
fn try_resolve_did<'mir, 'tcx>(tcx: TyCtxt<'tcx>, path: &[&str]) -> Option<DefId> {
2222
tcx.crates()
2323
.iter()
2424
.find(|&&krate| tcx.original_crate_name(krate).as_str() == path[0])
@@ -41,18 +41,47 @@ fn resolve_did<'mir, 'tcx>(tcx: TyCtxt<'tcx>, path: &[&str]) -> InterpResult<'tc
4141
}
4242
None
4343
})
44-
.ok_or_else(|| {
45-
err_unsup_format!("failed to find required Rust item: {:?}", path).into()
46-
})
4744
}
4845

4946
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
5047
/// Gets an instance for a path.
51-
fn resolve_path(&self, path: &[&str]) -> InterpResult<'tcx, ty::Instance<'tcx>> {
52-
Ok(ty::Instance::mono(
53-
self.eval_context_ref().tcx.tcx,
54-
resolve_did(self.eval_context_ref().tcx.tcx, path)?,
55-
))
48+
fn resolve_path(&self, path: &[&str]) -> ty::Instance<'tcx> {
49+
let did = try_resolve_did(self.eval_context_ref().tcx.tcx, path)
50+
.unwrap_or_else(|| panic!("failed to find required Rust item: {:?}", path));
51+
ty::Instance::mono(self.eval_context_ref().tcx.tcx, did)
52+
}
53+
54+
/// Evaluates the scalar at the specified path. Returns Some(val)
55+
/// if the path could be resolved, and None otherwise
56+
fn eval_path_scalar(
57+
&mut self,
58+
path: &[&str],
59+
) -> InterpResult<'tcx, ScalarMaybeUndef<Tag>> {
60+
let this = self.eval_context_mut();
61+
let instance = this.resolve_path(path);
62+
let cid = GlobalId { instance, promoted: None };
63+
let const_val = this.const_eval_raw(cid)?;
64+
let const_val = this.read_scalar(const_val.into())?;
65+
return Ok(const_val);
66+
}
67+
68+
/// Helper function to get a `libc` constant as a `Scalar`.
69+
fn eval_libc(&mut self, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
70+
self.eval_context_mut()
71+
.eval_path_scalar(&["libc", name])?
72+
.not_undef()
73+
}
74+
75+
/// Helper function to get a `libc` constant as an `i32`.
76+
fn eval_libc_i32(&mut self, name: &str) -> InterpResult<'tcx, i32> {
77+
self.eval_libc(name)?.to_i32()
78+
}
79+
80+
/// Helper function to get the `TyLayout` of a `libc` type
81+
fn libc_ty_layout(&mut self, name: &str) -> InterpResult<'tcx, TyLayout<'tcx>> {
82+
let this = self.eval_context_mut();
83+
let ty = this.resolve_path(&["libc", name]).monomorphic_ty(*this.tcx);
84+
this.layout_of(ty)
5685
}
5786

5887
/// Write a 0 of the appropriate size to `dest`.
@@ -97,7 +126,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
97126
if this.machine.communicate {
98127
// Fill the buffer using the host's rng.
99128
getrandom::getrandom(&mut data)
100-
.map_err(|err| err_unsup_format!("getrandom failed: {}", err))?;
129+
.map_err(|err| err_unsup_format!("host getrandom failed: {}", err))?;
101130
} else {
102131
let rng = this.memory.extra.rng.get_mut();
103132
rng.fill_bytes(&mut data);
@@ -312,26 +341,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
312341
}
313342
}
314343

315-
/// Helper function to get a `libc` constant as a `Scalar`.
316-
fn eval_libc(&mut self, name: &str) -> InterpResult<'tcx, Scalar<Tag>> {
317-
self.eval_context_mut()
318-
.eval_path_scalar(&["libc", name])?
319-
.ok_or_else(|| err_unsup_format!("Path libc::{} cannot be resolved.", name))?
320-
.not_undef()
321-
}
322-
323-
/// Helper function to get a `libc` constant as an `i32`.
324-
fn eval_libc_i32(&mut self, name: &str) -> InterpResult<'tcx, i32> {
325-
self.eval_libc(name)?.to_i32()
326-
}
327-
328-
/// Helper function to get the `TyLayout` of a `libc` type
329-
fn libc_ty_layout(&mut self, name: &str) -> InterpResult<'tcx, TyLayout<'tcx>> {
330-
let this = self.eval_context_mut();
331-
let ty = this.resolve_path(&["libc", name])?.monomorphic_ty(*this.tcx);
332-
this.layout_of(ty)
333-
}
334-
335344
// Writes several `ImmTy`s contiguosly into memory. This is useful when you have to pack
336345
// different values into a struct.
337346
fn write_packed_immediates(
@@ -530,7 +539,7 @@ pub fn immty_from_int_checked<'tcx>(
530539
) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
531540
let int = int.into();
532541
Ok(ImmTy::try_from_int(int, layout).ok_or_else(|| {
533-
err_unsup_format!("Signed value {:#x} does not fit in {} bits", int, layout.size.bits())
542+
err_unsup_format!("signed value {:#x} does not fit in {} bits", int, layout.size.bits())
534543
})?)
535544
}
536545

@@ -540,6 +549,6 @@ pub fn immty_from_uint_checked<'tcx>(
540549
) -> InterpResult<'tcx, ImmTy<'tcx, Tag>> {
541550
let int = int.into();
542551
Ok(ImmTy::try_from_uint(int, layout).ok_or_else(|| {
543-
err_unsup_format!("Signed value {:#x} does not fit in {} bits", int, layout.size.bits())
552+
err_unsup_format!("unsigned value {:#x} does not fit in {} bits", int, layout.size.bits())
544553
})?)
545554
}

src/shims/foreign_items.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
165165
.expect("No panic runtime found!");
166166
let panic_runtime = tcx.crate_name(*panic_runtime);
167167
let start_panic_instance =
168-
this.resolve_path(&[&*panic_runtime.as_str(), link_name])?;
168+
this.resolve_path(&[&*panic_runtime.as_str(), link_name]);
169169
return Ok(Some(&*this.load_mir(start_panic_instance.def, None)?));
170170
}
171171
_ => {}
@@ -454,20 +454,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
454454
}
455455
Ok(())
456456
}
457-
458-
/// Evaluates the scalar at the specified path. Returns Some(val)
459-
/// if the path could be resolved, and None otherwise
460-
fn eval_path_scalar(
461-
&mut self,
462-
path: &[&str],
463-
) -> InterpResult<'tcx, Option<ScalarMaybeUndef<Tag>>> {
464-
let this = self.eval_context_mut();
465-
if let Ok(instance) = this.resolve_path(path) {
466-
let cid = GlobalId { instance, promoted: None };
467-
let const_val = this.const_eval_raw(cid)?;
468-
let const_val = this.read_scalar(const_val.into())?;
469-
return Ok(Some(const_val));
470-
}
471-
return Ok(None);
472-
}
473457
}

src/shims/foreign_items/posix.rs

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -289,22 +289,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
289289

290290
trace!("sysconf() called with name {}", name);
291291
// TODO: Cache the sysconf integers via Miri's global cache.
292-
let paths = &[
293-
(&["libc", "_SC_PAGESIZE"], Scalar::from_int(PAGE_SIZE, dest.layout.size)),
294-
(&["libc", "_SC_GETPW_R_SIZE_MAX"], Scalar::from_int(-1, dest.layout.size)),
295-
(
296-
&["libc", "_SC_NPROCESSORS_ONLN"],
297-
Scalar::from_int(NUM_CPUS, dest.layout.size),
298-
),
292+
let sysconfs = &[
293+
("_SC_PAGESIZE", Scalar::from_int(PAGE_SIZE, dest.layout.size)),
294+
("_SC_GETPW_R_SIZE_MAX", Scalar::from_int(-1, dest.layout.size)),
295+
("_SC_NPROCESSORS_ONLN", Scalar::from_int(NUM_CPUS, dest.layout.size)),
299296
];
300297
let mut result = None;
301-
for &(path, path_value) in paths {
302-
if let Some(val) = this.eval_path_scalar(path)? {
303-
let val = val.to_i32()?;
304-
if val == name {
305-
result = Some(path_value);
306-
break;
307-
}
298+
for &(sysconf_name, value) in sysconfs {
299+
let sysconf_name = this.eval_libc_i32(sysconf_name)?;
300+
if sysconf_name == name {
301+
result = Some(value);
302+
break;
308303
}
309304
}
310305
if let Some(result) = result {

src/shims/foreign_items/posix/linux.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
5656

5757
"syscall" => {
5858
let sys_getrandom = this
59-
.eval_path_scalar(&["libc", "SYS_getrandom"])?
60-
.expect("Failed to get libc::SYS_getrandom")
59+
.eval_libc("SYS_getrandom")?
6160
.to_machine_usize(this)?;
6261

6362
let sys_statx = this
64-
.eval_path_scalar(&["libc", "SYS_statx"])?
65-
.expect("Failed to get libc::SYS_statx")
63+
.eval_libc("SYS_statx")?
6664
.to_machine_usize(this)?;
6765

6866
match this.read_scalar(args[0])?.to_machine_usize(this)? {

src/shims/fs.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
643643
// FIXME: This long path is required because `libc::statx` is an struct and also a
644644
// function and `resolve_path` is returning the latter.
645645
let statx_ty = this
646-
.resolve_path(&["libc", "unix", "linux_like", "linux", "gnu", "statx"])?
646+
.resolve_path(&["libc", "unix", "linux_like", "linux", "gnu", "statx"])
647647
.monomorphic_ty(*this.tcx);
648648
let statxbuf_ty = this.tcx.mk_mut_ptr(statx_ty);
649649
let statxbuf_layout = this.layout_of(statxbuf_ty)?;
@@ -655,13 +655,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
655655
// `flags` should be a `c_int` but the `syscall` function provides an `isize`.
656656
let flags: i32 =
657657
this.read_scalar(flags_op)?.to_machine_isize(&*this.tcx)?.try_into().map_err(|e| {
658-
err_unsup_format!("Failed to convert pointer sized operand to integer: {}", e)
658+
err_unsup_format!("failed to convert pointer sized operand to integer: {}", e)
659659
})?;
660660
let empty_path_flag = flags & this.eval_libc("AT_EMPTY_PATH")?.to_i32()? != 0;
661661
// `dirfd` should be a `c_int` but the `syscall` function provides an `isize`.
662662
let dirfd: i32 =
663663
this.read_scalar(dirfd_op)?.to_machine_isize(&*this.tcx)?.try_into().map_err(|e| {
664-
err_unsup_format!("Failed to convert pointer sized operand to integer: {}", e)
664+
err_unsup_format!("failed to convert pointer sized operand to integer: {}", e)
665665
})?;
666666
// We only support:
667667
// * interpreting `path` as an absolute directory,
@@ -676,7 +676,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
676676
(path.as_os_str().is_empty() && empty_path_flag)
677677
) {
678678
throw_unsup_format!(
679-
"Using statx is only supported with absolute paths, relative paths with the file \
679+
"using statx is only supported with absolute paths, relative paths with the file \
680680
descriptor `AT_FDCWD`, and empty paths with the `AT_EMPTY_PATH` flag set and any \
681681
file descriptor"
682682
)
@@ -886,7 +886,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
886886
let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?;
887887

888888
let dir_iter = this.machine.dir_handler.streams.get_mut(&dirp).ok_or_else(|| {
889-
err_unsup_format!("The DIR pointer passed to readdir64_r did not come from opendir")
889+
err_unsup_format!("the DIR pointer passed to readdir64_r did not come from opendir")
890890
})?;
891891
match dir_iter.next() {
892892
Some(Ok(dir_entry)) => {
@@ -973,7 +973,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
973973
let dirp = this.read_scalar(dirp_op)?.to_machine_usize(this)?;
974974

975975
let dir_iter = this.machine.dir_handler.streams.get_mut(&dirp).ok_or_else(|| {
976-
err_unsup_format!("The DIR pointer passed to readdir_r did not come from opendir")
976+
err_unsup_format!("the DIR pointer passed to readdir_r did not come from opendir")
977977
})?;
978978
match dir_iter.next() {
979979
Some(Ok(dir_entry)) => {

src/shims/time.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ fn get_time<'tcx>() -> InterpResult<'tcx, Duration> {
1212
/// Returns the time elapsed between the provided time and the unix epoch as a `Duration`.
1313
pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Duration> {
1414
time.duration_since(SystemTime::UNIX_EPOCH)
15-
.map_err(|_| err_unsup_format!("Times before the Unix epoch are not supported").into())
15+
.map_err(|_| err_unsup_format!("times before the Unix epoch are not supported").into())
1616
}
1717

1818
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}

0 commit comments

Comments
 (0)