hyperlight_guest/
shared_output_data.rs1use alloc::format;
18use alloc::string::ToString;
19use alloc::vec::Vec;
20use core::slice::from_raw_parts_mut;
21
22use hyperlight_common::flatbuffer_wrappers::guest_error::ErrorCode;
23
24use crate::error::{HyperlightGuestError, Result};
25use crate::P_PEB;
26
27pub fn push_shared_output_data(data: Vec<u8>) -> Result<()> {
28 let peb_ptr = unsafe { P_PEB.unwrap() };
29 let shared_buffer_size = unsafe { (*peb_ptr).output_stack.size as usize };
30 let odb =
31 unsafe { from_raw_parts_mut((*peb_ptr).output_stack.ptr as *mut u8, shared_buffer_size) };
32
33 if odb.is_empty() {
34 return Err(HyperlightGuestError::new(
35 ErrorCode::GuestError,
36 "Got a 0-size buffer in push_shared_output_data".to_string(),
37 ));
38 }
39
40 let stack_ptr_rel: u64 =
42 u64::from_le_bytes(odb[..8].try_into().expect("Shared output buffer too small"));
43
44 if stack_ptr_rel as usize > shared_buffer_size || stack_ptr_rel < 8 {
48 return Err(HyperlightGuestError::new(
49 ErrorCode::GuestError,
50 format!(
51 "Invalid stack pointer: {} in push_shared_output_data",
52 stack_ptr_rel
53 ),
54 ));
55 }
56
57 let size_required = data.len() + 8; let size_available = shared_buffer_size - stack_ptr_rel as usize;
60 if size_required > size_available {
61 return Err(HyperlightGuestError::new(
62 ErrorCode::GuestError,
63 format!(
64 "Not enough space in shared output buffer. Required: {}, Available: {}",
65 size_required, size_available
66 ),
67 ));
68 }
69
70 odb[stack_ptr_rel as usize..stack_ptr_rel as usize + data.len()].copy_from_slice(&data);
72
73 let bytes: [u8; 8] = stack_ptr_rel.to_le_bytes();
75 odb[stack_ptr_rel as usize + data.len()..stack_ptr_rel as usize + data.len() + 8]
76 .copy_from_slice(&bytes);
77
78 let new_stack_ptr_rel: u64 = (stack_ptr_rel as usize + data.len() + 8) as u64;
80 odb[0..8].copy_from_slice(&(new_stack_ptr_rel).to_le_bytes());
81
82 Ok(())
83}