<commit_before>include!("constants_header.rs");

use error::{self};
use scroll::{self, ctx, Endian};
use core::fmt;
use container::{Ctx, Container};

#[derive(Clone, PartialEq)]
pub struct ElfHeader {
    pub e_ident           : [u8; SIZEOF_IDENT],
    pub e_type            : u16,
    pub e_machine         : u16,
    pub e_version         : u32,
    pub e_entry           : u64,
    pub e_phoff           : u64,
    pub e_shoff           : u64,
    pub e_flags           : u32,
    pub e_ehsize          : u16,
    pub e_phentsize       : u16,
    pub e_phnum           : u16,
    pub e_shentsize       : u16,
    pub e_shnum           : u16,
    pub e_shstrndx        : u16,
}

impl ElfHeader {
    pub fn container(&self) -> error::Result<Container> {
        use error::Error;
        match self.e_ident[EI_CLASS] {
            ELFCLASS32 => { Ok(Container::Little) },
            ELFCLASS64 => { Ok(Container::Big) },
            class => Err(Error::Malformed(format!("Invalid class in ElfHeader: {}", class)))
        }
    }
    pub fn endianness(&self) -> error::Result<scroll::Endian> {
        use error::Error;
        match self.e_ident[EI_DATA] {
            ELFDATA2LSB => { Ok(scroll::LE) },
            ELFDATA2MSB => { Ok(scroll::BE) },
            class => Err(Error::Malformed(format!("Invalid endianness in ElfHeader: {}", class)))
        }
    }
    pub fn new(ctx: Ctx) -> Self {
        let (typ, ehsize, phentsize, shentsize) = match ctx.container {
            Container::Little => {
                (ELFCLASS32, super::super::elf32::header::SIZEOF_EHDR,
                 super::super::elf32::program_header::SIZEOF_PHDR,
                 super::super::elf32::section_header::SIZEOF_SHDR)
            },
            Container::Big => {
                (ELFCLASS64, super::super::elf64::header::SIZEOF_EHDR,
                 super::super::elf64::program_header::SIZEOF_PHDR,
                 super::super::elf64::section_header::SIZEOF_SHDR)
            }
        };
        let byteorder = match ctx.le { Endian::Little => ELFDATA2LSB, Endian::Big => ELFDATA2MSB };
        ElfHeader {
            e_ident: [
                127,
                69,
                76,
                70,
                typ,
                byteorder,
                1,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0
            ],
            e_type: ET_DYN,
            e_machine: EM_NONE,
            e_version: 1,
            e_entry: 0x0,
            e_phoff: 0x0,
            e_shoff: 0x0,
            e_flags: 0,
            e_ehsize: ehsize as u16,
            e_phentsize: phentsize as u16,
            e_phnum: 0,
            e_shentsize: shentsize as u16,
            e_shnum: 0,
            e_shstrndx: 0,
        }
    }
}

impl fmt::Debug for ElfHeader {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "e_ident: {:?} e_type: {} e_machine: 0x{:x} e_version: 0x{:x} e_entry: 0x{:x} \
                e_phoff: 0x{:x} e_shoff: 0x{:x} e_flags: {:x} e_ehsize: {} e_phentsize: {} \
                e_phnum: {} e_shentsize: {} e_shnum: {} e_shstrndx: {}",
               self.e_ident,
               et_to_str(self.e_type),
               self.e_machine,
               self.e_version,
               self.e_entry,
               self.e_phoff,
               self.e_shoff,
               self.e_flags,
               self.e_ehsize,
               self.e_phentsize,
               self.e_phnum,
               self.e_shentsize,
               self.e_shnum,
               self.e_shstrndx)
    }
}

impl<'a> ctx::TryFromCtx<'a> for ElfHeader {
    type Error = error::Error;
    fn try_from_ctx(buffer: &'a [u8], (offset, _): (usize, scroll::Endian)) -> error::Result<Self> {
        use scroll::{Pread};<commit_msg>elf.header: add SizeWith impl to ElfHeader<commit_after>include!("constants_header.rs");

use error::{self};
use scroll::{self, ctx, Endian};
use core::fmt;
use container::{Ctx, Container};

#[derive(Copy, Clone, PartialEq)]
pub struct ElfHeader {
    pub e_ident           : [u8; SIZEOF_IDENT],
    pub e_type            : u16,
    pub e_machine         : u16,
    pub e_version         : u32,
    pub e_entry           : u64,
    pub e_phoff           : u64,
    pub e_shoff           : u64,
    pub e_flags           : u32,
    pub e_ehsize          : u16,
    pub e_phentsize       : u16,
    pub e_phnum           : u16,
    pub e_shentsize       : u16,
    pub e_shnum           : u16,
    pub e_shstrndx        : u16,
}

impl ElfHeader {
    /// Return the size of the underlying program header, given a `container`
    #[inline]
    pub fn size(ctx: &Ctx) -> usize {
        use scroll::ctx::SizeWith;
        Self::size_with(ctx)
    }
    /// Returns the container type this header specifies
    pub fn container(&self) -> error::Result<Container> {
        use error::Error;
        match self.e_ident[EI_CLASS] {
            ELFCLASS32 => { Ok(Container::Little) },
            ELFCLASS64 => { Ok(Container::Big) },
            class => Err(Error::Malformed(format!("Invalid class in ElfHeader: {}", class)))
        }
    }
    /// Returns the byte order this header specifies
    pub fn endianness(&self) -> error::Result<scroll::Endian> {
        use error::Error;
        match self.e_ident[EI_DATA] {
            ELFDATA2LSB => { Ok(scroll::LE) },
            ELFDATA2MSB => { Ok(scroll::BE) },
            class => Err(Error::Malformed(format!("Invalid endianness in ElfHeader: {}", class)))
        }
    }
    pub fn new(ctx: Ctx) -> Self {
        let (typ, ehsize, phentsize, shentsize) = match ctx.container {
            Container::Little => {
                (ELFCLASS32, super::super::elf32::header::SIZEOF_EHDR,
                 super::super::elf32::program_header::SIZEOF_PHDR,
                 super::super::elf32::section_header::SIZEOF_SHDR)
            },
            Container::Big => {
                (ELFCLASS64, super::super::elf64::header::SIZEOF_EHDR,
                 super::super::elf64::program_header::SIZEOF_PHDR,
                 super::super::elf64::section_header::SIZEOF_SHDR)
            }
        };
        let byteorder = match ctx.le { Endian::Little => ELFDATA2LSB, Endian::Big => ELFDATA2MSB };
        ElfHeader {
            e_ident: [
                127,
                69,
                76,
                70,
                typ,
                byteorder,
                1,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0,
                0
            ],
            e_type: ET_DYN,
            e_machine: EM_NONE,
            e_version: 1,
            e_entry: 0x0,
            e_phoff: 0x0,
            e_shoff: 0x0,
            e_flags: 0,
            e_ehsize: ehsize as u16,
            e_phentsize: phentsize as u16,
            e_phnum: 0,
            e_shentsize: shentsize as u16,
            e_shnum: 0,
            e_shstrndx: 0,
        }
    }
}

impl fmt::Debug for ElfHeader {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f,
               "e_ident: {:?} e_type: {} e_machine: 0x{:x} e_version: 0x{:x} e_entry: 0x{:x} \
                e_phoff: 0x{:x} e_shoff: 0x{:x} e_flags: {:x} e_ehsize: {} e_phentsize: {} \
                e_phnum: {} e_shentsize: {} e_shnum: {} e_shstrndx: {}",
               self.e_ident,
               et_to_str(self.e_type),
               self.e_machine,
               self.e_version,
               self.e_entry,
               self.e_phoff,
               self.e_shoff,
               self.e_flags,
               self.e_ehsize,
               self.e_phentsize,
               self.e_phnum,
               self.e_shentsize,
               self.e_shnum,
               self.e_shstrndx)
    }
}

impl ctx::SizeWith<Ctx> for ElfHeader {
    type Units = usize;
    fn size_with(ctx: &Ctx) -> usize {
        match ctx.container {
            Container::Little => {
                super::super::elf32::header::SIZEOF_EHDR
            },
            Container::Big => {
                super::super::elf64::header::SIZEOF_EHDR
            },
        }
    }
}

impl<'a> ctx::TryFromCtx<'a> for ElfHeader {
    type Error = error::Error;
    fn try_from_ctx(buffer: &'a [u8], (offset, _): (usize, scroll::Endian)) -> error::Result<Self> {
        use scroll::{Pread};
{'fraction_non_alphanumeric': 0.12241541353383459, 'fraction_numerical': 0.022321428571428572, 'mean_word_length': 1.48482194979568, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1308969', 'n_tokens_mistral': 2858, 'n_tokens_neox': 2781, 'n_words': 536}