mirror of
https://github.com/encounter/object.git
synced 2026-03-30 11:32:22 -07:00
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:
+11
-5
@@ -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, §ion_kinds);
|
||||
}
|
||||
println!();
|
||||
|
||||
println!("Dynamic symbols:");
|
||||
for symbol in file.dynamic_symbols() {
|
||||
print_symbol(&symbol);
|
||||
print_symbol(&symbol, §ion_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
@@ -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
@@ -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
@@ -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(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user