isr-pdb 0.6.0

PDB parser for ISR
Documentation
use isr_core::schema::Profile;
use pdb::{AddressMap, Error, FallibleIterator, SymbolData, SymbolIter};

pub trait PdbSymbols<'p> {
    fn parse_symbols<'s>(
        &mut self,
        address_map: AddressMap<'s>,
        symbol_iter: SymbolIter<'p>,
    ) -> Result<(), Error>;
}

impl<'p> PdbSymbols<'p> for Profile {
    fn parse_symbols<'s>(
        &mut self,
        address_map: AddressMap<'s>,
        mut symbol_iter: SymbolIter<'p>,
    ) -> Result<(), Error> {
        while let Some(symbol) = symbol_iter.next()? {
            if let SymbolData::Public(data) = symbol.parse()? {
                let name = match std::str::from_utf8(data.name.as_bytes()) {
                    Ok(name) => name,
                    Err(_) => {
                        tracing::warn!(
                            name = %data.name,
                            "failed to convert symbol name to UTF-8"
                        );
                        continue;
                    }
                };

                let rva = match data.offset.to_rva(&address_map) {
                    Some(rva) => rva,
                    None => {
                        tracing::trace!(
                            name = %name,
                            rva = ?data.offset,
                            "failed to convert offset to RVA"
                        );
                        continue;
                    }
                };

                if let Some(v) = self.symbols.insert(name.to_owned(), u32::from(rva) as _) {
                    tracing::warn!(
                        name = %name,
                        rva1 = ?v,
                        rva2 = ?rva,
                        "duplicate symbol name with different RVAs"
                    );
                }
            }
        }

        Ok(())
    }
}