]>
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!( | |
136023e0 | 39 | "lea IMAGE_BASE(%rip), {}", |
1b1a35ee | 40 | lateout(reg) base, |
136023e0 | 41 | options(att_syntax, nostack, preserves_flags, nomem, pure), |
1b1a35ee XL |
42 | ) |
43 | }; | |
0731742a XL |
44 | base |
45 | } | |
46 | ||
47 | /// Returns `true` if the specified memory range is in the enclave. | |
48663c56 | 48 | /// |
6a06907d XL |
49 | /// For safety, this function also checks whether the range given overflows, |
50 | /// returning `false` if so. | |
0731742a XL |
51 | #[unstable(feature = "sgx_platform", issue = "56975")] |
52 | pub fn is_enclave_range(p: *const u8, len: usize) -> bool { | |
6a06907d XL |
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 | |
0731742a XL |
68 | } |
69 | ||
70 | /// Returns `true` if the specified memory range is in userspace. | |
48663c56 | 71 | /// |
6a06907d XL |
72 | /// For safety, this function also checks whether the range given overflows, |
73 | /// returning `false` if so. | |
0731742a XL |
74 | #[unstable(feature = "sgx_platform", issue = "56975")] |
75 | pub fn is_user_range(p: *const u8, len: usize) -> bool { | |
6a06907d XL |
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 | |
0731742a | 91 | } |