summaryrefslogtreecommitdiff
path: root/rust/examples/pdb-ng/src/symbol_parser.rs
diff options
context:
space:
mode:
authorJosh Ferrell <josh@vector35.com>2024-06-09 12:17:54 -0400
committerJosh Ferrell <josh@vector35.com>2024-06-10 15:17:01 -0400
commit43d478cf39f8faef9cf9d16ca47d3edd8152f4cb (patch)
tree95e60d5e324243246455e03dc0e6f47d7530327a /rust/examples/pdb-ng/src/symbol_parser.rs
parentd2ee93856b455a2fbd5a42b52bfe847d1c7f29d1 (diff)
Large PDB parsing performance improvements
Diffstat (limited to 'rust/examples/pdb-ng/src/symbol_parser.rs')
-rw-r--r--rust/examples/pdb-ng/src/symbol_parser.rs95
1 files changed, 48 insertions, 47 deletions
diff --git a/rust/examples/pdb-ng/src/symbol_parser.rs b/rust/examples/pdb-ng/src/symbol_parser.rs
index 5a1d8761..a80f4841 100644
--- a/rust/examples/pdb-ng/src/symbol_parser.rs
+++ b/rust/examples/pdb-ng/src/symbol_parser.rs
@@ -14,6 +14,7 @@
use std::collections::{BTreeMap, HashMap, HashSet};
use std::mem;
+use std::sync::OnceLock;
use anyhow::{anyhow, Result};
use itertools::Itertools;
@@ -515,7 +516,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
self.log(|| format!("Symbol {:?} ", sym.index()));
let (name, address) =
- if let Some(parsed) = self.handle_symbol_index(sym.index(), sym)? {
+ if let Some(parsed) = self.handle_symbol_index(sym.index(), &sym)? {
final_symbols.insert(sym.index());
match parsed {
ParsedSymbol::Data(ParsedDataSymbol { name, address, .. }) => {
@@ -617,17 +618,14 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
fn handle_symbol_index(
&mut self,
idx: SymbolIndex,
- sym: Symbol,
+ sym: &Symbol,
) -> Result<Option<&ParsedSymbol>> {
if let None = self.indexed_symbols.get(&idx) {
match sym.parse() {
Ok(data) => match self.handle_symbol(idx, &data) {
Ok(Some(parsed)) => {
self.log(|| format!("Symbol {} parsed into: {:?}", idx, parsed));
- match &parsed {
- _ => {}
- }
- self.indexed_symbols.insert(idx, parsed.clone());
+ self.indexed_symbols.insert(idx, parsed);
}
Ok(None) => {}
e => {
@@ -1786,7 +1784,7 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
raw_name: &String,
rva: Rva,
) -> Result<(Option<Conf<Ref<Type>>>, Option<QualifiedName>)> {
- let (mut t, mut name) = match demangle_ms(&self.arch, raw_name.clone(), true) {
+ let (mut t, mut name) = match demangle_ms(&self.arch, raw_name, true) {
Ok((Some(t), name)) => (Some(Conf::new(t, DEMANGLE_CONFIDENCE)), name),
Ok((_, name)) => (None, name),
_ => (None, vec![raw_name.clone()]),
@@ -1818,48 +1816,51 @@ impl<'a, S: Source<'a> + 'a> PDBParserInstance<'a, S> {
// These have types but they aren't actually set anywhere. So it's the demangler's
// job to take care of them, apparently?
- let name_to_type: HashMap<String, Vec<String>> = HashMap::from_iter([
- (
- "`RTTI Complete Object Locator'".to_string(),
- vec![
- "_s_RTTICompleteObjectLocator".to_string(),
- "_s__RTTICompleteObjectLocator".to_string(),
- "_s__RTTICompleteObjectLocator2".to_string(),
- ],
- ),
- (
- "`RTTI Class Hierarchy Descriptor'".to_string(),
- vec![
- "_s_RTTIClassHierarchyDescriptor".to_string(),
- "_s__RTTIClassHierarchyDescriptor".to_string(),
- "_s__RTTIClassHierarchyDescriptor2".to_string(),
- ],
- ),
- (
- // TODO: This type is dynamic
- "`RTTI Base Class Array'".to_string(),
- vec![
- "_s_RTTIBaseClassArray".to_string(),
- "_s__RTTIBaseClassArray".to_string(),
- "_s__RTTIBaseClassArray2".to_string(),
- ],
- ),
- (
- "`RTTI Base Class Descriptor at (".to_string(),
- vec![
- "_s_RTTIBaseClassDescriptor".to_string(),
- "_s__RTTIBaseClassDescriptor".to_string(),
- "_s__RTTICBaseClassDescriptor2".to_string(),
- ],
- ),
- (
- "`RTTI Type Descriptor'".to_string(),
- vec!["_TypeDescriptor".to_string()],
- ),
- ]);
+ static MEM: OnceLock<Vec<(String, Vec<String>)>> = OnceLock::new();
+ let name_to_type = MEM.get_or_init(|| {
+ vec![
+ (
+ "`RTTI Complete Object Locator'".to_string(),
+ vec![
+ "_s_RTTICompleteObjectLocator".to_string(),
+ "_s__RTTICompleteObjectLocator".to_string(),
+ "_s__RTTICompleteObjectLocator2".to_string(),
+ ],
+ ),
+ (
+ "`RTTI Class Hierarchy Descriptor'".to_string(),
+ vec![
+ "_s_RTTIClassHierarchyDescriptor".to_string(),
+ "_s__RTTIClassHierarchyDescriptor".to_string(),
+ "_s__RTTIClassHierarchyDescriptor2".to_string(),
+ ],
+ ),
+ (
+ // TODO: This type is dynamic
+ "`RTTI Base Class Array'".to_string(),
+ vec![
+ "_s_RTTIBaseClassArray".to_string(),
+ "_s__RTTIBaseClassArray".to_string(),
+ "_s__RTTIBaseClassArray2".to_string(),
+ ],
+ ),
+ (
+ "`RTTI Base Class Descriptor at (".to_string(),
+ vec![
+ "_s_RTTIBaseClassDescriptor".to_string(),
+ "_s__RTTIBaseClassDescriptor".to_string(),
+ "_s__RTTICBaseClassDescriptor2".to_string(),
+ ],
+ ),
+ (
+ "`RTTI Type Descriptor'".to_string(),
+ vec!["_TypeDescriptor".to_string()],
+ ),
+ ]
+ });
if let Some(last_name) = name.last() {
- for (search_name, search_types) in &name_to_type {
+ for (search_name, search_types) in name_to_type.iter() {
if last_name.contains(search_name) {
for search_type in search_types {
if let Some(ty) = self.named_types.get(search_type) {