use super::super::types::Argv;
use super::Alloc;
use crate::guest::alloc::{Allocator, Collector};
use crate::item::enarxcall::Number;
use crate::Result;
use core::ffi::{c_int, c_void};
use core::ptr::NonNull;
pub trait PassthroughAlloc {
const NUM: Number;
type Argv: Into<[usize; 4]>;
type Ret;
fn stage(self) -> Self::Argv;
}
impl<'a, T: PassthroughAlloc> Alloc<'a> for T {
const NUM: Number = T::NUM;
type Argv = T::Argv;
type Ret = T::Ret;
type Staged = ();
type Committed = ();
type Collected = Result<T::Ret>;
fn stage(self, _: &mut impl Allocator) -> Result<(Self::Argv, Self::Staged)> {
Ok((T::stage(self), ()))
}
fn collect(_: Self::Committed, ret: Result<Self::Ret>, _: &impl Collector) -> Self::Collected {
ret
}
}
pub struct BalloonMemory {
pub size_exponent: usize,
pub pages: usize,
pub addr: *mut c_void,
}
impl PassthroughAlloc for BalloonMemory {
const NUM: Number = Number::BalloonMemory;
type Argv = Argv<3>;
type Ret = usize;
fn stage(self) -> Self::Argv {
Argv([self.size_exponent, self.pages, self.addr as _])
}
}
#[repr(transparent)]
pub struct GetSgxQuoteSize;
impl PassthroughAlloc for GetSgxQuoteSize {
const NUM: Number = Number::GetSgxQuoteSize;
type Argv = Argv<0>;
type Ret = usize;
fn stage(self) -> Self::Argv {
Argv([])
}
}
#[repr(transparent)]
pub struct MemInfo;
impl PassthroughAlloc for MemInfo {
const NUM: Number = Number::MemInfo;
type Argv = Argv<0>;
type Ret = usize;
fn stage(self) -> Self::Argv {
Argv([])
}
}
pub struct MmapHost {
pub addr: NonNull<c_void>,
pub length: usize,
pub prot: c_int,
}
impl PassthroughAlloc for MmapHost {
const NUM: Number = Number::MmapHost;
type Argv = Argv<3>;
type Ret = ();
fn stage(self) -> Self::Argv {
Argv([self.addr.as_ptr() as _, self.length, self.prot as _])
}
}
pub struct MprotectHost {
pub addr: NonNull<c_void>,
pub length: usize,
pub prot: c_int,
}
impl PassthroughAlloc for MprotectHost {
const NUM: Number = Number::MprotectHost;
type Argv = Argv<3>;
type Ret = ();
fn stage(self) -> Self::Argv {
Argv([self.addr.as_ptr() as _, self.length, self.prot as _])
}
}
pub struct MunmapHost {
pub addr: NonNull<c_void>,
pub length: usize,
}
impl PassthroughAlloc for MunmapHost {
const NUM: Number = Number::MunmapHost;
type Argv = Argv<2>;
type Ret = ();
fn stage(self) -> Self::Argv {
Argv([self.addr.as_ptr() as _, self.length])
}
}
pub struct TrimSgxPages {
pub addr: NonNull<c_void>,
pub length: usize,
}
impl PassthroughAlloc for TrimSgxPages {
const NUM: Number = Number::TrimSgxPages;
type Argv = Argv<2>;
type Ret = ();
fn stage(self) -> Self::Argv {
Argv([self.addr.as_ptr() as _, self.length])
}
}