1use std::fs::File;
2
3use isr_core::{Profile, Symbols, types::Types};
4use pdb::PDB;
5
6use super::{Error, symbols::PdbSymbols as _, types::PdbTypes as _};
7
8pub fn create_profile<F, E>(pdb_file: File, serialize: F) -> Result<(), Error>
9where
10 F: FnOnce(&Profile) -> Result<(), E>,
11 E: std::error::Error + Send + Sync + 'static,
12{
13 let mut pdb = PDB::open(pdb_file)?;
14
15 tracing::debug!("collecting debug information");
16 let dbi = pdb.debug_information()?;
17 let architecture = dbi.machine_type()?.to_string().into();
18 tracing::debug!("architecture: {architecture}");
19
20 tracing::debug!("collecting symbols");
21 let address_map = pdb.address_map()?;
22 let symbol_table = pdb.global_symbols()?;
23 let symbols = Symbols::parse(address_map, symbol_table.iter())?;
24
25 tracing::debug!("collecting types");
26 let tpi = pdb.type_information()?;
27 let types = Types::parse(tpi.finder(), tpi.iter())?;
28
29 tracing::debug!("writing profile");
30 let profile = Profile::new(architecture, symbols, types);
31
32 serialize(&profile).map_err(|err| Error::Serialize(err.into()))?;
33
34 Ok(())
35}