Skip to content

Commit a0e7f9b

Browse files
committed
Fix x86 mov relocations with uint32
1 parent 5898d7a commit a0e7f9b

File tree

3 files changed

+53
-14
lines changed

3 files changed

+53
-14
lines changed

objdiff-core/src/arch/x86.rs

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ impl Arch for ArchX86 {
137137
{
138138
instruction.set_memory_displacement64(PLACEHOLDER);
139139
// Formatter always writes the displacement as Int32
140-
reloc_replace = Some((OpKind::Memory, NumberKind::Int32, PLACEHOLDER));
140+
reloc_replace = Some((OpKind::Memory, 4, PLACEHOLDER));
141141
} else if reloc_offset == offsets.immediate_offset() as u64
142142
&& reloc_size == offsets.immediate_size()
143143
{
@@ -155,18 +155,12 @@ impl Arch for ArchX86 {
155155
_ => OpKind::default(),
156156
}
157157
};
158-
let number_kind = match reloc_size {
159-
2 => NumberKind::UInt16,
160-
4 => NumberKind::UInt32,
161-
8 => NumberKind::UInt64,
162-
_ => NumberKind::default(),
163-
};
164158
if is_branch {
165159
instruction.set_near_branch64(PLACEHOLDER);
166160
} else {
167161
instruction.set_immediate32(PLACEHOLDER as u32);
168162
}
169-
reloc_replace = Some((op_kind, number_kind, PLACEHOLDER));
163+
reloc_replace = Some((op_kind, reloc_size, PLACEHOLDER));
170164
}
171165
}
172166

@@ -251,7 +245,7 @@ impl Arch for ArchX86 {
251245

252246
struct InstructionFormatterOutput<'a> {
253247
cb: &'a mut dyn FnMut(InstructionPart<'_>) -> Result<()>,
254-
reloc_replace: Option<(OpKind, NumberKind, u64)>,
248+
reloc_replace: Option<(OpKind, usize, u64)>,
255249
error: Option<anyhow::Error>,
256250
skip_next: bool,
257251
}
@@ -326,11 +320,17 @@ impl FormatterOutput for InstructionFormatterOutput<'_> {
326320
return;
327321
}
328322

329-
if let (Some(operand), Some((target_op_kind, target_number_kind, target_value))) =
323+
if let (Some(operand), Some((target_op_kind, reloc_size, target_value))) =
330324
(instruction_operand, self.reloc_replace)
331325
{
332326
if instruction.op_kind(operand) == target_op_kind
333-
&& number_kind == target_number_kind
327+
&& match (number_kind, reloc_size) {
328+
(NumberKind::Int8 | NumberKind::UInt8, 1)
329+
| (NumberKind::Int16 | NumberKind::UInt16, 2)
330+
| (NumberKind::Int32 | NumberKind::UInt32, 4)
331+
| (NumberKind::Int64 | NumberKind::UInt64, 8) => true,
332+
_ => false,
333+
}
334334
&& value == target_value
335335
{
336336
if let Err(e) = (self.cb)(InstructionPart::reloc()) {
@@ -571,4 +571,43 @@ mod test {
571571
.unwrap();
572572
assert_eq!(parts, &[InstructionPart::opcode("call", opcode), InstructionPart::reloc()]);
573573
}
574+
575+
#[test]
576+
fn test_process_instruction_with_reloc_4() {
577+
let arch = ArchX86 { arch: Architecture::X86, endianness: object::Endianness::Little };
578+
let code = [0x8b, 0x15, 0xa4, 0x21, 0x7e, 0x00];
579+
let opcode = iced_x86::Mnemonic::Mov as u16;
580+
let mut parts = Vec::new();
581+
arch.display_instruction(
582+
ResolvedInstructionRef {
583+
ins_ref: InstructionRef { address: 0x1234, size: 6, opcode },
584+
code: &code,
585+
relocation: Some(ResolvedRelocation {
586+
relocation: &Relocation {
587+
flags: RelocationFlags::Coff(pe::IMAGE_REL_I386_DIR32),
588+
address: 0x1234 + 2,
589+
target_symbol: 0,
590+
addend: 0,
591+
},
592+
symbol: &Default::default(),
593+
}),
594+
..Default::default()
595+
},
596+
&DiffObjConfig::default(),
597+
&mut |part| {
598+
parts.push(part.into_static());
599+
Ok(())
600+
},
601+
)
602+
.unwrap();
603+
assert_eq!(parts, &[
604+
InstructionPart::opcode("mov", opcode),
605+
InstructionPart::opaque("edx"),
606+
InstructionPart::basic(","),
607+
InstructionPart::basic(" "),
608+
InstructionPart::basic("["),
609+
InstructionPart::reloc(),
610+
InstructionPart::basic("]"),
611+
]);
612+
}
574613
}

objdiff-core/tests/arch_ppc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ fn diff_ppc() {
6161
let base_diff = diff.right.as_ref().unwrap();
6262
let sections_display = display::display_sections(
6363
&target_obj,
64-
&target_diff,
64+
target_diff,
6565
display::SymbolFilter::None,
6666
false,
6767
false,

objdiff-core/tests/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ pub fn display_diff(
1313
for row in &diff.instruction_rows {
1414
output.push('[');
1515
let mut separator = false;
16-
objdiff_core::diff::display::display_row(&obj, symbol_idx, row, &diff_config, |segment| {
16+
objdiff_core::diff::display::display_row(obj, symbol_idx, row, diff_config, |segment| {
1717
if separator {
1818
output.push_str(", ");
1919
} else {
@@ -47,6 +47,6 @@ macro_rules! include_bytes_align_as {
4747
#[macro_export]
4848
macro_rules! include_object {
4949
($path:literal) => {
50-
include_bytes_align_as!(u32, $path)
50+
include_bytes_align_as!(u64, $path)
5151
};
5252
}

0 commit comments

Comments
 (0)