Skip to content

Commit 4a78742

Browse files
committed
Fix data flow analysis for multiple text sections
* Data flow analysis results were only keyed by the symbol (function) address. That doen't work if there are multiple text sections, the result from the first function in one section will stomp the result from the first function in another because both have address zero. * Remove the ambiguity by keying off of the section address as well.
1 parent bd3ed0d commit 4a78742

File tree

3 files changed

+20
-5
lines changed

3 files changed

+20
-5
lines changed

objdiff-core/src/diff/display.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ pub fn display_row(
189189
let mut arg_idx = 0;
190190
let mut displayed_relocation = false;
191191
let analysis_result = if diff_config.show_data_flow {
192-
obj.flow_analysis_results.get(&resolved.symbol.address)
192+
obj.get_flow_analysis_result(&resolved.symbol)
193193
} else {
194194
None
195195
};

objdiff-core/src/obj/mod.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ pub struct Object {
273273
pub path: Option<std::path::PathBuf>,
274274
#[cfg(feature = "std")]
275275
pub timestamp: Option<filetime::FileTime>,
276-
pub flow_analysis_results: BTreeMap<u64, Box<dyn FlowAnalysisResult>>,
276+
flow_analysis_results: BTreeMap<u64, Box<dyn FlowAnalysisResult>>,
277277
}
278278

279279
impl Default for Object {
@@ -328,6 +328,16 @@ impl Object {
328328
self.symbols.iter().position(|symbol| symbol.section.is_some() && symbol.name == name)
329329
}
330330

331+
pub fn get_flow_analysis_result(&self, symbol: &Symbol) -> Option<&Box<dyn FlowAnalysisResult>> {
332+
let key = symbol.section.unwrap_or_default() as u64 + symbol.address;
333+
self.flow_analysis_results.get(&key)
334+
}
335+
336+
pub fn add_flow_analysis_result(&mut self, symbol: &Symbol, result: Box<dyn FlowAnalysisResult>) {
337+
let key = symbol.section.unwrap_or_default() as u64 + symbol.address;
338+
self.flow_analysis_results.insert(key, result);
339+
}
340+
331341
pub fn has_flow_analysis_result(&self) -> bool { !self.flow_analysis_results.is_empty() }
332342
}
333343

objdiff-core/src/obj/read.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use core::{cmp::Ordering, num::NonZeroU64};
88

99
use anyhow::{Context, Result, anyhow, bail, ensure};
1010
use object::{Object as _, ObjectSection as _, ObjectSymbol as _};
11+
use crate::obj::FlowAnalysisResult;
1112

1213
use crate::{
1314
arch::{Arch, new_arch},
@@ -439,6 +440,7 @@ fn perform_data_flow_analysis(obj: &mut Object, config: &DiffObjConfig) -> Resul
439440
}
440441

441442
let mut generated_relocations = Vec::<(usize, Vec<Relocation>)>::new();
443+
let mut generated_flow_results = Vec::<(Symbol, Box<dyn FlowAnalysisResult>)>::new();
442444
for (section_index, section) in obj.sections.iter().enumerate() {
443445
if section.kind != SectionKind::Code {
444446
continue;
@@ -474,12 +476,15 @@ fn perform_data_flow_analysis(obj: &mut Object, config: &DiffObjConfig) -> Resul
474476

475477
// Optional full data flow analysis
476478
if config.analyze_data_flow {
477-
obj.arch.data_flow_analysis(obj, symbol, code, &section.relocations).and_then(
478-
|flow_result| obj.flow_analysis_results.insert(symbol.address, flow_result),
479-
);
479+
if let Some(flow_result) = obj.arch.data_flow_analysis(obj, symbol, code, &section.relocations) {
480+
generated_flow_results.push((symbol.clone(), flow_result));
481+
}
480482
}
481483
}
482484
}
485+
for (symbol, flow_result) in generated_flow_results {
486+
obj.add_flow_analysis_result(&symbol, flow_result);
487+
}
483488
for (section_index, mut relocations) in generated_relocations {
484489
obj.sections[section_index].relocations.append(&mut relocations);
485490
}

0 commit comments

Comments
 (0)