Skip to content

Commit b373767

Browse files
committed
Fixed display of float constants in a LFS or LFD instruction in case where there is a branch to the subsequent instruction with a different register value.
1 parent 975d4a1 commit b373767

File tree

1 file changed

+30
-29
lines changed

1 file changed

+30
-29
lines changed

objdiff-core/src/arch/ppc/flow_analysis.rs

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -320,17 +320,12 @@ fn clamp_text_length(s: String, max: usize) -> String {
320320
if s.len() <= max { s } else { format!("{}…", s.chars().take(max - 3).collect::<String>()) }
321321
}
322322

323-
// Executing op with args at cur_address, update current_state with symbols that
324-
// come from relocations. That is, references to globals, floating point
325-
// constants, string constants, etc.
326-
fn fill_registers_from_relocation(
323+
fn get_register_content_from_reloc(
327324
reloc: &Relocation,
328-
current_state: &mut RegisterState,
329325
obj: &Object,
330326
op: ppc750cl::Opcode,
331-
args: &[ppc750cl::Argument; 5],
332-
) {
333-
let content = if let Some(bytes) = obj.symbol_data(reloc.target_symbol) {
327+
) -> RegisterContent {
328+
if let Some(bytes) = obj.symbol_data(reloc.target_symbol) {
334329
match guess_data_type_from_load_store_inst_op(op) {
335330
Some(DataType::Float) => {
336331
RegisterContent::FloatConstant(RawFloat(match obj.endianness {
@@ -356,17 +351,29 @@ fn fill_registers_from_relocation(
356351
}
357352
} else {
358353
RegisterContent::Symbol(reloc.target_symbol)
359-
};
354+
}
355+
}
356+
357+
// Executing op with args at cur_address, update current_state with symbols that
358+
// come from relocations. That is, references to globals, floating point
359+
// constants, string constants, etc.
360+
fn fill_registers_from_relocation(
361+
reloc: &Relocation,
362+
current_state: &mut RegisterState,
363+
obj: &Object,
364+
op: ppc750cl::Opcode,
365+
args: &[ppc750cl::Argument; 5],
366+
) {
360367
// Only update the register state for loads. We may store to a reloc
361368
// address but that doesn't update register contents.
362369
if !is_store_instruction(op) {
363370
match (op, args[0]) {
364371
// Everything else is a load of some sort
365372
(_, ppc750cl::Argument::GPR(gpr)) => {
366-
current_state[gpr] = content;
373+
current_state[gpr] = get_register_content_from_reloc(reloc, obj, op);
367374
}
368375
(_, ppc750cl::Argument::FPR(fpr)) => {
369-
current_state[fpr] = content;
376+
current_state[fpr] = get_register_content_from_reloc(reloc, obj, op);
370377
}
371378
_ => {}
372379
}
@@ -531,7 +538,7 @@ fn generate_flow_analysis_result(
531538
register_state_at: Vec<RegisterState>,
532539
relocations: &[Relocation],
533540
) -> Box<PPCFlowAnalysisResult> {
534-
use ppc750cl::{Argument, GPR, InsIter, Offset};
541+
use ppc750cl::{Argument, InsIter};
535542
let mut analysis_result = PPCFlowAnalysisResult::new();
536543
let default_register_state = RegisterState::new();
537544
for (addr, ins) in InsIter::new(code, 0) {
@@ -544,23 +551,17 @@ fn generate_flow_analysis_result(
544551
// We need to do this before we break out on showing relocations in the
545552
// subsequent if statement.
546553
if ins.op == ppc750cl::Opcode::Lfs || ins.op == ppc750cl::Opcode::Lfd {
547-
// The value is set on the line AFTER the load, get it from there
548-
if let Some(next_state) = register_state_at.get(index as usize + 1) {
549-
// When loading from SDA it will be a relocation so Reg+Offset will both be zero
550-
if let (Argument::FPR(fpr), Argument::Offset(Offset(0)), Argument::GPR(GPR(0))) =
551-
(args[0], args[1], args[2])
552-
{
553-
if let RegisterContent::Symbol(_index) = next_state[fpr] {
554-
// We loaded a global variable, not a constant,
555-
// don't do anything for this case.
556-
} else {
557-
analysis_result.set_argument_value_at_address(
558-
ins_address,
559-
1,
560-
FlowAnalysisValue::Text(format!("{}", next_state[fpr])),
561-
);
562-
continue;
563-
}
554+
if let Some(reloc) = relocations.iter().find(|r| (r.address as u32 & !3) == ins_address as u32) {
555+
let content = get_register_content_from_reloc(reloc, obj, ins.op);
556+
if matches!(content, RegisterContent::FloatConstant(_) | RegisterContent::DoubleConstant(_)) {
557+
analysis_result.set_argument_value_at_address(
558+
ins_address,
559+
1,
560+
FlowAnalysisValue::Text(format!("{}", content)),
561+
);
562+
563+
// Don't need to show any other data flow if we're showing that
564+
continue;
564565
}
565566
}
566567
}

0 commit comments

Comments
 (0)