Skip to content

Commit

Permalink
Add Trusty OS as tier 3 target
Browse files Browse the repository at this point in the history
  • Loading branch information
randomPoison committed Jan 31, 2023
1 parent f361413 commit dcd0c58
Show file tree
Hide file tree
Showing 15 changed files with 282 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,7 @@ rustc-std-workspace-core = { path = 'library/rustc-std-workspace-core' }
rustc-std-workspace-alloc = { path = 'library/rustc-std-workspace-alloc' }
rustc-std-workspace-std = { path = 'library/rustc-std-workspace-std' }

libc = { git = "https://github.com/randomPoison/libc.git", rev = "7ccd2753aa1e26301c73bdb6f9e2df8085ac39e6" }

[patch."https://github.com/rust-lang/rust-clippy"]
clippy_lints = { path = "src/tools/clippy/clippy_lints" }
27 changes: 27 additions & 0 deletions compiler/rustc_target/src/spec/aarch64_unknown_trusty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Trusty OS target for AArch64.

use super::{PanicStrategy, RelroLevel, Target, TargetOptions};

pub fn target() -> Target {
Target {
llvm_target: "aarch64-unknown-linux-musl".into(),
pointer_width: 64,
data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".into(),
arch: "aarch64".into(),
options: TargetOptions {
features: "+neon,+fp-armv8".into(),
executables: true,
max_atomic_width: Some(128),
panic_strategy: PanicStrategy::Abort,
os: "trusty".into(),
position_independent_executables: true,
crt_static_default: true,
crt_static_respected: true,
dynamic_linking: false,
env: "musl".into(),
relro_level: RelroLevel::Full,
mcount: "\u{1}_mcount".into(),
..Default::default()
},
}
}
31 changes: 31 additions & 0 deletions compiler/rustc_target/src/spec/armv7_unknown_trusty.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::spec::{Target, TargetOptions};

use super::{crt_objects::LinkSelfContainedDefault, PanicStrategy, RelroLevel};

pub fn target() -> Target {
Target {
// It's important we use "gnueabi" and not "musleabi" here. LLVM uses it
// to determine the calling convention and float ABI, and it doesn't
// support the "musleabi" value.
llvm_target: "armv7-unknown-linux-gnueabi".into(),
pointer_width: 32,
data_layout: "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64".into(),
arch: "arm".into(),
options: TargetOptions {
abi: "eabi".into(),
features: "+v7,+thumb2,+soft-float,-neon".into(),
max_atomic_width: Some(64),
mcount: "\u{1}mcount".into(),
os: "trusty".into(),
env: "musl".into(),
link_self_contained: LinkSelfContainedDefault::Musl,
dynamic_linking: false,
executables: true,
relro_level: RelroLevel::Full,
panic_strategy: PanicStrategy::Abort,
position_independent_executables: true,

..Default::default()
},
}
}
3 changes: 3 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,9 @@ supported_targets! {
("aarch64-unknown-hermit", aarch64_unknown_hermit),
("x86_64-unknown-hermit", x86_64_unknown_hermit),

("armv7-unknown-trusty", armv7_unknown_trusty),
("aarch64-unknown-trusty", aarch64_unknown_trusty),

("riscv32i-unknown-none-elf", riscv32i_unknown_none_elf),
("riscv32im-unknown-none-elf", riscv32im_unknown_none_elf),
("riscv32imc-unknown-none-elf", riscv32imc_unknown_none_elf),
Expand Down
4 changes: 4 additions & 0 deletions library/core/src/ffi/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ mod c_char_definition {
)
),
all(target_os = "fuchsia", target_arch = "aarch64"),
all(
target_os = "trusty",
any(target_arch = "aarch64", target_arch = "arm")
),
target_os = "horizon"
))] {
pub type c_char = u8;
Expand Down
1 change: 1 addition & 0 deletions library/std/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ fn main() {
|| target.contains("fuchsia")
|| (target.contains("sgx") && target.contains("fortanix"))
|| target.contains("hermit")
|| target.contains("trusty")
|| target.contains("l4re")
|| target.contains("redox")
|| target.contains("haiku")
Expand Down
3 changes: 3 additions & 0 deletions library/std/src/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ cfg_if::cfg_if! {
} else if #[cfg(target_os = "hermit")] {
mod hermit;
pub use self::hermit::*;
} else if #[cfg(target_os = "trusty")] {
mod trusty;
pub use self::trusty::*;
} else if #[cfg(target_os = "wasi")] {
mod wasi;
pub use self::wasi::*;
Expand Down
42 changes: 42 additions & 0 deletions library/std/src/sys/trusty/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//! System bindings for the Trusty OS.
#[path = "../unix/alloc.rs"]
pub mod alloc;
#[path = "../unsupported/args.rs"]
pub mod args;
#[path = "../unix/cmath.rs"]
pub mod cmath;
#[path = "../unsupported/common.rs"]
#[deny(unsafe_op_in_unsafe_fn)]
mod common;
#[path = "../unsupported/env.rs"]
pub mod env;
#[path = "../unsupported/fs.rs"]
pub mod fs;
#[path = "../unsupported/io.rs"]
pub mod io;
#[path = "../unsupported/locks/mod.rs"]
pub mod locks;
#[path = "../unsupported/net.rs"]
pub mod net;
#[path = "../unsupported/os.rs"]
pub mod os;
#[path = "../unix/os_str.rs"]
pub mod os_str;
#[path = "../unix/path.rs"]
pub mod path;
#[path = "../unsupported/pipe.rs"]
pub mod pipe;
#[path = "../unsupported/process.rs"]
pub mod process;
pub mod stdio;
#[path = "../unsupported/thread.rs"]
pub mod thread;
#[cfg(target_thread_local)]
#[path = "../unsupported/thread_local_dtor.rs"]
pub mod thread_local_dtor;
pub mod thread_local_key;
#[path = "../unsupported/time.rs"]
pub mod time;

pub use common::*;
81 changes: 81 additions & 0 deletions library/std/src/sys/trusty/stdio.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
use crate::io;

pub struct Stdin;
pub struct Stdout;
pub struct Stderr;

impl Stdin {
pub const fn new() -> Stdin {
Stdin
}
}

impl io::Read for Stdin {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
Ok(0)
}
}

impl Stdout {
pub const fn new() -> Stdout {
Stdout
}
}

impl io::Write for Stdout {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
_write(libc::STDOUT_FILENO, buf)
}

fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}

impl Stderr {
pub const fn new() -> Stderr {
Stderr
}
}

impl io::Write for Stderr {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
_write(libc::STDERR_FILENO, buf)
}

fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}

pub const STDIN_BUF_SIZE: usize = 0;

pub fn is_ebadf(_err: &io::Error) -> bool {
true
}

pub fn panic_output() -> Option<impl io::Write> {
Some(Stderr)
}

fn _write(fd: i32, message: &[u8]) -> io::Result<usize> {
let mut iov = libc::iovec { iov_base: message.as_ptr() as *mut _, iov_len: message.len() };
loop {
// SAFETY: syscall, safe arguments.
let ret = unsafe { libc::writev(fd, &iov, 1) };
if ret < 0 {
return Err(io::Error::last_os_error());
}
let ret = ret as usize;
if ret > iov.iov_len {
return Err(io::Error::last_os_error());
}
if ret == iov.iov_len {
return Ok(message.len());
}
// SAFETY: ret has been checked to be less than the length of
// the buffer
iov.iov_base = unsafe { iov.iov_base.add(ret) };
iov.iov_len -= ret;
}
}
31 changes: 31 additions & 0 deletions library/std/src/sys/trusty/thread_local_key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use crate::ptr;

pub type Key = usize;
type Dtor = unsafe extern "C" fn(*mut u8);

static mut STORAGE: crate::vec::Vec<(*mut u8, Option<Dtor>)> = Vec::new();

#[inline]
pub unsafe fn create(dtor: Option<Dtor>) -> Key {
let key = STORAGE.len();
STORAGE.push((ptr::null_mut(), dtor));
key
}

#[inline]
pub unsafe fn set(key: Key, value: *mut u8) {
STORAGE[key].0 = value;
}

#[inline]
pub unsafe fn get(key: Key) -> *mut u8 {
STORAGE[key].0
}

#[inline]
pub unsafe fn destroy(_key: Key) {}

#[inline]
pub fn requires_synchronized_create() -> bool {
false
}
1 change: 1 addition & 0 deletions library/std/src/sys_common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ cfg_if::cfg_if! {
cfg_if::cfg_if! {
if #[cfg(any(target_os = "l4re",
target_os = "hermit",
target_os = "trusty",
feature = "restricted-std",
all(target_family = "wasm", not(target_os = "emscripten")),
all(target_vendor = "fortanix", target_env = "sgx")))] {
Expand Down
3 changes: 2 additions & 1 deletion src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,8 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
(Some(Mode::Std), "backtrace_in_libstd", None),
/* Extra values not defined in the built-in targets yet, but used in std */
(Some(Mode::Std), "target_env", Some(&["libnx"])),
// (Some(Mode::Std), "target_os", Some(&[])),
// #[cfg(bootstrap)] trusty
(Some(Mode::Std), "target_os", Some(&["trusty"])),
(Some(Mode::Std), "target_arch", Some(&["asmjs", "spirv", "nvptx", "xtensa"])),
/* Extra names used by dependencies */
// FIXME: Used by serde_json, but we should not be triggering on external dependencies.
Expand Down
1 change: 1 addition & 0 deletions src/doc/rustc/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
- [armv7-unknown-linux-uclibceabihf](platform-support/armv7-unknown-linux-uclibceabihf.md)
- [\*-android and \*-androideabi](platform-support/android.md)
- [\*-unknown-fuchsia](platform-support/fuchsia.md)
- [\*-unknown-trusty](platform-support/trusty.md)
- [\*-kmc-solid_\*](platform-support/kmc-solid.md)
- [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
- [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
Expand Down
2 changes: 2 additions & 0 deletions src/doc/rustc/src/platform-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ target | std | host | notes
`aarch64-unknown-netbsd` | ✓ | ✓ |
[`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD
`aarch64-unknown-redox` | ? | | ARM64 Redox OS
[`aarch64-unknown-trusty`](platform-support/trusty.md) | ? | |
`aarch64-uwp-windows-msvc` | ? | |
`aarch64-wrs-vxworks` | ? | |
`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI)
Expand All @@ -242,6 +243,7 @@ target | std | host | notes
[`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | ARMv7 Linux with uClibc, hardfloat
`armv7-unknown-freebsd` | ✓ | ✓ | ARMv7 FreeBSD
`armv7-unknown-netbsd-eabihf` | ✓ | ✓ |
[`armv7-unknown-trusty`](platform-support/trusty.md) | ? | |
`armv7-wrs-vxworks-eabihf` | ? | |
[`armv7a-kmc-solid_asp3-eabi`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3
[`armv7a-kmc-solid_asp3-eabihf`](platform-support/kmc-solid.md) | ✓ | | ARM SOLID with TOPPERS/ASP3, hardfloat
Expand Down
51 changes: 51 additions & 0 deletions src/doc/rustc/src/platform-support/trusty.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# `aarch64-unknown-trusty` and `armv7-unknown-trusty`

**Tier: 3**

[Trusty] is a secure Operating System that provides a Trusted Execution
Environment (TEE) for Android.

## Target maintainers

- David LeGare, `dgl@immunant.com`, https://github.com/randomPoison

## Requirements

This target is cross-compiled. It has no special requirements for the host.

It fully supports alloc with the default allocator, and partially supports std.
Notably, most I/O functionality is not supported, e.g. filesystem support and
networking support are not present and any APIs that rely on them will panic at
runtime.

Trusty uses the ELF file format.

## Building the target

The targets can be built by enabling them for a `rustc` build, for example:

```toml
[build]
build-stage = 1
target = ["aarch64-unknown-trusty", "armv7-unknown-trusty"]
```

## Building Rust programs

There is currently no supported way to build a Trusty app with Cargo. You can
follow the [Trusty build instructions] to build the Trusty kernel along with any
Rust apps that are setup in the project.

## Testing

See the [Trusty build instructions] for information on how to build Rust code
within the main Trusty project. The main project also includes infrastructure
for testing Rust applications within a QEMU emulator.

## Cross-compilation toolchains and C code

See the [Trusty build instructions] for information on how C code is built
within Trusty.

[Trusty]: https://source.android.com/docs/security/features/trusty
[Trusty build instructions]: https://source.android.com/docs/security/features/trusty/download-and-build

0 comments on commit dcd0c58

Please sign in to comment.