use crate::errors::FileParseError;
use crate::field::{ByteOrder, Field};
pub struct SectionBlob<'a> {
pub section_index: usize,
pub data: &'a [u8],
}
pub struct EhFrameHdr {
pub version: Field<u8>,
pub eh_frame_ptr_enc: Field<u8>,
pub fde_count_enc: Field<u8>,
pub table_enc: Field<u8>,
pub payload: Vec<u8>,
}
impl EhFrameHdr {
pub fn parse(buffer: &[u8], offset: usize, size: usize) -> Result<Self, FileParseError> {
if size < 4 || buffer.len() < offset + size {
return Err(FileParseError::BufferOverflow);
}
Ok(Self {
version: Field::new(buffer[offset], offset, 1),
eh_frame_ptr_enc: Field::new(buffer[offset + 1], offset + 1, 1),
fde_count_enc: Field::new(buffer[offset + 2], offset + 2, 1),
table_enc: Field::new(buffer[offset + 3], offset + 3, 1),
payload: buffer[offset + 4..offset + size].to_vec(),
})
}
}
pub struct AddressArrayEntry {
pub value: Field<u64>,
}
pub struct AddressArray {
pub entries: Vec<AddressArrayEntry>,
}
impl AddressArray {
pub fn parse(
buffer: &[u8],
offset: usize,
size: usize,
width: usize,
order: ByteOrder,
) -> Result<Self, FileParseError> {
if width != 4 && width != 8 {
return Err(FileParseError::InvalidFileFormat);
}
let end = offset
.checked_add(size)
.ok_or(FileParseError::BufferOverflow)?;
let mut cursor = offset;
let mut entries = Vec::with_capacity(size / width);
while cursor + width <= end {
let value = if width == 4 {
order.read_u32(buffer, cursor)? as u64
} else {
order.read_u64(buffer, cursor)?
};
entries.push(AddressArrayEntry {
value: Field::new(value, cursor, width),
});
cursor += width;
}
Ok(Self { entries })
}
}