1- use std:: collections:: BTreeMap ;
1+ use std:: { collections:: BTreeMap , mem :: take } ;
22
33use anyhow:: Result ;
44
55use crate :: {
66 app:: DiffConfig ,
77 editops:: { editops_find, LevEditType } ,
88 obj:: {
9- mips, ppc, ObjArchitecture , ObjInfo , ObjInsArg , ObjInsArgDiff , ObjInsBranchFrom ,
10- ObjInsBranchTo , ObjInsDiff , ObjInsDiffKind , ObjReloc , ObjSection , ObjSectionKind ,
11- ObjSymbol , ObjSymbolFlags ,
9+ mips, ppc, ObjArchitecture , ObjDataDiff , ObjDataDiffKind , ObjInfo , ObjInsArg ,
10+ ObjInsArgDiff , ObjInsBranchFrom , ObjInsBranchTo , ObjInsDiff , ObjInsDiffKind , ObjReloc ,
11+ ObjSection , ObjSectionKind , ObjSymbol , ObjSymbolFlags ,
1212 } ,
1313} ;
1414
@@ -340,13 +340,13 @@ fn find_symbol<'a>(symbols: &'a mut [ObjSymbol], name: &str) -> Option<&'a mut O
340340pub fn diff_objs ( left : & mut ObjInfo , right : & mut ObjInfo , _diff_config : & DiffConfig ) -> Result < ( ) > {
341341 for left_section in & mut left. sections {
342342 if let Some ( right_section) = find_section ( right, & left_section. name ) {
343- for left_symbol in & mut left_section. symbols {
344- if let Some ( right_symbol ) =
345- find_symbol ( & mut right_section . symbols , & left_symbol . name )
346- {
347- left_symbol . diff_symbol = Some ( right_symbol . name . clone ( ) ) ;
348- right_symbol . diff_symbol = Some ( left_symbol . name . clone ( ) ) ;
349- if left_section . kind == ObjSectionKind :: Code {
343+ if left_section. kind == ObjSectionKind :: Code {
344+ for left_symbol in & mut left_section . symbols {
345+ if let Some ( right_symbol ) =
346+ find_symbol ( & mut right_section . symbols , & left_symbol . name )
347+ {
348+ left_symbol . diff_symbol = Some ( right_symbol . name . clone ( ) ) ;
349+ right_symbol . diff_symbol = Some ( left_symbol . name . clone ( ) ) ;
350350 diff_code (
351351 left. architecture ,
352352 & left_section. data ,
@@ -358,8 +358,189 @@ pub fn diff_objs(left: &mut ObjInfo, right: &mut ObjInfo, _diff_config: &DiffCon
358358 ) ?;
359359 }
360360 }
361+ } else if left_section. kind == ObjSectionKind :: Data {
362+ diff_data ( left_section, right_section) ;
361363 }
362364 }
363365 }
364366 Ok ( ( ) )
365367}
368+
369+ fn diff_data ( left : & mut ObjSection , right : & mut ObjSection ) {
370+ let edit_ops = editops_find ( & left. data , & right. data ) ;
371+ if edit_ops. is_empty ( ) && !left. data . is_empty ( ) {
372+ left. data_diff = vec ! [ ObjDataDiff {
373+ data: left. data. clone( ) ,
374+ kind: ObjDataDiffKind :: None ,
375+ len: left. data. len( ) ,
376+ } ] ;
377+ right. data_diff = vec ! [ ObjDataDiff {
378+ data: right. data. clone( ) ,
379+ kind: ObjDataDiffKind :: None ,
380+ len: right. data. len( ) ,
381+ } ] ;
382+ return ;
383+ }
384+
385+ let mut left_diff = Vec :: < ObjDataDiff > :: new ( ) ;
386+ let mut right_diff = Vec :: < ObjDataDiff > :: new ( ) ;
387+ let mut left_cur = 0usize ;
388+ let mut right_cur = 0usize ;
389+ let mut cur_op = LevEditType :: Keep ;
390+ let mut cur_left_data = Vec :: < u8 > :: new ( ) ;
391+ let mut cur_right_data = Vec :: < u8 > :: new ( ) ;
392+ for op in edit_ops {
393+ if left_cur < op. first_start {
394+ left_diff. push ( ObjDataDiff {
395+ data : left. data [ left_cur..op. first_start ] . to_vec ( ) ,
396+ kind : ObjDataDiffKind :: None ,
397+ len : op. first_start - left_cur,
398+ } ) ;
399+ left_cur = op. first_start ;
400+ }
401+ if right_cur < op. second_start {
402+ right_diff. push ( ObjDataDiff {
403+ data : right. data [ right_cur..op. second_start ] . to_vec ( ) ,
404+ kind : ObjDataDiffKind :: None ,
405+ len : op. second_start - right_cur,
406+ } ) ;
407+ right_cur = op. second_start ;
408+ }
409+ if cur_op != op. op_type {
410+ match cur_op {
411+ LevEditType :: Keep => { }
412+ LevEditType :: Replace => {
413+ let left_data = take ( & mut cur_left_data) ;
414+ let right_data = take ( & mut cur_right_data) ;
415+ let left_data_len = left_data. len ( ) ;
416+ let right_data_len = right_data. len ( ) ;
417+ left_diff. push ( ObjDataDiff {
418+ data : left_data,
419+ kind : ObjDataDiffKind :: Replace ,
420+ len : left_data_len,
421+ } ) ;
422+ right_diff. push ( ObjDataDiff {
423+ data : right_data,
424+ kind : ObjDataDiffKind :: Replace ,
425+ len : right_data_len,
426+ } ) ;
427+ }
428+ LevEditType :: Insert => {
429+ let right_data = take ( & mut cur_right_data) ;
430+ let right_data_len = right_data. len ( ) ;
431+ left_diff. push ( ObjDataDiff {
432+ data : vec ! [ ] ,
433+ kind : ObjDataDiffKind :: Insert ,
434+ len : right_data_len,
435+ } ) ;
436+ right_diff. push ( ObjDataDiff {
437+ data : right_data,
438+ kind : ObjDataDiffKind :: Insert ,
439+ len : right_data_len,
440+ } ) ;
441+ }
442+ LevEditType :: Delete => {
443+ let left_data = take ( & mut cur_left_data) ;
444+ let left_data_len = left_data. len ( ) ;
445+ left_diff. push ( ObjDataDiff {
446+ data : left_data,
447+ kind : ObjDataDiffKind :: Delete ,
448+ len : left_data_len,
449+ } ) ;
450+ right_diff. push ( ObjDataDiff {
451+ data : vec ! [ ] ,
452+ kind : ObjDataDiffKind :: Delete ,
453+ len : left_data_len,
454+ } ) ;
455+ }
456+ }
457+ }
458+ match op. op_type {
459+ LevEditType :: Replace => {
460+ cur_left_data. push ( left. data [ left_cur] ) ;
461+ cur_right_data. push ( right. data [ right_cur] ) ;
462+ left_cur += 1 ;
463+ right_cur += 1 ;
464+ }
465+ LevEditType :: Insert => {
466+ cur_right_data. push ( right. data [ right_cur] ) ;
467+ right_cur += 1 ;
468+ }
469+ LevEditType :: Delete => {
470+ cur_left_data. push ( left. data [ left_cur] ) ;
471+ left_cur += 1 ;
472+ }
473+ LevEditType :: Keep => unreachable ! ( ) ,
474+ }
475+ cur_op = op. op_type ;
476+ }
477+ // if left_cur < left.data.len() {
478+ // let len = left.data.len() - left_cur;
479+ // left_diff.push(ObjDataDiff {
480+ // data: left.data[left_cur..].to_vec(),
481+ // kind: ObjDataDiffKind::Delete,
482+ // len,
483+ // });
484+ // right_diff.push(ObjDataDiff { data: vec![], kind: ObjDataDiffKind::Delete, len });
485+ // } else if right_cur < right.data.len() {
486+ // let len = right.data.len() - right_cur;
487+ // left_diff.push(ObjDataDiff { data: vec![], kind: ObjDataDiffKind::Insert, len });
488+ // right_diff.push(ObjDataDiff {
489+ // data: right.data[right_cur..].to_vec(),
490+ // kind: ObjDataDiffKind::Insert,
491+ // len,
492+ // });
493+ // }
494+
495+ // TODO: merge with above
496+ match cur_op {
497+ LevEditType :: Keep => { }
498+ LevEditType :: Replace => {
499+ let left_data = take ( & mut cur_left_data) ;
500+ let right_data = take ( & mut cur_right_data) ;
501+ let left_data_len = left_data. len ( ) ;
502+ let right_data_len = right_data. len ( ) ;
503+ left_diff. push ( ObjDataDiff {
504+ data : left_data,
505+ kind : ObjDataDiffKind :: Replace ,
506+ len : left_data_len,
507+ } ) ;
508+ right_diff. push ( ObjDataDiff {
509+ data : right_data,
510+ kind : ObjDataDiffKind :: Replace ,
511+ len : right_data_len,
512+ } ) ;
513+ }
514+ LevEditType :: Insert => {
515+ let right_data = take ( & mut cur_right_data) ;
516+ let right_data_len = right_data. len ( ) ;
517+ left_diff. push ( ObjDataDiff {
518+ data : vec ! [ ] ,
519+ kind : ObjDataDiffKind :: Insert ,
520+ len : right_data_len,
521+ } ) ;
522+ right_diff. push ( ObjDataDiff {
523+ data : right_data,
524+ kind : ObjDataDiffKind :: Insert ,
525+ len : right_data_len,
526+ } ) ;
527+ }
528+ LevEditType :: Delete => {
529+ let left_data = take ( & mut cur_left_data) ;
530+ let left_data_len = left_data. len ( ) ;
531+ left_diff. push ( ObjDataDiff {
532+ data : left_data,
533+ kind : ObjDataDiffKind :: Delete ,
534+ len : left_data_len,
535+ } ) ;
536+ right_diff. push ( ObjDataDiff {
537+ data : vec ! [ ] ,
538+ kind : ObjDataDiffKind :: Delete ,
539+ len : left_data_len,
540+ } ) ;
541+ }
542+ }
543+
544+ left. data_diff = left_diff;
545+ right. data_diff = right_diff;
546+ }
0 commit comments