pub mod arm;
pub mod x86;
use crate::types::size;
#[repr(u8)]
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize))]
#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
pub enum Endianess {
LittleEndian,
BigEndian,
}
pub trait Architecture: Send + Sync + 'static {
fn bits(&self) -> u8;
fn endianess(&self) -> Endianess;
fn page_size(&self) -> usize;
fn size_addr(&self) -> usize;
fn address_space_bits(&self) -> u8;
fn ident(&self) -> ArchitectureIdent;
}
impl std::fmt::Debug for ArchitectureObj {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ArchitectureObj")
.field("bits", &self.bits())
.field("endianess", &self.endianess())
.field("page_size", &self.page_size())
.field("size_addr", &self.size_addr())
.field("address_space_bits", &self.address_space_bits())
.finish()
}
}
pub type ArchitectureObj = &'static dyn Architecture;
impl std::cmp::PartialEq<ArchitectureObj> for ArchitectureObj {
#[allow(clippy::vtable_address_comparisons)]
fn eq(&self, other: &ArchitectureObj) -> bool {
std::ptr::eq(*self, *other)
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "serde", derive(::serde::Serialize, ::serde::Deserialize))]
#[cfg_attr(feature = "abi_stable", derive(::abi_stable::StableAbi))]
pub enum ArchitectureIdent {
Unknown(usize),
X86(u8, bool),
AArch64(usize),
}
impl std::fmt::Display for ArchitectureIdent {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ArchitectureIdent::X86(32, false) => f.pad("x86_32"),
ArchitectureIdent::X86(32, true) => f.pad("x86_32 PAE"),
ArchitectureIdent::X86(64, false) => f.pad("x86_64"),
ArchitectureIdent::X86(64, true) => f.pad("x86_64 LA57"),
ArchitectureIdent::X86(_, _) => f.pad("x86"),
ArchitectureIdent::AArch64(_) => f.pad("AArch64"),
ArchitectureIdent::Unknown(id) => f.debug_tuple("Unknown").field(&id).finish(),
}
}
}
impl ArchitectureIdent {
pub fn into_obj(self) -> ArchitectureObj {
self.into()
}
}
impl From<ArchitectureIdent> for ArchitectureObj {
fn from(arch: ArchitectureIdent) -> ArchitectureObj {
const KB4: usize = size::kb(4);
match arch {
ArchitectureIdent::X86(32, false) => x86::x32::ARCH,
ArchitectureIdent::X86(32, true) => x86::x32_pae::ARCH,
ArchitectureIdent::X86(64, false) => x86::x64::ARCH,
ArchitectureIdent::AArch64(KB4) => arm::aarch64::ARCH,
_ => panic!("unsupported architecture! {:?}", arch),
}
}
}
#[cfg(feature = "serde")]
impl serde::Serialize for ArchitectureObj {
fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeStruct;
let mut state = serializer.serialize_struct("ArchitectureObj", 5)?;
state.serialize_field("bits", &self.bits())?;
state.serialize_field("endianess", &self.endianess())?;
state.serialize_field("page_size", &self.page_size())?;
state.serialize_field("size_addr", &self.size_addr())?;
state.serialize_field("address_space_bits", &self.address_space_bits())?;
state.end()
}
}