fn parse_elf_note<F>(phdr: &elf::Elf64_Phdr, kernel_image: &mut F) -> Result<Option<GuestAddress>>
where
    F: Read + Seek,
{
    // Type of note header that encodes a 32-bit entry point address to boot a guest kernel using
    // the PVH boot protocol.
    const XEN_ELFNOTE_PHYS32_ENTRY: u32 = 18;

    let n_align = phdr.p_align;

    // Seek to the beginning of the note segment.
    kernel_image
        .seek(SeekFrom::Start(phdr.p_offset))
        .map_err(|_| Error::SeekNoteHeader)?;

    // Now that the segment has been found, we must locate an ELF note with the correct type that
    // encodes the PVH entry point if there is one.
    let mut nhdr: elf::Elf64_Nhdr = Default::default();
    let mut read_size: usize = 0;
    let nhdr_sz = mem::size_of::<elf::Elf64_Nhdr>();

    while read_size < phdr.p_filesz as usize {
        nhdr.as_bytes()
            .read_from(0, kernel_image, nhdr_sz)
            .map_err(|_| Error::ReadNoteHeader)?;

        // Check if the note header's name and type match the ones specified by the PVH ABI.
        if nhdr.n_type == XEN_ELFNOTE_PHYS32_ENTRY && nhdr.n_namesz as usize == PVH_NOTE_STR_SZ {
            let mut buf = [0u8; PVH_NOTE_STR_SZ];
            kernel_image
                .read_exact(&mut buf)
                .map_err(|_| Error::ReadNoteHeader)?;
            if buf == [b'X', b'e', b'n', b'\0'] {
                break;
            }
        }

        // Skip the note header plus the size of its fields (with alignment).
        read_size += nhdr_sz
            + align_up(u64::from(nhdr.n_namesz), n_align)
            + align_up(u64::from(nhdr.n_descsz), n_align);

        kernel_image
            .seek(SeekFrom::Start(phdr.p_offset + read_size as u64))
            .map_err(|_| Error::SeekNoteHeader)?;
    }

    if read_size >= phdr.p_filesz as usize {
        // PVH ELF note not found, nothing else to do.
        return Ok(None);
    }

    // Otherwise the correct note type was found.
    // The note header struct has already been read, so we can seek from the current position and
    // just skip the name field contents.
    kernel_image
        .seek(SeekFrom::Current(
            align_up(u64::from(nhdr.n_namesz), n_align) as i64 - PVH_NOTE_STR_SZ as i64,
        ))
        .map_err(|_| Error::SeekNoteHeader)?;

    // The PVH entry point is a 32-bit address, so the descriptor field must be capable of storing
    // all such addresses.
    if (nhdr.n_descsz as usize) < mem::size_of::<u32>() {
        return Err(Error::InvalidPvhNote.into());
    }

    let mut pvh_addr_bytes = [0; mem::size_of::<u32>()];

    // Read 32-bit address stored in the PVH note descriptor field.
    kernel_image
        .read_exact(&mut pvh_addr_bytes)
        .map_err(|_| Error::ReadNoteHeader)?;

    Ok(Some(GuestAddress(
        u32::from_le_bytes(pvh_addr_bytes).into(),
    )))
}
/// Examines a supplied elf program header of type `PT_NOTE` to determine if it contains an entry
/// of type `XEN_ELFNOTE_PHYS32_ENTRY` (0x12). Notes of this type encode a physical 32-bit entry
/// point address into the kernel, which is used when launching guests in 32-bit (protected) mode
/// with paging disabled, as described by the PVH boot protocol.
/// Returns the encoded entry point address, or `None` if no `XEN_ELFNOTE_PHYS32_ENTRY` entries are
/// found in the note header.
Examines a supplied elf program header of type `PT_NOTE` to determine if it contains an entry
of type `XEN_ELFNOTE_PHYS32_ENTRY` (0x12). Notes of this type encode a physical 32-bit entry
point address into the kernel, which is used when launching guests in 32-bit (protected) mode
with paging disabled, as described by the PVH boot protocol.
Returns the encoded entry point address, or `None` if no `XEN_ELFNOTE_PHYS32_ENTRY` entries are
found in the note header.
Examines a supplied elf program header of type ` PT_NOTE ` to determine if it contains an entry of type ` XEN_ELFNOTE_PHYS32_ENTRY ` ( 0x12 ) . Notes of this type encode a physical 32 - bit entry point address into the kernel which is used when launching guests in 32 - bit ( protected ) mode with paging disabled as described by the PVH boot protocol . Returns the encoded entry point address or ` None ` if no ` XEN_ELFNOTE_PHYS32_ENTRY ` entries are found in the note header .
fn parse_elf_note<F>(phdr: &elf::Elf64_Phdr, kernel_image: &mut F) -> Result<Option<GuestAddress>>
where
    F: Read + Seek,
{
    // Type of note header that encodes a 32-bit entry point address to boot a guest kernel using
    // the PVH boot protocol.
    const XEN_ELFNOTE_PHYS32_ENTRY: u32 = 18;
    let n_align = phdr.p_align;
    // Seek to the beginning of the note segment.
    kernel_image
        .seek(SeekFrom::Start(phdr.p_offset))
        .map_err(|_| Error::SeekNoteHeader)?;
    // Now that the segment has been found, we must locate an ELF note with the correct type that
    // encodes the PVH entry point if there is one.
    let mut nhdr: elf::Elf64_Nhdr = Default::default();
    let mut read_size: usize = 0;
    let nhdr_sz = mem::size_of::<elf::Elf64_Nhdr>();
    while read_size < phdr.p_filesz as usize {
        nhdr.as_bytes()
            .read_from(0, kernel_image, nhdr_sz)
            .map_err(|_| Error::ReadNoteHeader)?;
        // Check if the note header's name and type match the ones specified by the PVH ABI.
        if nhdr.n_type == XEN_ELFNOTE_PHYS32_ENTRY && nhdr.n_namesz as usize == PVH_NOTE_STR_SZ {
            let mut buf = [0u8; PVH_NOTE_STR_SZ];
            kernel_image
                .read_exact(&mut buf)
                .map_err(|_| Error::ReadNoteHeader)?;
            if buf == [b'X', b'e', b'n', b'\0'] {
                break;
            }
        }
        // Skip the note header plus the size of its fields (with alignment).
        read_size += nhdr_sz
            + align_up(u64::from(nhdr.n_namesz), n_align)
            + align_up(u64::from(nhdr.n_descsz), n_align);
        kernel_image
            .seek(SeekFrom::Start(phdr.p_offset + read_size as u64))
            .map_err(|_| Error::SeekNoteHeader)?;
    }
    if read_size >= phdr.p_filesz as usize {
        // PVH ELF note not found, nothing else to do.
        return Ok(None);
    }
    // Otherwise the correct note type was found.
    // The note header struct has already been read, so we can seek from the current position and
    // just skip the name field contents.
    kernel_image
        .seek(SeekFrom::Current(
            align_up(u64::from(nhdr.n_namesz), n_align) as i64 - PVH_NOTE_STR_SZ as i64,
        ))
        .map_err(|_| Error::SeekNoteHeader)?;
    // The PVH entry point is a 32-bit address, so the descriptor field must be capable of storing
    // all such addresses.
    if (nhdr.n_descsz as usize) < mem::size_of::<u32>() {
        return Err(Error::InvalidPvhNote.into());
    }
    let mut pvh_addr_bytes = [0; mem::size_of::<u32>()];
    // Read 32-bit address stored in the PVH note descriptor field.
    kernel_image
        .read_exact(&mut pvh_addr_bytes)
        .map_err(|_| Error::ReadNoteHeader)?;
    Ok(Some(GuestAddress(
        u32::from_le_bytes(pvh_addr_bytes).into(),
    )))
}
fn parse_elf_note < F > ( phdr : & elf :: Elf64_Phdr , kernel_image : & mut F ) -> Result < Option < GuestAddress > > where F : Read + Seek , { // Type of note header that encodes a 32-bit entry point address to boot a guest kernel using // the PVH boot protocol. const XEN_ELFNOTE_PHYS32_ENTRY : u32 = 18 ; let n_align = phdr . p_align ; // Seek to the beginning of the note segment. kernel_image . seek ( SeekFrom :: Start ( phdr . p_offset ) ) . map_err ( | _ | Error :: SeekNoteHeader ) ? ; // Now that the segment has been found, we must locate an ELF note with the correct type that // encodes the PVH entry point if there is one. let mut nhdr : elf :: Elf64_Nhdr = Default :: default ( ) ; let mut read_size : usize = 0 ; let nhdr_sz = mem :: size_of :: < elf :: Elf64_Nhdr > ( ) ; while read_size < phdr . p_filesz as usize { nhdr . as_bytes ( ) . read_from ( 0 , kernel_image , nhdr_sz ) . map_err ( | _ | Error :: ReadNoteHeader ) ? ; // Check if the note header's name and type match the ones specified by the PVH ABI. if nhdr . n_type == XEN_ELFNOTE_PHYS32_ENTRY && nhdr . n_namesz as usize == PVH_NOTE_STR_SZ { let mut buf = [ 0u8 ; PVH_NOTE_STR_SZ ] ; kernel_image . read_exact ( & mut buf ) . map_err ( | _ | Error :: ReadNoteHeader ) ? ; if buf == [ b'X' , b'e' , b'n' , b'\0' ] { break ; } } // Skip the note header plus the size of its fields (with alignment). read_size += nhdr_sz + align_up ( u64 :: from ( nhdr . n_namesz ) , n_align ) + align_up ( u64 :: from ( nhdr . n_descsz ) , n_align ) ; kernel_image . seek ( SeekFrom :: Start ( phdr . p_offset + read_size as u64 ) ) . map_err ( | _ | Error :: SeekNoteHeader ) ? ; } if read_size >= phdr . p_filesz as usize { // PVH ELF note not found, nothing else to do. return Ok ( None ) ; } // Otherwise the correct note type was found. // The note header struct has already been read, so we can seek from the current position and // just skip the name field contents. kernel_image . seek ( SeekFrom :: Current ( align_up ( u64 :: from ( nhdr . n_namesz ) , n_align ) as i64 - PVH_NOTE_STR_SZ as i64 , ) ) . map_err ( | _ | Error :: SeekNoteHeader ) ? ; // The PVH entry point is a 32-bit address, so the descriptor field must be capable of storing // all such addresses. if ( nhdr . n_descsz as usize ) < mem :: size_of :: < u32 > ( ) { return Err ( Error :: InvalidPvhNote . into ( ) ) ; } let mut pvh_addr_bytes = [ 0 ; mem :: size_of :: < u32 > ( ) ] ; // Read 32-bit address stored in the PVH note descriptor field. kernel_image . read_exact ( & mut pvh_addr_bytes ) . map_err ( | _ | Error :: ReadNoteHeader ) ? ; Ok ( Some ( GuestAddress ( u32 :: from_le_bytes ( pvh_addr_bytes ) . into ( ) , ) ) ) }
Examines a supplied elf program header of type `PT_NOTE` to determine if it contains an entry
of type `XEN_ELFNOTE_PHYS32_ENTRY` (0x12).
Examines a supplied elf program header of type ` PT_NOTE ` to determine if it contains an entry of type ` XEN_ELFNOTE_PHYS32_ENTRY ` ( 0x12 ) .
phdr
&elf::Elf64_Phdr
kernel_image
&mut F
phdr
&elf::Elf64_Phdr
kernel_image
&mut F