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 14 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)] 25 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 35 pub fn len(&self) -> usize { 36 self.frame.len() 37 } 38 39 pub fn as_ptr(&self) -> *const u8 { 40 self.frame.as_ptr() 41 } 42 43 pub fn as_slice(&self) -> &[u8] { 44 self.frame.as_slice() 45 } 46 /// Save the callee-saved registers 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 52 pub fn get_registers(&self) -> [u64; 4] { 53 self.saved_registers 54 } 55 56 /// Save the return address 57 pub fn save_return_address(&mut self, address: u16) { 58 self.return_address = address; 59 } 60 61 /// Get the return address 62 pub fn get_return_address(&self) -> u16 { 63 self.return_address 64 } 65 66 /// Save the stack pointer 67 pub fn save_sp(&mut self, sp: u16) { 68 self.sp = sp; 69 } 70 71 /// Get the stack pointer 72 pub fn get_sp(&self) -> u16 { 73 self.sp 74 } 75 } 76