make statx a regular function (so we don't need to support the syscall)

This commit is contained in:
Ralf Jung 2024-05-04 14:41:12 +02:00
parent 823e31d9fa
commit 19aa8a021d
5 changed files with 23 additions and 26 deletions

View file

@ -16,8 +16,8 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
/// Zero-initialized pointer-sized extern statics are pretty common.
/// Most of them are for weak symbols, which we all set to null (indicating that the
/// symbol is not supported, and triggering fallback code which ends up calling a
/// syscall that we do support).
/// symbol is not supported, and triggering fallback code which ends up calling
/// some other shim that we do support).
fn null_ptr_extern_statics(
this: &mut MiriInterpCx<'mir, 'tcx>,
names: &[&str],
@ -59,8 +59,9 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
"linux" => {
Self::null_ptr_extern_statics(
this,
&["__cxa_thread_atexit_impl", "getrandom", "statx", "__clock_gettime64"],
&["__cxa_thread_atexit_impl", "__clock_gettime64"],
)?;
Self::weak_symbol_extern_statics(this, &["getrandom", "statx"])?;
// "environ"
let environ = this.machine.env_vars.unix().environ();
Self::add_extern_static(this, "environ", environ);

View file

@ -17,6 +17,7 @@ use crate::*;
pub trait FileDescription: std::fmt::Debug + Any {
fn name(&self) -> &'static str;
/// Reads as much as possible into the given buffer, and returns the number of bytes read.
fn read<'tcx>(
&mut self,
_communicate_allowed: bool,
@ -26,6 +27,7 @@ pub trait FileDescription: std::fmt::Debug + Any {
throw_unsup_format!("cannot read from {}", self.name());
}
/// Writes as much as possible from the given buffer, and returns the number of bytes written.
fn write<'tcx>(
&mut self,
_communicate_allowed: bool,
@ -35,6 +37,8 @@ pub trait FileDescription: std::fmt::Debug + Any {
throw_unsup_format!("cannot write to {}", self.name());
}
/// Seeks to the given offset (which can be relative to the beginning, end, or current position).
/// Returns the new position from the start of the stream.
fn seek<'tcx>(
&mut self,
_communicate_allowed: bool,

View file

@ -12,7 +12,7 @@ use shims::unix::linux::mem::EvalContextExt as _;
use shims::unix::linux::sync::futex;
pub fn is_dyn_sym(name: &str) -> bool {
matches!(name, "getrandom")
matches!(name, "getrandom" | "statx")
}
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
@ -29,7 +29,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
match link_name.as_str() {
// File related shims (but also see "syscall" below for statx)
// File related shims
"readdir64" => {
let [dirp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.linux_readdir64(dirp)?;
@ -41,6 +41,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
let result = this.sync_file_range(fd, offset, nbytes, flags)?;
this.write_scalar(result, dest)?;
}
"statx" => {
let [dirfd, pathname, flags, mask, statxbuf] =
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
let result = this.linux_statx(dirfd, pathname, flags, mask, statxbuf)?;
this.write_scalar(Scalar::from_i32(result), dest)?;
}
// epoll, eventfd
"epoll_create1" => {
@ -113,7 +119,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
// have the right type.
let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?;
let sys_statx = this.eval_libc("SYS_statx").to_target_usize(this)?;
let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?;
if args.is_empty() {
@ -134,20 +139,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
}
getrandom(this, &args[1], &args[2], &args[3], dest)?;
}
// `statx` is used by `libstd` to retrieve metadata information on `linux`
// instead of using `stat`,`lstat` or `fstat` as on `macos`.
id if id == sys_statx => {
// The first argument is the syscall id, so skip over it.
if args.len() < 6 {
throw_ub_format!(
"incorrect number of arguments for `statx` syscall: got {}, expected at least 6",
args.len()
);
}
let result =
this.linux_statx(&args[1], &args[2], &args[3], &args[4], &args[5])?;
this.write_scalar(Scalar::from_target_isize(result.into(), this), dest)?;
}
// `futex` is used by some synchronization primitives.
id if id == sys_futex => {
futex(this, &args[1..], dest)?;

View file

@ -1,7 +1,8 @@
#![feature(start)]
#![no_std]
//@compile-flags: -Zmiri-track-alloc-id=18 -Zmiri-track-alloc-accesses -Cpanic=abort
//@only-target-linux: alloc IDs differ between OSes for some reason
//@compile-flags: -Zmiri-track-alloc-id=20 -Zmiri-track-alloc-accesses -Cpanic=abort
//@normalize-stderr-test: "id 20" -> "id $$ALLOC"
//@only-target-linux: alloc IDs differ between OSes (due to extern static allocations)
extern "Rust" {
fn miri_alloc(size: usize, align: usize) -> *mut u8;

View file

@ -2,7 +2,7 @@ note: tracking was triggered
--> $DIR/alloc-access-tracking.rs:LL:CC
|
LL | let ptr = miri_alloc(123, 1);
| ^^^^^^^^^^^^^^^^^^ created Miri bare-metal heap allocation of 123 bytes (alignment ALIGN bytes) with id 18
| ^^^^^^^^^^^^^^^^^^ created Miri bare-metal heap allocation of 123 bytes (alignment ALIGN bytes) with id $ALLOC
|
= note: BACKTRACE:
= note: inside `start` at $DIR/alloc-access-tracking.rs:LL:CC
@ -11,7 +11,7 @@ note: tracking was triggered
--> $DIR/alloc-access-tracking.rs:LL:CC
|
LL | *ptr = 42; // Crucially, only a write is printed here, no read!
| ^^^^^^^^^ write access to allocation with id 18
| ^^^^^^^^^ write access to allocation with id $ALLOC
|
= note: BACKTRACE:
= note: inside `start` at $DIR/alloc-access-tracking.rs:LL:CC
@ -20,7 +20,7 @@ note: tracking was triggered
--> $DIR/alloc-access-tracking.rs:LL:CC
|
LL | assert_eq!(*ptr, 42);
| ^^^^^^^^^^^^^^^^^^^^ read access to allocation with id 18
| ^^^^^^^^^^^^^^^^^^^^ read access to allocation with id $ALLOC
|
= note: BACKTRACE:
= note: inside `start` at RUSTLIB/core/src/macros/mod.rs:LL:CC
@ -30,7 +30,7 @@ note: tracking was triggered
--> $DIR/alloc-access-tracking.rs:LL:CC
|
LL | miri_dealloc(ptr, 123, 1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ freed allocation with id 18
| ^^^^^^^^^^^^^^^^^^^^^^^^^ freed allocation with id $ALLOC
|
= note: BACKTRACE:
= note: inside `start` at $DIR/alloc-access-tracking.rs:LL:CC