Skip to content

Commit

Permalink
read/elf: small fixes to low level API (#685)
Browse files Browse the repository at this point in the history
Implement Default for SectionTable and RelocationSections.
Return a SectionIndex from SectionTable::section_by_name.
Add some helpers to Sym trait.
  • Loading branch information
philipc committed May 13, 2024
1 parent 017624a commit aa2f5ad
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 21 deletions.
2 changes: 1 addition & 1 deletion src/read/elf/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ where
.section_by_name(self.endian, section_name)
.map(|(index, section)| ElfSection {
file: self,
index: SectionIndex(index),
index,
section,
})
}
Expand Down
2 changes: 1 addition & 1 deletion src/read/elf/relocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<usize>,
}
Expand Down
25 changes: 14 additions & 11 deletions src/read/elf/section.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand All @@ -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]
Expand Down Expand Up @@ -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))
}

Expand Down Expand Up @@ -133,16 +140,12 @@ impl<'data, Elf: FileHeader, R: ReadRef<'data>> SectionTable<'data, Elf, R> {
) -> read::Result<SymbolTable<'data, Elf, R>> {
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.
Expand Down
36 changes: 28 additions & 8 deletions src/read/elf/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")?;
Expand Down Expand Up @@ -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]
Expand All @@ -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 {
Expand All @@ -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]
Expand Down Expand Up @@ -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
Expand All @@ -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<Endian: endian::Endian> Sym for elf::Sym32<Endian> {
Expand Down

0 comments on commit aa2f5ad

Please sign in to comment.