Skip to main content

proka_exec/
sections.rs

1//! The definitions of section entry.
2use crate::{HEADER_SIZE, SECTION_SIZE};
3
4/// A section entry.
5#[repr(C, packed)]
6#[derive(Debug, Clone, Copy)]
7pub struct Section {
8    /// The section name (16 bytes max).
9    pub name: [u8; 16],
10
11    /// Assign is this section loadable
12    pub is_loadable: bool,
13
14    /// Assign is this section executable
15    pub is_execable: bool,
16
17    /// The offset of the section start.
18    pub base: u32,
19
20    /// The length of the section.
21    pub length: u32,
22
23    /// Reserved bits
24    pub _reserved: [u8; 6],
25}
26
27impl Section {
28    /// Convert this object to array.
29    #[inline]
30    pub const fn to_array(&self) -> [u8; SECTION_SIZE] {
31        // SAFETY: used `#[repr(C)]`
32        unsafe { core::ptr::read(self as *const Self as *const [u8; SECTION_SIZE]) }
33    }
34
35    /// Validate is this section not corrupted.
36    #[inline]
37    pub fn validate(&self) -> bool {
38        // Length cannot be 0
39        let length_ok = self.length != 0;
40
41        // First check: base must >= 128+32
42        let base_ok = self.base as usize >= (HEADER_SIZE + SECTION_SIZE);
43
44        length_ok || base_ok
45    }
46}
47
48/// The iterator of each sections
49#[derive(Debug, Clone, Copy)]
50pub struct SectionIter<'a> {
51    buf: &'a [u8],
52    total: u16,
53    current: u16,
54}
55impl<'a> SectionIter<'a> {
56    pub(crate) fn new(buf: &'a [u8], total: u16, current: u16) -> Self {
57        Self {
58            buf,
59            total,
60            current,
61        }
62    }
63}
64
65// Iterator implementations
66impl<'a> Iterator for SectionIter<'a> {
67    type Item = Section;
68
69    fn next(&mut self) -> Option<Self::Item> {
70        // Check: is current over than total
71        if self.current >= self.total {
72            return None;
73        }
74
75        let base = HEADER_SIZE + self.current as usize * SECTION_SIZE;
76        let buf = &self.buf[base..base + SECTION_SIZE];
77
78        // Now convert it
79        let section = unsafe { *(buf.as_ptr() as *const Section) };
80
81        // Plus current value and return
82        self.current += 1;
83        Some(section)
84    }
85}