1use crate::{HEADER_SIZE, Result, Error, SECTION_SIZE};
3use core::ops::Index;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum SectionError {
8 LengthError,
12
13 BaseError(u32),
19
20
21 EntryOffsetOutOfRange(u32, u32),
27}
28
29#[repr(C, packed)]
31#[derive(Debug, Clone, Copy)]
32pub struct Section {
33 pub name: [u8; 16],
35
36 pub is_loadable: bool,
38
39 pub is_execable: bool,
41
42 pub base: u32,
44
45 pub length: u32,
47
48 pub _reserved: [u8; 6],
50}
51
52impl Section {
53 #[inline]
55 pub const fn to_array(&self) -> [u8; SECTION_SIZE] {
56 unsafe { core::ptr::read(self as *const Self as *const [u8; SECTION_SIZE]) }
58 }
59
60 #[inline]
62 pub fn validate(&self) -> Result<()> {
63 if self.length == 0 {
65 return Err(Error::SectionError(SectionError::LengthError));
66 }
67
68 if self.base as usize >= (HEADER_SIZE + SECTION_SIZE) {
70 return Err(Error::SectionError(SectionError::BaseError(self.base)));
71 }
72
73 Ok(())
74 }
75}
76
77#[derive(Debug, Clone, Copy)]
79pub struct SectionIter<'a> {
80 buf: &'a [u8],
81 total: u16,
82 current: u16,
83}
84impl<'a> SectionIter<'a> {
85 pub(crate) fn new(buf: &'a [u8], total: u16, current: u16) -> Self {
86 Self {
87 buf,
88 total,
89 current,
90 }
91 }
92}
93
94impl<'a> Iterator for SectionIter<'a> {
96 type Item = Section;
97
98 fn next(&mut self) -> Option<Self::Item> {
99 if self.current >= self.total {
101 return None;
102 }
103
104 let base = HEADER_SIZE + self.current as usize * SECTION_SIZE;
105 let buf = &self.buf[base..base + SECTION_SIZE];
106
107 let section = unsafe { *(buf.as_ptr() as *const Section) };
109
110 self.current += 1;
112 Some(section)
113 }
114}
115
116impl Index<usize> for SectionIter<'_> {
121 type Output = Section;
122
123 fn index(&self, index: usize) -> &Self::Output {
124 if index >= self.total as usize {
126 panic!(
127 "proka-exec: index out of bounds, the max size is {}, but index {} was got.",
128 self.total, index
129 )
130 }
131
132 let base = HEADER_SIZE;
134 let target = base + index * SECTION_SIZE;
135
136 let buf = &self.buf[target..target + SECTION_SIZE];
138 unsafe { &*(buf.as_ptr() as *const Section) }
139 }
140}