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

Signed-off-by: Alexandra Iordache <[email protected]>
  • Loading branch information
Alexandra Iordache committed Mar 13, 2020
1 parent 0ce5bfa commit b5432c7
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 187 deletions.
83 changes: 56 additions & 27 deletions src/loader/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,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};
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
use vm_memory::VolatileMemory;
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestUsize};

#[allow(dead_code)]
#[allow(non_camel_case_types)]
Expand All @@ -51,9 +53,6 @@ pub mod start_info;
#[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 @@ -193,6 +192,18 @@ 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_Nhdr {}
#[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 @@ -218,14 +229,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 @@ -260,14 +274,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 {
if phdr.p_type == elf::PT_NOTE {
// This segment describes a Note, check if PVH entry point is encoded.
Expand Down Expand Up @@ -329,11 +353,13 @@ where
let mut read_size: usize = 0;

while read_size < phdr.p_filesz as usize {
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 nhdr).map_err(|_| Error::ReadNoteHeader)?;
}
let nhdr_bytes = &mut [0u8; mem::size_of::<elf::Elf64_Nhdr>()][..];
nhdr_bytes
.as_volatile_slice()
.read_from(0, kernel_image, nhdr_bytes.len())
.map_err(|_| Error::ReadBzImageHeader)?;
nhdr = *elf::Elf64_Nhdr::from_mut_slice(nhdr_bytes).ok_or(Error::ReadNoteHeader)?;

// If the note header found is not the desired one, keep reading until
// the end of the segment
if nhdr.n_type == XEN_ELFNOTE_PHYS32_ENTRY {
Expand Down Expand Up @@ -413,15 +439,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 @@ -457,7 +486,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 b5432c7

Please sign in to comment.