use std::{ fmt::Display, path::{Path, PathBuf}, }; use crate::common::{Relocatable, Storage}; use crate::{common::BSI, error::Error}; use xmas_elf::header::Type as ElfType; use xmas_elf::ElfFile; use super::SectionIter; pub struct ElfObject<'data> { origin: PathBuf, elf: ElfFile<'data>, } impl<'data> ElfObject<'data> { pub fn new(storage: &'data mut Storage) -> Result { let origin = storage.origin()?; let elf = ElfFile::new(storage.bytes()?).map_err(|_| Error::InvalidObjectType(0))?; is_relocatable(&elf)?; let result = ElfObject { origin, elf }; Ok(result) } } impl Relocatable for ElfObject<'_> { fn origin(&self) -> &Path { &self.origin } fn sections(&self) -> BSI<'_> { Box::new(SectionIter { elf: &self.elf, iter: self.elf.section_iter(), }) } } impl Display for ElfObject<'_> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!( f, "==={:?}===\n>Symbols:\n{}\n>Sections:\n", self.origin().file_name().unwrap(), "TODO" )?; for section in self.sections() { let u = section.unwrap(); write!(f, "{}", u)?; } Ok(()) } } fn is_relocatable(elf: &ElfFile) -> Result<(), Error> { let raw_type = elf.header.pt2.type_(); let elf_type: ElfType = raw_type.as_type(); if elf_type != ElfType::Relocatable { return Err(Error::InvalidObjectType(raw_type.0.into())); } Ok(()) }