Skip to content

Commit f736269

Browse files
authored
Merge pull request rust-lang#3992 from YohDeadfall/android-syscall
Android: Added syscall support
2 parents 9023e35 + c8ce9e6 commit f736269

File tree

7 files changed

+93
-70
lines changed

7 files changed

+93
-70
lines changed

src/tools/miri/ci/ci.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ case $HOST_TARGET in
154154
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX time hashmap random threadname pthread fs libc-pipe
155155
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
156156
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX time hashmap random thread sync available-parallelism tls libc-pipe
157-
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap threadname pthread
157+
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX time hashmap random sync threadname pthread
158158
TEST_TARGET=wasm32-wasip2 run_tests_minimal $BASIC wasm
159159
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std empty_main wasm # this target doesn't really have std
160160
TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std

src/tools/miri/src/shims/unix/android/foreign_items.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rustc_span::Symbol;
22
use rustc_target::spec::abi::Abi;
33

44
use crate::shims::unix::android::thread::prctl;
5+
use crate::shims::unix::linux::syscall::syscall;
56
use crate::*;
67

78
pub fn is_dyn_sym(_name: &str) -> bool {
@@ -26,6 +27,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
2627
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
2728
}
2829

30+
// Dynamically invoked syscalls
31+
"syscall" => syscall(this, link_name, abi, args, dest)?,
32+
2933
// Threading
3034
"prctl" => prctl(this, link_name, abi, args, dest)?,
3135

src/tools/miri/src/shims/unix/linux/foreign_items.rs

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ use rustc_target::spec::abi::Abi;
44
use self::shims::unix::linux::epoll::EvalContextExt as _;
55
use self::shims::unix::linux::eventfd::EvalContextExt as _;
66
use self::shims::unix::linux::mem::EvalContextExt as _;
7-
use self::shims::unix::linux::sync::futex;
8-
use crate::helpers::check_min_arg_count;
7+
use self::shims::unix::linux::syscall::syscall;
98
use crate::machine::{SIGRTMAX, SIGRTMIN};
109
use crate::shims::unix::*;
1110
use crate::*;
@@ -117,53 +116,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
117116

118117
// Dynamically invoked syscalls
119118
"syscall" => {
120-
// We do not use `check_shim` here because `syscall` is variadic. The argument
121-
// count is checked bellow.
122-
this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?;
123-
// The syscall variadic function is legal to call with more arguments than needed,
124-
// extra arguments are simply ignored. The important check is that when we use an
125-
// argument, we have to also check all arguments *before* it to ensure that they
126-
// have the right type.
127-
128-
let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?;
129-
let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?;
130-
let sys_eventfd2 = this.eval_libc("SYS_eventfd2").to_target_usize(this)?;
131-
132-
let [op] = check_min_arg_count("syscall", args)?;
133-
match this.read_target_usize(op)? {
134-
// `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)`
135-
// is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
136-
num if num == sys_getrandom => {
137-
// Used by getrandom 0.1
138-
// The first argument is the syscall id, so skip over it.
139-
let [_, ptr, len, flags] =
140-
check_min_arg_count("syscall(SYS_getrandom, ...)", args)?;
141-
142-
let ptr = this.read_pointer(ptr)?;
143-
let len = this.read_target_usize(len)?;
144-
// The only supported flags are GRND_RANDOM and GRND_NONBLOCK,
145-
// neither of which have any effect on our current PRNG.
146-
// See <https://github.com/rust-lang/rust/pull/79196> for a discussion of argument sizes.
147-
let _flags = this.read_scalar(flags)?.to_i32()?;
148-
149-
this.gen_random(ptr, len)?;
150-
this.write_scalar(Scalar::from_target_usize(len, this), dest)?;
151-
}
152-
// `futex` is used by some synchronization primitives.
153-
num if num == sys_futex => {
154-
futex(this, args, dest)?;
155-
}
156-
num if num == sys_eventfd2 => {
157-
let [_, initval, flags] =
158-
check_min_arg_count("syscall(SYS_evetfd2, ...)", args)?;
159-
160-
let result = this.eventfd(initval, flags)?;
161-
this.write_int(result.to_i32()?, dest)?;
162-
}
163-
num => {
164-
throw_unsup_format!("syscall: unsupported syscall number {num}");
165-
}
166-
}
119+
syscall(this, link_name, abi, args, dest)?;
167120
}
168121

169122
// Miscellaneous

src/tools/miri/src/shims/unix/linux/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ pub mod eventfd;
33
pub mod foreign_items;
44
pub mod mem;
55
pub mod sync;
6+
pub mod syscall;
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use rustc_span::Symbol;
2+
use rustc_target::spec::abi::Abi;
3+
4+
use self::shims::unix::linux::eventfd::EvalContextExt as _;
5+
use crate::helpers::check_min_arg_count;
6+
use crate::shims::unix::linux::sync::futex;
7+
use crate::*;
8+
9+
pub fn syscall<'tcx>(
10+
this: &mut MiriInterpCx<'tcx>,
11+
link_name: Symbol,
12+
abi: Abi,
13+
args: &[OpTy<'tcx>],
14+
dest: &MPlaceTy<'tcx>,
15+
) -> InterpResult<'tcx> {
16+
// We do not use `check_shim` here because `syscall` is variadic. The argument
17+
// count is checked bellow.
18+
this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?;
19+
// The syscall variadic function is legal to call with more arguments than needed,
20+
// extra arguments are simply ignored. The important check is that when we use an
21+
// argument, we have to also check all arguments *before* it to ensure that they
22+
// have the right type.
23+
24+
let sys_getrandom = this.eval_libc("SYS_getrandom").to_target_usize(this)?;
25+
let sys_futex = this.eval_libc("SYS_futex").to_target_usize(this)?;
26+
let sys_eventfd2 = this.eval_libc("SYS_eventfd2").to_target_usize(this)?;
27+
28+
let [op] = check_min_arg_count("syscall", args)?;
29+
match this.read_target_usize(op)? {
30+
// `libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)`
31+
// is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
32+
num if num == sys_getrandom => {
33+
// Used by getrandom 0.1
34+
// The first argument is the syscall id, so skip over it.
35+
let [_, ptr, len, flags] = check_min_arg_count("syscall(SYS_getrandom, ...)", args)?;
36+
37+
let ptr = this.read_pointer(ptr)?;
38+
let len = this.read_target_usize(len)?;
39+
// The only supported flags are GRND_RANDOM and GRND_NONBLOCK,
40+
// neither of which have any effect on our current PRNG.
41+
// See <https://github.com/rust-lang/rust/pull/79196> for a discussion of argument sizes.
42+
let _flags = this.read_scalar(flags)?.to_i32()?;
43+
44+
this.gen_random(ptr, len)?;
45+
this.write_scalar(Scalar::from_target_usize(len, this), dest)?;
46+
}
47+
// `futex` is used by some synchronization primitives.
48+
num if num == sys_futex => {
49+
futex(this, args, dest)?;
50+
}
51+
num if num == sys_eventfd2 => {
52+
let [_, initval, flags] = check_min_arg_count("syscall(SYS_evetfd2, ...)", args)?;
53+
54+
let result = this.eventfd(initval, flags)?;
55+
this.write_int(result.to_i32()?, dest)?;
56+
}
57+
num => {
58+
throw_unsup_format!("syscall: unsupported syscall number {num}");
59+
}
60+
};
61+
62+
interp_ok(())
63+
}

src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//@only-target: linux
2+
//@only-target: android
23
//@compile-flags: -Zmiri-disable-isolation
34

45
// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint

src/tools/miri/tests/pass-dep/libc/libc-random.rs

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,27 @@ fn test_getrandom() {
2828

2929
let mut buf = [0u8; 5];
3030
unsafe {
31-
#[cfg(target_os = "linux")]
32-
assert_eq!(
33-
libc::syscall(
34-
libc::SYS_getrandom,
35-
ptr::null_mut::<libc::c_void>(),
36-
0 as libc::size_t,
37-
0 as libc::c_uint,
38-
),
39-
0,
40-
);
41-
#[cfg(target_os = "linux")]
42-
assert_eq!(
43-
libc::syscall(
44-
libc::SYS_getrandom,
45-
buf.as_mut_ptr() as *mut libc::c_void,
46-
5 as libc::size_t,
47-
0 as libc::c_uint,
48-
),
49-
5,
50-
);
31+
#[cfg(any(target_os = "linux", target_os = "android"))]
32+
{
33+
assert_eq!(
34+
libc::syscall(
35+
libc::SYS_getrandom,
36+
ptr::null_mut::<libc::c_void>(),
37+
0 as libc::size_t,
38+
0 as libc::c_uint,
39+
),
40+
0,
41+
);
42+
assert_eq!(
43+
libc::syscall(
44+
libc::SYS_getrandom,
45+
buf.as_mut_ptr() as *mut libc::c_void,
46+
5 as libc::size_t,
47+
0 as libc::c_uint,
48+
),
49+
5,
50+
);
51+
}
5152

5253
assert_eq!(
5354
libc::getrandom(ptr::null_mut::<libc::c_void>(), 0 as libc::size_t, 0 as libc::c_uint),

0 commit comments

Comments
 (0)