]>
Commit | Line | Data |
---|---|---|
0731742a XL |
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 | ||
dfeec247 | 13 | extern "C" { |
0731742a | 14 | static ENCLAVE_SIZE: usize; |
fc512014 XL |
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 } | |
0731742a XL |
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 { | |
1b1a35ee XL |
36 | let base: u64; |
37 | unsafe { | |
38 | asm!( | |
39 | "lea IMAGE_BASE(%rip), {}", | |
40 | lateout(reg) base, | |
41 | // NOTE(#76738): ATT syntax is used to support LLVM 8 and 9. | |
42 | options(att_syntax, nostack, preserves_flags, nomem, pure), | |
43 | ) | |
44 | }; | |
0731742a XL |
45 | base |
46 | } | |
47 | ||
48 | /// Returns `true` if the specified memory range is in the enclave. | |
48663c56 | 49 | /// |
6a06907d XL |
50 | /// For safety, this function also checks whether the range given overflows, |
51 | /// returning `false` if so. | |
0731742a XL |
52 | #[unstable(feature = "sgx_platform", issue = "56975")] |
53 | pub fn is_enclave_range(p: *const u8, len: usize) -> bool { | |
6a06907d XL |
54 | let start = p as usize; |
55 | ||
56 | // Subtract one from `len` when calculating `end` in case `p + len` is | |
57 | // exactly at the end of addressable memory (`p + len` would overflow, but | |
58 | // the range is still valid). | |
59 | let end = if len == 0 { | |
60 | start | |
61 | } else if let Some(end) = start.checked_add(len - 1) { | |
62 | end | |
63 | } else { | |
64 | return false; | |
65 | }; | |
66 | ||
67 | let base = image_base() as usize; | |
68 | start >= base && end <= base + (unsafe { ENCLAVE_SIZE } - 1) // unsafe ok: link-time constant | |
0731742a XL |
69 | } |
70 | ||
71 | /// Returns `true` if the specified memory range is in userspace. | |
48663c56 | 72 | /// |
6a06907d XL |
73 | /// For safety, this function also checks whether the range given overflows, |
74 | /// returning `false` if so. | |
0731742a XL |
75 | #[unstable(feature = "sgx_platform", issue = "56975")] |
76 | pub fn is_user_range(p: *const u8, len: usize) -> bool { | |
6a06907d XL |
77 | let start = p as usize; |
78 | ||
79 | // Subtract one from `len` when calculating `end` in case `p + len` is | |
80 | // exactly at the end of addressable memory (`p + len` would overflow, but | |
81 | // the range is still valid). | |
82 | let end = if len == 0 { | |
83 | start | |
84 | } else if let Some(end) = start.checked_add(len - 1) { | |
85 | end | |
86 | } else { | |
87 | return false; | |
88 | }; | |
89 | ||
90 | let base = image_base() as usize; | |
91 | end < base || start > base + (unsafe { ENCLAVE_SIZE } - 1) // unsafe ok: link-time constant | |
0731742a | 92 | } |