pelf 0.1.5

A library for parsing/generating/analyzing ELF
Documentation
use crate::prelude::*;

/// the elf64 section data.
pub enum Elf64SectionData {
    StringTable {
        table: ElfStringTable,
    },
    RawSymbolTable {
        symbols: RawElf64SymbolTable,
    },
    /// the raw bytes.
    Raw {
        bytes: Vec<u8>,
    },
}

pub type RawElf64SymbolTable = Vec<RawElf64Symbol>;

pub struct RawElf64Symbol {
    pub st_name: Elf64Word,
    pub st_info: u8,
    pub st_other: u8,
    pub st_shndx: Elf64SectionIndex,
    pub st_size: Elf64Xword,
}

pub struct ElfStringTable {
    pub entries: Vec<ElfStringTableEntry>,
}

impl ElfStringTable {
    pub fn find_by_index(&self, index: usize) -> Option<&ElfStringTableEntry> {
        self.entries.iter().find(|entry| entry.entry_index == index)
    }
}

impl From<Vec<u8>> for ElfStringTable {
    fn from(value: Vec<u8>) -> Self {
        let mut current_idx = 0;
        let mut start_indices: Vec<usize> = Vec::new();
        loop {
            if value.len() <= current_idx {
                break;
            }
            if value[current_idx] == 0x00 {
                current_idx += 1;
                continue;
            }

            start_indices.push(current_idx);
            current_idx += 1;
        }
        let entries = start_indices
            .into_iter()
            .map(|start| {
                let str_entry = String::from_utf8(
                    value[start..]
                        .iter()
                        .take_while(|b| **b != 0x00)
                        .copied()
                        .collect(),
                )
                .unwrap();
                ElfStringTableEntry {
                    entry_index: start,
                    value: str_entry,
                }
            })
            .collect();

        Self { entries }
    }
}

pub struct ElfStringTableEntry {
    pub entry_index: usize,
    pub value: String,
}