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).outputdata.outputDataSize as usize };
30 let odb = unsafe {
31 from_raw_parts_mut(
32 (*peb_ptr).outputdata.outputDataBuffer as *mut u8,
33 shared_buffer_size,
34 )
35 };
36
37 if odb.is_empty() {
38 return Err(HyperlightGuestError::new(
39 ErrorCode::GuestError,
40 "Got a 0-size buffer in push_shared_output_data".to_string(),
41 ));
42 }
43
44 let stack_ptr_rel: usize =
46 usize::from_le_bytes(odb[..8].try_into().expect("Shared output buffer too small"));
47
48 if stack_ptr_rel > shared_buffer_size || stack_ptr_rel < 8 {
52 return Err(HyperlightGuestError::new(
53 ErrorCode::GuestError,
54 format!(
55 "Invalid stack pointer: {} in push_shared_output_data",
56 stack_ptr_rel
57 ),
58 ));
59 }
60
61 let size_required = data.len() + 8; let size_available = shared_buffer_size - stack_ptr_rel;
64 if size_required > size_available {
65 return Err(HyperlightGuestError::new(
66 ErrorCode::GuestError,
67 format!(
68 "Not enough space in shared output buffer. Required: {}, Available: {}",
69 size_required, size_available
70 ),
71 ));
72 }
73
74 odb[stack_ptr_rel..stack_ptr_rel + data.len()].copy_from_slice(&data);
76
77 let bytes = stack_ptr_rel.to_le_bytes();
79 odb[stack_ptr_rel + data.len()..stack_ptr_rel + data.len() + 8].copy_from_slice(&bytes);
80
81 let new_stack_ptr_rel = stack_ptr_rel + data.len() + 8;
83 odb[0..8].copy_from_slice(&(new_stack_ptr_rel).to_le_bytes());
84
85 Ok(())
86}