use std::env; use std::io::Write; use pdb2 as pdb; 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 = 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"); } } }