MCPcopy Index your code
hub / github.com/encounter/objdiff / diff_instruction

Function diff_instruction

objdiff-core/src/diff/code.rs:419–534  ·  view source on GitHub ↗
(
    left_obj: &Object,
    right_obj: &Object,
    left_symbol_idx: usize,
    right_symbol_idx: usize,
    l: Option<InstructionRef>,
    r: Option<InstructionRef>,
    left_row: &InstructionDiffRo

Source from the content-addressed store, hash-verified

417}
418
419fn diff_instruction(
420 left_obj: &Object,
421 right_obj: &Object,
422 left_symbol_idx: usize,
423 right_symbol_idx: usize,
424 l: Option<InstructionRef>,
425 r: Option<InstructionRef>,
426 left_row: &InstructionDiffRow,
427 right_row: &InstructionDiffRow,
428 diff_config: &DiffObjConfig,
429 state: &mut InstructionDiffState,
430) -> Result<InstructionDiffResult> {
431 let (l, r) = match (l, r) {
432 (Some(l), Some(r)) => (l, r),
433 (Some(_), None) => {
434 state.diff_score += PENALTY_INSERT_DELETE;
435 return Ok(InstructionDiffResult::new(InstructionDiffKind::Delete));
436 }
437 (None, Some(_)) => {
438 state.diff_score += PENALTY_INSERT_DELETE;
439 return Ok(InstructionDiffResult::new(InstructionDiffKind::Insert));
440 }
441 (None, None) => return Ok(InstructionDiffResult::new(InstructionDiffKind::None)),
442 };
443
444 // If opcodes don't match, replace
445 if l.opcode != r.opcode {
446 state.diff_score += PENALTY_REPLACE;
447 return Ok(InstructionDiffResult::new(InstructionDiffKind::Replace));
448 }
449
450 let left_resolved = left_obj
451 .resolve_instruction_ref(left_symbol_idx, l)
452 .context("Failed to resolve left instruction")?;
453 let right_resolved = right_obj
454 .resolve_instruction_ref(right_symbol_idx, r)
455 .context("Failed to resolve right instruction")?;
456
457 if left_resolved.code != right_resolved.code
458 || !reloc_eq(left_obj, right_obj, left_resolved, right_resolved, diff_config)
459 {
460 // If either the raw code bytes or relocations don't match, process instructions and compare args
461 let left_ins = left_obj.arch.process_instruction(left_resolved, diff_config)?;
462 let right_ins = right_obj.arch.process_instruction(right_resolved, diff_config)?;
463 if left_ins.args.len() != right_ins.args.len() {
464 state.diff_score += PENALTY_REPLACE;
465 return Ok(InstructionDiffResult::new(InstructionDiffKind::Replace));
466 }
467 let mut result = InstructionDiffResult::new(InstructionDiffKind::None);
468 if left_ins.mnemonic != right_ins.mnemonic {
469 state.diff_score += PENALTY_REG_DIFF;
470 result.kind = InstructionDiffKind::OpMismatch;
471 }
472 for (a, b) in left_ins.args.iter().zip(right_ins.args.iter()) {
473 if arg_eq(
474 left_obj,
475 right_obj,
476 left_row,

Callers 1

diff_codeFunction · 0.85

Calls 7

arg_eqFunction · 0.85
arg_to_stringFunction · 0.85
process_instructionMethod · 0.80
pushMethod · 0.80
getMethod · 0.80
reloc_eqFunction · 0.70

Tested by

no test coverage detected