From 07ef93f16a29d4d8c20123113bd3ec8988cf169a Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 13 May 2025 22:48:39 -0600 Subject: [PATCH] Ignore extern symbols with symbol name lookups When searching for a symbol by name, only look at symbols that are defined within the object, ignoring extern symbols (symbols without section). Fixes #180 Fixes #181 --- objdiff-cli/src/views/function_diff.rs | 15 +++------------ objdiff-core/src/diff/mod.rs | 14 +++++--------- objdiff-core/src/obj/mod.rs | 4 ++++ objdiff-gui/src/views/diff.rs | 8 +++----- 4 files changed, 15 insertions(+), 26 deletions(-) diff --git a/objdiff-cli/src/views/function_diff.rs b/objdiff-cli/src/views/function_diff.rs index 0c95cd4..3366eef 100644 --- a/objdiff-cli/src/views/function_diff.rs +++ b/objdiff-cli/src/views/function_diff.rs @@ -450,11 +450,11 @@ impl UiView for FunctionDiffUi { fn reload(&mut self, state: &AppState) -> Result<()> { let left_sym = - state.left_obj.as_ref().and_then(|(o, _)| find_function(o, &self.symbol_name)); + state.left_obj.as_ref().and_then(|(o, _)| o.symbol_by_name(&self.symbol_name)); let right_sym = - state.right_obj.as_ref().and_then(|(o, _)| find_function(o, &self.symbol_name)); + state.right_obj.as_ref().and_then(|(o, _)| o.symbol_by_name(&self.symbol_name)); let prev_sym = - state.prev_obj.as_ref().and_then(|(o, _)| find_function(o, &self.symbol_name)); + state.prev_obj.as_ref().and_then(|(o, _)| o.symbol_by_name(&self.symbol_name)); self.num_rows = match ( get_symbol(state.left_obj.as_ref(), left_sym), get_symbol(state.right_obj.as_ref(), right_sym), @@ -650,12 +650,3 @@ fn get_symbol( let sym = sym?; Some((obj, sym, &diff.symbols[sym])) } - -fn find_function(obj: &Object, name: &str) -> Option { - for (symbol_idx, symbol) in obj.symbols.iter().enumerate() { - if symbol.name == name { - return Some(symbol_idx); - } - } - None -} diff --git a/objdiff-core/src/diff/mod.rs b/objdiff-core/src/diff/mod.rs index c1bc3b0..73e8a94 100644 --- a/objdiff-core/src/diff/mod.rs +++ b/objdiff-core/src/diff/mod.rs @@ -391,7 +391,7 @@ fn generate_mapping_symbols( MappingSymbol::Left(name) => (left_obj, name, right_obj), MappingSymbol::Right(name) => (right_obj, name, left_obj), }; - let Some(base_symbol_ref) = symbol_ref_by_name(base_obj, base_name) else { + let Some(base_symbol_ref) = base_obj.symbol_by_name(base_name) else { return Ok(()); }; let base_section_kind = symbol_section_kind(base_obj, &base_obj.symbols[base_symbol_ref]); @@ -457,10 +457,6 @@ pub struct MappingConfig { pub selecting_right: Option, } -fn symbol_ref_by_name(obj: &Object, name: &str) -> Option { - obj.symbols.iter().position(|s| s.name == name) -} - fn apply_symbol_mappings( left: &Object, right: &Object, @@ -472,25 +468,25 @@ fn apply_symbol_mappings( // If we're selecting a symbol to use as a comparison, mark it as used // This ensures that we don't match it to another symbol at any point if let Some(left_name) = &mapping_config.selecting_left { - if let Some(left_symbol) = symbol_ref_by_name(left, left_name) { + if let Some(left_symbol) = left.symbol_by_name(left_name) { left_used.insert(left_symbol); } } if let Some(right_name) = &mapping_config.selecting_right { - if let Some(right_symbol) = symbol_ref_by_name(right, right_name) { + if let Some(right_symbol) = right.symbol_by_name(right_name) { right_used.insert(right_symbol); } } // Apply manual symbol mappings for (left_name, right_name) in &mapping_config.mappings { - let Some(left_symbol_index) = symbol_ref_by_name(left, left_name) else { + let Some(left_symbol_index) = left.symbol_by_name(left_name) else { continue; }; if left_used.contains(&left_symbol_index) { continue; } - let Some(right_symbol_index) = symbol_ref_by_name(right, right_name) else { + let Some(right_symbol_index) = right.symbol_by_name(right_name) else { continue; }; if right_used.contains(&right_symbol_index) { diff --git a/objdiff-core/src/obj/mod.rs b/objdiff-core/src/obj/mod.rs index d8a13f9..e182ed9 100644 --- a/objdiff-core/src/obj/mod.rs +++ b/objdiff-core/src/obj/mod.rs @@ -308,6 +308,10 @@ impl Object { let offset = symbol.address.checked_sub(section.address)?; section.data.get(offset as usize..offset as usize + symbol.size as usize) } + + pub fn symbol_by_name(&self, name: &str) -> Option { + self.symbols.iter().position(|symbol| symbol.section.is_some() && symbol.name == name) + } } #[derive(Debug, Clone, Eq, PartialEq, Hash)] diff --git a/objdiff-gui/src/views/diff.rs b/objdiff-gui/src/views/diff.rs index 3390d93..6af6b8b 100644 --- a/objdiff-gui/src/views/diff.rs +++ b/objdiff-gui/src/views/diff.rs @@ -49,7 +49,9 @@ impl<'a> DiffColumnContext<'a> { let selected_symbol = match view { View::SymbolDiff => None, View::FunctionDiff | View::ExtabDiff => match (obj, selected_symbol) { - (Some(obj), Some(s)) => find_symbol(&obj.0, s).map(SelectedSymbol::Symbol), + (Some(obj), Some(s)) => { + obj.0.symbol_by_name(&s.symbol_name).map(SelectedSymbol::Symbol) + } _ => None, }, View::DataDiff => match (obj, selected_symbol) { @@ -779,10 +781,6 @@ fn missing_obj_ui(ui: &mut Ui, appearance: &Appearance) { }); } -fn find_symbol(obj: &Object, selected_symbol: &SymbolRefByName) -> Option { - obj.symbols.iter().position(|symbol| symbol.name == selected_symbol.symbol_name) -} - fn find_section(obj: &Object, section_name: &str) -> Option { obj.sections.iter().position(|section| section.name == section_name) }