Skip to content

Commit 8bb8339

Browse files
袁浩Sword-Destiny
袁浩
authored andcommitted
add teeos std impl
Signed-off-by: 袁浩 <[email protected]>
1 parent 2896841 commit 8bb8339

File tree

17 files changed

+1143
-6
lines changed

17 files changed

+1143
-6
lines changed

compiler/rustc_target/src/spec/targets/aarch64_unknown_teeos.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ pub fn target() -> Target {
44
let mut base = base::teeos::opts();
55
base.features = "+strict-align,+neon,+fp-armv8".into();
66
base.max_atomic_width = Some(128);
7-
base.linker = Some("aarch64-linux-gnu-ld".into());
87

98
Target {
109
llvm_target: "aarch64-unknown-none".into(),

library/panic_abort/src/lib.rs

+10
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
8181
}
8282
core::intrinsics::unreachable();
8383
}
84+
} else if #[cfg(target_os = "teeos")] {
85+
mod teeos {
86+
extern "C" {
87+
pub fn TEE_Panic(code: u32) -> !;
88+
}
89+
}
90+
91+
unsafe fn abort() -> ! {
92+
teeos::TEE_Panic(1);
93+
}
8494
} else {
8595
unsafe fn abort() -> ! {
8696
core::intrinsics::abort();

library/std/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ fn main() {
3434
|| target.contains("xous")
3535
|| target.contains("hurd")
3636
|| target.contains("uefi")
37+
|| target.contains("teeos")
3738
// See src/bootstrap/synthetic_targets.rs
3839
|| env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
3940
{

library/std/src/sys/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ cfg_if::cfg_if! {
5353
} else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
5454
mod sgx;
5555
pub use self::sgx::*;
56+
} else if #[cfg(target_os = "teeos")] {
57+
mod teeos;
58+
pub use self::teeos::*;
5659
} else {
5760
mod unsupported;
5861
pub use self::unsupported::*;

library/std/src/sys/teeos/alloc.rs

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use crate::alloc::{GlobalAlloc, Layout, System};
2+
use crate::ptr;
3+
use crate::sys::common::alloc::{realloc_fallback, MIN_ALIGN};
4+
5+
#[stable(feature = "alloc_system_type", since = "1.28.0")]
6+
unsafe impl GlobalAlloc for System {
7+
#[inline]
8+
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
9+
// jemalloc provides alignment less than MIN_ALIGN for small allocations.
10+
// So only rely on MIN_ALIGN if size >= align.
11+
// Also see <https://github.com/rust-lang/rust/issues/45955> and
12+
// <https://github.com/rust-lang/rust/issues/62251#issuecomment-507580914>.
13+
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
14+
libc::malloc(layout.size()) as *mut u8
15+
} else {
16+
aligned_malloc(&layout)
17+
}
18+
}
19+
20+
#[inline]
21+
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
22+
// See the comment above in `alloc` for why this check looks the way it does.
23+
if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() {
24+
libc::calloc(layout.size(), 1) as *mut u8
25+
} else {
26+
let ptr = self.alloc(layout);
27+
if !ptr.is_null() {
28+
ptr::write_bytes(ptr, 0, layout.size());
29+
}
30+
ptr
31+
}
32+
}
33+
34+
#[inline]
35+
unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
36+
libc::free(ptr as *mut libc::c_void)
37+
}
38+
39+
#[inline]
40+
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
41+
if layout.align() <= MIN_ALIGN && layout.align() <= new_size {
42+
libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8
43+
} else {
44+
realloc_fallback(self, ptr, layout, new_size)
45+
}
46+
}
47+
}
48+
49+
#[inline]
50+
unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 {
51+
let mut out = ptr::null_mut();
52+
// posix_memalign requires that the alignment be a multiple of `sizeof(void*)`.
53+
// Since these are all powers of 2, we can just use max.
54+
let align = layout.align().max(crate::mem::size_of::<usize>());
55+
let ret = libc::posix_memalign(&mut out, align, layout.size());
56+
if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
57+
}
+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
use crate::cell::UnsafeCell;
2+
use crate::ptr;
3+
use crate::sync::atomic::{AtomicPtr, Ordering::Relaxed};
4+
use crate::sys::locks::mutex::{self, Mutex};
5+
use crate::sys::time::TIMESPEC_MAX;
6+
use crate::sys_common::lazy_box::{LazyBox, LazyInit};
7+
use crate::time::Duration;
8+
9+
extern "C" {
10+
pub fn pthread_cond_timedwait(
11+
cond: *mut libc::pthread_cond_t,
12+
lock: *mut libc::pthread_mutex_t,
13+
adstime: *const libc::timespec,
14+
) -> libc::c_int;
15+
}
16+
17+
struct AllocatedCondvar(UnsafeCell<libc::pthread_cond_t>);
18+
19+
pub struct Condvar {
20+
inner: LazyBox<AllocatedCondvar>,
21+
mutex: AtomicPtr<libc::pthread_mutex_t>,
22+
}
23+
24+
#[inline]
25+
fn raw(c: &Condvar) -> *mut libc::pthread_cond_t {
26+
c.inner.0.get()
27+
}
28+
29+
unsafe impl Send for AllocatedCondvar {}
30+
unsafe impl Sync for AllocatedCondvar {}
31+
32+
impl LazyInit for AllocatedCondvar {
33+
fn init() -> Box<Self> {
34+
let condvar = Box::new(AllocatedCondvar(UnsafeCell::new(libc::PTHREAD_COND_INITIALIZER)));
35+
36+
let r = unsafe { libc::pthread_cond_init(condvar.0.get(), crate::ptr::null()) };
37+
assert_eq!(r, 0);
38+
39+
condvar
40+
}
41+
}
42+
43+
impl Drop for AllocatedCondvar {
44+
#[inline]
45+
fn drop(&mut self) {
46+
let r = unsafe { libc::pthread_cond_destroy(self.0.get()) };
47+
debug_assert_eq!(r, 0);
48+
}
49+
}
50+
51+
impl Condvar {
52+
pub const fn new() -> Condvar {
53+
Condvar { inner: LazyBox::new(), mutex: AtomicPtr::new(ptr::null_mut()) }
54+
}
55+
56+
#[inline]
57+
fn verify(&self, mutex: *mut libc::pthread_mutex_t) {
58+
match self.mutex.compare_exchange(ptr::null_mut(), mutex, Relaxed, Relaxed) {
59+
Ok(_) => {} // Stored the address
60+
Err(n) if n == mutex => {} // Lost a race to store the same address
61+
_ => panic!("attempted to use a condition variable with two mutexes"),
62+
}
63+
}
64+
65+
#[inline]
66+
pub fn notify_one(&self) {
67+
let r = unsafe { libc::pthread_cond_signal(raw(self)) };
68+
debug_assert_eq!(r, 0);
69+
}
70+
71+
#[inline]
72+
pub fn notify_all(&self) {
73+
let r = unsafe { libc::pthread_cond_broadcast(raw(self)) };
74+
debug_assert_eq!(r, 0);
75+
}
76+
77+
#[inline]
78+
pub unsafe fn wait(&self, mutex: &Mutex) {
79+
let mutex = mutex::raw(mutex);
80+
self.verify(mutex);
81+
let r = libc::pthread_cond_wait(raw(self), mutex);
82+
debug_assert_eq!(r, 0);
83+
}
84+
85+
pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
86+
use crate::sys::time::Timespec;
87+
88+
let mutex = mutex::raw(mutex);
89+
self.verify(mutex);
90+
91+
let timeout = Timespec::now(libc::CLOCK_MONOTONIC)
92+
.checked_add_duration(&dur)
93+
.and_then(|t| t.to_timespec())
94+
.unwrap_or(TIMESPEC_MAX);
95+
96+
let r = pthread_cond_timedwait(raw(self), mutex, &timeout);
97+
assert!(r == libc::ETIMEDOUT || r == 0);
98+
r == 0
99+
}
100+
}
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
pub mod condvar;
2+
#[path = "../../unix/locks/pthread_mutex.rs"]
3+
pub mod mutex;
4+
#[path = "../../unsupported/locks/rwlock.rs"]
5+
pub mod rwlock;
6+
7+
pub(crate) use condvar::Condvar;
8+
pub(crate) use mutex::Mutex;
9+
pub(crate) use rwlock::RwLock;

library/std/src/sys/teeos/mod.rs

+167
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
//! System bindings for the Teeos platform
2+
//!
3+
//! This module contains the facade (aka platform-specific) implementations of
4+
//! OS level functionality for Teeos.
5+
#![allow(unsafe_op_in_unsafe_fn)]
6+
#![allow(unused_variables)]
7+
#![allow(dead_code)]
8+
9+
pub use self::rand::hashmap_random_keys;
10+
11+
pub mod alloc;
12+
#[path = "../unsupported/args.rs"]
13+
pub mod args;
14+
#[path = "../unix/cmath.rs"]
15+
pub mod cmath;
16+
#[path = "../unsupported/env.rs"]
17+
pub mod env;
18+
pub mod locks;
19+
//pub mod fd;
20+
#[path = "../unsupported/fs.rs"]
21+
pub mod fs;
22+
#[path = "../unsupported/io.rs"]
23+
pub mod io;
24+
#[path = "../unix/memchr.rs"]
25+
pub mod memchr;
26+
pub mod net;
27+
#[path = "../unsupported/once.rs"]
28+
pub mod once;
29+
pub mod os;
30+
#[path = "../unix/os_str.rs"]
31+
pub mod os_str;
32+
#[path = "../unix/path.rs"]
33+
pub mod path;
34+
#[path = "../unsupported/pipe.rs"]
35+
pub mod pipe;
36+
#[path = "../unsupported/process.rs"]
37+
pub mod process;
38+
mod rand;
39+
pub mod stdio;
40+
pub mod thread;
41+
pub mod thread_local_dtor;
42+
#[path = "../unix/thread_local_key.rs"]
43+
pub mod thread_local_key;
44+
#[path = "../unsupported/thread_parking.rs"]
45+
pub mod thread_parking;
46+
#[allow(non_upper_case_globals)]
47+
#[path = "../unix/time.rs"]
48+
pub mod time;
49+
50+
use crate::io::ErrorKind;
51+
52+
pub fn abort_internal() -> ! {
53+
unsafe { libc::abort() }
54+
}
55+
56+
// Trusted Applications are loaded as dynamic libraries on Teeos,
57+
// so this should never be called.
58+
pub fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {}
59+
60+
// SAFETY: must be called only once during runtime cleanup.
61+
// this is not guaranteed to run, for example when the program aborts.
62+
pub unsafe fn cleanup() {
63+
unimplemented!()
64+
// We do NOT have stack overflow handler, because TEE OS will kill TA when it happens.
65+
// So cleanup is commented
66+
// stack_overflow::cleanup();
67+
}
68+
69+
#[inline]
70+
pub(crate) fn is_interrupted(errno: i32) -> bool {
71+
errno == libc::EINTR
72+
}
73+
74+
// Note: code below is 1:1 copied from unix/mod.rs
75+
pub fn decode_error_kind(errno: i32) -> ErrorKind {
76+
use ErrorKind::*;
77+
match errno as libc::c_int {
78+
libc::E2BIG => ArgumentListTooLong,
79+
libc::EADDRINUSE => AddrInUse,
80+
libc::EADDRNOTAVAIL => AddrNotAvailable,
81+
libc::EBUSY => ResourceBusy,
82+
libc::ECONNABORTED => ConnectionAborted,
83+
libc::ECONNREFUSED => ConnectionRefused,
84+
libc::ECONNRESET => ConnectionReset,
85+
libc::EDEADLK => Deadlock,
86+
libc::EDQUOT => FilesystemQuotaExceeded,
87+
libc::EEXIST => AlreadyExists,
88+
libc::EFBIG => FileTooLarge,
89+
libc::EHOSTUNREACH => HostUnreachable,
90+
libc::EINTR => Interrupted,
91+
libc::EINVAL => InvalidInput,
92+
libc::EISDIR => IsADirectory,
93+
libc::ELOOP => FilesystemLoop,
94+
libc::ENOENT => NotFound,
95+
libc::ENOMEM => OutOfMemory,
96+
libc::ENOSPC => StorageFull,
97+
libc::ENOSYS => Unsupported,
98+
libc::EMLINK => TooManyLinks,
99+
libc::ENAMETOOLONG => InvalidFilename,
100+
libc::ENETDOWN => NetworkDown,
101+
libc::ENETUNREACH => NetworkUnreachable,
102+
libc::ENOTCONN => NotConnected,
103+
libc::ENOTDIR => NotADirectory,
104+
libc::ENOTEMPTY => DirectoryNotEmpty,
105+
libc::EPIPE => BrokenPipe,
106+
libc::EROFS => ReadOnlyFilesystem,
107+
libc::ESPIPE => NotSeekable,
108+
libc::ESTALE => StaleNetworkFileHandle,
109+
libc::ETIMEDOUT => TimedOut,
110+
libc::ETXTBSY => ExecutableFileBusy,
111+
libc::EXDEV => CrossesDevices,
112+
113+
libc::EACCES | libc::EPERM => PermissionDenied,
114+
115+
// These two constants can have the same value on some systems,
116+
// but different values on others, so we can't use a match
117+
// clause
118+
x if x == libc::EAGAIN || x == libc::EWOULDBLOCK => WouldBlock,
119+
120+
_ => Uncategorized,
121+
}
122+
}
123+
124+
#[doc(hidden)]
125+
pub trait IsMinusOne {
126+
fn is_minus_one(&self) -> bool;
127+
}
128+
129+
macro_rules! impl_is_minus_one {
130+
($($t:ident)*) => ($(impl IsMinusOne for $t {
131+
fn is_minus_one(&self) -> bool {
132+
*self == -1
133+
}
134+
})*)
135+
}
136+
137+
impl_is_minus_one! { i8 i16 i32 i64 isize }
138+
139+
pub fn cvt<T: IsMinusOne>(t: T) -> crate::io::Result<T> {
140+
if t.is_minus_one() { Err(crate::io::Error::last_os_error()) } else { Ok(t) }
141+
}
142+
143+
pub fn cvt_r<T, F>(mut f: F) -> crate::io::Result<T>
144+
where
145+
T: IsMinusOne,
146+
F: FnMut() -> T,
147+
{
148+
loop {
149+
match cvt(f()) {
150+
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
151+
other => return other,
152+
}
153+
}
154+
}
155+
156+
pub fn cvt_nz(error: libc::c_int) -> crate::io::Result<()> {
157+
if error == 0 { Ok(()) } else { Err(crate::io::Error::from_raw_os_error(error)) }
158+
}
159+
160+
use crate::io as std_io;
161+
pub fn unsupported<T>() -> std_io::Result<T> {
162+
Err(unsupported_err())
163+
}
164+
165+
pub fn unsupported_err() -> std_io::Error {
166+
std_io::Error::new(std_io::ErrorKind::Unsupported, "operation not supported on this platform")
167+
}

0 commit comments

Comments
 (0)