This commit is contained in:
Michael Zhang 2021-06-30 00:03:15 -05:00
parent 138bbb39a9
commit f514441c16
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
4 changed files with 60 additions and 40 deletions

View file

@ -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<Section>,
@ -18,13 +17,15 @@ macro_rules! elf {
impl Elf {
pub(crate) fn continue_read<R: Read>(e_ident: E_IDENT, r: R) -> Result<Self> {
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<W: Write>(&self, w: W) -> Result<()> {
self.header.write(w)?;
Ok(())
}
}

View file

@ -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<R: Read>(e_ident: E_IDENT, r: R) -> Result<Self> {
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<W: 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);
}

View file

@ -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<R: Read>(mut r: R) -> Result<Self> {

View file

@ -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<Accum> {
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<Accum> {
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<Elf>) -> 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(())
}
};