about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorYoh Deadfall <yoh.deadfall@hotmail.com>2024-10-25 18:34:00 +0300
committerYoh Deadfall <yoh.deadfall@hotmail.com>2024-10-28 12:05:10 +0300
commitc8ce9e68d4cdae32b8a0859e4e381356452d2dc2 (patch)
tree2dbf8cdc135223b2a917efd28af2cabc55f47f09 /src
parent340d2f7847829c680965691c9d99a24e038f1ef7 (diff)
downloadrust-c8ce9e68d4cdae32b8a0859e4e381356452d2dc2.tar.gz
rust-c8ce9e68d4cdae32b8a0859e4e381356452d2dc2.zip
Android: Added syscall support
Diffstat (limited to 'src')
-rwxr-xr-xsrc/tools/miri/ci/ci.sh2
-rw-r--r--src/tools/miri/src/shims/unix/android/foreign_items.rs4
-rw-r--r--src/tools/miri/src/shims/unix/linux/foreign_items.rs51
-rw-r--r--src/tools/miri/src/shims/unix/linux/mod.rs1
-rw-r--r--src/tools/miri/src/shims/unix/linux/syscall.rs63
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs1
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-random.rs41
7 files changed, 93 insertions, 70 deletions
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index 4e7cbc50ca0..0356d7ecf10 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -154,7 +154,7 @@ case $HOST_TARGET in
     TEST_TARGET=i686-unknown-freebsd   run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
     TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
     TEST_TARGET=x86_64-pc-solaris      run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
-    TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX time hashmap threadname pthread
+    TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX time hashmap random sync threadname pthread
     TEST_TARGET=wasm32-wasip2          run_tests_minimal $BASIC wasm
     TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
     TEST_TARGET=thumbv7em-none-eabihf  run_tests_minimal no_std
diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs
index b6f04951fc7..2e10e82d936 100644
--- a/src/tools/miri/src/shims/unix/android/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs
@@ -2,6 +2,7 @@ use rustc_span::Symbol;
 use rustc_target::spec::abi::Abi;
 
 use crate::shims::unix::android::thread::prctl;
+use crate::shims::unix::linux::syscall::syscall;
 use crate::*;
 
 pub fn is_dyn_sym(_name: &str) -> bool {
@@ -26,6 +27,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
             }
 
+            // Dynamically invoked syscalls
+            "syscall" => syscall(this, link_name, abi, args, dest)?,
+
             // Threading
             "prctl" => prctl(this, link_name, abi, args, dest)?,
 
diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
index 6616a9845c0..a126d5b4fab 100644
--- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
@@ -4,8 +4,7 @@ use rustc_target::spec::abi::Abi;
 use self::shims::unix::linux::epoll::EvalContextExt as _;
 use self::shims::unix::linux::eventfd::EvalContextExt as _;
 use self::shims::unix::linux::mem::EvalContextExt as _;
-use self::shims::unix::linux::sync::futex;
-use crate::helpers::check_min_arg_count;
+use self::shims::unix::linux::syscall::syscall;
 use crate::machine::{SIGRTMAX, SIGRTMIN};
 use crate::shims::unix::*;
 use crate::*;
@@ -117,53 +116,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Dynamically invoked syscalls
             "syscall" => {
-                // We do not use `check_shim` here because `syscall` is variadic. The argument
-                // count is checked bellow.
-                this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?;
-                // The syscall variadic function is legal to call with more arguments than needed,
-                // extra arguments are simply ignored. The important check is that when we use an
-                // argument, we have to also check all arguments *before* it to ensure that they
-                // have the right type.
-
-                let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?;
-                let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?;
-                let sys_eventfd2 = this.eval_libc("SYS_eventfd2").to_target_usize(this)?;
-
-                let [op] = check_min_arg_count("syscall", args)?;
-                match this.read_target_usize(op)? {
-                    // `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)`
-                    // is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
-                    num if num == sys_getrandom => {
-                        // Used by getrandom 0.1
-                        // The first argument is the syscall id, so skip over it.
-                        let [_, ptr, len, flags] =
-                            check_min_arg_count("syscall(SYS_getrandom, ...)", args)?;
-
-                        let ptr = this.read_pointer(ptr)?;
-                        let len = this.read_target_usize(len)?;
-                        // The only supported flags are GRND_RANDOM and GRND_NONBLOCK,
-                        // neither of which have any effect on our current PRNG.
-                        // See <https://github.com/rust-lang/rust/pull/79196> for a discussion of argument sizes.
-                        let _flags = this.read_scalar(flags)?.to_i32()?;
-
-                        this.gen_random(ptr, len)?;
-                        this.write_scalar(Scalar::from_target_usize(len, this), dest)?;
-                    }
-                    // `futex` is used by some synchronization primitives.
-                    num if num == sys_futex => {
-                        futex(this, args, dest)?;
-                    }
-                    num if num == sys_eventfd2 => {
-                        let [_, initval, flags] =
-                            check_min_arg_count("syscall(SYS_evetfd2, ...)", args)?;
-
-                        let result = this.eventfd(initval, flags)?;
-                        this.write_int(result.to_i32()?, dest)?;
-                    }
-                    num => {
-                        throw_unsup_format!("syscall: unsupported syscall number {num}");
-                    }
-                }
+                syscall(this, link_name, abi, args, dest)?;
             }
 
             // Miscellaneous
diff --git a/src/tools/miri/src/shims/unix/linux/mod.rs b/src/tools/miri/src/shims/unix/linux/mod.rs
index 84b604eb9b8..159e5aca031 100644
--- a/src/tools/miri/src/shims/unix/linux/mod.rs
+++ b/src/tools/miri/src/shims/unix/linux/mod.rs
@@ -3,3 +3,4 @@ pub mod eventfd;
 pub mod foreign_items;
 pub mod mem;
 pub mod sync;
+pub mod syscall;
diff --git a/src/tools/miri/src/shims/unix/linux/syscall.rs b/src/tools/miri/src/shims/unix/linux/syscall.rs
new file mode 100644
index 00000000000..72e02447d80
--- /dev/null
+++ b/src/tools/miri/src/shims/unix/linux/syscall.rs
@@ -0,0 +1,63 @@
+use rustc_span::Symbol;
+use rustc_target::spec::abi::Abi;
+
+use self::shims::unix::linux::eventfd::EvalContextExt as _;
+use crate::helpers::check_min_arg_count;
+use crate::shims::unix::linux::sync::futex;
+use crate::*;
+
+pub fn syscall<'tcx>(
+    this: &mut MiriInterpCx<'tcx>,
+    link_name: Symbol,
+    abi: Abi,
+    args: &[OpTy<'tcx>],
+    dest: &MPlaceTy<'tcx>,
+) -> InterpResult<'tcx> {
+    // We do not use `check_shim` here because `syscall` is variadic. The argument
+    // count is checked bellow.
+    this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?;
+    // The syscall variadic function is legal to call with more arguments than needed,
+    // extra arguments are simply ignored. The important check is that when we use an
+    // argument, we have to also check all arguments *before* it to ensure that they
+    // have the right type.
+
+    let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?;
+    let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?;
+    let sys_eventfd2 = this.eval_libc("SYS_eventfd2").to_target_usize(this)?;
+
+    let [op] = check_min_arg_count("syscall", args)?;
+    match this.read_target_usize(op)? {
+        // `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)`
+        // is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
+        num if num == sys_getrandom => {
+            // Used by getrandom 0.1
+            // The first argument is the syscall id, so skip over it.
+            let [_, ptr, len, flags] = check_min_arg_count("syscall(SYS_getrandom, ...)", args)?;
+
+            let ptr = this.read_pointer(ptr)?;
+            let len = this.read_target_usize(len)?;
+            // The only supported flags are GRND_RANDOM and GRND_NONBLOCK,
+            // neither of which have any effect on our current PRNG.
+            // See <https://github.com/rust-lang/rust/pull/79196> for a discussion of argument sizes.
+            let _flags = this.read_scalar(flags)?.to_i32()?;
+
+            this.gen_random(ptr, len)?;
+            this.write_scalar(Scalar::from_target_usize(len, this), dest)?;
+        }
+        // `futex` is used by some synchronization primitives.
+        num if num == sys_futex => {
+            futex(this, args, dest)?;
+        }
+        num if num == sys_eventfd2 => {
+            let [_, initval, flags] = check_min_arg_count("syscall(SYS_evetfd2, ...)", args)?;
+
+            let result = this.eventfd(initval, flags)?;
+            this.write_int(result.to_i32()?, dest)?;
+        }
+        num => {
+            throw_unsup_format!("syscall: unsupported syscall number {num}");
+        }
+    };
+
+    interp_ok(())
+}
diff --git a/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs b/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
index 20e642a0a29..2a36c10f7d4 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
@@ -1,4 +1,5 @@
 //@only-target: linux
+//@only-target: android
 //@compile-flags: -Zmiri-disable-isolation
 
 // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-random.rs b/src/tools/miri/tests/pass-dep/libc/libc-random.rs
index 8f4398cbd8f..7c4010f6c0a 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-random.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-random.rs
@@ -28,26 +28,27 @@ fn test_getrandom() {
 
     let mut buf = [0u8; 5];
     unsafe {
-        #[cfg(target_os = "linux")]
-        assert_eq!(
-            libc::syscall(
-                libc::SYS_getrandom,
-                ptr::null_mut::<libc::c_void>(),
-                0 as libc::size_t,
-                0 as libc::c_uint,
-            ),
-            0,
-        );
-        #[cfg(target_os = "linux")]
-        assert_eq!(
-            libc::syscall(
-                libc::SYS_getrandom,
-                buf.as_mut_ptr() as *mut libc::c_void,
-                5 as libc::size_t,
-                0 as libc::c_uint,
-            ),
-            5,
-        );
+        #[cfg(any(target_os = "linux", target_os = "android"))]
+        {
+            assert_eq!(
+                libc::syscall(
+                    libc::SYS_getrandom,
+                    ptr::null_mut::<libc::c_void>(),
+                    0 as libc::size_t,
+                    0 as libc::c_uint,
+                ),
+                0,
+            );
+            assert_eq!(
+                libc::syscall(
+                    libc::SYS_getrandom,
+                    buf.as_mut_ptr() as *mut libc::c_void,
+                    5 as libc::size_t,
+                    0 as libc::c_uint,
+                ),
+                5,
+            );
+        }
 
         assert_eq!(
             libc::getrandom(ptr::null_mut::<libc::c_void>(), 0 as libc::size_t, 0 as libc::c_uint),