Skip to content

Commit

Permalink
add basic support for android targets
Browse files Browse the repository at this point in the history
  • Loading branch information
Lander Brandt committed Mar 9, 2022
1 parent 5aeff5d commit 7828dcc
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 7 deletions.
17 changes: 17 additions & 0 deletions src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,23 @@ impl MemoryExtra {
this.write_scalar(Scalar::from_u8(0), &place.into())?;
Self::add_extern_static(this, "_tls_used", place.ptr);
}
"android" =>
for symbol_name in &["signal", "bsd_signal"] {
let layout = this.machine.layouts.usize;
let dlsym = Dlsym::from_str(symbol_name.as_bytes(), &this.tcx.sess.target.os)?
.unwrap_or_else(|| {
panic!(
"hardcoded `extern static` symbol {} has no dlsym handler",
symbol_name
)
});
let (provenance, offset) =
this.memory.create_fn_alloc(FnVal::Other(dlsym)).into_parts();
let ptr = Pointer::new(Some(provenance), offset);
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
this.write_pointer(ptr, &place.into())?;
Self::add_extern_static(this, symbol_name, place.ptr);
},
_ => {} // No "extern statics" supported on this target
}
Ok(())
Expand Down
3 changes: 2 additions & 1 deletion src/shims/dlsym.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ impl Dlsym {
pub fn from_str(name: &[u8], target_os: &str) -> InterpResult<'static, Option<Dlsym>> {
let name = &*String::from_utf8_lossy(name);
Ok(match target_os {
"linux" | "macos" => posix::Dlsym::from_str(name, target_os)?.map(Dlsym::Posix),
"linux" | "macos" | "android" =>
posix::Dlsym::from_str(name, target_os)?.map(Dlsym::Posix),
"windows" => windows::Dlsym::from_str(name)?.map(Dlsym::Windows),
os => bug!("dlsym not implemented for target_os {}", os),
})
Expand Down
10 changes: 5 additions & 5 deletions src/shims/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let this = self.eval_context_mut();
let target_os = &this.tcx.sess.target.os;
assert!(
target_os == "linux" || target_os == "macos",
matches!(target_os.as_str(), "linux" | "macos" | "android"),
"`getenv` is only available for the UNIX target family"
);

Expand Down Expand Up @@ -214,7 +214,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let mut this = self.eval_context_mut();
let target_os = &this.tcx.sess.target.os;
assert!(
target_os == "linux" || target_os == "macos",
matches!(target_os.as_str(), "linux" | "macos" | "android"),
"`setenv` is only available for the UNIX target family"
);

Expand Down Expand Up @@ -288,7 +288,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let this = self.eval_context_mut();
let target_os = &this.tcx.sess.target.os;
assert!(
target_os == "linux" || target_os == "macos",
matches!(target_os.as_str(), "linux" | "macos" | "android"),
"`unsetenv` is only available for the UNIX target family"
);

Expand Down Expand Up @@ -322,7 +322,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let this = self.eval_context_mut();
let target_os = &this.tcx.sess.target.os;
assert!(
target_os == "linux" || target_os == "macos",
matches!(target_os.as_str(), "linux" | "macos" | "android"),
"`getcwd` is only available for the UNIX target family"
);

Expand Down Expand Up @@ -381,7 +381,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let this = self.eval_context_mut();
let target_os = &this.tcx.sess.target.os;
assert!(
target_os == "linux" || target_os == "macos",
matches!(target_os.as_str(), "linux" | "macos" | "android"),
"`getcwd` is only available for the UNIX target family"
);

Expand Down
2 changes: 1 addition & 1 deletion src/shims/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx

// Platform-specific shims
_ => match this.tcx.sess.target.os.as_str() {
"linux" | "macos" => return shims::posix::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
"linux" | "macos" | "android" => return shims::posix::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
"windows" => return shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
target => throw_unsup_format!("the target `{}` is not supported", target),
}
Expand Down
49 changes: 49 additions & 0 deletions src/shims/posix/android/dlsym.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use helpers::check_arg_count;
use log::trace;
use rustc_middle::mir;

use crate::*;

#[derive(Debug, Copy, Clone)]
pub enum Dlsym {
signal,
}

impl Dlsym {
// Returns an error for unsupported symbols, and None if this symbol
// should become a NULL pointer (pretend it does not exist).
pub fn from_str(name: &str) -> InterpResult<'static, Option<Dlsym>> {
Ok(match &*name {
"__pthread_get_minstack" => None,
"getrandom" => None, // std falls back to syscall(SYS_getrandom, ...) when this is NULL.
"statx" => None, // std falls back to syscall(SYS_statx, ...) when this is NULL.
"signal" | "bsd_signal" => Some(Dlsym::signal), // these have the same signature/implementation
_ => throw_unsup_format!("unsupported Android dlsym: {}", name),
})
}
}

impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn call_dlsym(
&mut self,
dlsym: Dlsym,
args: &[OpTy<'tcx, Tag>],
ret: Option<(&PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let (dest, ret) = ret.expect("we don't support any diverging dlsym");
assert!(this.tcx.sess.target.os == "android");

match dlsym {
Dlsym::signal => {
let &[ref _sig, ref _func] = check_arg_count(args)?;
this.write_null(dest)?;
}
}

trace!("{:?}", this.dump_place(**dest));
this.go_to_block(ret);
Ok(())
}
}
28 changes: 28 additions & 0 deletions src/shims/posix/android/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use rustc_middle::mir;
use rustc_span::Symbol;
use rustc_target::spec::abi::Abi;

use crate::*;
use shims::foreign_items::EmulateByNameResult;

impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
fn emulate_foreign_item_by_name(
&mut self,
link_name: Symbol,
abi: Abi,
args: &[OpTy<'tcx, Tag>],
dest: &PlaceTy<'tcx, Tag>,
ret: mir::BasicBlock,
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
let this = self.eval_context_mut();

match &*link_name.as_str() {
_ => {
// By default we piggyback off the items emulated for Linux. For now this functions
// serves to make adding android-specific syscalls easy
return shims::posix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret);
}
}
}
}
2 changes: 2 additions & 0 deletions src/shims/posix/android/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod dlsym;
pub mod foreign_items;
4 changes: 4 additions & 0 deletions src/shims/posix/dlsym.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ use rustc_middle::mir;
use rustc_target::spec::abi::Abi;

use crate::*;
use shims::posix::android::dlsym as android;
use shims::posix::linux::dlsym as linux;
use shims::posix::macos::dlsym as macos;

#[derive(Debug, Copy, Clone)]
pub enum Dlsym {
Linux(linux::Dlsym),
MacOs(macos::Dlsym),
Android(android::Dlsym),
}

impl Dlsym {
Expand All @@ -18,6 +20,7 @@ impl Dlsym {
Ok(match target_os {
"linux" => linux::Dlsym::from_str(name)?.map(Dlsym::Linux),
"macos" => macos::Dlsym::from_str(name)?.map(Dlsym::MacOs),
"android" => android::Dlsym::from_str(name)?.map(Dlsym::Android),
_ => unreachable!(),
})
}
Expand All @@ -39,6 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
match dlsym {
Dlsym::Linux(dlsym) => linux::EvalContextExt::call_dlsym(this, dlsym, args, ret),
Dlsym::MacOs(dlsym) => macos::EvalContextExt::call_dlsym(this, dlsym, args, ret),
Dlsym::Android(dlsym) => android::EvalContextExt::call_dlsym(this, dlsym, args, ret),
}
}
}
1 change: 1 addition & 0 deletions src/shims/posix/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
match this.tcx.sess.target.os.as_str() {
"linux" => return shims::posix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
"macos" => return shims::posix::macos::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
"android" => return shims::posix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
_ => unreachable!(),
}
}
Expand Down
1 change: 1 addition & 0 deletions src/shims/posix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod fs;
mod sync;
mod thread;

mod android;
mod linux;
mod macos;

Expand Down

0 comments on commit 7828dcc

Please sign in to comment.