use crate::syscall::{
BaseSyscallHandler, SYS_ENARX_GDB_PEEK, SYS_ENARX_GDB_READ, SYS_ENARX_GDB_START,
SYS_ENARX_GDB_WRITE,
};
use crate::untrusted::{AddressValidator, UntrustedRef, UntrustedRefMut, ValidateSlice};
use crate::Register;
use crate::{request, Block, Result};
use primordial::Address;
pub trait EnarxSyscallHandler: BaseSyscallHandler + AddressValidator + Sized {
fn get_attestation(
&mut self,
nonce: UntrustedRef<u8>,
nonce_len: libc::size_t,
buf: UntrustedRefMut<u8>,
buf_len: libc::size_t,
) -> Result;
fn gdb_start(&mut self) -> Result {
self.trace("gdb_start", 0);
unsafe { self.proxy(request!(SYS_ENARX_GDB_START)) }
}
fn gdb_read(&mut self, buf: UntrustedRefMut<u8>, count: libc::size_t) -> Result {
let buf = buf.validate_slice(count, self).ok_or(libc::EFAULT)?;
let c = self.new_cursor();
let count = usize::min(count, Block::buf_capacity());
let (_, hostbuf) = c.alloc::<u8>(count).or(Err(libc::EMSGSIZE))?;
let hostbuf = hostbuf.as_ptr();
let host_virt = Self::translate_shim_to_host_addr(hostbuf);
let ret = unsafe { self.proxy(request!(SYS_ENARX_GDB_READ => host_virt, count))? };
let result_len: usize = ret[0].into();
if count < result_len {
self.attacked();
}
let c = self.new_cursor();
unsafe {
c.copy_into_slice(count, buf[..result_len].as_mut())
.or(Err(libc::EFAULT))?;
}
Ok(ret)
}
fn gdb_peek(&mut self) -> Result {
self.trace("gdb_peek", 0);
unsafe { self.proxy(request!(SYS_ENARX_GDB_PEEK)) }
}
fn gdb_write(&mut self, buf: UntrustedRef<u8>, count: libc::size_t) -> Result {
let count = usize::min(count, Block::buf_capacity());
let buf = buf.validate_slice(count, self).ok_or(libc::EFAULT)?;
let c = self.new_cursor();
let (_, buf) = c.copy_from_slice(buf.as_ref()).or(Err(libc::EMSGSIZE))?;
let buf = buf.as_ptr();
let host_virt = Self::translate_shim_to_host_addr(buf);
let ret = unsafe { self.proxy(request!(SYS_ENARX_GDB_WRITE => host_virt, count))? };
let result_len: usize = ret[0].into();
if result_len > count {
self.attacked()
}
Ok(ret)
}
}
#[repr(C)]
#[derive(Copy, Clone, Default, Debug)]
pub struct MemInfo {
pub virt_start: Address<usize, u8>,
pub mem_slots: usize,
}