From bd3812250a05c59b319e79c34bd086c9a9773343 Mon Sep 17 00:00:00 2001 From: Philip Craig Date: Mon, 13 May 2024 14:56:43 +1000 Subject: [PATCH] read/elf: small fixes to low level API Implement Default for SectionTable and RelocationSections. Return a SectionIndex from SectionTable::section_by_name. Add some helpers to Sym trait. --- src/read/elf/file.rs | 2 +- src/read/elf/relocation.rs | 2 +- src/read/elf/section.rs | 25 ++++++++++++++----------- src/read/elf/symbol.rs | 36 ++++++++++++++++++++++++++++-------- 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/src/read/elf/file.rs b/src/read/elf/file.rs index 55b51bf5..ca4e3ef9 100644 --- a/src/read/elf/file.rs +++ b/src/read/elf/file.rs @@ -147,7 +147,7 @@ where .section_by_name(self.endian, section_name) .map(|(index, section)| ElfSection { file: self, - index: SectionIndex(index), + index, section, }) } diff --git a/src/read/elf/relocation.rs b/src/read/elf/relocation.rs index a0ae7bfe..3790e027 100644 --- a/src/read/elf/relocation.rs +++ b/src/read/elf/relocation.rs @@ -14,7 +14,7 @@ use crate::read::{ use super::{ElfFile, FileHeader, SectionHeader, SectionTable}; /// A mapping from section index to associated relocation sections. -#[derive(Debug)] +#[derive(Debug, Default)] pub struct RelocationSections { relocations: Vec, } diff --git a/src/read/elf/section.rs b/src/read/elf/section.rs index dba63870..6e0e615e 100644 --- a/src/read/elf/section.rs +++ b/src/read/elf/section.rs @@ -20,7 +20,7 @@ use super::{ /// Also includes the string table used for the section names. /// /// Returned by [`FileHeader::sections`]. -#[derive(Debug, Default, Clone, Copy)] +#[derive(Debug, Clone, Copy)] pub struct SectionTable<'data, Elf: FileHeader, R = &'data [u8]> where R: ReadRef<'data>, @@ -29,6 +29,15 @@ where strings: StringTable<'data, R>, } +impl<'data, Elf: FileHeader, R: ReadRef<'data>> Default for SectionTable<'data, Elf, R> { + fn default() -> Self { + SectionTable { + sections: &[], + strings: StringTable::default(), + } + } +} + impl<'data, Elf: FileHeader, R: ReadRef<'data>> SectionTable<'data, Elf, R> { /// Create a new section table. #[inline] @@ -86,10 +95,8 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SectionTable<'data, Elf, R> { &self, endian: Elf::Endian, name: &[u8], - ) -> Option<(usize, &'data Elf::SectionHeader)> { - self.sections - .iter() - .enumerate() + ) -> Option<(SectionIndex, &'data Elf::SectionHeader)> { + self.enumerate() .find(|(_, section)| self.section_name(endian, section) == Ok(name)) } @@ -133,16 +140,12 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SectionTable<'data, Elf, R> { ) -> read::Result> { debug_assert!(sh_type == elf::SHT_DYNSYM || sh_type == elf::SHT_SYMTAB); - let (index, section) = match self - .iter() - .enumerate() - .find(|s| s.1.sh_type(endian) == sh_type) - { + let (index, section) = match self.enumerate().find(|s| s.1.sh_type(endian) == sh_type) { Some(s) => s, None => return Ok(SymbolTable::default()), }; - SymbolTable::parse(endian, data, self, SectionIndex(index), section) + SymbolTable::parse(endian, data, self, index, section) } /// Return the symbol table at the given section index. diff --git a/src/read/elf/symbol.rs b/src/read/elf/symbol.rs index a0066abe..3c0bee35 100644 --- a/src/read/elf/symbol.rs +++ b/src/read/elf/symbol.rs @@ -69,9 +69,9 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SymbolTable<'data, Elf, R> { let mut shndx_section = SectionIndex(0); let mut shndx = &[][..]; - for (i, s) in sections.iter().enumerate() { + for (i, s) in sections.enumerate() { if s.sh_type(endian) == elf::SHT_SYMTAB_SHNDX && s.link(endian) == section_index { - shndx_section = SectionIndex(i); + shndx_section = i; shndx = s .data_as_array(endian, data) .read_error("Invalid ELF symtab_shndx data")?; @@ -431,7 +431,7 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> #[inline] fn is_undefined(&self) -> bool { - self.symbol.st_shndx(self.endian) == elf::SHN_UNDEF + self.symbol.is_undefined(self.endian) } #[inline] @@ -441,12 +441,12 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> #[inline] fn is_common(&self) -> bool { - self.symbol.st_shndx(self.endian) == elf::SHN_COMMON + self.symbol.is_common(self.endian) } #[inline] fn is_weak(&self) -> bool { - self.symbol.st_bind() == elf::STB_WEAK + self.symbol.is_weak() } fn scope(&self) -> SymbolScope { @@ -469,12 +469,12 @@ impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ObjectSymbol<'data> #[inline] fn is_global(&self) -> bool { - self.symbol.st_bind() != elf::STB_LOCAL + !self.symbol.is_local() } #[inline] fn is_local(&self) -> bool { - self.symbol.st_bind() == elf::STB_LOCAL + self.symbol.is_local() } #[inline] @@ -513,7 +513,7 @@ pub trait Sym: Debug + Pod { .read_error("Invalid ELF symbol name offset") } - /// Return true if the symbol is undefined. + /// Return true if the symbol section is `SHN_UNDEF`. #[inline] fn is_undefined(&self, endian: Self::Endian) -> bool { self.st_shndx(endian) == elf::SHN_UNDEF @@ -531,6 +531,26 @@ pub trait Sym: Debug + Pod { _ => false, } } + + /// Return true if the symbol section is `SHN_COMMON`. + fn is_common(&self, endian: Self::Endian) -> bool { + self.st_shndx(endian) == elf::SHN_COMMON + } + + /// Return true if the symbol section is `SHN_ABS`. + fn is_absolute(&self, endian: Self::Endian) -> bool { + self.st_shndx(endian) == elf::SHN_ABS + } + + /// Return true if the symbol binding is `STB_LOCAL`. + fn is_local(&self) -> bool { + self.st_bind() == elf::STB_LOCAL + } + + /// Return true if the symbol binding is `STB_WEAK`. + fn is_weak(&self) -> bool { + self.st_bind() == elf::STB_WEAK + } } impl Sym for elf::Sym32 {