Skip to content

Commit 7828dcc

Browse files
author
Lander Brandt
committed
add basic support for android targets
1 parent 5aeff5d commit 7828dcc

File tree

10 files changed

+110
-7
lines changed

10 files changed

+110
-7
lines changed

src/machine.rs

+17
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,23 @@ impl MemoryExtra {
253253
this.write_scalar(Scalar::from_u8(0), &place.into())?;
254254
Self::add_extern_static(this, "_tls_used", place.ptr);
255255
}
256+
"android" =>
257+
for symbol_name in &["signal", "bsd_signal"] {
258+
let layout = this.machine.layouts.usize;
259+
let dlsym = Dlsym::from_str(symbol_name.as_bytes(), &this.tcx.sess.target.os)?
260+
.unwrap_or_else(|| {
261+
panic!(
262+
"hardcoded `extern static` symbol {} has no dlsym handler",
263+
symbol_name
264+
)
265+
});
266+
let (provenance, offset) =
267+
this.memory.create_fn_alloc(FnVal::Other(dlsym)).into_parts();
268+
let ptr = Pointer::new(Some(provenance), offset);
269+
let place = this.allocate(layout, MiriMemoryKind::ExternStatic.into())?;
270+
this.write_pointer(ptr, &place.into())?;
271+
Self::add_extern_static(this, symbol_name, place.ptr);
272+
},
256273
_ => {} // No "extern statics" supported on this target
257274
}
258275
Ok(())

src/shims/dlsym.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ impl Dlsym {
1818
pub fn from_str(name: &[u8], target_os: &str) -> InterpResult<'static, Option<Dlsym>> {
1919
let name = &*String::from_utf8_lossy(name);
2020
Ok(match target_os {
21-
"linux" | "macos" => posix::Dlsym::from_str(name, target_os)?.map(Dlsym::Posix),
21+
"linux" | "macos" | "android" =>
22+
posix::Dlsym::from_str(name, target_os)?.map(Dlsym::Posix),
2223
"windows" => windows::Dlsym::from_str(name)?.map(Dlsym::Windows),
2324
os => bug!("dlsym not implemented for target_os {}", os),
2425
})

src/shims/env.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
116116
let this = self.eval_context_mut();
117117
let target_os = &this.tcx.sess.target.os;
118118
assert!(
119-
target_os == "linux" || target_os == "macos",
119+
matches!(target_os.as_str(), "linux" | "macos" | "android"),
120120
"`getenv` is only available for the UNIX target family"
121121
);
122122

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

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

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

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

src/shims/foreign_items.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
687687

688688
// Platform-specific shims
689689
_ => match this.tcx.sess.target.os.as_str() {
690-
"linux" | "macos" => return shims::posix::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
690+
"linux" | "macos" | "android" => return shims::posix::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
691691
"windows" => return shims::windows::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
692692
target => throw_unsup_format!("the target `{}` is not supported", target),
693693
}

src/shims/posix/android/dlsym.rs

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
use helpers::check_arg_count;
2+
use log::trace;
3+
use rustc_middle::mir;
4+
5+
use crate::*;
6+
7+
#[derive(Debug, Copy, Clone)]
8+
pub enum Dlsym {
9+
signal,
10+
}
11+
12+
impl Dlsym {
13+
// Returns an error for unsupported symbols, and None if this symbol
14+
// should become a NULL pointer (pretend it does not exist).
15+
pub fn from_str(name: &str) -> InterpResult<'static, Option<Dlsym>> {
16+
Ok(match &*name {
17+
"__pthread_get_minstack" => None,
18+
"getrandom" => None, // std falls back to syscall(SYS_getrandom, ...) when this is NULL.
19+
"statx" => None, // std falls back to syscall(SYS_statx, ...) when this is NULL.
20+
"signal" | "bsd_signal" => Some(Dlsym::signal), // these have the same signature/implementation
21+
_ => throw_unsup_format!("unsupported Android dlsym: {}", name),
22+
})
23+
}
24+
}
25+
26+
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
27+
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
28+
fn call_dlsym(
29+
&mut self,
30+
dlsym: Dlsym,
31+
args: &[OpTy<'tcx, Tag>],
32+
ret: Option<(&PlaceTy<'tcx, Tag>, mir::BasicBlock)>,
33+
) -> InterpResult<'tcx> {
34+
let this = self.eval_context_mut();
35+
let (dest, ret) = ret.expect("we don't support any diverging dlsym");
36+
assert!(this.tcx.sess.target.os == "android");
37+
38+
match dlsym {
39+
Dlsym::signal => {
40+
let &[ref _sig, ref _func] = check_arg_count(args)?;
41+
this.write_null(dest)?;
42+
}
43+
}
44+
45+
trace!("{:?}", this.dump_place(**dest));
46+
this.go_to_block(ret);
47+
Ok(())
48+
}
49+
}
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
use rustc_middle::mir;
2+
use rustc_span::Symbol;
3+
use rustc_target::spec::abi::Abi;
4+
5+
use crate::*;
6+
use shims::foreign_items::EmulateByNameResult;
7+
8+
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
9+
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
10+
fn emulate_foreign_item_by_name(
11+
&mut self,
12+
link_name: Symbol,
13+
abi: Abi,
14+
args: &[OpTy<'tcx, Tag>],
15+
dest: &PlaceTy<'tcx, Tag>,
16+
ret: mir::BasicBlock,
17+
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
18+
let this = self.eval_context_mut();
19+
20+
match &*link_name.as_str() {
21+
_ => {
22+
// By default we piggyback off the items emulated for Linux. For now this functions
23+
// serves to make adding android-specific syscalls easy
24+
return shims::posix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret);
25+
}
26+
}
27+
}
28+
}

src/shims/posix/android/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pub mod dlsym;
2+
pub mod foreign_items;

src/shims/posix/dlsym.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ use rustc_middle::mir;
22
use rustc_target::spec::abi::Abi;
33

44
use crate::*;
5+
use shims::posix::android::dlsym as android;
56
use shims::posix::linux::dlsym as linux;
67
use shims::posix::macos::dlsym as macos;
78

89
#[derive(Debug, Copy, Clone)]
910
pub enum Dlsym {
1011
Linux(linux::Dlsym),
1112
MacOs(macos::Dlsym),
13+
Android(android::Dlsym),
1214
}
1315

1416
impl Dlsym {
@@ -18,6 +20,7 @@ impl Dlsym {
1820
Ok(match target_os {
1921
"linux" => linux::Dlsym::from_str(name)?.map(Dlsym::Linux),
2022
"macos" => macos::Dlsym::from_str(name)?.map(Dlsym::MacOs),
23+
"android" => android::Dlsym::from_str(name)?.map(Dlsym::Android),
2124
_ => unreachable!(),
2225
})
2326
}
@@ -39,6 +42,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
3942
match dlsym {
4043
Dlsym::Linux(dlsym) => linux::EvalContextExt::call_dlsym(this, dlsym, args, ret),
4144
Dlsym::MacOs(dlsym) => macos::EvalContextExt::call_dlsym(this, dlsym, args, ret),
45+
Dlsym::Android(dlsym) => android::EvalContextExt::call_dlsym(this, dlsym, args, ret),
4246
}
4347
}
4448
}

src/shims/posix/foreign_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
465465
match this.tcx.sess.target.os.as_str() {
466466
"linux" => return shims::posix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
467467
"macos" => return shims::posix::macos::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
468+
"android" => return shims::posix::linux::foreign_items::EvalContextExt::emulate_foreign_item_by_name(this, link_name, abi, args, dest, ret),
468469
_ => unreachable!(),
469470
}
470471
}

src/shims/posix/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod fs;
55
mod sync;
66
mod thread;
77

8+
mod android;
89
mod linux;
910
mod macos;
1011

0 commit comments

Comments
 (0)