Skip to main content

kernel/sched/loader/defs/
phdrs.rs

1// SPDX-License-Identifier: GPL-3.0-only
2//! ELF program header definitions
3//!
4//! Authors: MarioS271
5
6use super::error::ElfError;
7use super::header::ElfHeader;
8use core::slice::from_raw_parts;
9
10#[repr(C)]
11pub struct ElfPhdr {
12    pub p_type: u32,
13    pub p_flags: u32,
14    pub p_offset: u64,
15    pub p_vaddr: u64,
16    pub p_paddr: u64,
17    pub p_filesz: u64,
18    pub p_memsz: u64,
19    pub p_align: u64,
20}
21
22impl ElfPhdr {
23    pub const PT_LOAD: u32 = 1;
24    pub const PF_X: u32 = 1;
25    pub const PF_W: u32 = 2;
26    pub const PF_R: u32 = 4;
27}
28
29pub fn parse_phdrs<'a>(elf: &'a [u8], header: &ElfHeader) -> Result<&'a [ElfPhdr], ElfError> {
30    let phoff = header.e_phoff as usize;
31    let phnum = header.e_phnum as usize;
32    let phentsize = header.e_phentsize as usize;
33
34    let table_size = phnum.checked_mul(phentsize).ok_or(ElfError::PhdrsOutOfBounds)?;
35    let end = phoff.checked_add(table_size).ok_or(ElfError::PhdrsOutOfBounds)?;
36
37    if end > elf.len() {
38        return Err(ElfError::PhdrsOutOfBounds)
39    }
40
41    let base = unsafe { elf.as_ptr().add(phoff) };
42    if base as usize % align_of::<ElfPhdr>() != 0 {
43        return Err(ElfError::MisalignedPhdrs)
44    }
45
46    unsafe {
47        Ok(from_raw_parts(base as *const ElfPhdr, phnum))
48    }
49}