|
1 | 1 | use crate::instructions::Register; |
2 | 2 | use crate::memory::FLAG_DIRTY; |
3 | 3 | use crate::memory::Memory; |
4 | | -use crate::{CoreMachine, Error, RISCV_GENERAL_REGISTER_NUMBER, RISCV_PAGE_SHIFTS, RISCV_PAGESIZE}; |
| 4 | +use crate::{ |
| 5 | + CoreMachine, DEFAULT_SHADOW_STACK_SIZE, Error, RISCV_GENERAL_REGISTER_NUMBER, |
| 6 | + RISCV_PAGE_SHIFTS, RISCV_PAGESIZE, |
| 7 | +}; |
5 | 8 | use serde::{Deserialize, Serialize}; |
6 | 9 |
|
7 | 10 | // Snapshot provides a mechanism for suspending and resuming a virtual machine. |
@@ -40,14 +43,20 @@ pub struct Snapshot { |
40 | 43 | } |
41 | 44 |
|
42 | 45 | pub fn make_snapshot<T: CoreMachine>(machine: &mut T) -> Result<Snapshot, Error> { |
| 46 | + let mut snap_ss = machine.ss().to_vec(); |
| 47 | + if let Some(pos) = snap_ss.iter().position(|&x| x != 0) { |
| 48 | + snap_ss.drain(..pos); |
| 49 | + } else { |
| 50 | + snap_ss.clear(); |
| 51 | + } |
43 | 52 | let mut snap = Snapshot { |
44 | 53 | version: machine.version(), |
45 | 54 | pc: machine.pc().to_u64(), |
46 | 55 | load_reservation_address: machine.memory().lr().to_u64(), |
47 | 56 | cfi: machine.cfi().into(), |
48 | 57 | elp: machine.elp(), |
49 | 58 | ssp: machine.ssp().to_u64(), |
50 | | - ss: machine.ss().to_vec(), |
| 59 | + ss: snap_ss, |
51 | 60 | ..Default::default() |
52 | 61 | }; |
53 | 62 | for (i, v) in machine.registers().iter().enumerate() { |
@@ -108,6 +117,6 @@ pub fn resume<T: CoreMachine>(machine: &mut T, snapshot: &Snapshot) -> Result<() |
108 | 117 | machine.set_cfi(snapshot.cfi.into()); |
109 | 118 | machine.set_elp(snapshot.elp); |
110 | 119 | machine.set_ssp(&T::REG::from_u64(snapshot.ssp)); |
111 | | - machine.ss_mut().copy_from_slice(&snapshot.ss); |
| 120 | + machine.ss_mut()[DEFAULT_SHADOW_STACK_SIZE - snapshot.ss.len()..].copy_from_slice(&snapshot.ss); |
112 | 121 | Ok(()) |
113 | 122 | } |
0 commit comments