Skip to content

Commit cea4cd7

Browse files
committed
Fix scan_instructions_internal when reading 2-bytes instruction
1 parent 4171615 commit cea4cd7

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

objdiff-core/src/arch/arm.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,9 @@ impl Arch for ArchArm {
224224
}
225225

226226
// Check how many bytes we can/should read
227-
let num_code_bytes = if data.len() >= 4 {
227+
let bytes_until_next_mapping =
228+
next_mapping.map(|m| (m.address - address) as usize).unwrap_or(usize::MAX);
229+
let num_code_bytes = if data.len() >= 4 && bytes_until_next_mapping >= 4 {
228230
if mode == unarm::ParseMode::Data && address & 3 != 0 {
229231
// 32-bit .word value should be aligned on a 4-byte boundary, otherwise use .hword
230232
2

objdiff-core/tests/arch_arm.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,31 @@ fn combine_text_sections() {
5757
insta::assert_snapshot!(output);
5858
}
5959

60+
#[test]
61+
#[cfg(feature = "arm")]
62+
fn thumb_short_data_mapping() {
63+
// When a .2byte directive is used in Thumb code, the assembler emits
64+
// $d/$t mapping symbols for a 2-byte data region. The disassembler must
65+
// not read 4 bytes as a .word when the next mapping symbol limits the
66+
// data region to 2 bytes.
67+
let diff_config = diff::DiffObjConfig::default();
68+
let obj = obj::read::parse(
69+
include_object!("data/arm/code_1_vblank.o"),
70+
&diff_config,
71+
diff::DiffSide::Base,
72+
)
73+
.unwrap();
74+
let symbol_idx = obj.symbols.iter().position(|s| s.name == "VBlankDMA_Level1").unwrap();
75+
let diff = diff::code::no_diff_code(&obj, symbol_idx, &diff_config).unwrap();
76+
let output = common::display_diff(&obj, &diff, symbol_idx, &diff_config);
77+
// .2byte data followed by Thumb code must not be merged into a 4-byte .word
78+
assert!(
79+
!output.contains(".word"),
80+
"2-byte data regions should not be decoded as 4-byte .word values.\n\
81+
The disassembler must respect mapping symbol boundaries."
82+
);
83+
}
84+
6085
#[test]
6186
#[cfg(feature = "arm")]
6287
fn trim_trailing_hword() {
338 KB
Binary file not shown.

0 commit comments

Comments
 (0)