Skip to content

Commit b5432c7

Browse files
author
Alexandra Iordache
committed
replace struct_util with ByteValued from vm-memory
Fixes #20 Signed-off-by: Alexandra Iordache <aghecen@amazon.com>
1 parent 0ce5bfa commit b5432c7

File tree

2 files changed

+56
-187
lines changed

2 files changed

+56
-187
lines changed

src/loader/mod.rs

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

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

3436
#[allow(dead_code)]
3537
#[allow(non_camel_case_types)]
@@ -51,9 +53,6 @@ pub mod start_info;
5153
#[allow(non_upper_case_globals)]
5254
#[cfg_attr(feature = "cargo-clippy", allow(clippy::all))]
5355
mod elf;
54-
#[cfg(any(feature = "elf", feature = "bzimage"))]
55-
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
56-
mod struct_util;
5756

5857
#[derive(Debug, PartialEq)]
5958
/// Kernel loader errors.
@@ -193,6 +192,18 @@ pub trait KernelLoader {
193192
/// Raw ELF (a.k.a. vmlinux) kernel image support.
194193
pub struct Elf;
195194

195+
#[cfg(feature = "elf")]
196+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
197+
unsafe impl ByteValued for elf::Elf64_Ehdr {}
198+
#[cfg(feature = "elf")]
199+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
200+
unsafe impl ByteValued for elf::Elf64_Nhdr {}
201+
#[cfg(feature = "elf")]
202+
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
203+
unsafe impl ByteValued for elf::Elf64_Phdr {}
204+
205+
unsafe impl ByteValued for bootparam::setup_header {}
206+
196207
#[cfg(feature = "elf")]
197208
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
198209
impl KernelLoader for Elf {
@@ -218,14 +229,17 @@ impl KernelLoader for Elf {
218229
where
219230
F: Read + Seek,
220231
{
221-
let mut ehdr: elf::Elf64_Ehdr = Default::default();
222232
kernel_image
223233
.seek(SeekFrom::Start(0))
224234
.map_err(|_| Error::SeekElfStart)?;
225-
unsafe {
226-
// read_struct is safe when reading a POD struct. It can be used and dropped without issue.
227-
struct_util::read_struct(kernel_image, &mut ehdr).map_err(|_| Error::ReadElfHeader)?;
228-
}
235+
236+
// TODO: use `Bytes` trait methods when rust-vmm/vm-memory#83 is merged.
237+
let ehdr_bytes = &mut [0u8; mem::size_of::<elf::Elf64_Ehdr>()][..];
238+
ehdr_bytes
239+
.as_volatile_slice()
240+
.read_from(0, kernel_image, ehdr_bytes.len())
241+
.map_err(|_| Error::ReadElfHeader)?;
242+
let ehdr = elf::Elf64_Ehdr::from_mut_slice(ehdr_bytes).ok_or(Error::ReadElfHeader)?;
229243

230244
// Sanity checks
231245
if ehdr.e_ident[elf::EI_MAG0 as usize] != elf::ELFMAG0 as u8
@@ -260,14 +274,24 @@ impl KernelLoader for Elf {
260274
kernel_image
261275
.seek(SeekFrom::Start(ehdr.e_phoff))
262276
.map_err(|_| Error::SeekProgramHeader)?;
263-
let phdrs: Vec<elf::Elf64_Phdr> = unsafe {
264-
// Reading the structs is safe for a slice of POD structs.
265-
struct_util::read_struct_slice(kernel_image, ehdr.e_phnum as usize)
266-
.map_err(|_| Error::ReadProgramHeader)?
267-
};
277+
278+
// TODO: use `Bytes` trait methods when rust-vmm/vm-memory#83 is merged.
279+
let phdr_sz = mem::size_of::<elf::Elf64_Phdr>();
280+
let phdrs_bytes = &mut vec![0u8; ehdr.e_phnum as usize * phdr_sz][..];
281+
phdrs_bytes
282+
.as_volatile_slice()
283+
.read_from(0, kernel_image, phdrs_bytes.len())
284+
.map_err(|_| Error::ReadProgramHeader)?;
285+
let mut phdrs: Vec<&elf::Elf64_Phdr> = vec![];
286+
for i in 0usize..ehdr.e_phnum as usize {
287+
phdrs.push(
288+
elf::Elf64_Phdr::from_slice(&phdrs_bytes[i * phdr_sz..(i + 1) * phdr_sz])
289+
.ok_or(Error::ReadElfHeader)?,
290+
);
291+
}
268292

269293
// Read in each section pointed to by the program headers.
270-
for phdr in &phdrs {
294+
for phdr in phdrs {
271295
if phdr.p_type != elf::PT_LOAD || phdr.p_filesz == 0 {
272296
if phdr.p_type == elf::PT_NOTE {
273297
// This segment describes a Note, check if PVH entry point is encoded.
@@ -329,11 +353,13 @@ where
329353
let mut read_size: usize = 0;
330354

331355
while read_size < phdr.p_filesz as usize {
332-
unsafe {
333-
// read_struct is safe when reading a POD struct.
334-
// It can be used and dropped without issue.
335-
struct_util::read_struct(kernel_image, &mut nhdr).map_err(|_| Error::ReadNoteHeader)?;
336-
}
356+
let nhdr_bytes = &mut [0u8; mem::size_of::<elf::Elf64_Nhdr>()][..];
357+
nhdr_bytes
358+
.as_volatile_slice()
359+
.read_from(0, kernel_image, nhdr_bytes.len())
360+
.map_err(|_| Error::ReadBzImageHeader)?;
361+
nhdr = *elf::Elf64_Nhdr::from_mut_slice(nhdr_bytes).ok_or(Error::ReadNoteHeader)?;
362+
337363
// If the note header found is not the desired one, keep reading until
338364
// the end of the segment
339365
if nhdr.n_type == XEN_ELFNOTE_PHYS32_ENTRY {
@@ -413,15 +439,18 @@ impl KernelLoader for BzImage {
413439
let mut kernel_size = kernel_image
414440
.seek(SeekFrom::End(0))
415441
.map_err(|_| Error::SeekBzImageEnd)? as usize;
416-
let mut boot_header: bootparam::setup_header = Default::default();
417442
kernel_image
418443
.seek(SeekFrom::Start(0x1F1))
419444
.map_err(|_| Error::SeekBzImageHeader)?;
420-
unsafe {
421-
// read_struct is safe when reading a POD struct. It can be used and dropped without issue.
422-
struct_util::read_struct(kernel_image, &mut boot_header)
423-
.map_err(|_| Error::ReadBzImageHeader)?;
424-
}
445+
446+
// TODO: use `Bytes` trait methods when rust-vmm/vm-memory#83 is merged.
447+
let boothdr_bytes = &mut [0u8; mem::size_of::<bootparam::setup_header>()][..];
448+
boothdr_bytes
449+
.as_volatile_slice()
450+
.read_from(0, kernel_image, boothdr_bytes.len())
451+
.map_err(|_| Error::ReadBzImageHeader)?;
452+
let boot_header = bootparam::setup_header::from_mut_slice(boothdr_bytes)
453+
.ok_or(Error::ReadBzImageHeader)?;
425454

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

459488
let mut loader_result: KernelLoaderResult = Default::default();
460-
loader_result.setup_header = Some(boot_header);
489+
loader_result.setup_header = Some(*boot_header);
461490
loader_result.kernel_load = mem_offset;
462491

463492
//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)