Skip to content

Commit 15e14aa

Browse files
author
Alexandra Iordache
committed
replace struct_util with ByteValued from vm-memory
Fixes #20 Closes rust-vmm/vmm-sys-util#77 Signed-off-by: Alexandra Iordache <aghecen@amazon.com>
1 parent 0c754f3 commit 15e14aa

File tree

2 files changed

+46
-182
lines changed

2 files changed

+46
-182
lines changed

src/loader/mod.rs

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ use std::io::{Read, Seek};
2727
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
2828
use std::mem;
2929

30-
use vm_memory::{Address, Bytes, GuestAddress, GuestMemory, GuestUsize};
30+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
31+
use vm_memory::VolatileMemory;
32+
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestUsize};
3133

3234
#[allow(dead_code)]
3335
#[allow(non_camel_case_types)]
@@ -42,9 +44,6 @@ pub mod bootparam;
4244
#[allow(non_upper_case_globals)]
4345
#[cfg_attr(feature = "cargo-clippy", allow(clippy::all))]
4446
mod elf;
45-
#[cfg(any(feature = "elf", feature = "bzimage"))]
46-
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
47-
mod struct_util;
4847

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

173+
#[cfg(feature = "elf")]
174+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
175+
unsafe impl ByteValued for elf::Elf64_Ehdr {}
176+
#[cfg(feature = "elf")]
177+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
178+
unsafe impl ByteValued for elf::Elf64_Phdr {}
179+
180+
unsafe impl ByteValued for bootparam::setup_header {}
181+
174182
#[cfg(feature = "elf")]
175183
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
176184
impl KernelLoader for Elf {
@@ -196,14 +204,17 @@ impl KernelLoader for Elf {
196204
where
197205
F: Read + Seek,
198206
{
199-
let mut ehdr: elf::Elf64_Ehdr = Default::default();
200207
kernel_image
201208
.seek(SeekFrom::Start(0))
202209
.map_err(|_| Error::SeekElfStart)?;
203-
unsafe {
204-
// read_struct is safe when reading a POD struct. It can be used and dropped without issue.
205-
struct_util::read_struct(kernel_image, &mut ehdr).map_err(|_| Error::ReadElfHeader)?;
206-
}
210+
211+
// TODO: use `Bytes` trait methods when rust-vmm/vm-memory#83 is merged.
212+
let ehdr_bytes = &mut [0u8; mem::size_of::<elf::Elf64_Ehdr>()][..];
213+
ehdr_bytes
214+
.as_volatile_slice()
215+
.read_from(0, kernel_image, ehdr_bytes.len())
216+
.map_err(|_| Error::ReadElfHeader)?;
217+
let ehdr = elf::Elf64_Ehdr::from_mut_slice(ehdr_bytes).ok_or(Error::ReadElfHeader)?;
207218

208219
// Sanity checks
209220
if ehdr.e_ident[elf::EI_MAG0 as usize] != elf::ELFMAG0 as u8
@@ -238,14 +249,24 @@ impl KernelLoader for Elf {
238249
kernel_image
239250
.seek(SeekFrom::Start(ehdr.e_phoff))
240251
.map_err(|_| Error::SeekProgramHeader)?;
241-
let phdrs: Vec<elf::Elf64_Phdr> = unsafe {
242-
// Reading the structs is safe for a slice of POD structs.
243-
struct_util::read_struct_slice(kernel_image, ehdr.e_phnum as usize)
244-
.map_err(|_| Error::ReadProgramHeader)?
245-
};
252+
253+
// TODO: use `Bytes` trait methods when rust-vmm/vm-memory#83 is merged.
254+
let phdr_sz = mem::size_of::<elf::Elf64_Phdr>();
255+
let phdrs_bytes = &mut vec![0u8; ehdr.e_phnum as usize * phdr_sz][..];
256+
phdrs_bytes
257+
.as_volatile_slice()
258+
.read_from(0, kernel_image, phdrs_bytes.len())
259+
.map_err(|_| Error::ReadProgramHeader)?;
260+
let mut phdrs: Vec<&elf::Elf64_Phdr> = vec![];
261+
for i in 0usize..ehdr.e_phnum as usize {
262+
phdrs.push(
263+
elf::Elf64_Phdr::from_slice(&phdrs_bytes[i * phdr_sz..(i + 1) * phdr_sz])
264+
.ok_or(Error::ReadElfHeader)?,
265+
);
266+
}
246267

247268
// Read in each section pointed to by the program headers.
248-
for phdr in &phdrs {
269+
for phdr in phdrs {
249270
if phdr.p_type != elf::PT_LOAD || phdr.p_filesz == 0 {
250271
continue;
251272
}
@@ -314,15 +335,18 @@ impl KernelLoader for BzImage {
314335
let mut kernel_size = kernel_image
315336
.seek(SeekFrom::End(0))
316337
.map_err(|_| Error::SeekBzImageEnd)? as usize;
317-
let mut boot_header: bootparam::setup_header = Default::default();
318338
kernel_image
319339
.seek(SeekFrom::Start(0x1F1))
320340
.map_err(|_| Error::SeekBzImageHeader)?;
321-
unsafe {
322-
// read_struct is safe when reading a POD struct. It can be used and dropped without issue.
323-
struct_util::read_struct(kernel_image, &mut boot_header)
324-
.map_err(|_| Error::ReadBzImageHeader)?;
325-
}
341+
342+
// TODO: use `Bytes` trait methods when rust-vmm/vm-memory#83 is merged.
343+
let boothdr_bytes = &mut [0u8; mem::size_of::<bootparam::setup_header>()][..];
344+
boothdr_bytes
345+
.as_volatile_slice()
346+
.read_from(0, kernel_image, boothdr_bytes.len())
347+
.map_err(|_| Error::ReadBzImageHeader)?;
348+
let boot_header = bootparam::setup_header::from_mut_slice(boothdr_bytes)
349+
.ok_or(Error::ReadBzImageHeader)?;
326350

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

360384
let mut loader_result: KernelLoaderResult = Default::default();
361-
loader_result.setup_header = Some(boot_header);
385+
loader_result.setup_header = Some(*boot_header);
362386
loader_result.kernel_load = mem_offset;
363387

364388
//seek the compressed vmlinux.bin and read to memory

src/loader/struct_util.rs

Lines changed: 0 additions & 160 deletions
This file was deleted.

0 commit comments

Comments
 (0)