Skip to content

Commit

Permalink
replace struct_util with ByteValued from vm-memory
Browse files Browse the repository at this point in the history
Fixes #20
Closes rust-vmm/vmm-sys-util#77

Signed-off-by: Alexandra Iordache <[email protected]>
  • Loading branch information
Alexandra Iordache committed Mar 11, 2020
1 parent 0c754f3 commit 3cec84e
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 182 deletions.
68 changes: 46 additions & 22 deletions src/loader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ use std::io::{Read, Seek};
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use std::mem;

use vm_memory::{Address, Bytes, GuestAddress, GuestMemory, GuestUsize};
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestUsize, VolatileMemory,
};

#[allow(dead_code)]
#[allow(non_camel_case_types)]
Expand All @@ -42,9 +44,6 @@ pub mod bootparam;
#[allow(non_upper_case_globals)]
#[cfg_attr(feature = "cargo-clippy", allow(clippy::all))]
mod elf;
#[cfg(any(feature = "elf", feature = "bzimage"))]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
mod struct_util;

#[derive(Debug, PartialEq)]
/// Kernel loader errors.
Expand Down Expand Up @@ -171,6 +170,15 @@ pub trait KernelLoader {
/// Raw ELF (a.k.a. vmlinux) kernel image support.
pub struct Elf;

#[cfg(feature = "elf")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
unsafe impl ByteValued for elf::Elf64_Ehdr {}
#[cfg(feature = "elf")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
unsafe impl ByteValued for elf::Elf64_Phdr {}

unsafe impl ByteValued for bootparam::setup_header {}

#[cfg(feature = "elf")]
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
impl KernelLoader for Elf {
Expand All @@ -196,14 +204,17 @@ impl KernelLoader for Elf {
where
F: Read + Seek,
{
let mut ehdr: elf::Elf64_Ehdr = Default::default();
kernel_image
.seek(SeekFrom::Start(0))
.map_err(|_| Error::SeekElfStart)?;
unsafe {
// read_struct is safe when reading a POD struct. It can be used and dropped without issue.
struct_util::read_struct(kernel_image, &mut ehdr).map_err(|_| Error::ReadElfHeader)?;
}

// TODO: use `Bytes` trait methods when rust-vmm/vm-memory#83 is merged.
let ehdr_bytes = &mut [0u8; mem::size_of::<elf::Elf64_Ehdr>()][..];
ehdr_bytes
.as_volatile_slice()
.read_from(0, kernel_image, ehdr_bytes.len())
.map_err(|_| Error::ReadElfHeader)?;
let ehdr = elf::Elf64_Ehdr::from_mut_slice(ehdr_bytes).ok_or(Error::ReadElfHeader)?;

// Sanity checks
if ehdr.e_ident[elf::EI_MAG0 as usize] != elf::ELFMAG0 as u8
Expand Down Expand Up @@ -238,14 +249,24 @@ impl KernelLoader for Elf {
kernel_image
.seek(SeekFrom::Start(ehdr.e_phoff))
.map_err(|_| Error::SeekProgramHeader)?;
let phdrs: Vec<elf::Elf64_Phdr> = unsafe {
// Reading the structs is safe for a slice of POD structs.
struct_util::read_struct_slice(kernel_image, ehdr.e_phnum as usize)
.map_err(|_| Error::ReadProgramHeader)?
};

// TODO: use `Bytes` trait methods when rust-vmm/vm-memory#83 is merged.
let phdr_sz = mem::size_of::<elf::Elf64_Phdr>();
let phdrs_bytes = &mut vec![0u8; ehdr.e_phnum as usize * phdr_sz][..];
phdrs_bytes
.as_volatile_slice()
.read_from(0, kernel_image, phdrs_bytes.len())
.map_err(|_| Error::ReadProgramHeader)?;
let mut phdrs: Vec<&elf::Elf64_Phdr> = vec![];
for i in 0usize..ehdr.e_phnum as usize {
phdrs.push(
elf::Elf64_Phdr::from_slice(&phdrs_bytes[i * phdr_sz..(i + 1) * phdr_sz])
.ok_or(Error::ReadElfHeader)?,
);
}

// Read in each section pointed to by the program headers.
for phdr in &phdrs {
for phdr in phdrs {
if phdr.p_type != elf::PT_LOAD || phdr.p_filesz == 0 {
continue;
}
Expand Down Expand Up @@ -314,15 +335,18 @@ impl KernelLoader for BzImage {
let mut kernel_size = kernel_image
.seek(SeekFrom::End(0))
.map_err(|_| Error::SeekBzImageEnd)? as usize;
let mut boot_header: bootparam::setup_header = Default::default();
kernel_image
.seek(SeekFrom::Start(0x1F1))
.map_err(|_| Error::SeekBzImageHeader)?;
unsafe {
// read_struct is safe when reading a POD struct. It can be used and dropped without issue.
struct_util::read_struct(kernel_image, &mut boot_header)
.map_err(|_| Error::ReadBzImageHeader)?;
}

// TODO: use `Bytes` trait methods when rust-vmm/vm-memory#83 is merged.
let boothdr_bytes = &mut [0u8; mem::size_of::<bootparam::setup_header>()][..];
boothdr_bytes
.as_volatile_slice()
.read_from(0, kernel_image, boothdr_bytes.len())
.map_err(|_| Error::ReadBzImageHeader)?;
let boot_header = bootparam::setup_header::from_mut_slice(boothdr_bytes)
.ok_or(Error::ReadBzImageHeader)?;

// if the HdrS magic number is not found at offset 0x202, the boot protocol version is "old",
// the image type is assumed as zImage, not bzImage.
Expand Down Expand Up @@ -358,7 +382,7 @@ impl KernelLoader for BzImage {
boot_header.code32_start = mem_offset.raw_value() as u32;

let mut loader_result: KernelLoaderResult = Default::default();
loader_result.setup_header = Some(boot_header);
loader_result.setup_header = Some(*boot_header);
loader_result.kernel_load = mem_offset;

//seek the compressed vmlinux.bin and read to memory
Expand Down
160 changes: 0 additions & 160 deletions src/loader/struct_util.rs

This file was deleted.

0 comments on commit 3cec84e

Please sign in to comment.