Delete Symbol::section_kind

This didn't map cleanly to all object file formats, and can be obtained
via Symbol::section_index instead.

Also, SymbolKind::Unknown is now used more often, instead of trying to
derive something from the section kind.
This commit is contained in:
Philip Craig
2019-04-10 18:59:58 +10:00
parent fba2cba1f8
commit c600365c7c
5 changed files with 33 additions and 71 deletions
+11 -5
View File
@@ -1,4 +1,5 @@
use object::{Object, SectionKind, Symbol, SymbolKind};
use object::{Object, ObjectSection, SectionIndex, SectionKind, Symbol, SymbolKind};
use std::collections::HashMap;
use std::{env, fs, process};
fn main() {
@@ -36,25 +37,30 @@ fn main() {
}
};
let section_kinds = file.sections().map(|s| (s.index(), s.kind())).collect();
println!("Debugging symbols:");
for symbol in file.symbols() {
print_symbol(&symbol);
print_symbol(&symbol, &section_kinds);
}
println!();
println!("Dynamic symbols:");
for symbol in file.dynamic_symbols() {
print_symbol(&symbol);
print_symbol(&symbol, &section_kinds);
}
}
}
fn print_symbol(symbol: &Symbol<'_>) {
fn print_symbol(symbol: &Symbol<'_>, section_kinds: &HashMap<SectionIndex, SectionKind>) {
if let SymbolKind::Section | SymbolKind::File = symbol.kind() {
return;
}
let mut kind = match symbol.section_kind() {
let mut kind = match symbol
.section_index()
.and_then(|index| section_kinds.get(&index))
{
Some(SectionKind::Unknown) => '?',
Some(SectionKind::Text) => 't',
Some(SectionKind::Data) => 'd',
+11 -25
View File
@@ -74,7 +74,6 @@ where
{
strtab: &'file strtab::Strtab<'data>,
symbols: elf::sym::SymIterator<'data>,
section_kinds: Vec<SectionKind>,
}
/// An iterator over the relocations in an `ElfSection`.
@@ -193,18 +192,16 @@ where
}
fn symbol_by_index(&self, index: u64) -> Option<Symbol<'data>> {
// TODO: determine section_kind too
self.elf
.syms
.get(index as usize)
.map(|symbol| parse_symbol(&symbol, &self.elf.strtab, &[]))
.map(|symbol| parse_symbol(&symbol, &self.elf.strtab))
}
fn symbols(&'file self) -> ElfSymbolIterator<'data, 'file> {
ElfSymbolIterator {
strtab: &self.elf.strtab,
symbols: self.elf.syms.iter(),
section_kinds: self.sections().map(|x| x.kind()).collect(),
}
}
@@ -212,7 +209,6 @@ where
ElfSymbolIterator {
strtab: &self.elf.dynstrtab,
symbols: self.elf.dynsyms.iter(),
section_kinds: self.sections().map(|x| x.kind()).collect(),
}
}
@@ -498,15 +494,11 @@ impl<'data, 'file> Iterator for ElfSymbolIterator<'data, 'file> {
fn next(&mut self) -> Option<Self::Item> {
self.symbols
.next()
.map(|symbol| parse_symbol(&symbol, self.strtab, &self.section_kinds))
.map(|symbol| parse_symbol(&symbol, self.strtab))
}
}
fn parse_symbol<'data>(
symbol: &elf::sym::Sym,
strtab: &strtab::Strtab<'data>,
section_kinds: &[SectionKind],
) -> Symbol<'data> {
fn parse_symbol<'data>(symbol: &elf::sym::Sym, strtab: &strtab::Strtab<'data>) -> Symbol<'data> {
let name = strtab.get(symbol.st_name).and_then(Result::ok);
let kind = match elf::sym::st_type(symbol.st_info) {
elf::sym::STT_OBJECT => SymbolKind::Data,
@@ -517,26 +509,20 @@ fn parse_symbol<'data>(
elf::sym::STT_TLS => SymbolKind::Tls,
_ => SymbolKind::Unknown,
};
let section_index = if symbol.st_shndx == elf::section_header::SHN_UNDEF as usize
|| symbol.st_shndx >= elf::section_header::SHN_LORESERVE as usize
{
None
} else {
Some(SectionIndex(symbol.st_shndx))
};
let section_kind = section_index.map(|index| {
section_kinds
.get(index.0)
.cloned()
.unwrap_or(SectionKind::Unknown)
});
let undefined = symbol.st_shndx == elf::section_header::SHN_UNDEF as usize;
let section_index =
if undefined || symbol.st_shndx >= elf::section_header::SHN_LORESERVE as usize {
None
} else {
Some(SectionIndex(symbol.st_shndx))
};
Symbol {
name,
address: symbol.st_value,
size: symbol.st_size,
kind,
section_index,
section_kind,
undefined,
global: elf::sym::st_bind(symbol.st_info) != elf::sym::STB_LOCAL,
}
}
+2 -8
View File
@@ -231,7 +231,7 @@ where
pub struct Symbol<'data> {
kind: SymbolKind,
section_index: Option<SectionIndex>,
section_kind: Option<SectionKind>,
undefined: bool,
global: bool,
name: Option<&'data str>,
address: u64,
@@ -636,16 +636,10 @@ impl<'data> Symbol<'data> {
self.section_index
}
/// Returns the section kind for the symbol, or `None` if the symbol is undefined.
#[inline]
pub fn section_kind(&self) -> Option<SectionKind> {
self.section_kind
}
/// Return true if the symbol is undefined.
#[inline]
pub fn is_undefined(&self) -> bool {
self.section_kind.is_none()
self.undefined
}
/// Return true if the symbol is global.
+7 -31
View File
@@ -66,7 +66,6 @@ where
/// An iterator over the symbols of a `MachOFile`.
pub struct MachOSymbolIterator<'data> {
symbols: mach::symbols::SymbolIterator<'data>,
section_kinds: Vec<SectionKind>,
}
/// An iterator over the relocations in an `MachOSection`.
@@ -161,12 +160,11 @@ where
}
fn symbol_by_index(&self, index: u64) -> Option<Symbol<'data>> {
// TODO: determine section_kind too
self.macho
.symbols
.as_ref()
.and_then(|symbols| symbols.get(index as usize).ok())
.and_then(|(name, nlist)| parse_symbol(name, &nlist, &[]))
.and_then(|(name, nlist)| parse_symbol(name, &nlist))
}
fn symbols(&'file self) -> MachOSymbolIterator<'data> {
@@ -175,12 +173,7 @@ where
None => mach::symbols::SymbolIterator::default(),
};
let section_kinds = self.sections().map(|section| section.kind()).collect();
MachOSymbolIterator {
symbols,
section_kinds,
}
MachOSymbolIterator { symbols }
}
fn dynamic_symbols(&'file self) -> MachOSymbolIterator<'data> {
@@ -200,7 +193,7 @@ where
size: 0,
kind: SymbolKind::Section,
section_index: None,
section_kind: None,
undefined: false,
global: false,
});
}
@@ -401,7 +394,7 @@ impl<'data> Iterator for MachOSymbolIterator<'data> {
fn next(&mut self) -> Option<Self::Item> {
while let Some(Ok((name, nlist))) = self.symbols.next() {
let symbol = parse_symbol(name, &nlist, &self.section_kinds);
let symbol = parse_symbol(name, &nlist);
if symbol.is_some() {
return symbol;
}
@@ -410,11 +403,7 @@ impl<'data> Iterator for MachOSymbolIterator<'data> {
}
}
fn parse_symbol<'data>(
name: &'data str,
nlist: &mach::symbols::Nlist,
section_kinds: &[SectionKind],
) -> Option<Symbol<'data>> {
fn parse_symbol<'data>(name: &'data str, nlist: &mach::symbols::Nlist) -> Option<Symbol<'data>> {
if nlist.n_type & mach::symbols::N_STAB != 0 {
return None;
}
@@ -429,27 +418,14 @@ fn parse_symbol<'data>(
// TODO: better handling for other n_type values
None
};
let section_kind = section_index.map(|index| {
section_kinds
.get(index.0 - 1)
.cloned()
.unwrap_or(SectionKind::Unknown)
});
let kind = match section_kind {
Some(SectionKind::Text) => SymbolKind::Text,
Some(SectionKind::Data)
| Some(SectionKind::ReadOnlyData)
| Some(SectionKind::UninitializedData) => SymbolKind::Data,
_ => SymbolKind::Unknown,
};
Some(Symbol {
name: Some(name),
address: nlist.n_value,
// Only calculated for symbol maps
size: 0,
kind,
kind: SymbolKind::Unknown,
section_index,
section_kind,
undefined: nlist.is_undefined(),
global: nlist.is_global(),
})
}
+2 -2
View File
@@ -298,7 +298,7 @@ impl<'data, 'file> Iterator for PeSymbolIterator<'data, 'file> {
kind: SymbolKind::Unknown,
// TODO: can we find a section?
section_index: None,
section_kind: Some(SectionKind::Unknown),
undefined: false,
global: true,
name: export.name,
address: export.rva as u64,
@@ -313,7 +313,7 @@ impl<'data, 'file> Iterator for PeSymbolIterator<'data, 'file> {
return Some(Symbol {
kind: SymbolKind::Unknown,
section_index: None,
section_kind: None,
undefined: true,
global: true,
name,
address: 0,