use super::{
ElfClass,
raw::{
Elf32Sym, ElfDynRaw, ElfEhdrRaw, ElfPhdrRaw, ElfRelRaw, ElfRelaRaw, ElfShdrRaw, ElfSymRaw,
ElfWord,
},
};
use core::fmt::{self, Display};
use elf::abi::{ELFDATA2LSB, ELFDATA2MSB, ELFDATANONE};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct ElfDataEncoding(u8);
impl ElfDataEncoding {
pub const NONE: Self = Self(ELFDATANONE);
pub const LSB: Self = Self(ELFDATA2LSB);
pub const MSB: Self = Self(ELFDATA2MSB);
#[inline]
pub const fn new(raw: u8) -> Self {
Self(raw)
}
#[inline]
pub const fn raw(self) -> u8 {
self.0
}
}
impl From<u8> for ElfDataEncoding {
#[inline]
fn from(value: u8) -> Self {
Self::new(value)
}
}
impl From<ElfDataEncoding> for u8 {
#[inline]
fn from(value: ElfDataEncoding) -> Self {
value.raw()
}
}
impl Display for ElfDataEncoding {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.0 {
ELFDATANONE => f.write_str("ELFDATANONE"),
ELFDATA2LSB => f.write_str("ELFDATA2LSB"),
ELFDATA2MSB => f.write_str("ELFDATA2MSB"),
raw => write!(f, "unknown ELF data encoding {raw}"),
}
}
}
pub trait ElfLayout: 'static {
const CLASS: ElfClass;
const DATA_ENCODING: ElfDataEncoding = if cfg!(target_endian = "little") {
ElfDataEncoding::LSB
} else {
ElfDataEncoding::MSB
};
const REL_MASK: usize;
const REL_BIT: usize;
const EHDR_SIZE: usize;
type Phdr: ElfPhdrRaw;
type Shdr: ElfShdrRaw;
type Dyn: ElfDynRaw;
type Ehdr: ElfEhdrRaw;
type Rela: ElfRelaRaw;
type Rel: ElfRelRaw;
type Relr: ElfWord;
type Word: ElfWord;
type Sym: ElfSymRaw;
}
#[derive(Debug, Clone, Copy)]
pub struct Elf32Layout;
impl ElfLayout for Elf32Layout {
const CLASS: ElfClass = ElfClass::ELF32;
const REL_MASK: usize = 0xFF;
const REL_BIT: usize = 8;
const EHDR_SIZE: usize = core::mem::size_of::<Self::Ehdr>();
type Phdr = elf::segment::Elf32_Phdr;
type Shdr = elf::section::Elf32_Shdr;
type Dyn = elf::dynamic::Elf32_Dyn;
type Ehdr = elf::file::Elf32_Ehdr;
type Rela = elf::relocation::Elf32_Rela;
type Rel = elf::relocation::Elf32_Rel;
type Relr = u32;
type Word = u32;
type Sym = Elf32Sym;
}
#[derive(Debug, Clone, Copy)]
pub struct Elf64Layout;
impl ElfLayout for Elf64Layout {
const CLASS: ElfClass = ElfClass::ELF64;
const REL_MASK: usize = 0xFFFFFFFF;
const REL_BIT: usize = 32;
const EHDR_SIZE: usize = core::mem::size_of::<Self::Ehdr>();
type Phdr = elf::segment::Elf64_Phdr;
type Shdr = elf::section::Elf64_Shdr;
type Dyn = elf::dynamic::Elf64_Dyn;
type Ehdr = elf::file::Elf64_Ehdr;
type Rela = elf::relocation::Elf64_Rela;
type Rel = elf::relocation::Elf64_Rel;
type Relr = u64;
type Word = u64;
type Sym = elf::symbol::Elf64_Sym;
}
#[cfg(target_pointer_width = "64")]
pub type NativeElfLayout = Elf64Layout;
#[cfg(not(target_pointer_width = "64"))]
pub type NativeElfLayout = Elf32Layout;
pub(crate) type ElfEhdr = <NativeElfLayout as ElfLayout>::Ehdr;