use std::env;
use getopts::Options;
use pdb::FallibleIterator;
fn print_usage(program: &str, opts: Options) {
let brief = format!("Usage: {} input.pdb", program);
print!("{}", opts.usage(&brief));
}
fn dump_framedata(filename: &str) -> pdb::Result<()> {
let file = std::fs::File::open(filename)?;
let mut pdb = pdb::PDB::open(file)?;
let string_table = pdb.string_table()?;
println!("Frame data:");
println!("Address Blk Size Locals Params StkMax Prolog SavedReg SEH C++EH Start BP Type Program");
println!();
let frame_table = pdb.frame_table()?;
let mut frames = frame_table.iter();
while let Some(data) = frames.next()? {
let program_string = match data.program {
Some(prog_ref) => prog_ref.to_string_lossy(&string_table)?,
None => Default::default(),
};
println!(
"{} {:8x} {:8x} {:8x} {:8x} {:8x} {:8x} {} {} {} {} {:5} {}",
data.code_start,
data.code_size,
data.locals_size,
data.params_size,
data.max_stack_size.unwrap_or(0),
data.prolog_size,
data.saved_regs_size,
if data.has_structured_eh { 'Y' } else { 'N' },
if data.has_cpp_eh { 'Y' } else { 'N' },
if data.is_function_start { 'Y' } else { 'N' },
if data.uses_base_pointer { 'Y' } else { 'N' },
data.ty,
program_string,
);
}
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_framedata(filename) {
Ok(_) => (),
Err(e) => eprintln!("error dumping PDB: {}", e),
}
}