1use zx;
6
7unsafe extern "C" {
8 fn __get_unsafe_stack_ptr() -> usize;
9}
10
11#[inline(never)]
16fn get_safe_stack_ptr() -> usize {
17 let mut sp: usize;
18 unsafe {
19 #[cfg(target_arch = "x86_64")]
20 std::arch::asm!(
21 "mov {0}, rsp",
22 out(reg) sp,
23 options(nomem)
24 );
25 #[cfg(target_arch = "aarch64")]
26 std::arch::asm!(
27 "mov {0}, sp",
28 out(reg) sp,
29 options(nomem)
30 );
31 #[cfg(target_arch = "riscv64")]
32 std::arch::asm!(
33 "mv {0}, sp",
34 out(reg) sp,
35 options(nomem)
36 );
37 }
38 sp
39}
40
41fn get_unsafe_stack_ptr() -> usize {
45 unsafe { __get_unsafe_stack_ptr() }
46}
47
48pub fn clean_stack() {
49 const CLEAN_SIZE: usize = 0x100000;
51 let page_size: usize = zx::system_get_page_size() as usize;
52 let stack_ptr_factories = [get_unsafe_stack_ptr, get_safe_stack_ptr];
53 for factory in stack_ptr_factories {
54 let v = factory();
57 let v = v - 64;
59 let max_addr = v - (v % page_size);
60 let start_addr = max_addr - CLEAN_SIZE;
61 let _ =
62 fuchsia_runtime::vmar_root_self().op_range(zx::VmarOp::ZERO, start_addr, CLEAN_SIZE);
63 }
64}
65
66#[cfg(test)]
67mod test {
68 use super::*;
69
70 #[inline(never)]
71 fn clean_stack_at_level(level: usize) -> usize {
72 if level == 0 {
73 clean_stack();
74 0
75 } else {
76 1 + clean_stack_at_level(level - 1)
77 }
78 }
79
80 #[::fuchsia::test]
81 fn test_clean_stack() {
82 let mut array = [0u8; 256];
83 for i in 0..256 {
84 array[i] = 255 - (i as u8);
85 }
86 for i in 0..4096 {
87 assert_eq!(clean_stack_at_level(i), i);
88 }
89 for i in 0..256 {
90 assert_eq!(array[i], 255 - (i as u8));
91 }
92 }
93}