use crate::arch::Arch;
mod generated {
#![allow(non_camel_case_types, non_upper_case_globals, dead_code)]
include!("generated.rs");
}
pub use generated::{
BARYL_SUB_ARCH, BARYL_SUB_BREAKPOINTS, BARYL_SUB_CORPUS, BARYL_SUB_COVERAGE, BARYL_SUB_ENGINE,
BARYL_SUB_ENLIGHTEN, BARYL_SUB_FUZZ, BARYL_SUB_NET, BARYL_SUB_STATS, Control, Subsystems,
};
impl Default for Control {
fn default() -> Self {
unsafe { core::mem::zeroed() }
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ControlError {
NotPublished,
ArchMismatch { want: u32, found: u32 },
NullRegs,
}
impl core::fmt::Display for ControlError {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::NotPublished => write!(f, "the vm is not published until first VM entry"),
Self::ArchMismatch { want, found } => {
write!(f, "built for arch {want:#x}, engine paired with {found:#x}")
},
Self::NullRegs => write!(f, "the engine published no register table"),
}
}
}
impl core::error::Error for ControlError {}
impl Subsystems {
pub fn regs<A: Arch>(&self) -> Result<&A, ControlError> {
match self.isa {
0 => Err(ControlError::NotPublished),
id if id != A::ID => Err(ControlError::ArchMismatch { want: A::ID, found: id }),
_ if self.regs.is_null() => Err(ControlError::NullRegs),
_ => Ok(unsafe { &*self.regs.cast() }),
}
}
pub fn arch_id(&self) -> Option<u32> {
(self.isa != 0).then_some(self.isa)
}
pub fn abi_version(&self) -> Option<u32> {
(self.isa != 0).then_some(self.abi)
}
}