use super::super::nom::{IResult, ErrorKind, le_u8};
use super::super::{Fault, nom_bullshit};
use super::abi::{ElfAbi, Abi, parse_elf_abi};
use super::endian::{ElfEndian, Endian, parse_elf_endian};
use super::class::{ElfClass, Class, parse_elf_class};
use super::traits::{ElfMagicNumber};
#[derive(Copy,Clone,Debug,Hash)]
pub struct ElfMagicNumbers {
class: ElfClass,
endian: ElfEndian,
abi: ElfAbi,
abi_version: u8,
}
impl Abi for ElfMagicNumbers {
#[inline(always)]
fn get_abi(&self) -> ElfAbi {
self.abi.clone()
}
}
impl Endian for ElfMagicNumbers {
#[inline(always)]
fn get_endian(&self) -> ElfEndian {
self.endian.clone()
}
}
impl Class for ElfMagicNumbers {
#[inline(always)]
fn get_class(&self) -> ElfClass {
self.class.clone()
}
}
impl ElfMagicNumber for ElfMagicNumbers {
#[inline(always)]
fn get_abi_version(&self) -> u8 {
self.abi_version.clone()
}
}
named!(check_magic<&[u8],&[u8],u32>,
add_return_error!(ErrorKind::Custom(1u32),
tag!(b"\x7F\x45\x4C\x46")
));
named!(pub parse_elf_magic<&[u8],ElfMagicNumbers,u32>, do_parse!(
check_magic >>
class: parse_elf_class >>
endian: parse_elf_endian >>
take!(1) >>
abi: parse_elf_abi >>
abi_version: le_u8 >>
take!(7) >>
( ElfMagicNumbers{
class, endian, abi, abi_version
})
));
#[test]
fn test_check_magic() {
let dut0 = b"\x7F\x45\x4C\x46\xDE\xAD\xBE\xEF";
let (rem,var) = match check_magic(dut0) {
IResult::Done(x,y) => (x,y),
IResult::Incomplete(n) => panic!("check magic failed {:?}",n),
IResult::Error(e) => panic!("check magic failed {:?}",e)
};
assert_eq!(rem.len(), 4);
assert_eq!(rem, b"\xDE\xAD\xBE\xEF");
assert_eq!(var.len(), 4);
assert_eq!(var, b"\x7F\x45\x4C\x46");
let dut1 = b"\x00\x45\x4C\x46\xDE\xAD\xBE\xEF";
match check_magic(dut1) {
IResult::Done(_,_) => panic!("check magic should fail"),
IResult::Incomplete(n) => panic!("check magic wrong error {:?}",n),
IResult::Error(e) => {
match nom_bullshit(e) {
ErrorKind::Custom(1u32) => { }
ErrorKind::Custom(x) => panic!("check magic wrong error code {:?}", x),
e => panic!("check magic wrong error code {:?}", e)
}
}
};
}
#[test]
fn test_parse_elf_magic() {
let dut0: &[u8] = b"\x7F\x45\x4C\x46\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
let (rem, magic) = match parse_elf_magic(dut0) {
IResult::Done(x,m) => (x,m),
IResult::Incomplete(n) => panic!("check_version failed {:?}",n),
IResult::Error(e) => panic!("check_version failed {:?}",e)
};
assert_eq!(rem.len(), 1);
assert_eq!(rem[0],0);
assert_eq!(magic.get_abi(), ElfAbi::SystemV);
assert_eq!(magic.get_endian(), ElfEndian::Little);
assert_eq!(magic.get_class(), ElfClass::Bits64);
assert_eq!(magic.get_abi_version(), 0);
}