]> git.lizzy.rs Git - rust.git/blob - library/std/src/sys/sgx/abi/mem.rs
1e743894a9fea3444fbc1a71213354b5acee4248
[rust.git] / library / std / src / sys / sgx / abi / mem.rs
1 // Do not remove inline: will result in relocation failure
2 #[inline(always)]
3 pub(crate) unsafe fn rel_ptr<T>(offset: u64) -> *const T {
4     (image_base() + offset) as *const T
5 }
6
7 // Do not remove inline: will result in relocation failure
8 #[inline(always)]
9 pub(crate) unsafe fn rel_ptr_mut<T>(offset: u64) -> *mut T {
10     (image_base() + offset) as *mut T
11 }
12
13 extern "C" {
14     static ENCLAVE_SIZE: usize;
15     static HEAP_BASE: u64;
16     static HEAP_SIZE: usize;
17 }
18
19 /// Returns the base memory address of the heap
20 pub(crate) fn heap_base() -> *const u8 {
21     unsafe { rel_ptr_mut(HEAP_BASE) }
22 }
23
24 /// Returns the size of the heap
25 pub(crate) fn heap_size() -> usize {
26     unsafe { HEAP_SIZE }
27 }
28
29 // Do not remove inline: will result in relocation failure
30 // For the same reason we use inline ASM here instead of an extern static to
31 // locate the base
32 /// Returns address at which current enclave is loaded.
33 #[inline(always)]
34 #[unstable(feature = "sgx_platform", issue = "56975")]
35 pub fn image_base() -> u64 {
36     let base: u64;
37     unsafe {
38         asm!(
39             "lea {}, qword ptr [rip + IMAGE_BASE]",
40             lateout(reg) base,
41             options(nostack, preserves_flags, nomem, pure),
42         )
43     };
44     base
45 }
46
47 /// Returns `true` if the specified memory range is in the enclave.
48 ///
49 /// For safety, this function also checks whether the range given overflows,
50 /// returning `false` if so.
51 #[unstable(feature = "sgx_platform", issue = "56975")]
52 pub fn is_enclave_range(p: *const u8, len: usize) -> bool {
53     let start = p as usize;
54
55     // Subtract one from `len` when calculating `end` in case `p + len` is
56     // exactly at the end of addressable memory (`p + len` would overflow, but
57     // the range is still valid).
58     let end = if len == 0 {
59         start
60     } else if let Some(end) = start.checked_add(len - 1) {
61         end
62     } else {
63         return false;
64     };
65
66     let base = image_base() as usize;
67     start >= base && end <= base + (unsafe { ENCLAVE_SIZE } - 1) // unsafe ok: link-time constant
68 }
69
70 /// Returns `true` if the specified memory range is in userspace.
71 ///
72 /// For safety, this function also checks whether the range given overflows,
73 /// returning `false` if so.
74 #[unstable(feature = "sgx_platform", issue = "56975")]
75 pub fn is_user_range(p: *const u8, len: usize) -> bool {
76     let start = p as usize;
77
78     // Subtract one from `len` when calculating `end` in case `p + len` is
79     // exactly at the end of addressable memory (`p + len` would overflow, but
80     // the range is still valid).
81     let end = if len == 0 {
82         start
83     } else if let Some(end) = start.checked_add(len - 1) {
84         end
85     } else {
86         return false;
87     };
88
89     let base = image_base() as usize;
90     end < base || start > base + (unsafe { ENCLAVE_SIZE } - 1) // unsafe ok: link-time constant
91 }