Skip to content

Commit

Permalink
elf.parse: added lazy_parse function
Browse files Browse the repository at this point in the history
  • Loading branch information
jessehui committed Jan 26, 2021
1 parent 8d91dd7 commit 54420bb
Showing 1 changed file with 48 additions and 1 deletion.
49 changes: 48 additions & 1 deletion src/elf/mod.rs
Expand Up @@ -202,9 +202,56 @@ if_sylvan! {
pub fn is_object_file(&self) -> bool {
self.header.e_type == header::ET_REL
}

pub fn parse_elf_hdr(bytes: &'a [u8]) -> error::Result<Header> {
bytes.pread::<Header>(0)
}

// Lazy parse the ELF contents after parsing headers, program headers and interpreter. This function mainly just assembles
// an Elf struct. Once we have the struct, we can choose to parse whatever we want.
pub fn lazy_parse(header: Header, program_headers: ProgramHeaders, interpreter: Option<&'a str>) -> error::Result<Self> {
let entry = header.e_entry as usize;
let is_lib = header.e_type == header::ET_DYN;
let is_lsb = header.e_ident[header::EI_DATA] == header::ELFDATA2LSB;
let endianness = scroll::Endian::from(is_lsb);
let class = header.e_ident[header::EI_CLASS];
if class != header::ELFCLASS64 && class != header::ELFCLASS32 {
return Err(error::Error::Malformed(format!("Unknown values in ELF ident header: class: {} endianness: {}",
class,
header.e_ident[header::EI_DATA])));
}
let is_64 = class == header::ELFCLASS64;
let container = if is_64 { Container::Big } else { Container::Little };
let ctx = Ctx::new(container, endianness);

Ok(Elf {
header,
program_headers,
section_headers: Default::default(),
shdr_strtab: Default::default(),
dynamic: None,
dynsyms: Default::default(),
dynstrtab: Strtab::default(),
syms: Default::default(),
strtab: Default::default(),
dynrelas: Default::default(),
dynrels: Default::default(),
pltrelocs: Default::default(),
shdr_relocs: Default::default(),
soname: None,
interpreter,
libraries: vec![],
is_64,
is_lib,
entry: entry as u64,
little_endian: is_lsb,
ctx,
})
}

/// Parses the contents of the byte stream in `bytes`, and maybe returns a unified binary
pub fn parse(bytes: &'a [u8]) -> error::Result<Self> {
let header = bytes.pread::<Header>(0)?;
let header = Self::parse_elf_hdr(bytes)?;
let entry = header.e_entry as usize;
let is_lib = header.e_type == header::ET_DYN;
let is_lsb = header.e_ident[header::EI_DATA] == header::ELFDATA2LSB;
Expand Down

0 comments on commit 54420bb

Please sign in to comment.