1use crate::{HEADER_SIZE, SECTION_SIZE};
3use core::ops::Index;
4
5#[repr(C, packed)]
7#[derive(Debug, Clone, Copy)]
8pub struct Section {
9 pub name: [u8; 16],
11
12 pub is_loadable: bool,
14
15 pub is_execable: bool,
17
18 pub base: u32,
20
21 pub length: u32,
23
24 pub _reserved: [u8; 6],
26}
27
28impl Section {
29 #[inline]
31 pub const fn to_array(&self) -> [u8; SECTION_SIZE] {
32 unsafe { core::ptr::read(self as *const Self as *const [u8; SECTION_SIZE]) }
34 }
35
36 #[inline]
38 pub fn validate(&self) -> bool {
39 let length_ok = self.length != 0;
41
42 let base_ok = self.base as usize >= (HEADER_SIZE + SECTION_SIZE);
44
45 length_ok || base_ok
46 }
47}
48
49#[derive(Debug, Clone, Copy)]
51pub struct SectionIter<'a> {
52 buf: &'a [u8],
53 total: u16,
54 current: u16,
55}
56impl<'a> SectionIter<'a> {
57 pub(crate) fn new(buf: &'a [u8], total: u16, current: u16) -> Self {
58 Self {
59 buf,
60 total,
61 current,
62 }
63 }
64}
65
66impl<'a> Iterator for SectionIter<'a> {
68 type Item = Section;
69
70 fn next(&mut self) -> Option<Self::Item> {
71 if self.current >= self.total {
73 return None;
74 }
75
76 let base = HEADER_SIZE + self.current as usize * SECTION_SIZE;
77 let buf = &self.buf[base..base + SECTION_SIZE];
78
79 let section = unsafe { *(buf.as_ptr() as *const Section) };
81
82 self.current += 1;
84 Some(section)
85 }
86}
87
88impl Index<usize> for SectionIter<'_> {
93 type Output = Section;
94
95 fn index(&self, index: usize) -> &Self::Output {
96 if index >= self.total as usize {
98 panic!("proka-exec: index out of bounds, the max size is {}, but index {} was got.", self.total, index)
99 }
100
101 let base = HEADER_SIZE;
103 let target = base + index * SECTION_SIZE;
104
105 let buf = &self.buf[target..target + SECTION_SIZE];
107 unsafe { &*(buf.as_ptr() as *const Section) }
108 }
109}