@@ -320,17 +320,12 @@ fn clamp_text_length(s: String, max: usize) -> String {
320
320
if s. len ( ) <= max { s } else { format ! ( "{}…" , s. chars( ) . take( max - 3 ) . collect:: <String >( ) ) }
321
321
}
322
322
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 (
327
324
reloc : & Relocation ,
328
- current_state : & mut RegisterState ,
329
325
obj : & Object ,
330
326
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 ) {
334
329
match guess_data_type_from_load_store_inst_op ( op) {
335
330
Some ( DataType :: Float ) => {
336
331
RegisterContent :: FloatConstant ( RawFloat ( match obj. endianness {
@@ -356,17 +351,29 @@ fn fill_registers_from_relocation(
356
351
}
357
352
} else {
358
353
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
+ ) {
360
367
// Only update the register state for loads. We may store to a reloc
361
368
// address but that doesn't update register contents.
362
369
if !is_store_instruction ( op) {
363
370
match ( op, args[ 0 ] ) {
364
371
// Everything else is a load of some sort
365
372
( _, ppc750cl:: Argument :: GPR ( gpr) ) => {
366
- current_state[ gpr] = content ;
373
+ current_state[ gpr] = get_register_content_from_reloc ( reloc , obj , op ) ;
367
374
}
368
375
( _, ppc750cl:: Argument :: FPR ( fpr) ) => {
369
- current_state[ fpr] = content ;
376
+ current_state[ fpr] = get_register_content_from_reloc ( reloc , obj , op ) ;
370
377
}
371
378
_ => { }
372
379
}
@@ -531,7 +538,7 @@ fn generate_flow_analysis_result(
531
538
register_state_at : Vec < RegisterState > ,
532
539
relocations : & [ Relocation ] ,
533
540
) -> Box < PPCFlowAnalysisResult > {
534
- use ppc750cl:: { Argument , GPR , InsIter , Offset } ;
541
+ use ppc750cl:: { Argument , InsIter } ;
535
542
let mut analysis_result = PPCFlowAnalysisResult :: new ( ) ;
536
543
let default_register_state = RegisterState :: new ( ) ;
537
544
for ( addr, ins) in InsIter :: new ( code, 0 ) {
@@ -544,23 +551,17 @@ fn generate_flow_analysis_result(
544
551
// We need to do this before we break out on showing relocations in the
545
552
// subsequent if statement.
546
553
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 ;
564
565
}
565
566
}
566
567
}
0 commit comments