use super::utils::Convert;
use super::*;
use std::convert::TryFrom;
#[derive(Debug, Default)]
pub struct Array {
pub value: Elf64Addr,
}
#[repr(C)]
#[derive(Default)]
struct Elf32Array {
pub value: Elf32Addr,
}
#[repr(C)]
#[derive(Default)]
struct Elf64Array {
pub value: Elf64Addr,
}
pub struct ArraySectionAccessor<'a> {
elfio: &'a Elfio,
section: &'a dyn ElfSectionTrait,
}
impl<'a> ArraySectionAccessor<'a> {
pub fn new(elfio: &'a Elfio, section: &'a dyn ElfSectionTrait) -> ArraySectionAccessor<'a> {
ArraySectionAccessor { elfio, section }
}
pub fn get_entries_num(&self) -> ElfXword {
let entry_size;
if self.elfio.get_class() == constant::ELFCLASS64 {
entry_size = 8;
} else {
entry_size = 4;
}
if entry_size != 0 {
return self.section.get_size() / entry_size;
}
0
}
pub fn get_entry(&self, index: ElfXword) -> Option<Array> {
let entries_num = self.get_entries_num();
if entries_num == 0 || index > entries_num - 1 {
return None;
}
let entry_size;
if self.elfio.get_class() == constant::ELFCLASS64 {
entry_size = 8;
} else {
entry_size = 4;
}
let offset: usize = (index * entry_size) as usize;
let end: usize = offset + entry_size as usize;
let entry_area = &self.section.get_data()[offset..end];
let converter = self.elfio.get_converter();
if self.elfio.get_class() == constant::ELFCLASS64 {
let entry = Elf64Array {
value: converter.convert(u64::from_ne_bytes(
<[u8; 8]>::try_from(&entry_area[0..8])
.unwrap_or([0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8]),
)),
};
Some(Array { value: entry.value })
} else {
let entry = Elf32Array {
value: converter.convert(u32::from_ne_bytes(
<[u8; 4]>::try_from(&entry_area[0..4]).unwrap_or([0u8, 0u8, 0u8, 0u8]),
)),
};
Some(Array {
value: entry.value as Elf64Addr,
})
}
}
}