]> git.proxmox.com Git - rustc.git/blame - library/std/src/sys/sgx/abi/mod.rs
New upstream version 1.49.0~beta.4+dfsg1
[rustc.git] / library / std / src / sys / sgx / abi / mod.rs
CommitLineData
532ac7d7
XL
1#![cfg_attr(test, allow(unused))] // RT initialization logic is not compiled for test
2
532ac7d7 3use crate::io::Write;
60c5eb7d 4use core::sync::atomic::{AtomicUsize, Ordering};
0731742a
XL
5
6// runtime features
0731742a 7pub(super) mod panic;
60c5eb7d 8mod reloc;
0731742a
XL
9
10// library features
11pub mod mem;
12pub mod thread;
13pub mod tls;
14#[macro_use]
15pub mod usercalls;
16
532ac7d7 17#[cfg(not(test))]
9fa01778 18global_asm!(include_str!("entry.S"));
0731742a 19
3dfed10e
XL
20#[repr(C)]
21struct EntryReturn(u64, u64);
22
532ac7d7 23#[cfg(not(test))]
0731742a
XL
24#[no_mangle]
25unsafe 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);
33
34 if secondary && RELOC_STATE.load(Ordering::Relaxed) != DONE {
48663c56 35 rtabort!("Entered secondary TCS before main TCS!")
0731742a
XL
36 }
37
38 // Try to atomically swap UNINIT with BUSY. The returned state can be:
39 match RELOC_STATE.compare_and_swap(UNINIT, BUSY, Ordering::Acquire) {
40 // This thread just obtained the lock and other threads will observe BUSY
41 UNINIT => {
42 reloc::relocate_elf_rela();
43 RELOC_STATE.store(DONE, Ordering::Release);
60c5eb7d 44 }
0731742a 45 // We need to wait until the initialization is done.
60c5eb7d
XL
46 BUSY => {
47 while RELOC_STATE.load(Ordering::Acquire) == BUSY {
29967ef6 48 core::hint::spin_loop();
60c5eb7d
XL
49 }
50 }
0731742a 51 // Initialization is done.
60c5eb7d
XL
52 DONE => {}
53 _ => unreachable!(),
0731742a
XL
54 }
55}
56
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
532ac7d7 60#[cfg(not(test))]
0731742a 61#[no_mangle]
3dfed10e 62extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64) -> EntryReturn {
0731742a
XL
63 // FIXME: how to support TLS in library mode?
64 let tls = Box::new(tls::Tls::new());
65 let _tls_guard = unsafe { tls.activate() };
66
67 if secondary {
68 super::thread::Thread::entry();
69
3dfed10e 70 EntryReturn(0, 0)
0731742a
XL
71 } else {
72 extern "C" {
73 fn main(argc: isize, argv: *const *const u8) -> isize;
74 }
75
76 // check entry is being called according to ABI
532ac7d7
XL
77 rtassert!(p3 == 0);
78 rtassert!(p4 == 0);
79 rtassert!(p5 == 0);
0731742a
XL
80
81 unsafe {
82 // The actual types of these arguments are `p1: *const Arg, p2:
83 // usize`. We can't currently customize the argument list of Rust's
84 // main function, so we pass these in as the standard pointer-sized
85 // values in `argc` and `argv`.
86 let ret = main(p2 as _, p1 as _);
87 exit_with_code(ret)
88 }
89 }
90}
91
92pub(super) fn exit_with_code(code: isize) -> ! {
93 if code != 0 {
94 if let Some(mut out) = panic::SgxPanicOutput::new() {
95 let _ = write!(out, "Exited with status code {}", code);
96 }
97 }
98 usercalls::exit(code != 0);
99}
48663c56
XL
100
101#[cfg(not(test))]
102#[no_mangle]
103extern "C" fn abort_reentry() -> ! {
104 usercalls::exit(false)
105}