diff --git a/src/snapshot.rs b/src/snapshot.rs index 07fde0b..3032937 100644 --- a/src/snapshot.rs +++ b/src/snapshot.rs @@ -191,50 +191,6 @@ impl<'a, 'b> Snapshot<'a, 'b> { Ok(()) } - // given a set of ranges from iomem and a set of Blocks derived from the - // psuedo-elf phys section headers, derive a set of ranges that can be used - // to create a snapshot. - fn find_kcore_blocks(ranges: &[Range], headers: &[Block]) -> Vec { - let mut result = vec![]; - - 'outer: for range in ranges { - let mut range = range.clone(); - - 'inner: for header in headers { - match ( - header.range.contains(&range.start), - // TODO: ranges is currently inclusive, but not a - // RangeInclusive. this should be adjusted. - header.range.contains(&(range.end - 1)), - ) { - (true, true) => { - let block = Block { - offset: header.offset + range.start - header.range.start, - range: range.clone(), - }; - - result.push(block); - continue 'outer; - } - (true, false) => { - let block = Block { - offset: header.offset + range.start - header.range.start, - range: range.start..header.range.end, - }; - - result.push(block); - range.start = header.range.end; - } - _ => { - continue 'inner; - } - }; - } - } - - result - } - fn kcore(&self) -> Result<()> { if !is_kcore_ok() { return Err(Error::LockedDownKcore); @@ -244,22 +200,42 @@ impl<'a, 'b> Snapshot<'a, 'b> { let mut file = elf::File::open_stream(&mut image.src).map_err(Error::Elf)?; file.phdrs.retain(|&x| x.progtype == elf::types::PT_LOAD); - file.phdrs.sort_by(|a, b| a.vaddr.cmp(&b.vaddr)); - let start = file.phdrs[0].vaddr - self.memory_ranges[0].start; - let mut physical_ranges = vec![]; + let first_memory_range = &self.memory_ranges[0]; + let first_physical_address = first_memory_range.start; + let last_memory_range = &self.memory_ranges[self.memory_ranges.len() - 1]; + let last_physical_address = last_memory_range.end + 1; + let mut found_first: bool = false; + let mut blocks = vec![]; for phdr in file.phdrs { - let entry_start = phdr.vaddr - start; - let entry_end = entry_start + phdr.memsz; + // Skip PT_LOAD that do not represent physical memory + // TODO: compare to (-1) + if phdr.paddr == 0xffff_ffff || phdr.paddr == 0xffff_ffff_ffff_ffff { + continue; + } + + // Skip entries that don't make sense + let physical_end = phdr.paddr + phdr.memsz; + if physical_end > last_physical_address { + continue; + } - physical_ranges.push(Block { - range: entry_start..entry_end, + if phdr.paddr == first_physical_address { + found_first = true; + } + + // If PT_LOAD describing first memory range not found then skip + if !found_first { + continue; + } + + blocks.push(Block { + range: phdr.paddr..physical_end, offset: phdr.offset, }); } - let blocks = Self::find_kcore_blocks(&self.memory_ranges, &physical_ranges); image.write_blocks(&blocks)?; Ok(()) } @@ -286,55 +262,3 @@ impl<'a, 'b> Snapshot<'a, 'b> { Ok(()) } } - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn translate_ranges() { - let ranges = [10..20, 30..35, 45..55]; - - let core_ranges = [ - Block { - range: 10..20, - offset: 0, - }, - Block { - range: 25..35, - offset: 10, - }, - Block { - range: 40..50, - offset: 20, - }, - Block { - range: 50..55, - offset: 35, - }, - ]; - - let expected = vec![ - Block { - offset: 0, - range: 10..20, - }, - Block { - offset: 10 + 5, - range: 30..35, - }, - Block { - offset: 25, - range: 45..50, - }, - Block { - offset: 35, - range: 50..55, - }, - ]; - - let result = Snapshot::find_kcore_blocks(&ranges, &core_ranges); - - assert_eq!(result, expected); - } -}