use crate::context::*;
use crate::context::{PropU16, PropU32};
use crate::ident::*;
use crate::utils::*;
use crate::{Class, Data, Version};
#[derive(Debug, Clone)]
pub enum ParseElfError {
FromIdent(ParseIdentError),
FromVariant(ParseVariantError),
}
#[derive(Debug, Clone)]
pub enum ParseVariantError {
BrokenHeader,
BadPropertyType,
BadPropertyEhsize,
}
#[derive(Debug, Clone, Copy)]
pub enum Elf<'a> {
Little32(Variant<'a, Little32>),
Little64(Variant<'a, Little64>),
Big32(Variant<'a, Big32>),
Big64(Variant<'a, Big64>),
}
impl<'a> Elf<'a> {
pub fn parse(data: &'a [u8]) -> Result<Self, ParseElfError> {
use {Class::*, Data::*, ParseElfError::*, Version::*};
let ident = Ident::parse(data).map_err(FromIdent)?;
let elf = match (ident.class(), ident.data(), ident.version()) {
(Class32, Little, One) => {
Elf::Little32(Variant::<Little32>::parse(data).map_err(FromVariant)?)
}
(Class32, Big, One) => Elf::Big32(Variant::<Big32>::parse(data).map_err(FromVariant)?),
(Class64, Little, One) => {
Elf::Little64(Variant::<Little64>::parse(data).map_err(FromVariant)?)
}
(Class64, Big, One) => Elf::Big64(Variant::<Big64>::parse(data).map_err(FromVariant)?),
};
Ok(elf)
}
}
#[derive(Debug, Clone, Copy)]
pub struct Variant<'a, T: Context> {
data: &'a [u8],
header: &'a ElfHeader<T>,
}
impl<'a, T: Context> Variant<'a, T> {
pub fn parse(data: &'a [u8]) -> Result<Self, ParseVariantError> {
use ParseVariantError::*;
let eheader: &ElfHeader<T> = read(data, 0).ok_or(BrokenHeader)?;
let _type = eheader.checked_type().ok_or(BadPropertyType)?;
if core::mem::size_of::<ElfHeader<T>>() != eheader.ehsize() as usize {
return Err(BadPropertyEhsize);
}
Ok(Variant {
data,
header: eheader,
})
}
pub fn data(&self) -> &'a [u8] {
self.data
}
pub fn header(&self) -> &'a ElfHeader<T> {
self.header
}
}
#[repr(C)]
#[derive(Debug, Clone)]
pub struct ElfHeader<T: Context> {
pub ident: Ident,
pub typa: PropU16,
pub machine: PropU16,
pub version: PropU32,
pub entry: T::PropUsize,
pub phoff: T::PropUsize,
pub shoff: T::PropUsize,
pub flags: PropU32,
pub ehsize: PropU16,
pub phentsize: PropU16,
pub phnum: PropU16,
pub shentsize: PropU16,
pub shnum: PropU16,
pub shstrndx: PropU16,
}
impl<T: Context> ElfHeader<T> {
pub fn ident(&self) -> &Ident {
&self.ident
}
pub fn checked_type(&self) -> Option<ElfType> {
ElfType::try_from(T::interpret(self.typa)).ok()
}
pub fn typa(&self) -> ElfType {
self.checked_type().unwrap()
}
pub fn machine(&self) -> u16 {
T::interpret(self.machine)
}
pub fn version(&self) -> u32 {
T::interpret(self.version)
}
pub fn entry(&self) -> T::Integer {
T::interpret(self.entry)
}
pub fn phoff(&self) -> T::Integer {
T::interpret(self.phoff)
}
pub fn shoff(&self) -> T::Integer {
T::interpret(self.shoff)
}
pub fn flags(&self) -> u32 {
T::interpret(self.flags)
}
pub fn ehsize(&self) -> u16 {
T::interpret(self.ehsize)
}
pub fn phentsize(&self) -> u16 {
T::interpret(self.phentsize)
}
pub fn phnum(&self) -> u16 {
T::interpret(self.phnum)
}
pub fn shentsize(&self) -> u16 {
T::interpret(self.shentsize)
}
pub fn shnum(&self) -> u16 {
T::interpret(self.shnum)
}
pub fn shstrndx(&self) -> u16 {
T::interpret(self.shstrndx)
}
}
unsafe impl<T: Context> Pod for ElfHeader<T> {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ElfType {
None,
Rel,
Exec,
Dyn,
Core,
OsSpecific(u16),
ProcessorSpecific(u16),
}
impl TryFrom<u16> for ElfType {
type Error = ();
fn try_from(value: u16) -> Result<Self, Self::Error> {
use ElfType::*;
match value {
0x00 => Ok(None),
0x01 => Ok(Rel),
0x02 => Ok(Exec),
0x03 => Ok(Dyn),
0x04 => Ok(Core),
x @ 0xFE00..=0xFEFF => Ok(OsSpecific(x)),
x @ 0xFF00..=0xFFFF => Ok(ProcessorSpecific(x)),
_ => Err(()),
}
}
}
impl From<ElfType> for u16 {
fn from(value: ElfType) -> Self {
use ElfType::*;
match value {
None => 0x00,
Rel => 0x01,
Exec => 0x02,
Dyn => 0x03,
Core => 0x04,
OsSpecific(x) => x,
ProcessorSpecific(x) => x,
}
}
}
pub const ELF_MACHINE_NONE: u16 = 0x00;
pub const ELF_MACHINE_M32: u16 = 0x01;
pub const ELF_MACHINE_SPARC: u16 = 0x02;
pub const ELF_MACHINE_X86: u16 = 0x03;
pub const ELF_MACHINE_68K: u16 = 0x04;
pub const ELF_MACHINE_88K: u16 = 0x05;
pub const ELF_MACHINE_IAMCU: u16 = 0x06;
pub const ELF_MACHINE_860: u16 = 0x07;
pub const ELF_MACHINE_MIPS: u16 = 0x08;
pub const ELF_MACHINE_S370: u16 = 0x09;
pub const ELF_MACHINE_MIPS_RS3_LE: u16 = 0x0A;
pub const ELF_MACHINE_PARISC: u16 = 0x0F;
pub const ELF_MACHINE_VPP500: u16 = 0x11;
pub const ELF_MACHINE_SPARC32PLUS: u16 = 0x12;
pub const ELF_MACHINE_960: u16 = 0x13;
pub const ELF_MACHINE_PPC: u16 = 0x14;
pub const ELF_MACHINE_PPC64: u16 = 0x15;
pub const ELF_MACHINE_S390: u16 = 0x16;
pub const ELF_MACHINE_SPU: u16 = 0x17;
pub const ELF_MACHINE_V800: u16 = 36;
pub const ELF_MACHINE_FR20: u16 = 37;
pub const ELF_MACHINE_RH32: u16 = 38;
pub const ELF_MACHINE_RCE: u16 = 39;
pub const ELF_MACHINE_ARM: u16 = 40;
pub const ELF_MACHINE_ALPHA: u16 = 41;
pub const ELF_MACHINE_SH: u16 = 42;
pub const ELF_MACHINE_SPARCV9: u16 = 43;
pub const ELF_MACHINE_TRICORE: u16 = 44;
pub const ELF_MACHINE_ARC: u16 = 45;
pub const ELF_MACHINE_H8_300: u16 = 46;
pub const ELF_MACHINE_H8_300H: u16 = 47;
pub const ELF_MACHINE_H8S: u16 = 48;
pub const ELF_MACHINE_H8_500: u16 = 49;
pub const ELF_MACHINE_IA_64: u16 = 50;
pub const ELF_MACHINE_MIPS_X: u16 = 51;
pub const ELF_MACHINE_COLDFIRE: u16 = 52;
pub const ELF_MACHINE_68HC12: u16 = 53;
pub const ELF_MACHINE_MMA: u16 = 54;
pub const ELF_MACHINE_PCP: u16 = 55;
pub const ELF_MACHINE_NCPU: u16 = 56;
pub const ELF_MACHINE_NDR1: u16 = 57;
pub const ELF_MACHINE_STARCORE: u16 = 58;
pub const ELF_MACHINE_ME16: u16 = 59;
pub const ELF_MACHINE_ST100: u16 = 60;
pub const ELF_MACHINE_TINYJ: u16 = 61;
pub const ELF_MACHINE_X86_64: u16 = 62;
pub const ELF_MACHINE_PDSP: u16 = 63;
pub const ELF_MACHINE_PDP10: u16 = 64;
pub const ELF_MACHINE_PDP11: u16 = 65;
pub const ELF_MACHINE_FX66: u16 = 66;
pub const ELF_MACHINE_ST9PLUS: u16 = 67;
pub const ELF_MACHINE_ST7: u16 = 68;
pub const ELF_MACHINE_68HC16: u16 = 69;
pub const ELF_MACHINE_68HC11: u16 = 70;
pub const ELF_MACHINE_68HC08: u16 = 71;
pub const ELF_MACHINE_68HC05: u16 = 72;
pub const ELF_MACHINE_SVX: u16 = 73;
pub const ELF_MACHINE_ST19: u16 = 74;
pub const ELF_MACHINE_VAX: u16 = 75;
pub const ELF_MACHINE_CRIS: u16 = 76;
pub const ELF_MACHINE_JAVELIN: u16 = 77;
pub const ELF_MACHINE_FIREPATH: u16 = 78;
pub const ELF_MACHINE_ZSP: u16 = 79;
pub const ELF_MACHINE_MMIX: u16 = 80;
pub const ELF_MACHINE_HUANY: u16 = 81;
pub const ELF_MACHINE_PRISM: u16 = 82;
pub const ELF_MACHINE_AVR: u16 = 83;
pub const ELF_MACHINE_FR30: u16 = 84;
pub const ELF_MACHINE_D10V: u16 = 85;
pub const ELF_MACHINE_D30V: u16 = 86;
pub const ELF_MACHINE_V850: u16 = 87;
pub const ELF_MACHINE_M32R: u16 = 88;
pub const ELF_MACHINE_MN10300: u16 = 89;
pub const ELF_MACHINE_MN10200: u16 = 90;
pub const ELF_MACHINE_PJ: u16 = 91;
pub const ELF_MACHINE_OPENRISC: u16 = 92;
pub const ELF_MACHINE_ARC_COMPACT: u16 = 93;
pub const ELF_MACHINE_XTENSA: u16 = 94;
pub const ELF_MACHINE_VIDEOCORE: u16 = 95;
pub const ELF_MACHINE_TMM_GPP: u16 = 96;
pub const ELF_MACHINE_NS32K: u16 = 97;
pub const ELF_MACHINE_TPC: u16 = 98;
pub const ELF_MACHINE_SNP1K: u16 = 99;
pub const ELF_MACHINE_ST200: u16 = 100;
pub const ELF_MACHINE_IP2K: u16 = 101;
pub const ELF_MACHINE_MAX: u16 = 102;
pub const ELF_MACHINE_CR: u16 = 103;
pub const ELF_MACHINE_F2MC16: u16 = 104;
pub const ELF_MACHINE_MSP430: u16 = 105;
pub const ELF_MACHINE_BLACKFIN: u16 = 106;
pub const ELF_MACHINE_SE_C33: u16 = 107;
pub const ELF_MACHINE_SEP: u16 = 108;
pub const ELF_MACHINE_ARCA: u16 = 109;
pub const ELF_MACHINE_UNICORE: u16 = 110;
pub const ELF_MACHINE_EXCESS: u16 = 111;
pub const ELF_MACHINE_DXP: u16 = 112;
pub const ELF_MACHINE_ALTERA_NIOS2: u16 = 113;
pub const ELF_MACHINE_CRX: u16 = 114;
pub const ELF_MACHINE_XGATE: u16 = 115;
pub const ELF_MACHINE_C166: u16 = 116;
pub const ELF_MACHINE_M16C: u16 = 117;
pub const ELF_MACHINE_DSPIC30F: u16 = 118;
pub const ELF_MACHINE_CE: u16 = 119;
pub const ELF_MACHINE_M32C: u16 = 120;
pub const ELF_MACHINE_TSK3000: u16 = 131;
pub const ELF_MACHINE_RS08: u16 = 132;
pub const ELF_MACHINE_SHARC: u16 = 133;
pub const ELF_MACHINE_ECOG2: u16 = 134;
pub const ELF_MACHINE_SCORE7: u16 = 135;
pub const ELF_MACHINE_DSP24: u16 = 136;
pub const ELF_MACHINE_VIDEOCORE3: u16 = 137;
pub const ELF_MACHINE_LATTICEMICO32: u16 = 138;
pub const ELF_MACHINE_SE_C17: u16 = 139;
pub const ELF_MACHINE_TI_C6000: u16 = 140;
pub const ELF_MACHINE_TI_C2000: u16 = 141;
pub const ELF_MACHINE_TI_C5500: u16 = 142;
pub const ELF_MACHINE_TI_ARP32: u16 = 143;
pub const ELF_MACHINE_TI_PRU: u16 = 144;
pub const ELF_MACHINE_MMDSP_PLUS: u16 = 160;
pub const ELF_MACHINE_CYPRESS_M8C: u16 = 161;
pub const ELF_MACHINE_R32C: u16 = 162;
pub const ELF_MACHINE_TRIMEDIA: u16 = 163;
pub const ELF_MACHINE_QDSP6: u16 = 164;
pub const ELF_MACHINE_8051: u16 = 165;
pub const ELF_MACHINE_STXP7X: u16 = 166;
pub const ELF_MACHINE_NDS32: u16 = 167;
pub const ELF_MACHINE_ECOG1X: u16 = 168;
pub const ELF_MACHINE_MAXQ30: u16 = 169;
pub const ELF_MACHINE_XIMO16: u16 = 170;
pub const ELF_MACHINE_MANIK: u16 = 171;
pub const ELF_MACHINE_CRAYNV2: u16 = 172;
pub const ELF_MACHINE_RX: u16 = 173;
pub const ELF_MACHINE_METAG: u16 = 174;
pub const ELF_MACHINE_MCST_ELBRUS: u16 = 175;
pub const ELF_MACHINE_ECOG16: u16 = 176;
pub const ELF_MACHINE_CR16: u16 = 177;
pub const ELF_MACHINE_ETPU: u16 = 178;
pub const ELF_MACHINE_SLE9X: u16 = 179;
pub const ELF_MACHINE_L10M: u16 = 180;
pub const ELF_MACHINE_K10M: u16 = 181;
pub const ELF_MACHINE_AARCH64: u16 = 183;
pub const ELF_MACHINE_AVR32: u16 = 185;
pub const ELF_MACHINE_STM8: u16 = 186;
pub const ELF_MACHINE_TILE64: u16 = 187;
pub const ELF_MACHINE_TILEPRO: u16 = 188;
pub const ELF_MACHINE_MICROBLAZE: u16 = 189;
pub const ELF_MACHINE_CUDA: u16 = 190;
pub const ELF_MACHINE_TILEGX: u16 = 191;
pub const ELF_MACHINE_CLOUDSHIELD: u16 = 192;
pub const ELF_MACHINE_COREA_1ST: u16 = 193;
pub const ELF_MACHINE_COREA_2ND: u16 = 194;
pub const ELF_MACHINE_ARC_COMPACT2: u16 = 195;
pub const ELF_MACHINE_OPEN8: u16 = 196;
pub const ELF_MACHINE_RL78: u16 = 197;
pub const ELF_MACHINE_VIDEOCORE5: u16 = 198;
pub const ELF_MACHINE_78KOR: u16 = 199;
pub const ELF_MACHINE_56800EX: u16 = 200;
pub const ELF_MACHINE_BA1: u16 = 201;
pub const ELF_MACHINE_BA2: u16 = 202;
pub const ELF_MACHINE_XCORE: u16 = 203;
pub const ELF_MACHINE_MCHP_PIC: u16 = 204;
pub const ELF_MACHINE_KM32: u16 = 210;
pub const ELF_MACHINE_KMX32: u16 = 211;
pub const ELF_MACHINE_KMX16: u16 = 212;
pub const ELF_MACHINE_KMX8: u16 = 213;
pub const ELF_MACHINE_KVARC: u16 = 214;
pub const ELF_MACHINE_CDP: u16 = 215;
pub const ELF_MACHINE_COGE: u16 = 216;
pub const ELF_MACHINE_COOL: u16 = 217;
pub const ELF_MACHINE_NORC: u16 = 218;
pub const ELF_MACHINE_CSR_KALIMBA: u16 = 219;
pub const ELF_MACHINE_Z80: u16 = 220;
pub const ELF_MACHINE_VISIUM: u16 = 221;
pub const ELF_MACHINE_FT32: u16 = 222;
pub const ELF_MACHINE_MOXIE: u16 = 223;
pub const ELF_MACHINE_AMDGPU: u16 = 224;
pub const ELF_MACHINE_RISCV: u16 = 243;