Files
object/examples/nm.rs
T
Philip Craig 1bed32cf64 Change Symbol::name to Option<&str>
Because goblin is already parsing them as str, and for consistency with
section names.
2017-11-01 18:29:23 +10:00

91 lines
2.6 KiB
Rust

extern crate memmap;
extern crate object;
use std::{env, fs, process};
use object::{Object, SectionKind, SymbolKind};
fn main() {
let arg_len = env::args().len();
if arg_len <= 1 {
eprintln!("Usage: {} <file> ...", env::args().next().unwrap());
process::exit(1);
}
for file_path in env::args().skip(1) {
if arg_len > 2 {
println!();
println!("{}:", file_path);
}
let file = match fs::File::open(&file_path) {
Ok(file) => file,
Err(err) => {
println!("Failed to open file '{}': {}", file_path, err,);
continue;
}
};
let file = match unsafe { memmap::Mmap::map(&file) } {
Ok(mmap) => mmap,
Err(err) => {
println!("Failed to map file '{}': {}", file_path, err,);
continue;
}
};
let file = match object::File::parse(&*file) {
Ok(file) => file,
Err(err) => {
println!("Failed to parse file '{}': {}", file_path, err);
continue;
}
};
for symbol in &*file.symbols() {
match symbol.kind() {
SymbolKind::Section | SymbolKind::File => continue,
_ => {}
}
let kind = match symbol.section_kind() {
Some(SectionKind::Unknown) => '?',
Some(SectionKind::Text) => if symbol.is_global() {
'T'
} else {
't'
},
Some(SectionKind::Data) => if symbol.is_global() {
'D'
} else {
'd'
},
Some(SectionKind::ReadOnlyData) => if symbol.is_global() {
'R'
} else {
'r'
},
Some(SectionKind::UninitializedData) => if symbol.is_global() {
'B'
} else {
'b'
},
Some(SectionKind::Other) => if symbol.is_global() {
'S'
} else {
's'
},
None => 'U',
};
if symbol.is_undefined() {
print!("{:16} ", "");
} else {
print!("{:016x} ", symbol.address());
}
println!(
"{:016x} {} {}",
symbol.size(),
kind,
symbol.name().unwrap_or("<unknown>"),
);
}
}
}