use crate::elf::ElfMachine;
use elf::abi::{
ELFCLASS32, ELFCLASS64, ELFDATA2LSB, ELFDATA2MSB, EM_386, EM_AARCH64, EM_ARM, EM_LOONGARCH,
EM_RISCV, EM_X86_64,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum ArchKind {
X86_64,
AArch64,
RiscV64,
RiscV32,
LoongArch64,
X86,
Arm,
}
impl ArchKind {
#[inline]
pub const fn native() -> Self {
<NativeArch as crate::relocation::RelocationArch>::KIND
}
#[inline]
pub fn is_native(self) -> bool {
self == Self::native()
}
#[inline]
pub const fn e_machine(self) -> ElfMachine {
match self {
Self::X86_64 => ElfMachine::new(EM_X86_64),
Self::AArch64 => ElfMachine::new(EM_AARCH64),
Self::RiscV64 | Self::RiscV32 => ElfMachine::new(EM_RISCV),
Self::LoongArch64 => ElfMachine::new(EM_LOONGARCH),
Self::X86 => ElfMachine::new(EM_386),
Self::Arm => ElfMachine::new(EM_ARM),
}
}
#[inline]
pub const fn from_e_machine(machine: ElfMachine, class: u8) -> Option<Self> {
match (machine.raw(), class) {
(EM_X86_64, ELFCLASS64) => Some(Self::X86_64),
(EM_AARCH64, ELFCLASS64) => Some(Self::AArch64),
(EM_RISCV, ELFCLASS64) => Some(Self::RiscV64),
(EM_RISCV, ELFCLASS32) => Some(Self::RiscV32),
(EM_LOONGARCH, ELFCLASS64) => Some(Self::LoongArch64),
(EM_386, ELFCLASS32) => Some(Self::X86),
(EM_ARM, ELFCLASS32) => Some(Self::Arm),
_ => None,
}
}
pub fn from_elf_bytes(bytes: &[u8]) -> Option<Self> {
if bytes.len() < 20 || !bytes.starts_with(b"\x7fELF") {
return None;
}
let class = bytes[4];
let machine = match bytes[5] {
ELFDATA2LSB => u16::from_le_bytes([bytes[18], bytes[19]]),
ELFDATA2MSB => u16::from_be_bytes([bytes[18], bytes[19]]),
_ => return None,
};
Self::from_e_machine(ElfMachine::new(machine), class)
}
}
impl core::fmt::Display for ArchKind {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::X86_64 => f.write_str("x86_64"),
Self::AArch64 => f.write_str("aarch64"),
Self::RiscV64 => f.write_str("riscv64"),
Self::RiscV32 => f.write_str("riscv32"),
Self::LoongArch64 => f.write_str("loongarch64"),
Self::X86 => f.write_str("x86"),
Self::Arm => f.write_str("arm"),
}
}
}
pub mod aarch64;
pub mod arm;
pub mod loongarch64;
pub(crate) mod riscv;
pub mod riscv32;
pub mod riscv64;
pub mod x86;
pub mod x86_64;
cfg_if::cfg_if! {
if #[cfg(target_arch = "x86_64")]{
pub use x86_64::*;
pub use x86_64::relocation::X86_64Arch as NativeArch;
}else if #[cfg(target_arch = "riscv64")]{
pub use riscv64::*;
pub use riscv64::relocation::RiscV64Arch as NativeArch;
}else if #[cfg(target_arch = "riscv32")]{
pub use riscv32::*;
pub use riscv32::relocation::RiscV32Arch as NativeArch;
}else if #[cfg(target_arch="aarch64")]{
pub use aarch64::*;
pub use aarch64::relocation::AArch64Arch as NativeArch;
}else if #[cfg(target_arch="loongarch64")]{
pub use loongarch64::*;
pub use loongarch64::relocation::LoongArch64Arch as NativeArch;
}else if #[cfg(target_arch = "x86")]{
pub use x86::*;
pub use x86::relocation::X86Arch as NativeArch;
}else if #[cfg(target_arch = "arm")]{
pub use arm::*;
pub use arm::relocation::ArmArch as NativeArch;
}
}
#[cfg(feature = "object")]
pub(crate) mod object;