forked from getsentry/pdb
-
Notifications
You must be signed in to change notification settings - Fork 3
/
pdb_symbols.rs
97 lines (82 loc) · 2.54 KB
/
pdb_symbols.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use std::env;
use getopts::Options;
use pdb::{FallibleIterator, PdbInternalSectionOffset};
fn print_usage(program: &str, opts: Options) {
let brief = format!("Usage: {} input.pdb", program);
print!("{}", opts.usage(&brief));
}
fn print_row(offset: PdbInternalSectionOffset, kind: &str, name: pdb::RawString<'_>) {
println!(
"{:x}\t{:x}\t{}\t{}",
offset.section, offset.offset, kind, name
);
}
fn print_symbol(symbol: &pdb::Symbol<'_>) -> pdb::Result<()> {
match symbol.parse()? {
pdb::SymbolData::Public(data) => {
print_row(data.offset, "function", data.name);
}
pdb::SymbolData::Data(data) => {
print_row(data.offset, "data", data.name);
}
pdb::SymbolData::Procedure(data) => {
print_row(data.offset, "function", data.name);
}
_ => {
// ignore everything else
}
}
Ok(())
}
fn walk_symbols(mut symbols: pdb::SymbolIter<'_>) -> pdb::Result<()> {
println!("segment\toffset\tkind\tname");
while let Some(symbol) = symbols.next()? {
match print_symbol(&symbol) {
Ok(_) => (),
Err(e) => eprintln!("error printing symbol {:?}: {}", symbol, e),
}
}
Ok(())
}
fn dump_pdb(filename: &str) -> pdb::Result<()> {
let file = std::fs::File::open(filename)?;
let mut pdb = pdb::PDB::open(file)?;
let symbol_table = pdb.global_symbols()?;
println!("Global symbols:");
walk_symbols(symbol_table.iter())?;
println!("Module private symbols:");
let dbi = pdb.debug_information()?;
let mut modules = dbi.modules()?;
while let Some(module) = modules.next()? {
println!("Module: {}", module.object_file_name());
let info = match pdb.module_info(&module)? {
Some(info) => info,
None => {
println!(" no module info");
continue;
}
};
walk_symbols(info.symbols()?)?;
}
Ok(())
}
fn main() {
let args: Vec<String> = env::args().collect();
let program = args[0].clone();
let mut opts = Options::new();
opts.optflag("h", "help", "print this help menu");
let matches = match opts.parse(&args[1..]) {
Ok(m) => m,
Err(f) => panic!("{}", f.to_string()),
};
let filename = if matches.free.len() == 1 {
&matches.free[0]
} else {
print_usage(&program, opts);
return;
};
match dump_pdb(filename) {
Ok(_) => (),
Err(e) => eprintln!("error dumping PDB: {}", e),
}
}