Skip to content

Commit

Permalink
make basic things work on Android
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed May 19, 2024
1 parent 4f8b3ef commit c65f39c
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 29 deletions.
11 changes: 6 additions & 5 deletions ci/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 pthread-sync
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
Expand Down
18 changes: 7 additions & 11 deletions src/shims/extern_static.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,30 +55,26 @@ 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(
this,
&["__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"
Expand Down
32 changes: 32 additions & 0 deletions src/shims/unix/android/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions src/shims/unix/android/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod foreign_items;
11 changes: 7 additions & 4 deletions src/shims/unix/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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),
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -585,7 +587,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
Expand Down Expand Up @@ -614,9 +616,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
);
}
Expand Down Expand Up @@ -740,6 +742,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),
Expand Down
1 change: 1 addition & 0 deletions src/shims/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod socket;
mod sync;
mod thread;

mod android;
mod freebsd;
mod linux;
mod macos;
Expand Down
7 changes: 1 addition & 6 deletions tests/fail/environ-gets-deallocated.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
//@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"
))]
#[cfg(not(target_os = "macos",))]
fn get_environ() -> *const *const u8 {
extern "C" {
static mut environ: *const *const u8;
Expand Down
20 changes: 19 additions & 1 deletion tests/pass-dep/libc/libc-misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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();
Expand Down Expand Up @@ -60,6 +77,7 @@ fn test_dlsym() {

fn main() {
test_thread_local_errno();
test_environ();

test_dlsym();

Expand Down
8 changes: 6 additions & 2 deletions tests/pass/shims/env/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

0 comments on commit c65f39c

Please sign in to comment.