elf64 0.1.2

Parse elf format
Documentation
use super::{Address, Error, Encoding, Index, Entry};

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum SymbolBinding {
    Local,
    Global,
    Weak,
    OsSpecific(u8),
    ProcessorSpecific(u8),
    Unknown(u8),
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum SymbolType {
    Nothing,
    Object,
    Function,
    Section,
    File,
    OsSpecific(u8),
    ProcessorSpecific(u8),
    Unknown(u8),
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SymbolInfo {
    pub binding: SymbolBinding,
    pub ty: SymbolType,
}

impl From<u8> for SymbolInfo {
    fn from(v: u8) -> Self {
        SymbolInfo {
            binding: match (v & 0xf0) / 0x10 {
                0x00 => SymbolBinding::Local,
                0x01 => SymbolBinding::Global,
                0x02 => SymbolBinding::Weak,
                t @ 0x0a..=0x0c => SymbolBinding::OsSpecific(t - 0x0a),
                t @ 0x0d..=0x0f => SymbolBinding::ProcessorSpecific(t - 0x0d),
                t => SymbolBinding::Unknown(t),
            },
            ty: match v & 0x0f {
                0x00 => SymbolType::Nothing,
                0x01 => SymbolType::Object,
                0x02 => SymbolType::Function,
                0x03 => SymbolType::Section,
                0x04 => SymbolType::File,
                t @ 0x0a..=0x0c => SymbolType::OsSpecific(t - 0x0a),
                t @ 0x0d..=0x0f => SymbolType::ProcessorSpecific(t - 0x0d),
                t => SymbolType::Unknown(t),
            },
        }
    }
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct SymbolEntry {
    pub name: u32,
    pub info: SymbolInfo,
    pub reserved: u8,
    pub section_index: Index,
    pub value: Address,
    pub size: u64,
}

impl Entry for SymbolEntry {
    type Error = Error;

    const SIZE: usize = 0x18;

    fn new(slice: &[u8], encoding: Encoding) -> Result<Self, Self::Error> {
        if slice.len() < Self::SIZE {
            return Err(Error::SliceTooShort);
        }

        Ok(SymbolEntry {
            name: read_int!(&slice[0x00..], &encoding, u32),
            info: slice[0x04].into(),
            reserved: slice[0x05],
            section_index: read_int!(&slice[0x06..], &encoding, u16).into(),
            value: read_int!(&slice[0x08..], &encoding, u64),
            size: read_int!(&slice[0x10..], &encoding, u64),
        })
    }
}