1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use crate::enclave::state::{self, State};
use crate::enclave::{atexit, parse};
use crate::tcs::ThreadControl;
use core::sync::atomic::AtomicBool;
use sgx_types::error::SgxResult;
pub static UNINIT_FLAG: AtomicBool = AtomicBool::new(false);
pub fn dtors() -> SgxResult {
if let Some(uninit_array) = parse::uninit_array()? {
let fn_array = uninit_array.get_array();
for f in fn_array {
f.get_fn()();
}
}
Ok(())
}
#[inline]
pub fn at_exit_cleaup() {
atexit::cleanup();
}
pub fn rtuninit(tc: ThreadControl) -> SgxResult {
use crate::call;
use crate::tcs;
use core::ptr;
use core::sync::atomic::Ordering;
use sgx_types::error::SgxStatus;
if UNINIT_FLAG.load(Ordering::SeqCst) {
state::set_state(State::Crashed);
return Ok(());
}
let current = tcs::current();
let tcs = tc.tcs();
assert!(ptr::eq(current.tcs(), tcs));
cfg_if! {
if #[cfg(feature = "sim")] {
let is_legal = tc.is_init();
} else if #[cfg(feature = "hyper")] {
let is_legal = tc.is_init();
} else {
use crate::feature::SysFeatures;
use crate::edmm::{self, layout::LayoutTable};
let is_legal = if SysFeatures::get().is_edmm() {
tc.is_utility() || !LayoutTable::new().is_dyn_tcs_exist()
} else {
tc.is_init()
};
}
}
if !is_legal {
state::set_state(State::Crashed);
bail!(SgxStatus::Unexpected);
}
UNINIT_FLAG.store(true, Ordering::SeqCst);
#[cfg(not(any(feature = "sim", feature = "hyper")))]
{
if SysFeatures::get().is_edmm() && edmm::tcs::accept_trim_tcs(tcs).is_err() {
state::set_state(State::Crashed);
bail!(SgxStatus::Unexpected);
}
}
let guard = call::FIRST_ECALL.lock();
if call::FIRST_ECALL.is_completed() {
at_exit_cleaup();
let _ = dtors();
}
drop(guard);
state::set_state(State::Crashed);
Ok(())
}
#[allow(unused_variables)]
pub fn global_exit(tc: ThreadControl) -> SgxResult {
extern "C" {
fn global_exit_ecall();
}
unsafe { global_exit_ecall() }
cfg_if! {
if #[cfg(feature = "sim")] {
rtuninit(tc)
} else if #[cfg(feature = "hyper")] {
rtuninit(tc)
} else {
use crate::feature::SysFeatures;
if !SysFeatures::get().is_edmm() {
rtuninit(tc)
} else {
Ok(())
}
}
}
}