Auto merge of #3616 - RalfJung:android, r=RalfJung
make basic things work on Android Fixes https://github.com/rust-lang/miri/issues/3608
This commit is contained in:
commit
0e41a801f3
@ -145,11 +145,12 @@ case $HOST_TARGET in
|
|||||||
TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice
|
TEST_TARGET=s390x-unknown-linux-gnu run_tests # big-endian architecture of choice
|
||||||
# Partially supported targets (tier 2)
|
# 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)
|
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
|
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=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-freebsd run_tests_minimal $BASIC $UNIX threadname libc-time fs
|
||||||
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=i686-unknown-freebsd run_tests_minimal $BASIC $UNIX threadname libc-time fs
|
||||||
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=x86_64-unknown-illumos run_tests_minimal $BASIC $UNIX pthread-sync
|
||||||
TEST_TARGET=aarch64-linux-android run_tests_minimal empty_main hello panic/panic
|
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-wasi run_tests_minimal empty_main wasm heap_alloc libc-mem
|
||||||
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal empty_main wasm
|
TEST_TARGET=wasm32-unknown-unknown run_tests_minimal empty_main wasm
|
||||||
TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std
|
TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std
|
||||||
|
@ -55,6 +55,12 @@ pub fn init_extern_statics(this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<
|
|||||||
let val = ImmTy::from_int(val, this.machine.layouts.u8);
|
let val = ImmTy::from_int(val, this.machine.layouts.u8);
|
||||||
Self::alloc_extern_static(this, "__rust_alloc_error_handler_should_panic", val)?;
|
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() {
|
match this.tcx.sess.target.os.as_ref() {
|
||||||
"linux" => {
|
"linux" => {
|
||||||
Self::null_ptr_extern_statics(
|
Self::null_ptr_extern_statics(
|
||||||
@ -62,23 +68,13 @@ pub fn init_extern_statics(this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<
|
|||||||
&["__cxa_thread_atexit_impl", "__clock_gettime64"],
|
&["__cxa_thread_atexit_impl", "__clock_gettime64"],
|
||||||
)?;
|
)?;
|
||||||
Self::weak_symbol_extern_statics(this, &["getrandom", "statx"])?;
|
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" => {
|
"freebsd" => {
|
||||||
Self::null_ptr_extern_statics(this, &["__cxa_thread_atexit_impl"])?;
|
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" => {
|
"android" => {
|
||||||
Self::null_ptr_extern_statics(this, &["bsd_signal"])?;
|
Self::null_ptr_extern_statics(this, &["bsd_signal"])?;
|
||||||
Self::weak_symbol_extern_statics(this, &["signal"])?;
|
Self::weak_symbol_extern_statics(this, &["signal", "getrandom"])?;
|
||||||
}
|
|
||||||
"solaris" | "illumos" => {
|
|
||||||
let environ = this.machine.env_vars.unix().environ();
|
|
||||||
Self::add_extern_static(this, "environ", environ);
|
|
||||||
}
|
}
|
||||||
"windows" => {
|
"windows" => {
|
||||||
// "_tls_used"
|
// "_tls_used"
|
||||||
|
32
src/tools/miri/src/shims/unix/android/foreign_items.rs
Normal file
32
src/tools/miri/src/shims/unix/android/foreign_items.rs
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
1
src/tools/miri/src/shims/unix/android/mod.rs
Normal file
1
src/tools/miri/src/shims/unix/android/mod.rs
Normal file
@ -0,0 +1 @@
|
|||||||
|
pub mod foreign_items;
|
@ -9,6 +9,7 @@
|
|||||||
use crate::shims::unix::*;
|
use crate::shims::unix::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
use shims::unix::android::foreign_items as android;
|
||||||
use shims::unix::freebsd::foreign_items as freebsd;
|
use shims::unix::freebsd::foreign_items as freebsd;
|
||||||
use shims::unix::linux::foreign_items as linux;
|
use shims::unix::linux::foreign_items as linux;
|
||||||
use shims::unix::macos::foreign_items as macos;
|
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.
|
// Give specific OSes a chance to allow their symbols.
|
||||||
_ =>
|
_ =>
|
||||||
match target_os {
|
match target_os {
|
||||||
|
"android" => android::is_dyn_sym(name),
|
||||||
"freebsd" => freebsd::is_dyn_sym(name),
|
"freebsd" => freebsd::is_dyn_sym(name),
|
||||||
"linux" => linux::is_dyn_sym(name),
|
"linux" => linux::is_dyn_sym(name),
|
||||||
"macos" => macos::is_dyn_sym(name),
|
"macos" => macos::is_dyn_sym(name),
|
||||||
@ -267,7 +269,7 @@ fn emulate_foreign_item_inner(
|
|||||||
|
|
||||||
"reallocarray" => {
|
"reallocarray" => {
|
||||||
// Currently this function does not exist on all Unixes, e.g. on macOS.
|
// 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!(
|
throw_unsup_format!(
|
||||||
"`reallocarray` is not supported on {}",
|
"`reallocarray` is not supported on {}",
|
||||||
this.tcx.sess.target.os
|
this.tcx.sess.target.os
|
||||||
@ -593,7 +595,7 @@ fn emulate_foreign_item_inner(
|
|||||||
"getentropy" => {
|
"getentropy" => {
|
||||||
// This function is non-standard but exists with the same signature and behavior on
|
// This function is non-standard but exists with the same signature and behavior on
|
||||||
// Linux, macOS, FreeBSD and Solaris/Illumos.
|
// 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!(
|
throw_unsup_format!(
|
||||||
"`getentropy` is not supported on {}",
|
"`getentropy` is not supported on {}",
|
||||||
this.tcx.sess.target.os
|
this.tcx.sess.target.os
|
||||||
@ -622,9 +624,9 @@ fn emulate_foreign_item_inner(
|
|||||||
"getrandom" => {
|
"getrandom" => {
|
||||||
// This function is non-standard but exists with the same signature and behavior on
|
// This function is non-standard but exists with the same signature and behavior on
|
||||||
// Linux, FreeBSD and Solaris/Illumos.
|
// 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!(
|
throw_unsup_format!(
|
||||||
"`getentropy` is not supported on {}",
|
"`getrandom` is not supported on {}",
|
||||||
this.tcx.sess.target.os
|
this.tcx.sess.target.os
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -748,6 +750,7 @@ fn emulate_foreign_item_inner(
|
|||||||
_ => {
|
_ => {
|
||||||
let target_os = &*this.tcx.sess.target.os;
|
let target_os = &*this.tcx.sess.target.os;
|
||||||
return match 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),
|
"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),
|
"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),
|
"macos" => macos::EvalContextExt::emulate_foreign_item_inner(this, link_name, abi, args, dest),
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
mod sync;
|
mod sync;
|
||||||
mod thread;
|
mod thread;
|
||||||
|
|
||||||
|
mod android;
|
||||||
mod freebsd;
|
mod freebsd;
|
||||||
mod linux;
|
mod linux;
|
||||||
mod macos;
|
mod macos;
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
//@ignore-target-windows: Windows does not have a global environ list that the program can access directly
|
//@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 {
|
fn get_environ() -> *const *const u8 {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
static mut environ: *const *const u8;
|
static mut environ: *const *const u8;
|
||||||
@ -13,14 +7,6 @@ fn get_environ() -> *const *const u8 {
|
|||||||
unsafe { environ }
|
unsafe { environ }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
fn get_environ() -> *const *const u8 {
|
|
||||||
extern "C" {
|
|
||||||
fn _NSGetEnviron() -> *mut *const *const u8;
|
|
||||||
}
|
|
||||||
unsafe { *_NSGetEnviron() }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let pointer = get_environ();
|
let pointer = get_environ();
|
||||||
let _x = unsafe { *pointer };
|
let _x = unsafe { *pointer };
|
||||||
|
@ -10,9 +10,11 @@
|
|||||||
fn test_thread_local_errno() {
|
fn test_thread_local_errno() {
|
||||||
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
|
#[cfg(any(target_os = "illumos", target_os = "solaris"))]
|
||||||
use libc::___errno as __errno_location;
|
use libc::___errno as __errno_location;
|
||||||
|
#[cfg(target_os = "android")]
|
||||||
|
use libc::__errno as __errno_location;
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
use libc::__errno_location;
|
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;
|
use libc::__error as __errno_location;
|
||||||
|
|
||||||
unsafe {
|
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")]
|
#[cfg(target_os = "linux")]
|
||||||
fn test_sigrt() {
|
fn test_sigrt() {
|
||||||
let min = libc::SIGRTMIN();
|
let min = libc::SIGRTMIN();
|
||||||
@ -60,6 +77,7 @@ fn test_dlsym() {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
test_thread_local_errno();
|
test_thread_local_errno();
|
||||||
|
test_environ();
|
||||||
|
|
||||||
test_dlsym();
|
test_dlsym();
|
||||||
|
|
||||||
|
8
src/tools/miri/tests/pass/shims/env/home.rs
vendored
8
src/tools/miri/tests/pass/shims/env/home.rs
vendored
@ -2,8 +2,12 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env::remove_var("HOME"); // make sure we enter the interesting codepath
|
// Remove the env vars to hit the underlying shim -- except
|
||||||
env::remove_var("USERPROFILE"); // Windows also looks as this env var
|
// 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)]
|
#[allow(deprecated)]
|
||||||
env::home_dir().unwrap();
|
env::home_dir().unwrap();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user