From c182df75df01d46b7f40de880942ab09c9421fd3 Mon Sep 17 00:00:00 2001 From: Johannes Stoelp Date: Fri, 29 Apr 2022 00:10:58 +0200 Subject: make crate no_std compatible --- src/lib.rs | 67 ++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index a5d3a7c..9bec615 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,13 @@ +#![no_std] + #[derive(Debug)] pub enum Error { /// Wrong or missing ELF file magic. WrongElfMagic, /// No more bytes left while parsing the ELF file. OutOfBytes, + /// Const generic on `Elf` is too small to hold all `LOAD` from the ELF file. + OutOfLoadSegments, /// Unknown value in `e_ident:EI_CLASS` byte. UnknownBitness(u8), /// Unknown value in `e_ident:EI_DATA` byte. @@ -12,10 +16,10 @@ pub enum Error { UnknownMachine(u16), } -type Result = std::result::Result; +type Result = core::result::Result; trait FromEndian: Sized { - const N: usize = std::mem::size_of::(); + const N: usize = core::mem::size_of::(); fn from_le_bytes>(bytes: B) -> Option; fn from_be_bytes>(bytes: B) -> Option; } @@ -177,7 +181,7 @@ impl<'bytes> ElfReader<'bytes> { } } -#[derive(Debug)] +#[derive(Debug, Clone, Copy)] pub struct LoadSegment<'bytes> { pub vaddr: u64, pub bytes: &'bytes [u8], @@ -188,14 +192,14 @@ pub struct LoadSegment<'bytes> { } #[derive(Debug)] -pub struct Elf<'bytes> { - pub machine: Machine, - pub entry: u64, - pub load_segments: Vec>, +pub struct Elf<'bytes, const N: usize> { + machine: Machine, + entry: u64, + load_segments: [Option>; N], } -impl Elf<'_> { - pub fn parse<'bytes>(b: &'bytes [u8]) -> Result> { +impl Elf<'_, N> { + pub fn parse<'bytes>(b: &'bytes [u8]) -> Result> { let mut r = ElfReader::new(b); // @@ -232,7 +236,8 @@ impl Elf<'_> { // Parse load program header. // - let mut load_segments = Vec::with_capacity(usize::from(phnum)); + let mut load_segments = [None; N]; + let mut load_segments_slice = &mut load_segments[..]; const PT_LOAD: u32 = 1; const PF_X: u32 = 1 << 0; @@ -242,7 +247,10 @@ impl Elf<'_> { let phoff = usize::try_from(phoff).expect("phoff too large!"); for ph in 0..phnum { - let off = ph.checked_mul(phentsize).map(usize::from).expect("phdr offset overflowed"); + let off = ph + .checked_mul(phentsize) + .map(usize::from) + .expect("phdr offset overflowed"); let pos = phoff.checked_add(off).expect("phdr position overflowed"); r.set_pos(pos); @@ -281,14 +289,20 @@ impl Elf<'_> { let w = (flags & PF_W) != 0; let r = (flags & PF_R) != 0; - load_segments.push(LoadSegment { - vaddr, - bytes, - zero_pad: memsz - filesz, - x, - w, - r, - }); + load_segments_slice = if let Some((slot, rest)) = load_segments_slice.split_first_mut() + { + *slot = Some(LoadSegment { + vaddr, + bytes, + zero_pad: memsz - filesz, + x, + w, + r, + }); + rest + } else { + return Err(Error::OutOfLoadSegments); + }; } Ok(Elf { @@ -297,4 +311,19 @@ impl Elf<'_> { load_segments, }) } + + #[inline] + pub fn machine(&self) -> Machine { + self.machine + } + + #[inline] + pub fn entry(&self) -> u64 { + self.entry + } + + #[inline] + pub fn load_segments(&self) -> impl Iterator> { + self.load_segments.iter().flatten() + } } -- cgit v1.2.3