zehn 0.1.1

A library for reading and writing ELF binaries
Documentation
use crate::object::{Class, Endianness, Object};
use crate::util::ReadExt;
use crate::util::Result;
use crate::util::WriteExt;
use std::io::{Read, Write};

#[derive(Debug, Clone)]
pub struct Symbol {
    pub sym_name: u32,
    pub sym_info: u8,
    pub sym_other: u8,
    pub sym_shndx: u16,
    pub sym_value: u64,
    pub sym_size: u64,
}

impl Symbol {
    pub fn get_name(&self, obj: &Object) -> Result<String> {
        let strtab = obj
            .find_section(".strtab")
            .expect("Unable to get the name for a symbol: Section \".strtab\" was not present!");
        let mut name = &strtab.body[self.sym_name as usize..];
        Ok(name.read_cstr()?)
    }

    pub fn read(class: &Class, endian: &Endianness, mut buf: impl Read) -> Result<Self> {
        let prog = match class {
            Class::Bits32 => Self {
                sym_name: buf.read_u32(endian)?,
                sym_info: buf.read_u8()?,
                sym_other: buf.read_u8()?,
                sym_shndx: buf.read_u16(endian)?,
                sym_value: buf.read_u32(endian)? as u64,
                sym_size: buf.read_u32(endian)? as u64,
            },
            Class::Bits64 => Self {
                sym_name: buf.read_u32(endian)?,
                sym_info: buf.read_u8()?,
                sym_other: buf.read_u8()?,
                sym_shndx: buf.read_u16(endian)?,
                sym_value: buf.read_u64(endian)?,
                sym_size: buf.read_u64(endian)?,
            },
        };
        Ok(prog)
    }
    pub fn write(&self, class: &Class, endian: &Endianness, mut buf: impl Write) -> Result<usize> {
        let mut written = 0;
        match class {
            Class::Bits32 => {
                written += buf.write_u32(endian, self.sym_name)?;
                written += buf.write_u8(self.sym_info)?;
                written += buf.write_u8(self.sym_other)?;
                written += buf.write_u16(endian, self.sym_shndx)?;
                written += buf.write_u32(endian, self.sym_value as u32)?;
                written += buf.write_u32(endian, self.sym_size as u32)?;
            }
            Class::Bits64 => {
                written += buf.write_u32(endian, self.sym_name)?;
                written += buf.write_u8(self.sym_info)?;
                written += buf.write_u8(self.sym_other)?;
                written += buf.write_u16(endian, self.sym_shndx)?;
                written += buf.write_u64(endian, self.sym_value)?;
                written += buf.write_u64(endian, self.sym_size)?;
            }
        }
        Ok(written)
    }
}