extern crate num_traits;
use super::utils::*;
use super::*;
use num_traits::*;
pub trait ElfHeaderAccessTrait {
ELFIO_GET_ACCESS_DECL!(u8, class);
ELFIO_GET_ACCESS_DECL!(u8, elf_version);
ELFIO_GET_ACCESS_DECL!(u8, encoding);
ELFIO_GET_ACCESS_DECL!(ElfHalf, header_size);
ELFIO_GET_ACCESS_DECL!(ElfHalf, section_entry_size);
ELFIO_GET_ACCESS_DECL!(ElfHalf, segment_entry_size);
ELFIO_GET_SET_ACCESS_DECL!(ElfWord, version);
ELFIO_GET_SET_ACCESS_DECL!(u8, os_abi);
ELFIO_GET_SET_ACCESS_DECL!(u8, abi_version);
ELFIO_GET_SET_ACCESS_DECL!(ElfHalf, type);
ELFIO_GET_SET_ACCESS_DECL!(ElfHalf, machine);
ELFIO_GET_SET_ACCESS_DECL!(ElfWord, flags);
ELFIO_GET_SET_ACCESS_DECL!(Elf64Addr, entry);
ELFIO_GET_SET_ACCESS_DECL!(ElfHalf, sections_num);
ELFIO_GET_SET_ACCESS_DECL!(Elf64Off, sections_offset);
ELFIO_GET_SET_ACCESS_DECL!(ElfHalf, segments_num);
ELFIO_GET_SET_ACCESS_DECL!(Elf64Off, segments_offset);
ELFIO_GET_SET_ACCESS_DECL!(ElfHalf, section_name_str_index);
fn set_converter(&mut self, converter: &Converter);
}
pub trait ElfHeaderTrait: ElfHeaderAccessTrait + Load {}
#[repr(C)]
#[derive(Debug)]
pub struct ElfHeader<Addr, Offset> {
e_ident: [u8; constant::EI_NIDENT],
e_type: ElfHalf,
e_machine: ElfHalf,
e_version: ElfWord,
e_entry: Addr,
e_phoff: Offset,
e_shoff: Offset,
e_flags: ElfWord,
e_ehsize: ElfHalf,
e_phentsize: ElfHalf,
e_phnum: ElfHalf,
e_shentsize: ElfHalf,
e_shnum: ElfHalf,
e_shstrndx: ElfHalf,
converter: Converter,
}
impl<Addr, Offset> ElfHeader<Addr, Offset>
where
Addr: Zero + Load + AsPrimitive<u64>,
Offset: Zero + Load + AsPrimitive<u64>,
Converter: Convert<Addr> + Convert<Offset>,
{
pub fn new() -> ElfHeader<Addr, Offset> {
ElfHeader::<Addr, Offset> {
converter: Converter { is_needed: false },
e_ident: [
constant::ELFMAG0,
constant::ELFMAG1,
constant::ELFMAG2,
constant::ELFMAG3,
constant::ELFCLASSNONE,
constant::ELFDATANONE,
constant::EV_NONE,
0,
0,
0,
0,
0,
0,
0,
0,
0,
],
e_type: 0,
e_machine: 0,
e_version: 0,
e_entry: Addr::zero(),
e_phoff: Offset::zero(),
e_shoff: Offset::zero(),
e_flags: 0,
e_ehsize: 0,
e_phentsize: 0,
e_phnum: 0,
e_shentsize: 0,
e_shnum: 0,
e_shstrndx: 0,
}
}
}
impl<Addr, Offset> ElfHeaderTrait for ElfHeader<Addr, Offset>
where
u32: AsPrimitive<Addr> + AsPrimitive<Offset>,
u64: AsPrimitive<Addr> + AsPrimitive<Offset>,
Addr: Zero + Load + AsPrimitive<u64>,
Offset: Zero + Load + AsPrimitive<u64>,
Converter: Convert<Addr> + Convert<Offset>,
{
}
impl<Addr, Offset> ElfHeaderAccessTrait for ElfHeader<Addr, Offset>
where
u32: AsPrimitive<Addr> + AsPrimitive<Offset>,
u64: AsPrimitive<Addr> + AsPrimitive<Offset>,
Addr: Zero + Load + AsPrimitive<u64>,
Offset: Zero + Load + AsPrimitive<u64>,
Converter: Convert<Addr> + Convert<Offset>,
{
ELFIO_GET_ACCESS!(u8, class, e_ident[constant::EI_CLASS]);
ELFIO_GET_ACCESS!(u8, elf_version, e_ident[constant::EI_VERSION]);
ELFIO_GET_ACCESS!(u8, encoding, e_ident[constant::EI_DATA]);
ELFIO_GET_ACCESS!(ElfHalf, header_size, e_ehsize);
ELFIO_GET_ACCESS!(ElfHalf, section_entry_size, e_shentsize);
ELFIO_GET_ACCESS!(ElfHalf, segment_entry_size, e_phentsize);
ELFIO_GET_SET_ACCESS!(ElfWord, version, e_version);
ELFIO_GET_SET_ACCESS!(u8, os_abi, e_ident[constant::EI_OSABI]);
ELFIO_GET_SET_ACCESS!(u8, abi_version, e_ident[constant::EI_ABIVERSION]);
ELFIO_GET_SET_ACCESS!(ElfHalf, type, e_type);
ELFIO_GET_SET_ACCESS!(ElfHalf, machine, e_machine);
ELFIO_GET_SET_ACCESS!(ElfWord, flags, e_flags);
ELFIO_GET_SET_ACCESS!(ElfHalf, section_name_str_index, e_shstrndx);
ELFIO_GET_SET_ACCESS!(Elf64Addr, entry, e_entry);
ELFIO_GET_SET_ACCESS!(ElfHalf, sections_num, e_shnum);
ELFIO_GET_SET_ACCESS!(Elf64Off, sections_offset, e_shoff);
ELFIO_GET_SET_ACCESS!(ElfHalf, segments_num, e_phnum);
ELFIO_GET_SET_ACCESS!(Elf64Off, segments_offset, e_phoff);
fn set_converter(&mut self, converter: &Converter) {
self.converter = *converter;
}
}
impl<Addr, Offset> Load for ElfHeader<Addr, Offset>
where
Addr: Zero + Load + AsPrimitive<u64>,
Offset: Zero + Load + AsPrimitive<u64>,
Converter: Convert<Addr> + Convert<Offset>,
{
fn load(&mut self, reader: &mut (dyn ElfioReadSeek)) -> io::Result<()> {
(&mut self.e_ident).load(reader)?;
self.e_type.load(reader)?;
self.e_machine.load(reader)?;
self.e_version.load(reader)?;
self.e_entry.load(reader)?;
self.e_phoff.load(reader)?;
self.e_shoff.load(reader)?;
self.e_flags.load(reader)?;
self.e_ehsize.load(reader)?;
self.e_phentsize.load(reader)?;
self.e_phnum.load(reader)?;
self.e_shentsize.load(reader)?;
self.e_shnum.load(reader)?;
self.e_shstrndx.load(reader)?;
Ok(())
}
}