diff --git a/objdiff-core/src/arch/arm.rs b/objdiff-core/src/arch/arm.rs index 35416c9f..ba839cdd 100644 --- a/objdiff-core/src/arch/arm.rs +++ b/objdiff-core/src/arch/arm.rs @@ -184,6 +184,7 @@ impl Arch for ArchArm { .disasm_modes .get(§ion_index) .map(|x| x.as_slice()) + .filter(|x| !x.is_empty()) .unwrap_or(&fallback_mappings); let first_mapping_idx = mapping_symbols .binary_search_by_key(&start_addr, |x| x.address) diff --git a/objdiff-core/tests/arch_arm.rs b/objdiff-core/tests/arch_arm.rs index 9c507e1d..caab3a71 100644 --- a/objdiff-core/tests/arch_arm.rs +++ b/objdiff-core/tests/arch_arm.rs @@ -98,3 +98,22 @@ fn trim_trailing_hword() { let output = common::display_diff(&obj, &diff, symbol_idx, &diff_config); insta::assert_snapshot!(output); } + +#[test] +#[cfg(feature = "arm")] +fn no_mapping_symbols_in_text() { + // A .text section that contains code bytes but is not covered by any + // mapping symbol must not panic while scanning instructions. + let diff_config = diff::DiffObjConfig::default(); + let obj = obj::read::parse( + include_object!("data/arm/issue_352.o"), + &diff_config, + diff::DiffSide::Base, + ) + .unwrap(); + for (symbol_idx, symbol) in obj.symbols.iter().enumerate() { + if symbol.section.is_some() && symbol.size > 0 { + let _ = diff::code::no_diff_code(&obj, symbol_idx, &diff_config); + } + } +} diff --git a/objdiff-core/tests/data/arm/issue_352.o b/objdiff-core/tests/data/arm/issue_352.o new file mode 100644 index 00000000..6b13eaa7 Binary files /dev/null and b/objdiff-core/tests/data/arm/issue_352.o differ