diff --git a/objdiff-cli/src/cmd/diff.rs b/objdiff-cli/src/cmd/diff.rs index 186936d..59a4761 100644 --- a/objdiff-cli/src/cmd/diff.rs +++ b/objdiff-cli/src/cmd/diff.rs @@ -88,9 +88,13 @@ pub fn run(args: Args) -> Result<()> { let mut count = 0usize; for (i, obj) in project_config.objects.iter_mut().enumerate() { resolve_paths(obj); - if load_obj(&obj.target_path)? - .and_then(|o| find_function(&o, &args.symbol)) - .is_some() + + if obj + .target_path + .as_deref() + .map(|o| obj::elf::has_function(o, &args.symbol)) + .transpose()? + .unwrap_or_default() { idx = Some(i); count += 1; @@ -175,12 +179,6 @@ pub fn run(args: Args) -> Result<()> { Ok(()) } -fn load_obj(path: &Option) -> Result> { - path.as_deref() - .map(|p| obj::elf::read(p).with_context(|| format!("Loading {}", p.display()))) - .transpose() -} - fn find_function(obj: &ObjInfo, name: &str) -> Option { for section in &obj.sections { if section.kind != ObjSectionKind::Code { @@ -533,8 +531,16 @@ impl FunctionDiffUi { } fn reload(&mut self) -> Result<()> { - let mut target = load_obj(&self.target_path)?; - let mut base = load_obj(&self.base_path)?; + let mut target = self + .target_path + .as_deref() + .map(|p| obj::elf::read(p).with_context(|| format!("Loading {}", p.display()))) + .transpose()?; + let mut base = self + .base_path + .as_deref() + .map(|p| obj::elf::read(p).with_context(|| format!("Loading {}", p.display()))) + .transpose()?; let config = diff::DiffObjConfig::default(); diff::diff_objs(&config, target.as_mut(), base.as_mut())?; diff --git a/objdiff-core/src/obj/elf.rs b/objdiff-core/src/obj/elf.rs index 57ff70c..06ad30b 100644 --- a/objdiff-core/src/obj/elf.rs +++ b/objdiff-core/src/obj/elf.rs @@ -394,6 +394,17 @@ pub fn read(obj_path: &Path) -> Result { Ok(result) } +pub fn has_function(obj_path: &Path, symbol_name: &str) -> Result { + let data = { + let file = fs::File::open(obj_path)?; + unsafe { memmap2::Mmap::map(&file) }? + }; + Ok(File::parse(&*data)? + .symbol_by_name(symbol_name) + .filter(|o| o.kind() == SymbolKind::Text) + .is_some()) +} + fn split_meta(obj_file: &File<'_>) -> Result> { Ok(if let Some(section) = obj_file.section_by_name(SPLITMETA_SECTION) { if section.size() != 0 {