diff --git a/elf/src/elf.rs b/elf/src/elf.rs index 7899996..7971007 100644 --- a/elf/src/elf.rs +++ b/elf/src/elf.rs @@ -2,7 +2,6 @@ use std::io::Read; use anyhow::Result; -use crate::constants::*; use crate::header::E_IDENT; use crate::section::*; @@ -10,7 +9,7 @@ macro_rules! elf { ($size:ty) => { use std::io::Write; - #[derive(Debug, Default)] + #[derive(Debug)] pub struct Elf { pub header: Header, pub sections: Vec
, @@ -18,13 +17,15 @@ macro_rules! elf { impl Elf { pub(crate) fn continue_read(e_ident: E_IDENT, r: R) -> Result { - let mut elf: Self = Elf::default(); - elf.header = Header::continue_read(e_ident, r)?; - - Ok(elf) + let header = Header::continue_read(e_ident, r)?; + Ok(Elf { + header, + sections: Vec::new(), + }) } pub fn write(&self, w: W) -> Result<()> { + self.header.write(w)?; Ok(()) } } diff --git a/elf/src/header.rs b/elf/src/header.rs index f1c3c7e..cdf2552 100644 --- a/elf/src/header.rs +++ b/elf/src/header.rs @@ -1,4 +1,4 @@ -use std::io::Read; +use std::io::{Read, Write}; use std::mem::MaybeUninit; use anyhow::Result; @@ -10,7 +10,7 @@ use crate::constants::*; pub type E_IDENT = [u8; EI_NIDENT]; macro_rules! elf_header { - ($size:ty, $read_size:ident) => { + ($size:ty, $read_size:ident, $write_size:ident) => { #[derive(Debug)] pub struct Header { pub e_ident: E_IDENT, @@ -29,26 +29,14 @@ macro_rules! elf_header { pub e_shstrndx: u16, } - impl Default for Header { - fn default() -> Self { - let mut header: Self = unsafe { MaybeUninit::zeroed().assume_init() }; - header.e_ident[EI_MAG0] = ELFMAG0; - header.e_ident[EI_MAG1] = ELFMAG1; - header.e_ident[EI_MAG2] = ELFMAG2; - header.e_ident[EI_MAG3] = ELFMAG3; - header - } - } - impl Header { pub(crate) fn continue_read(e_ident: E_IDENT, r: R) -> Result { - let mut header = Header::default(); - - header.e_ident = e_ident; + let mut header: Self = unsafe { MaybeUninit::zeroed().assume_init() }; + header.e_ident.copy_from_slice(&e_ident); let mut r = match header.e_ident[EI_DATA] { ELFDATA2LSB => ByteOrdered::runtime(r, Endianness::Little), ELFDATA2MSB => ByteOrdered::runtime(r, Endianness::Big), - _ => bail!("unknown endianness"), + e => bail!("unknown endianness: {}", e), }; header.e_type = r.read_u16()?; @@ -67,16 +55,41 @@ macro_rules! elf_header { Ok(header) } + + pub fn write(&self, w: W) -> Result<()> { + println!("self: {:?}", self); + let mut w = match self.e_ident[EI_DATA] { + ELFDATA2LSB => ByteOrdered::runtime(w, Endianness::Little), + ELFDATA2MSB => ByteOrdered::runtime(w, Endianness::Big), + e => bail!("unknown endianness: {}", e), + }; + + w.write(&self.e_ident)?; + w.write_u16(self.e_type)?; + w.write_u16(self.e_machine)?; + w.write_u32(self.e_version)?; + w.$write_size(self.e_entry)?; + w.$write_size(self.e_phoff)?; + w.$write_size(self.e_shoff)?; + w.write_u32(self.e_flags)?; + w.write_u16(self.e_ehsize)?; + w.write_u16(self.e_phentsize)?; + w.write_u16(self.e_phnum)?; + w.write_u16(self.e_shentsize)?; + w.write_u16(self.e_shnum)?; + w.write_u16(self.e_shstrndx)?; + Ok(()) + } } }; } pub mod header32 { pub use super::*; - elf_header!(u32, read_u32); + elf_header!(u32, read_u32, write_u32); } pub mod header64 { pub use super::*; - elf_header!(u64, read_u64); + elf_header!(u64, read_u64, write_u64); } diff --git a/elf/src/lib.rs b/elf/src/lib.rs index d00c537..bba686d 100644 --- a/elf/src/lib.rs +++ b/elf/src/lib.rs @@ -31,14 +31,14 @@ pub enum Elf { Elf64(crate::elf::elf64::Elf), } -impl Default for Elf { - fn default() -> Self { - match SYSTEM_BITNESS { - Bitness::Bits32 => Elf::Elf32(elf32::Elf::default()), - Bitness::Bits64 => Elf::Elf64(elf64::Elf::default()), - } - } -} +// impl Default for Elf { +// fn default() -> Self { +// match SYSTEM_BITNESS { +// Bitness::Bits32 => Elf::Elf32(elf32::Elf::default()), +// Bitness::Bits64 => Elf::Elf64(elf64::Elf::default()), +// } +// } +// } impl Elf { pub fn read(mut r: R) -> Result { diff --git a/src/link.rs b/src/link.rs index a2879dc..93b82e1 100644 --- a/src/link.rs +++ b/src/link.rs @@ -1,6 +1,6 @@ use std::fs::File; -use anyhow::Result; +use anyhow::{Context, Result}; use elf::{elf32::Elf as Elf32, elf64::Elf as Elf64, Elf}; use rayon::prelude::*; @@ -38,9 +38,11 @@ struct Accum { fn sort_all_elfs_by_bitness(mut accum: Accum, unit: LinkUnit) -> Result { match unit { LinkUnit::Path(path) => { - let file = File::open(path)?; - let elf = Elf::read(&file)?; - // println!("elf: {:?}", elf); + let file = + File::open(&path).with_context(|| format!("could not open elf file {:?}", path))?; + let elf = Elf::read(&file) + .with_context(|| format!("could not parse elf file from {:?}", path))?; + match elf { Elf::Elf32(v) => accum.elfs32.push(v), Elf::Elf64(v) => accum.elfs64.push(v), @@ -49,7 +51,10 @@ fn sort_all_elfs_by_bitness(mut accum: Accum, unit: LinkUnit) -> Result { Ok(accum) } - _ => bail!("lol"), + _ => { + // TODO + Ok(Accum::default()) + } } } @@ -76,7 +81,6 @@ macro_rules! link { use anyhow::{Context, Result}; pub fn link(output: PathBuf, elfs: Vec) -> Result<()> { - let res = Elf::default(); println!("Hellosu {:?}", elfs); let path = crate::utils::normalize_path(&output); @@ -87,7 +91,9 @@ macro_rules! link { .open(&path) .with_context(|| format!("could not create output file {:?}", path))?; - res.write(file)?; + // let res = Elf { + // }; + // res.write(file).context("could not write output file")?; Ok(()) } };