1 use crate::{ebpf::STACK_SIZE, vec, Vec}; 2 3 pub struct StackFrame { 4 return_address: u16, 5 saved_registers: [u64; 4], 6 sp: u16, 7 frame: Vec<u8>, 8 } 9 10 impl StackFrame { 11 /// Create a new stack frame 12 /// 13 /// The stack frame is created with a capacity of `STACK_SIZE` == 512 bytes new() -> Self14 pub fn new() -> Self { 15 Self { 16 sp: 0, 17 return_address: 0, 18 saved_registers: [0; 4], 19 frame: vec![0; STACK_SIZE], 20 } 21 } 22 23 /// Create a new stack frame with a given capacity 24 #[allow(unused)] with_capacity(capacity: usize) -> Self25 pub fn with_capacity(capacity: usize) -> Self { 26 Self { 27 sp: 0, 28 return_address: 0, 29 saved_registers: [0; 4], 30 frame: vec![0; capacity], 31 } 32 } 33 34 /// The capacity of the stack frame len(&self) -> usize35 pub fn len(&self) -> usize { 36 self.frame.len() 37 } 38 as_ptr(&self) -> *const u839 pub fn as_ptr(&self) -> *const u8 { 40 self.frame.as_ptr() 41 } 42 as_slice(&self) -> &[u8]43 pub fn as_slice(&self) -> &[u8] { 44 self.frame.as_slice() 45 } 46 /// Save the callee-saved registers save_registers(&mut self, regs: &[u64])47 pub fn save_registers(&mut self, regs: &[u64]) { 48 self.saved_registers.copy_from_slice(regs); 49 } 50 51 /// Get the callee-saved registers get_registers(&self) -> [u64; 4]52 pub fn get_registers(&self) -> [u64; 4] { 53 self.saved_registers 54 } 55 56 /// Save the return address save_return_address(&mut self, address: u16)57 pub fn save_return_address(&mut self, address: u16) { 58 self.return_address = address; 59 } 60 61 /// Get the return address get_return_address(&self) -> u1662 pub fn get_return_address(&self) -> u16 { 63 self.return_address 64 } 65 66 /// Save the stack pointer save_sp(&mut self, sp: u16)67 pub fn save_sp(&mut self, sp: u16) { 68 self.sp = sp; 69 } 70 71 /// Get the stack pointer get_sp(&self) -> u1672 pub fn get_sp(&self) -> u16 { 73 self.sp 74 } 75 } 76