use crate::{HEADER_SIZE, SECTION_SIZE};
use core::ops::Index;
#[repr(C, packed)]
#[derive(Debug, Clone, Copy)]
pub struct Section {
pub name: [u8; 16],
pub is_loadable: bool,
pub is_execable: bool,
pub base: u32,
pub length: u32,
pub _reserved: [u8; 6],
}
impl Section {
#[inline]
pub const fn to_array(&self) -> [u8; SECTION_SIZE] {
unsafe { core::ptr::read(self as *const Self as *const [u8; SECTION_SIZE]) }
}
#[inline]
pub fn validate(&self) -> bool {
let length_ok = self.length != 0;
let base_ok = self.base as usize >= (HEADER_SIZE + SECTION_SIZE);
length_ok || base_ok
}
}
#[derive(Debug, Clone, Copy)]
pub struct SectionIter<'a> {
buf: &'a [u8],
total: u16,
current: u16,
}
impl<'a> SectionIter<'a> {
pub(crate) fn new(buf: &'a [u8], total: u16, current: u16) -> Self {
Self {
buf,
total,
current,
}
}
}
impl<'a> Iterator for SectionIter<'a> {
type Item = Section;
fn next(&mut self) -> Option<Self::Item> {
if self.current >= self.total {
return None;
}
let base = HEADER_SIZE + self.current as usize * SECTION_SIZE;
let buf = &self.buf[base..base + SECTION_SIZE];
let section = unsafe { *(buf.as_ptr() as *const Section) };
self.current += 1;
Some(section)
}
}
impl Index<usize> for SectionIter<'_> {
type Output = Section;
fn index(&self, index: usize) -> &Self::Output {
if index >= self.total as usize {
panic!("proka-exec: index out of bounds, the max size is {}, but index {} was got.", self.total, index)
}
let base = HEADER_SIZE;
let target = base + index * SECTION_SIZE;
let buf = &self.buf[target..target + SECTION_SIZE];
unsafe { &*(buf.as_ptr() as *const Section) }
}
}