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
|
use std::env;
use std::io::Write;
use getopts::Options;
use pdb::{FallibleIterator, SymbolData, PDB};
fn dump_pdb(filename: &str) -> pdb::Result<()> {
let file = std::fs::File::open(filename)?;
let mut pdb = PDB::open(file)?;
let address_map = pdb.address_map()?;
let string_table = pdb.string_table()?;
println!("Module private symbols:");
let dbi = pdb.debug_information()?;
let mut modules = dbi.modules()?;
while let Some(module) = modules.next()? {
println!();
println!("Module: {}", module.module_name());
let info = match pdb.module_info(&module)? {
Some(info) => info,
None => {
println!(" no module info");
continue;
}
};
let program = info.line_program()?;
let mut symbols = info.symbols()?;
while let Some(symbol) = symbols.next()? {
if let Ok(SymbolData::Procedure(proc)) = symbol.parse() {
let sign = if proc.global { "+" } else { "-" };
println!("{} {}", sign, proc.name);
let mut lines = program.lines_for_symbol(proc.offset);
while let Some(line_info) = lines.next()? {
let rva = line_info.offset.to_rva(&address_map).expect("invalid rva");
let file_info = program.get_file_info(line_info.file_index)?;
let file_name = file_info.name.to_string_lossy(&string_table)?;
println!(" {} {}:{}", rva, file_name, line_info.line_start);
}
}
}
}
Ok(())
}
fn main() {
let args: Vec<String> = env::args().collect();
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);
println!("specify path to a PDB");
return;
};
match dump_pdb(filename) {
Ok(_) => {}
Err(e) => {
writeln!(&mut std::io::stderr(), "error dumping PDB: {}", e).expect("stderr write");
}
}
}
|