use super::utils::*;
use super::*;
use num_traits::{AsPrimitive, Zero};
pub trait ElfSectionAccessTrait {
ELFIO_GET_SET_ACCESS_DECL!(ElfWord, name_string_offset);
ELFIO_GET_SET_ACCESS_DECL!(ElfWord, type);
ELFIO_GET_SET_ACCESS_DECL!(ElfXword, flags);
ELFIO_GET_SET_ACCESS_DECL!(Elf64Addr, address);
ELFIO_GET_SET_ACCESS_DECL!(Elf64Off, offset);
ELFIO_GET_SET_ACCESS_DECL!(ElfXword, size);
ELFIO_GET_SET_ACCESS_DECL!(ElfWord, link);
ELFIO_GET_SET_ACCESS_DECL!(ElfWord, info);
ELFIO_GET_SET_ACCESS_DECL!(ElfXword, addr_align);
ELFIO_GET_SET_ACCESS_DECL!(ElfXword, entry_size);
fn get_name(&self) -> &str;
fn set_name(&mut self, name: &str);
fn get_data(&self) -> &[u8];
fn set_data(&mut self, data: &[u8]);
}
pub trait ElfSectionTrait: ElfSectionAccessTrait + Load {}
#[repr(C)]
#[derive(Debug)]
pub struct ElfSection<Addr, Offset, Word> {
sh_name: ElfWord,
sh_type: ElfWord,
sh_flags: Word,
sh_addr: Addr,
sh_offset: Offset,
sh_size: Word,
sh_link: ElfWord,
sh_info: ElfWord,
sh_addralign: Word,
sh_entsize: Word,
name: String,
converter: Converter,
data: Vec<u8>,
}
impl<Addr, Offset, Word> ElfSection<Addr, Offset, Word>
where
Addr: Zero + Load + AsPrimitive<u64>,
Offset: Zero + Load + AsPrimitive<u64>,
Word: Zero + Load + AsPrimitive<u64>,
Converter: Convert<Addr> + Convert<Offset> + Convert<Word>,
{
pub fn new(conv: &Converter) -> ElfSection<Addr, Offset, Word> {
Self {
converter: *conv,
name: String::from(""),
data: Vec::new(),
sh_name: 0,
sh_type: 0,
sh_flags: Word::zero(),
sh_addr: Addr::zero(),
sh_offset: Offset::zero(),
sh_size: Word::zero(),
sh_link: 0,
sh_info: 0,
sh_addralign: Word::zero(),
sh_entsize: Word::zero(),
}
}
}
impl<Addr, Offset, Word> ElfSectionTrait for ElfSection<Addr, Offset, Word>
where
u32: AsPrimitive<Addr> + AsPrimitive<Offset> + AsPrimitive<Word>,
u64: AsPrimitive<Addr> + AsPrimitive<Offset> + AsPrimitive<Word>,
Addr: Zero + Load + AsPrimitive<u64>,
Offset: Zero + Load + AsPrimitive<u64>,
Word: Zero + Load + AsPrimitive<u64>,
Converter: Convert<Addr> + Convert<Offset> + Convert<Word>,
{
}
impl<Addr, Offset, Word> ElfSectionAccessTrait for ElfSection<Addr, Offset, Word>
where
u32: AsPrimitive<Addr> + AsPrimitive<Offset> + AsPrimitive<Word>,
u64: AsPrimitive<Addr> + AsPrimitive<Offset> + AsPrimitive<Word>,
Addr: Zero + Load + AsPrimitive<u64>,
Offset: Zero + Load + AsPrimitive<u64>,
Word: Zero + Load + AsPrimitive<u64>,
Converter: Convert<Addr> + Convert<Offset> + Convert<Word>,
{
ELFIO_GET_SET_ACCESS!(ElfWord, name_string_offset, sh_name);
ELFIO_GET_SET_ACCESS!(ElfWord, type, sh_type);
ELFIO_GET_SET_ACCESS!(ElfXword, flags, sh_flags);
ELFIO_GET_SET_ACCESS!(Elf64Addr, address, sh_addr);
ELFIO_GET_SET_ACCESS!(Elf64Off, offset, sh_offset);
ELFIO_GET_SET_ACCESS!(ElfXword, size, sh_size);
ELFIO_GET_SET_ACCESS!(ElfWord, link, sh_link);
ELFIO_GET_SET_ACCESS!(ElfWord, info, sh_info);
ELFIO_GET_SET_ACCESS!(ElfXword, addr_align, sh_addralign);
ELFIO_GET_SET_ACCESS!(ElfXword, entry_size, sh_entsize);
fn get_name(&self) -> &str {
&self.name
}
fn set_name(&mut self, name: &str) {
self.name = name.to_string();
}
fn get_data(&self) -> &[u8] {
&self.data
}
fn set_data(&mut self, data: &[u8]) {
self.data = data.to_vec();
}
}
impl<Addr, Offset, Word> Load for ElfSection<Addr, Offset, Word>
where
u32: AsPrimitive<Addr> + AsPrimitive<Offset> + AsPrimitive<Word>,
u64: AsPrimitive<Addr> + AsPrimitive<Offset> + AsPrimitive<Word>,
Addr: Zero + Load + AsPrimitive<u64>,
Offset: Zero + Load + AsPrimitive<u64>,
Word: Zero + Load + AsPrimitive<u64>,
Converter: Convert<Addr> + Convert<Offset> + Convert<Word>,
{
fn load(&mut self, reader: &mut (dyn ElfioReadSeek)) -> io::Result<()> {
self.sh_name.load(reader)?;
self.sh_type.load(reader)?;
self.sh_flags.load(reader)?;
self.sh_addr.load(reader)?;
self.sh_offset.load(reader)?;
self.sh_size.load(reader)?;
self.sh_link.load(reader)?;
self.sh_info.load(reader)?;
self.sh_addralign.load(reader)?;
self.sh_entsize.load(reader)?;
self.data = vec![0; self.get_size().as_()];
if self.get_type() != constant::SHT_NULL && self.get_type() != constant::SHT_NOBITS {
reader.seek(io::SeekFrom::Start(self.get_offset()))?;
reader.read_exact(&mut self.data)?;
}
Ok(())
}
}