pub fn load_kernel<F>(guest_mem: &GuestMemory, kernel_image: &mut F) -> Result<GuestAddress>
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.
        sys_util::read_struct(kernel_image, &mut ehdr).map_err(|_| Error::ReadElfHeader)?;
    }

    // Sanity checks
    if ehdr.e_ident[elf::EI_MAG0 as usize] != elf::ELFMAG0 as u8
        || ehdr.e_ident[elf::EI_MAG1 as usize] != elf::ELFMAG1
        || ehdr.e_ident[elf::EI_MAG2 as usize] != elf::ELFMAG2
        || ehdr.e_ident[elf::EI_MAG3 as usize] != elf::ELFMAG3
    {
        return Err(Error::InvalidElfMagicNumber);
    }
    if ehdr.e_ident[elf::EI_DATA as usize] != elf::ELFDATA2LSB as u8 {
        return Err(Error::BigEndianElfOnLittle);
    }
    if ehdr.e_phentsize as usize != mem::size_of::<elf::Elf64_Phdr>() {
        return Err(Error::InvalidProgramHeaderSize);
    }
    if (ehdr.e_phoff as usize) < mem::size_of::<elf::Elf64_Ehdr>() {
        // If the program header is backwards, bail.
        return Err(Error::InvalidProgramHeaderOffset);
    }
    if (ehdr.e_entry as usize) < x86_64::layout::HIMEM_START {
        return Err(Error::InvalidEntryAddress);
    }

    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.
        sys_util::read_struct_slice(kernel_image, ehdr.e_phnum as usize)
            .map_err(|_| Error::ReadProgramHeader)?
    };

    // Read in each section pointed to by the program headers.
    for phdr in &phdrs {
        if (phdr.p_type & elf::PT_LOAD) == 0 || phdr.p_filesz == 0 {
            continue;
        }

        kernel_image
            .seek(SeekFrom::Start(phdr.p_offset))
            .map_err(|_| Error::SeekKernelStart)?;

        let mem_offset = GuestAddress(phdr.p_paddr as usize);
        if mem_offset.offset() < x86_64::layout::HIMEM_START {
            return Err(Error::InvalidProgramHeaderAddress);
        }

        guest_mem
            .read_to_memory(mem_offset, kernel_image, phdr.p_filesz as usize)
            .map_err(|_| Error::ReadKernelImage)?;
    }

    Ok(GuestAddress(ehdr.e_entry as usize))
}
/// Loads a kernel from a vmlinux elf image to a slice
///
/// # Arguments
///
/// * `guest_mem` - The guest memory region the kernel is written to.
/// * `kernel_image` - Input vmlinux image.
///
/// Returns the entry address of the kernel.
Loads a kernel from a vmlinux elf image to a slice
Loads a kernel from a vmlinux elf image to a slice
pub fn load_kernel<F>(guest_mem: &GuestMemory, kernel_image: &mut F) -> Result<GuestAddress>
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.
        sys_util::read_struct(kernel_image, &mut ehdr).map_err(|_| Error::ReadElfHeader)?;
    }
    // Sanity checks
    if ehdr.e_ident[elf::EI_MAG0 as usize] != elf::ELFMAG0 as u8
        || ehdr.e_ident[elf::EI_MAG1 as usize] != elf::ELFMAG1
        || ehdr.e_ident[elf::EI_MAG2 as usize] != elf::ELFMAG2
        || ehdr.e_ident[elf::EI_MAG3 as usize] != elf::ELFMAG3
    {
        return Err(Error::InvalidElfMagicNumber);
    }
    if ehdr.e_ident[elf::EI_DATA as usize] != elf::ELFDATA2LSB as u8 {
        return Err(Error::BigEndianElfOnLittle);
    }
    if ehdr.e_phentsize as usize != mem::size_of::<elf::Elf64_Phdr>() {
        return Err(Error::InvalidProgramHeaderSize);
    }
    if (ehdr.e_phoff as usize) < mem::size_of::<elf::Elf64_Ehdr>() {
        // If the program header is backwards, bail.
        return Err(Error::InvalidProgramHeaderOffset);
    }
    if (ehdr.e_entry as usize) < x86_64::layout::HIMEM_START {
        return Err(Error::InvalidEntryAddress);
    }
    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.
        sys_util::read_struct_slice(kernel_image, ehdr.e_phnum as usize)
            .map_err(|_| Error::ReadProgramHeader)?
    };
    // Read in each section pointed to by the program headers.
    for phdr in &phdrs {
        if (phdr.p_type & elf::PT_LOAD) == 0 || phdr.p_filesz == 0 {
            continue;
        }
        kernel_image
            .seek(SeekFrom::Start(phdr.p_offset))
            .map_err(|_| Error::SeekKernelStart)?;
        let mem_offset = GuestAddress(phdr.p_paddr as usize);
        if mem_offset.offset() < x86_64::layout::HIMEM_START {
            return Err(Error::InvalidProgramHeaderAddress);
        }
        guest_mem
            .read_to_memory(mem_offset, kernel_image, phdr.p_filesz as usize)
            .map_err(|_| Error::ReadKernelImage)?;
    }
    Ok(GuestAddress(ehdr.e_entry as usize))
}
pub fn load_kernel < F > ( guest_mem : & GuestMemory , kernel_image : & mut F ) -> Result < GuestAddress > 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. sys_util :: read_struct ( kernel_image , & mut ehdr ) . map_err ( | _ | Error :: ReadElfHeader ) ? ; } // Sanity checks if ehdr . e_ident [ elf :: EI_MAG0 as usize ] != elf :: ELFMAG0 as u8 || ehdr . e_ident [ elf :: EI_MAG1 as usize ] != elf :: ELFMAG1 || ehdr . e_ident [ elf :: EI_MAG2 as usize ] != elf :: ELFMAG2 || ehdr . e_ident [ elf :: EI_MAG3 as usize ] != elf :: ELFMAG3 { return Err ( Error :: InvalidElfMagicNumber ) ; } if ehdr . e_ident [ elf :: EI_DATA as usize ] != elf :: ELFDATA2LSB as u8 { return Err ( Error :: BigEndianElfOnLittle ) ; } if ehdr . e_phentsize as usize != mem :: size_of :: < elf :: Elf64_Phdr > ( ) { return Err ( Error :: InvalidProgramHeaderSize ) ; } if ( ehdr . e_phoff as usize ) < mem :: size_of :: < elf :: Elf64_Ehdr > ( ) { // If the program header is backwards, bail. return Err ( Error :: InvalidProgramHeaderOffset ) ; } if ( ehdr . e_entry as usize ) < x86_64 :: layout :: HIMEM_START { return Err ( Error :: InvalidEntryAddress ) ; } 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. sys_util :: read_struct_slice ( kernel_image , ehdr . e_phnum as usize ) . map_err ( | _ | Error :: ReadProgramHeader ) ? } ; // Read in each section pointed to by the program headers. for phdr in & phdrs { if ( phdr . p_type & elf :: PT_LOAD ) == 0 || phdr . p_filesz == 0 { continue ; } kernel_image . seek ( SeekFrom :: Start ( phdr . p_offset ) ) . map_err ( | _ | Error :: SeekKernelStart ) ? ; let mem_offset = GuestAddress ( phdr . p_paddr as usize ) ; if mem_offset . offset ( ) < x86_64 :: layout :: HIMEM_START { return Err ( Error :: InvalidProgramHeaderAddress ) ; } guest_mem . read_to_memory ( mem_offset , kernel_image , phdr . p_filesz as usize ) . map_err ( | _ | Error :: ReadKernelImage ) ? ; } Ok ( GuestAddress ( ehdr . e_entry as usize ) ) }
Loads a kernel from a vmlinux elf image to a slice
Loads a kernel from a vmlinux elf image to a slice
guest_mem
&GuestMemory
kernel_image
&mut F
guest_mem
&GuestMemory
kernel_image
&mut F