about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-05-19 10:14:36 +0000
committerbors <bors@rust-lang.org>2024-05-19 10:14:36 +0000
commit0e41a801f34b14d52a5637b173ff2d8884e1709d (patch)
tree3c5a9f038a5c44d2dd89b714190f2dd9edaf84bf
parent3726afad7edc24a4ae0c3a16f6f2a18921d5c405 (diff)
parent844de64396bfa0d545513f35ef6091fe63ce03e0 (diff)
downloadrust-0e41a801f34b14d52a5637b173ff2d8884e1709d.tar.gz
rust-0e41a801f34b14d52a5637b173ff2d8884e1709d.zip
Auto merge of #3616 - RalfJung:android, r=RalfJung
make basic things work on Android

Fixes https://github.com/rust-lang/miri/issues/3608
-rwxr-xr-xsrc/tools/miri/ci/ci.sh11
-rw-r--r--src/tools/miri/src/shims/extern_static.rs18
-rw-r--r--src/tools/miri/src/shims/unix/android/foreign_items.rs32
-rw-r--r--src/tools/miri/src/shims/unix/android/mod.rs1
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs11
-rw-r--r--src/tools/miri/src/shims/unix/mod.rs1
-rw-r--r--src/tools/miri/tests/fail/environ-gets-deallocated.rs14
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-misc.rs20
-rw-r--r--src/tools/miri/tests/pass/shims/env/home.rs8
9 files changed, 79 insertions, 37 deletions
diff --git a/src/tools/miri/ci/ci.sh b/src/tools/miri/ci/ci.sh
index 2a6ca8f4783..50ac4539c26 100755
--- a/src/tools/miri/ci/ci.sh
+++ b/src/tools/miri/ci/ci.sh
@@ -145,11 +145,12 @@ case $HOST_TARGET in
     TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice
     # Partially supported targets (tier 2)
     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)
-    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
-    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
-    TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random env
-    TEST_TARGET=x86_64-pc-solaris      run_tests_minimal $BASIC panic/panic concurrency/simple pthread-sync libc-mem libc-misc libc-random env
-    TEST_TARGET=aarch64-linux-android  run_tests_minimal empty_main hello panic/panic
+    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
+    TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal $BASIC $UNIX threadname libc-time fs
+    TEST_TARGET=i686-unknown-freebsd   run_tests_minimal $BASIC $UNIX threadname libc-time fs
+    TEST_TARGET=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX pthread-sync
+    TEST_TARGET=x86_64-pc-solaris      run_tests_minimal $BASIC $UNIX pthread-sync
+    TEST_TARGET=aarch64-linux-android  run_tests_minimal $BASIC $UNIX
     TEST_TARGET=wasm32-wasi            run_tests_minimal empty_main wasm heap_alloc libc-mem
     TEST_TARGET=wasm32-unknown-unknown run_tests_minimal empty_main wasm
     TEST_TARGET=thumbv7em-none-eabihf  run_tests_minimal no_std
diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs
index 12fede39e27..b9817a18773 100644
--- a/src/tools/miri/src/shims/extern_static.rs
+++ b/src/tools/miri/src/shims/extern_static.rs
@@ -55,6 +55,12 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
         let val = ImmTy::from_int(val, this.machine.layouts.u8);
         Self::alloc_extern_static(this, "__rust_alloc_error_handler_should_panic", val)?;
 
+        if this.target_os_is_unix() {
+            // "environ" is mandated by POSIX.
+            let environ = this.machine.env_vars.unix().environ();
+            Self::add_extern_static(this, "environ", environ);
+        }
+
         match this.tcx.sess.target.os.as_ref() {
             "linux" => {
                 Self::null_ptr_extern_statics(
@@ -62,23 +68,13 @@ impl<'mir, 'tcx> MiriMachine<'mir, 'tcx> {
                     &["__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);
             }
             "freebsd" => {
                 Self::null_ptr_extern_statics(this, &["__cxa_thread_atexit_impl"])?;
-                // "environ"
-                let environ = this.machine.env_vars.unix().environ();
-                Self::add_extern_static(this, "environ", environ);
             }
             "android" => {
                 Self::null_ptr_extern_statics(this, &["bsd_signal"])?;
-                Self::weak_symbol_extern_statics(this, &["signal"])?;
-            }
-            "solaris" | "illumos" => {
-                let environ = this.machine.env_vars.unix().environ();
-                Self::add_extern_static(this, "environ", environ);
+                Self::weak_symbol_extern_statics(this, &["signal", "getrandom"])?;
             }
             "windows" => {
                 // "_tls_used"
diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs
new file mode 100644
index 00000000000..f85b8a725f2
--- /dev/null
+++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs
@@ -0,0 +1,32 @@
+use rustc_span::Symbol;
+use rustc_target::spec::abi::Abi;
+
+use crate::*;
+
+pub fn is_dyn_sym(_name: &str) -> bool {
+    false
+}
+
+impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
+pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
+    fn emulate_foreign_item_inner(
+        &mut self,
+        link_name: Symbol,
+        abi: Abi,
+        args: &[OpTy<'tcx, Provenance>],
+        dest: &MPlaceTy<'tcx, Provenance>,
+    ) -> InterpResult<'tcx, EmulateItemResult> {
+        let this = self.eval_context_mut();
+        match link_name.as_str() {
+            // Miscellaneous
+            "__errno" => {
+                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let errno_place = this.last_error_place()?;
+                this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
+            }
+
+            _ => return Ok(EmulateItemResult::NotSupported),
+        }
+        Ok(EmulateItemResult::NeedsJumping)
+    }
+}
diff --git a/src/tools/miri/src/shims/unix/android/mod.rs b/src/tools/miri/src/shims/unix/android/mod.rs
new file mode 100644
index 00000000000..09c6507b24f
--- /dev/null
+++ b/src/tools/miri/src/shims/unix/android/mod.rs
@@ -0,0 +1 @@
+pub mod foreign_items;
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 74fb2fb4b2b..396011cc22a 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -9,6 +9,7 @@ use crate::shims::alloc::EvalContextExt as _;
 use crate::shims::unix::*;
 use crate::*;
 
+use shims::unix::android::foreign_items as android;
 use shims::unix::freebsd::foreign_items as freebsd;
 use shims::unix::linux::foreign_items as linux;
 use shims::unix::macos::foreign_items as macos;
@@ -26,6 +27,7 @@ pub fn is_dyn_sym(name: &str, target_os: &str) -> bool {
         // Give specific OSes a chance to allow their symbols.
         _ =>
             match target_os {
+                "android" => android::is_dyn_sym(name),
                 "freebsd" => freebsd::is_dyn_sym(name),
                 "linux" => linux::is_dyn_sym(name),
                 "macos" => macos::is_dyn_sym(name),
@@ -267,7 +269,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
             "reallocarray" => {
                 // Currently this function does not exist on all Unixes, e.g. on macOS.
-                if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd") {
+                if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "android") {
                     throw_unsup_format!(
                         "`reallocarray` is not supported on {}",
                         this.tcx.sess.target.os
@@ -593,7 +595,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "getentropy" => {
                 // This function is non-standard but exists with the same signature and behavior on
                 // Linux, macOS, FreeBSD and Solaris/Illumos.
-                if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "freebsd" | "illumos" | "solaris") {
+                if !matches!(&*this.tcx.sess.target.os, "linux" | "macos" | "freebsd" | "illumos" | "solaris" | "android") {
                     throw_unsup_format!(
                         "`getentropy` is not supported on {}",
                         this.tcx.sess.target.os
@@ -622,9 +624,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "getrandom" => {
                 // This function is non-standard but exists with the same signature and behavior on
                 // Linux, FreeBSD and Solaris/Illumos.
-                if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "illumos" | "solaris") {
+                if !matches!(&*this.tcx.sess.target.os, "linux" | "freebsd" | "illumos" | "solaris" | "android") {
                     throw_unsup_format!(
-                        "`getentropy` is not supported on {}",
+                        "`getrandom` is not supported on {}",
                         this.tcx.sess.target.os
                     );
                 }
@@ -748,6 +750,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             _ => {
                 let target_os = &*this.tcx.sess.target.os;
                 return match target_os {
+                    "android" => android::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
                     "freebsd" => freebsd::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
                     "linux" => linux::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
                     "macos" => macos::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
diff --git a/src/tools/miri/src/shims/unix/mod.rs b/src/tools/miri/src/shims/unix/mod.rs
index 6dee30d895c..dc9068fddde 100644
--- a/src/tools/miri/src/shims/unix/mod.rs
+++ b/src/tools/miri/src/shims/unix/mod.rs
@@ -8,6 +8,7 @@ mod socket;
 mod sync;
 mod thread;
 
+mod android;
 mod freebsd;
 mod linux;
 mod macos;
diff --git a/src/tools/miri/tests/fail/environ-gets-deallocated.rs b/src/tools/miri/tests/fail/environ-gets-deallocated.rs
index 08545a72567..5391a9176d0 100644
--- a/src/tools/miri/tests/fail/environ-gets-deallocated.rs
+++ b/src/tools/miri/tests/fail/environ-gets-deallocated.rs
@@ -1,11 +1,5 @@
 //@ignore-target-windows: Windows does not have a global environ list that the program can access directly
 
-#[cfg(any(
-    target_os = "linux",
-    target_os = "freebsd",
-    target_os = "solaris",
-    target_os = "illumos"
-))]
 fn get_environ() -> *const *const u8 {
     extern "C" {
         static mut environ: *const *const u8;
@@ -13,14 +7,6 @@ fn get_environ() -> *const *const u8 {
     unsafe { environ }
 }
 
-#[cfg(target_os = "macos")]
-fn get_environ() -> *const *const u8 {
-    extern "C" {
-        fn _NSGetEnviron() -> *mut *const *const u8;
-    }
-    unsafe { *_NSGetEnviron() }
-}
-
 fn main() {
     let pointer = get_environ();
     let _x = unsafe { *pointer };
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-misc.rs b/src/tools/miri/tests/pass-dep/libc/libc-misc.rs
index 736e0bf8eb7..f7e1d9faa6a 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-misc.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-misc.rs
@@ -10,9 +10,11 @@ use std::mem::transmute;
 fn test_thread_local_errno() {
     #[cfg(any(target_os = "illumos", target_os = "solaris"))]
     use libc::___errno as __errno_location;
+    #[cfg(target_os = "android")]
+    use libc::__errno as __errno_location;
     #[cfg(target_os = "linux")]
     use libc::__errno_location;
-    #[cfg(any(target_os = "macos", target_os = "freebsd"))]
+    #[cfg(any(target_os = "freebsd", target_os = "macos"))]
     use libc::__error as __errno_location;
 
     unsafe {
@@ -28,6 +30,21 @@ fn test_thread_local_errno() {
     }
 }
 
+fn test_environ() {
+    // Just a smoke test for now, checking that the extern static exists.
+    extern "C" {
+        static mut environ: *const *const libc::c_char;
+    }
+
+    unsafe {
+        let mut e = environ;
+        // Iterate to the end.
+        while !(*e).is_null() {
+            e = e.add(1);
+        }
+    }
+}
+
 #[cfg(target_os = "linux")]
 fn test_sigrt() {
     let min = libc::SIGRTMIN();
@@ -60,6 +77,7 @@ fn test_dlsym() {
 
 fn main() {
     test_thread_local_errno();
+    test_environ();
 
     test_dlsym();
 
diff --git a/src/tools/miri/tests/pass/shims/env/home.rs b/src/tools/miri/tests/pass/shims/env/home.rs
index c237f9ed9ff..8b4b907a51d 100644
--- a/src/tools/miri/tests/pass/shims/env/home.rs
+++ b/src/tools/miri/tests/pass/shims/env/home.rs
@@ -2,8 +2,12 @@
 use std::env;
 
 fn main() {
-    env::remove_var("HOME"); // make sure we enter the interesting codepath
-    env::remove_var("USERPROFILE"); // Windows also looks as this env var
+    // Remove the env vars to hit the underlying shim -- except
+    // on android where the env var is all we have.
+    #[cfg(not(target_os = "android"))]
+    env::remove_var("HOME");
+    env::remove_var("USERPROFILE");
+
     #[allow(deprecated)]
     env::home_dir().unwrap();
 }