]>
Commit | Line | Data |
---|---|---|
fc512014 XL |
1 | use object::{ |
2 | Object, ObjectSection, ObjectSymbol, SectionIndex, SectionKind, Symbol, SymbolKind, | |
3 | SymbolSection, | |
4 | }; | |
f035d41b XL |
5 | use std::collections::HashMap; |
6 | use std::{env, fs, process}; | |
7 | ||
8 | fn main() { | |
9 | let arg_len = env::args().len(); | |
10 | if arg_len <= 1 { | |
11 | eprintln!("Usage: {} <file> ...", env::args().next().unwrap()); | |
12 | process::exit(1); | |
13 | } | |
14 | ||
15 | for file_path in env::args().skip(1) { | |
16 | if arg_len > 2 { | |
17 | println!(); | |
18 | println!("{}:", file_path); | |
19 | } | |
20 | ||
21 | let file = match fs::File::open(&file_path) { | |
22 | Ok(file) => file, | |
23 | Err(err) => { | |
24 | println!("Failed to open file '{}': {}", file_path, err,); | |
25 | continue; | |
26 | } | |
27 | }; | |
28 | let file = match unsafe { memmap::Mmap::map(&file) } { | |
29 | Ok(mmap) => mmap, | |
30 | Err(err) => { | |
31 | println!("Failed to map file '{}': {}", file_path, err,); | |
32 | continue; | |
33 | } | |
34 | }; | |
35 | let file = match object::File::parse(&*file) { | |
36 | Ok(file) => file, | |
37 | Err(err) => { | |
38 | println!("Failed to parse file '{}': {}", file_path, err); | |
39 | continue; | |
40 | } | |
41 | }; | |
42 | ||
43 | let section_kinds = file.sections().map(|s| (s.index(), s.kind())).collect(); | |
44 | ||
45 | println!("Debugging symbols:"); | |
fc512014 | 46 | for symbol in file.symbols() { |
f035d41b XL |
47 | print_symbol(&symbol, §ion_kinds); |
48 | } | |
49 | println!(); | |
50 | ||
51 | println!("Dynamic symbols:"); | |
fc512014 | 52 | for symbol in file.dynamic_symbols() { |
f035d41b XL |
53 | print_symbol(&symbol, §ion_kinds); |
54 | } | |
55 | } | |
56 | } | |
57 | ||
fc512014 | 58 | fn print_symbol(symbol: &Symbol<'_, '_>, section_kinds: &HashMap<SectionIndex, SectionKind>) { |
f035d41b XL |
59 | if let SymbolKind::Section | SymbolKind::File = symbol.kind() { |
60 | return; | |
61 | } | |
62 | ||
63 | let mut kind = match symbol.section() { | |
64 | SymbolSection::Unknown | SymbolSection::None => '?', | |
65 | SymbolSection::Undefined => 'U', | |
66 | SymbolSection::Absolute => 'A', | |
67 | SymbolSection::Common => 'C', | |
68 | SymbolSection::Section(index) => match section_kinds.get(&index) { | |
69 | None | |
70 | | Some(SectionKind::Unknown) | |
71 | | Some(SectionKind::Other) | |
72 | | Some(SectionKind::OtherString) | |
73 | | Some(SectionKind::Debug) | |
74 | | Some(SectionKind::Linker) | |
75 | | Some(SectionKind::Note) | |
76 | | Some(SectionKind::Metadata) => '?', | |
77 | Some(SectionKind::Text) => 't', | |
78 | Some(SectionKind::Data) | Some(SectionKind::Tls) | Some(SectionKind::TlsVariables) => { | |
79 | 'd' | |
80 | } | |
81 | Some(SectionKind::ReadOnlyData) | Some(SectionKind::ReadOnlyString) => 'r', | |
82 | Some(SectionKind::UninitializedData) | Some(SectionKind::UninitializedTls) => 'b', | |
83 | Some(SectionKind::Common) => 'C', | |
84 | }, | |
85 | }; | |
86 | ||
87 | if symbol.is_global() { | |
88 | kind = kind.to_ascii_uppercase(); | |
89 | } | |
90 | ||
91 | if symbol.is_undefined() { | |
92 | print!("{:16} ", ""); | |
93 | } else { | |
94 | print!("{:016x} ", symbol.address()); | |
95 | } | |
96 | println!( | |
97 | "{:016x} {} {}", | |
98 | symbol.size(), | |
99 | kind, | |
100 | symbol.name().unwrap_or("<unknown>"), | |
101 | ); | |
102 | } |