/// A table of symbol entries in an ELF file. /// /// Also includes the string table used for the symbol names. /// /// Returned by [`SectionTable::symbols`]. #[derive(Debug, Clone, Copy)] pubstruct SymbolTable<'data, Elf: FileHeader, R = &'data [u8]> where
R: ReadRef<'data>,
{
section: SectionIndex,
string_section: SectionIndex,
shndx_section: SectionIndex,
symbols: &'data [Elf::Sym],
strings: StringTable<'data, R>,
shndx: &'data [U32<Elf::Endian>],
}
/// Return the section index of this symbol table. #[inline] pubfn section(&self) -> SectionIndex { self.section
}
/// Return the section index of the shndx table. #[inline] pubfn shndx_section(&self) -> SectionIndex { self.shndx_section
}
/// Return the section index of the linked string table. #[inline] pubfn string_section(&self) -> SectionIndex { self.string_section
}
/// Return the string table used for the symbol names. #[inline] pubfn strings(&self) -> StringTable<'data, R> { self.strings
}
/// Return the symbol table. #[inline] pubfn symbols(&self) -> &'data [Elf::Sym] { self.symbols
}
/// Iterate over the symbols. /// /// This includes the null symbol at index 0, which you will usually need to skip. #[inline] pubfn iter(&self) -> slice::Iter<'data, Elf::Sym> { self.symbols.iter()
}
/// Iterate over the symbols and their indices. /// /// This includes the null symbol at index 0, which you will usually need to skip. #[inline] pubfn enumerate(&self) -> impl Iterator<Item = (SymbolIndex, &tyle='color:blue'>'data Elf::Sym)> { self.symbols
.iter()
.enumerate()
.map(|(i, sym)| (SymbolIndex(i), sym))
}
/// Return true if the symbol table is empty. #[inline] pubfn is_empty(&self) -> bool { self.symbols.is_empty()
}
/// The number of symbols. #[inline] pubfn len(&self) -> usize { self.symbols.len()
}
/// Get the symbol at the given index. /// /// Returns an error for null entry at index 0. pubfn symbol(&self, index: SymbolIndex) -> read::Result<&e='color:blue'>'data Elf::Sym> { if index == SymbolIndex(0) { return Err(read::Error("Invalid ELF symbol index"));
} self.symbols
.get(index.0)
.read_error("Invalid ELF symbol index")
}
/// Return the extended section index for the given symbol if present. #[inline] pubfn shndx(&self, endian: Elf::Endian, index: SymbolIndex) -> Option<u32> { self.shndx.get(index.0).map(|x| x.get(endian))
}
/// Return the section index for the given symbol. /// /// This uses the extended section index if present. pubfn symbol_section(
&self,
endian: Elf::Endian,
symbol: &Elf::Sym,
index: SymbolIndex,
) -> read::Result<Option<SectionIndex>> { match symbol.st_shndx(endian) {
elf::SHN_UNDEF => Ok(None),
elf::SHN_XINDEX => { let shndx = self
.shndx(endian, index)
.read_error("Missing ELF symbol extended index")?; if shndx == 0 {
Ok(None)
} else {
Ok(Some(SectionIndex(shndx as usize)))
}
}
shndx if shndx < elf::SHN_LORESERVE => Ok(Some(SectionIndex(shndx.into()))),
_ => Ok(None),
}
}
/// Return the symbol name for the given symbol. pubfn symbol_name(&self, endian: Elf::Endian, symbol: &Elf::Sym) -> read::Result<&'data [u8]> {
symbol.name(endian, self.strings)
}
/// Construct a map from addresses to a user-defined map entry. pubfn map<Entry: SymbolMapEntry, F: Fn(&'data Elf::Sym) -> Option<Entry>>(
&self,
endian: Elf::Endian,
f: F,
) -> SymbolMap<Entry> { letmut symbols = Vec::with_capacity(self.symbols.len()); for symbol inself.symbols { if !symbol.is_definition(endian) { continue;
} iflet Some(entry) = f(symbol) {
symbols.push(entry);
}
}
SymbolMap::new(symbols)
}
}
/// A symbol table in an [`ElfFile32`](super::ElfFile32). pubtype ElfSymbolTable32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
ElfSymbolTable<'data, 'file, elf::FileHeader32<Endian>, R>; /// A symbol table in an [`ElfFile32`](super::ElfFile32). pubtype ElfSymbolTable64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
ElfSymbolTable<'data, 'file, elf::FileHeader64<Endian>, R>;
/// A symbol table in an [`ElfFile`](super::ElfFile). #[derive(Debug, Clone, Copy)] pubstruct ElfSymbolTable<'data, 'file, Elf, R = &'data [u8]> where
Elf: FileHeader,
R: ReadRef<'data>,
{ pub(super) endian: Elf::Endian, pub(super) symbols: &'file SymbolTable<'data, Elf, R>,
}
/// An iterator for the symbols in an [`ElfFile32`](super::ElfFile32). pubtype ElfSymbolIterator32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
ElfSymbolIterator<'data, 'file, elf::FileHeader32<Endian>, R>; /// An iterator for the symbols in an [`ElfFile64`](super::ElfFile64). pubtype ElfSymbolIterator64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
ElfSymbolIterator<'data, 'file, elf::FileHeader64<Endian>, R>;
/// An iterator for the symbols in an [`ElfFile`](super::ElfFile). pubstruct ElfSymbolIterator<'data, 'file, Elf, R = &'data [u8]> where
Elf: FileHeader,
R: ReadRef<'data>,
{
endian: Elf::Endian,
symbols: &'file SymbolTable<'data, Elf, R>,
index: SymbolIndex,
}
impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> Iterator for ElfSymbolIterator<'data, 'file, Elf, R>
{ type Item = ElfSymbol<'data, 'file, Elf, R>;
fn next(&mutself) -> Option<Self::Item> { let index = self.index; let symbol = self.symbols.symbols.get(index.0)?; self.index.0 += 1;
Some(ElfSymbol {
endian: self.endian,
symbols: self.symbols,
index,
symbol,
})
}
}
/// A symbol in an [`ElfFile32`](super::ElfFile32). pubtype ElfSymbol32<'data, 'file, Endian = Endianness, R = &'data [u8]> =
ElfSymbol<'data, 'file, elf::FileHeader32<Endian>, R>; /// A symbol in an [`ElfFile64`](super::ElfFile64). pubtype ElfSymbol64<'data, 'file, Endian = Endianness, R = &'data [u8]> =
ElfSymbol<'data, 'file, elf::FileHeader64<Endian>, R>;
/// A symbol in an [`ElfFile`](super::ElfFile). /// /// Most functionality is provided by the [`ObjectSymbol`] trait implementation. #[derive(Debug, Clone, Copy)] pubstruct ElfSymbol<'data, 'file, Elf, R = &'data [u8]> where
Elf: FileHeader,
R: ReadRef<'data>,
{ pub(super) endian: Elf::Endian, pub(super) symbols: &'file SymbolTable<'data, Elf, R>, pub(super) index: SymbolIndex, pub(super) symbol: &'data Elf::Sym,
}
impl<'data, 'file, Elf: FileHeader, R: ReadRef<'data>> ElfSymbol<'data, 'file, Elf, R> { /// Get the endianness of the ELF file. pubfn endian(&self) -> Elf::Endian { self.endian
}
/// Return a reference to the raw symbol structure. #[inline] #[deprecated(note = "Use `elf_symbol` instead")] pubfn raw_symbol(&self) -> &'data Elf::Sym { self.symbol
}
/// Get the raw ELF symbol structure. pubfn elf_symbol(&self) -> &'data Elf::Sym { self.symbol
}
}
/// A trait for generic access to [`elf::Sym32`] and [`elf::Sym64`]. #[allow(missing_docs)] pubtrait Sym: Debug + Pod { type Word: Into<u64>; type Endian: endian::Endian;
/// Parse the symbol name from the string table. fn name<'data, R: ReadRef<'data>>(
&self,
endian: Self::Endian,
strings: StringTable<'data, R>,
) -> read::Result<&'data [u8]> {
strings
.get(self.st_name(endian))
.read_error("Invalid ELF symbol name offset")
}
/// 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
}
/// Return true if the symbol is a definition of a function or data object. fn is_definition(&self, endian: Self::Endian) -> bool { let shndx = self.st_shndx(endian); if shndx == elf::SHN_UNDEF || (shndx >= elf::SHN_LORESERVE && shndx != elf::SHN_XINDEX) { returnfalse;
} matchself.st_type() {
elf::STT_NOTYPE => self.st_size(endian).into() != 0,
elf::STT_FUNC | elf::STT_OBJECT => true,
_ => 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> { type Word = u32; type Endian = Endian;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.