]>
git.proxmox.com Git - rustc.git/blob - library/std/src/sys/sgx/abi/mod.rs
1 #![cfg_attr(test, allow(unused))] // RT initialization logic is not compiled for test
4 use core
::sync
::atomic
::{AtomicUsize, Ordering}
;
18 global_asm
!(include_str
!("entry.S"));
21 struct EntryReturn(u64, u64);
25 unsafe extern "C" fn tcs_init(secondary
: bool
) {
26 // Be very careful when changing this code: it runs before the binary has been
27 // relocated. Any indirect accesses to symbols will likely fail.
28 const UNINIT
: usize = 0;
29 const BUSY
: usize = 1;
30 const DONE
: usize = 2;
31 // Three-state spin-lock
32 static RELOC_STATE
: AtomicUsize
= AtomicUsize
::new(UNINIT
);
34 if secondary
&& RELOC_STATE
.load(Ordering
::Relaxed
) != DONE
{
35 rtabort
!("Entered secondary TCS before main TCS!")
38 // Try to atomically swap UNINIT with BUSY. The returned state can be:
39 match RELOC_STATE
.compare_exchange(UNINIT
, BUSY
, Ordering
::Acquire
, Ordering
::Acquire
) {
40 // This thread just obtained the lock and other threads will observe BUSY
42 reloc
::relocate_elf_rela();
43 RELOC_STATE
.store(DONE
, Ordering
::Release
);
45 // We need to wait until the initialization is done.
47 while RELOC_STATE
.load(Ordering
::Acquire
) == BUSY
{
48 core
::hint
::spin_loop();
51 // Initialization is done.
57 // FIXME: this item should only exist if this is linked into an executable
58 // (main function exists). If this is a library, the crate author should be
59 // able to specify this
62 extern "C" fn entry(p1
: u64, p2
: u64, p3
: u64, secondary
: bool
, p4
: u64, p5
: u64) -> EntryReturn
{
63 // FIXME: how to support TLS in library mode?
64 let tls
= Box
::new(tls
::Tls
::new());
65 let tls_guard
= unsafe { tls.activate() }
;
68 let join_notifier
= super::thread
::Thread
::entry();
75 fn main(argc
: isize, argv
: *const *const u8) -> isize;
78 // check entry is being called according to ABI
84 // The actual types of these arguments are `p1: *const Arg, p2:
85 // usize`. We can't currently customize the argument list of Rust's
86 // main function, so we pass these in as the standard pointer-sized
87 // values in `argc` and `argv`.
88 let ret
= main(p2
as _
, p1
as _
);
94 pub(super) fn exit_with_code(code
: isize) -> ! {
96 if let Some(mut out
) = panic
::SgxPanicOutput
::new() {
97 let _
= write
!(out
, "Exited with status code {}", code
);
100 usercalls
::exit(code
!= 0);
105 extern "C" fn abort_reentry() -> ! {
106 usercalls
::exit(false)