Skip to content

Commit 0e41a80

Browse files
committed
Auto merge of #3616 - RalfJung:android, r=RalfJung
make basic things work on Android Fixes rust-lang/miri#3608
2 parents 3726afa + 844de64 commit 0e41a80

File tree

9 files changed

+79
-37
lines changed

9 files changed

+79
-37
lines changed

src/tools/miri/ci/ci.sh

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,12 @@ case $HOST_TARGET in
145145
TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice
146146
# Partially supported targets (tier 2)
147147
BASIC="empty_main integer vec string btreemap hello hashmap heap_alloc align" # ensures we have the basics: stdout/stderr, system allocator, randomness (for HashMap initialization)
148-
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-mem libc-misc libc-random libc-time fs env num_cpus
149-
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC panic/panic concurrency/simple atomic threadname libc-mem libc-misc libc-random libc-time fs env num_cpus
150-
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random env
151-
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random env
152-
TEST_TARGET=aarch64-linux-android run_tests_minimal empty_main hello panic/panic
148+
UNIX="panic/panic concurrency/simple atomic libc-mem libc-misc libc-random env num_cpus" # the things that are very similar across all Unixes, and hence easily supported there
149+
TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX threadname libc-time fs
150+
TEST_TARGET=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX threadname libc-time fs
151+
TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX pthread-sync
152+
TEST_TARGET=x86_64-pc-solaris run_tests_minimal $BASIC $UNIX pthread-sync
153+
TEST_TARGET=aarch64-linux-android run_tests_minimal $BASIC $UNIX
153154
TEST_TARGET=wasm32-wasi run_tests_minimal empty_main wasm heap_alloc libc-mem
154155
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal empty_main wasm
155156
TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std

src/tools/miri/src/shims/extern_static.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,30 +55,26 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
5555
let val = ImmTy::from_int(val, this.machine.layouts.u8);
5656
Self::alloc_extern_static(this, "__rust_alloc_error_handler_should_panic", val)?;
5757

58+
if this.target_os_is_unix() {
59+
// "environ" is mandated by POSIX.
60+
let environ = this.machine.env_vars.unix().environ();
61+
Self::add_extern_static(this, "environ", environ);
62+
}
63+
5864
match this.tcx.sess.target.os.as_ref() {
5965
"linux" => {
6066
Self::null_ptr_extern_statics(
6167
this,
6268
&["__cxa_thread_atexit_impl", "__clock_gettime64"],
6369
)?;
6470
Self::weak_symbol_extern_statics(this, &["getrandom", "statx"])?;
65-
// "environ"
66-
let environ = this.machine.env_vars.unix().environ();
67-
Self::add_extern_static(this, "environ", environ);
6871
}
6972
"freebsd" => {
7073
Self::null_ptr_extern_statics(this, &["__cxa_thread_atexit_impl"])?;
71-
// "environ"
72-
let environ = this.machine.env_vars.unix().environ();
73-
Self::add_extern_static(this, "environ", environ);
7474
}
7575
"android" => {
7676
Self::null_ptr_extern_statics(this, &["bsd_signal"])?;
77-
Self::weak_symbol_extern_statics(this, &["signal"])?;
78-
}
79-
"solaris" | "illumos" => {
80-
let environ = this.machine.env_vars.unix().environ();
81-
Self::add_extern_static(this, "environ", environ);
77+
Self::weak_symbol_extern_statics(this, &["signal", "getrandom"])?;
8278
}
8379
"windows" => {
8480
// "_tls_used"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use rustc_span::Symbol;
2+
use rustc_target::spec::abi::Abi;
3+
4+
use crate::*;
5+
6+
pub fn is_dyn_sym(_name: &str) -> bool {
7+
false
8+
}
9+
10+
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
11+
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
12+
fn emulate_foreign_item_inner(
13+
&mut self,
14+
link_name: Symbol,
15+
abi: Abi,
16+
args: &[OpTy<'tcx, Provenance>],
17+
dest: &MPlaceTy<'tcx, Provenance>,
18+
) -> InterpResult<'tcx, EmulateItemResult> {
19+
let this = self.eval_context_mut();
20+
match link_name.as_str() {
21+
// Miscellaneous
22+
"__errno" => {
23+
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
24+
let errno_place = this.last_error_place()?;
25+
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
26+
}
27+
28+
_ => return Ok(EmulateItemResult::NotSupported),
29+
}
30+
Ok(EmulateItemResult::NeedsJumping)
31+
}
32+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod foreign_items;

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use crate::shims::alloc::EvalContextExt as _;
99
use crate::shims::unix::*;
1010
use crate::*;
1111

12+
use shims::unix::android::foreign_items as android;
1213
use shims::unix::freebsd::foreign_items as freebsd;
1314
use shims::unix::linux::foreign_items as linux;
1415
use shims::unix::macos::foreign_items as macos;
@@ -26,6 +27,7 @@ pub fn is_dyn_sym(name: &str, target_os: &str) -> bool {
2627
// Give specific OSes a chance to allow their symbols.
2728
_ =>
2829
match target_os {
30+
"android" => android::is_dyn_sym(name),
2931
"freebsd" => freebsd::is_dyn_sym(name),
3032
"linux" => linux::is_dyn_sym(name),
3133
"macos" => macos::is_dyn_sym(name),
@@ -267,7 +269,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
267269

268270
"reallocarray" => {
269271
// Currently this function does not exist on all Unixes, e.g. on macOS.
270-
if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd") {
272+
if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "android") {
271273
throw_unsup_format!(
272274
"`reallocarray` is not supported on {}",
273275
this.tcx.sess.target.os
@@ -593,7 +595,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
593595
"getentropy" => {
594596
// This function is non-standard but exists with the same signature and behavior on
595597
// Linux, macOS, FreeBSD and Solaris/Illumos.
596-
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "freebsd" | "illumos" | "solaris") {
598+
if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "freebsd" | "illumos" | "solaris" | "android") {
597599
throw_unsup_format!(
598600
"`getentropy` is not supported on {}",
599601
this.tcx.sess.target.os
@@ -622,9 +624,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
622624
"getrandom" => {
623625
// This function is non-standard but exists with the same signature and behavior on
624626
// Linux, FreeBSD and Solaris/Illumos.
625-
if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "illumos" | "solaris") {
627+
if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "illumos" | "solaris" | "android") {
626628
throw_unsup_format!(
627-
"`getentropy` is not supported on {}",
629+
"`getrandom` is not supported on {}",
628630
this.tcx.sess.target.os
629631
);
630632
}
@@ -748,6 +750,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
748750
_ => {
749751
let target_os = &*this.tcx.sess.target.os;
750752
return match target_os {
753+
"android" => android::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
751754
"freebsd" => freebsd::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
752755
"linux" => linux::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
753756
"macos" => macos::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ mod socket;
88
mod sync;
99
mod thread;
1010

11+
mod android;
1112
mod freebsd;
1213
mod linux;
1314
mod macos;

src/tools/miri/tests/fail/environ-gets-deallocated.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,12 @@
11
//@ignore-target-windows: Windows does not have a global environ list that the program can access directly
22

3-
#[cfg(any(
4-
target_os = "linux",
5-
target_os = "freebsd",
6-
target_os = "solaris",
7-
target_os = "illumos"
8-
))]
93
fn get_environ() -> *const *const u8 {
104
extern "C" {
115
static mut environ: *const *const u8;
126
}
137
unsafe { environ }
148
}
159

16-
#[cfg(target_os = "macos")]
17-
fn get_environ() -> *const *const u8 {
18-
extern "C" {
19-
fn _NSGetEnviron() -> *mut *const *const u8;
20-
}
21-
unsafe { *_NSGetEnviron() }
22-
}
23-
2410
fn main() {
2511
let pointer = get_environ();
2612
let _x = unsafe { *pointer };

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ use std::mem::transmute;
1010
fn test_thread_local_errno() {
1111
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
1212
use libc::___errno as __errno_location;
13+
#[cfg(target_os = "android")]
14+
use libc::__errno as __errno_location;
1315
#[cfg(target_os = "linux")]
1416
use libc::__errno_location;
15-
#[cfg(any(target_os = "macos", target_os = "freebsd"))]
17+
#[cfg(any(target_os = "freebsd", target_os = "macos"))]
1618
use libc::__error as __errno_location;
1719

1820
unsafe {
@@ -28,6 +30,21 @@ fn test_thread_local_errno() {
2830
}
2931
}
3032

33+
fn test_environ() {
34+
// Just a smoke test for now, checking that the extern static exists.
35+
extern "C" {
36+
static mut environ: *const *const libc::c_char;
37+
}
38+
39+
unsafe {
40+
let mut e = environ;
41+
// Iterate to the end.
42+
while !(*e).is_null() {
43+
e = e.add(1);
44+
}
45+
}
46+
}
47+
3148
#[cfg(target_os = "linux")]
3249
fn test_sigrt() {
3350
let min = libc::SIGRTMIN();
@@ -60,6 +77,7 @@ fn test_dlsym() {
6077

6178
fn main() {
6279
test_thread_local_errno();
80+
test_environ();
6381

6482
test_dlsym();
6583

src/tools/miri/tests/pass/shims/env/home.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,12 @@
22
use std::env;
33

44
fn main() {
5-
env::remove_var("HOME"); // make sure we enter the interesting codepath
6-
env::remove_var("USERPROFILE"); // Windows also looks as this env var
5+
// Remove the env vars to hit the underlying shim -- except
6+
// on android where the env var is all we have.
7+
#[cfg(not(target_os = "android"))]
8+
env::remove_var("HOME");
9+
env::remove_var("USERPROFILE");
10+
711
#[allow(deprecated)]
812
env::home_dir().unwrap();
913
}

0 commit comments

Comments
 (0)