-
Notifications
You must be signed in to change notification settings - Fork 352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Miri fails to run a binary targeting Android #2010
Comments
Yeah, I never tested any Android targets, so there are probably quite a few things missing. I'd be open to adding it as a "best effort" kind of target (where we would disable tests if it turns out things break in non-trivial-to-fix-ways). We don't have an official target support policy but de-facto it's "Linux, macOS, and Windows" (and quite a few OS shims are macOS/Linux only, like file system access). Regarding this concrete problem, if you add Though looking at the libstd code you linked, that will just mean we panic. So that's no good. Looks like for the first time Miri might have to actually implement a weak symbol. I imagine this should work similarly to our existing |
Completely understand and this sounds reasonable to me. I was actually pleasantly surprised that things even barely worked :) Was something like this what you had in mind for the implementation (this is pseudocode -- I don't have a build environment set up yet)? Expand to view diffdiff --git a/src/machine.rs b/src/machine.rs
index bb43cb95..87d2128c 100644
--- a/src/machine.rs
+++ b/src/machine.rs
@@ -253,6 +253,19 @@ 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 &[b"signal"] {
+ let dlsym = Dlsym::from_str(symbol_name, &this.tcx.sess.target.os)?
+ .unwrap_or_else(|| {
+ panic!("hardcoded `extern static` symbol {} has no dlsym handler")
+ });
+ let ptr = this.memory.create_fn_alloc(FnVal::Other(dlsym));
+ Self::add_extern_static(
+ this,
+ std::str::from_utf8(symbol_name).expect("failed to convert symbol name to str"),
+ place.ptr,
+ );
+ },
_ => {} // No "extern statics" supported on this target
}
Ok(())
diff --git a/src/shims/posix/linux/dlsym.rs b/src/shims/posix/linux/dlsym.rs
index 1b7ac275..20e71406 100644
--- a/src/shims/posix/linux/dlsym.rs
+++ b/src/shims/posix/linux/dlsym.rs
@@ -3,7 +3,11 @@ use rustc_middle::mir;
use crate::*;
#[derive(Debug, Copy, Clone)]
-pub enum Dlsym {}
+#[allow(non_camel_case_types)]
+pub enum Dlsym {
+ /// for android only
+ signal,
+}
impl Dlsym {
// Returns an error for unsupported symbols, and None if this symbol
@@ -13,6 +17,7 @@ impl Dlsym {
"__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" => Some(Dlsym::signal),
_ => throw_unsup_format!("unsupported Linux dlsym: {}", name),
})
}
@@ -27,9 +32,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
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 == "linux");
+ let (dest, ret) = ret.expect("we don't support any diverging dlsym");
+ assert!(matches!(this.tcx.sess.target.os, "linux" | "android"));
+
+ match dlsym {
+ Dlsym::signal => {
+ let &[ref _sig, ref _func] = check_arg_count(args)?;
+ this.write_null(dest)?;
+ }
+ }
- match dlsym {}
+ trace!("{:?}", this.dump_place(**dest));
+ this.go_to_block(ret);
+ Ok(())
}
} If this is going down the right path then I could probably start experimenting tomorrow... One note: I know you said to add another enum variant and presumably that'd be adding another variant here for Android? If that's what you meant, does it still make sense since we'd be duplicating mostly everything between the two platform modules? |
I was originally thinking the
Right so that is something that is hard for me to judge -- should we treat Android as yet another POSIX system, next to Linux and macOS, or treat it like a variant of Linux? Given its Given that Miri is basically working at the level of the libc here, and Android has its own, my inclination is to treat it like its own variant of POSIX. So maybe we could start with that, and if there turns out to be too much code duplication with Linux we can reevaluate? So, that would mean adding |
I'm attempting to run tests targeting an Android application under Miri and it fails to get past the
std::rt::init()
routine. The error is as follows:The issue seems to be with how the
std::sys::unix::android::signal()
function is implemented with weak linking: https://github.com/rust-lang/rust/blob/1eb72580d076935a3e590deb6e5813a5aef3eca4/library/std/src/sys/unix/android.rs#L74-L81We could init the extern static for Android, but I'm genuinely not sure how to go about looking up the implementation pointer it should be linked to or if we should implement some other workaround for this.
The text was updated successfully, but these errors were encountered: