use catalejo_memory::primitive::{Primitive, PrimitiveUnion};
use crate::{exception::backend::Backend, ffi::binding};
#[inline]
pub unsafe fn read(
fault_backend: &Backend,
target_source: *const PrimitiveUnion,
target_value: *mut PrimitiveUnion,
target_type: Primitive,
) -> binding::catalejo_outcome_t {
if fault_backend.validate().is_err() {
return binding::CATALEJO_OUTCOME_ERROR;
}
macro_rules! implement {
($target_type:ident) => {
tokel::stream!(
[< binding::catalejo_read _ $target_type >]:concatenate (target_source.cast::<$target_type>(), target_value.cast::<$target_type>())
)
};
}
unsafe {
match target_type {
Primitive::U8 => implement!(u8),
Primitive::U16 => implement!(u16),
Primitive::U32 => implement!(u32),
Primitive::U64 => implement!(u64),
}
}
}
#[inline]
pub unsafe fn write(
fault_backend: &Backend,
target_value: *mut PrimitiveUnion,
target_source: *const PrimitiveUnion,
target_type: Primitive,
) -> binding::catalejo_outcome_t {
if fault_backend.validate().is_err() {
return binding::CATALEJO_OUTCOME_ERROR;
}
macro_rules! implement {
($target_type:ident) => {
tokel::stream!(
[< binding::catalejo_write _ $target_type >]:concatenate (target_value.cast::<$target_type>(), target_source.cast::<$target_type>())
)
};
}
unsafe {
match target_type {
Primitive::U8 => implement!(u8),
Primitive::U16 => implement!(u16),
Primitive::U32 => implement!(u32),
Primitive::U64 => implement!(u64),
}
}
}
#[inline]
pub unsafe fn copy(
fault_backend: &Backend,
target: *mut u8,
source: *const u8,
count: usize,
) -> Result<(), usize> {
if fault_backend.validate().is_err() {
return Err(0);
}
let outcome = unsafe { binding::catalejo_copy(target, source, count) };
match outcome.outcome_status {
binding::CATALEJO_OUTCOME_SUCCESS => Ok(()),
binding::CATALEJO_OUTCOME_ERROR => Err(outcome.byte_count),
#[cfg(not(feature = "stealth-mode"))]
_ => unreachable!(),
#[cfg(feature = "stealth-mode")]
_ => std::process::abort(),
}
}