1
- use std:: collections:: BTreeMap ;
1
+ use std:: { collections:: BTreeMap , mem :: take } ;
2
2
3
3
use anyhow:: Result ;
4
4
5
5
use crate :: {
6
6
app:: DiffConfig ,
7
7
editops:: { editops_find, LevEditType } ,
8
8
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 ,
12
12
} ,
13
13
} ;
14
14
@@ -340,13 +340,13 @@ fn find_symbol<'a>(symbols: &'a mut [ObjSymbol], name: &str) -> Option<&'a mut O
340
340
pub fn diff_objs ( left : & mut ObjInfo , right : & mut ObjInfo , _diff_config : & DiffConfig ) -> Result < ( ) > {
341
341
for left_section in & mut left. sections {
342
342
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 ( ) ) ;
350
350
diff_code (
351
351
left. architecture ,
352
352
& left_section. data ,
@@ -358,8 +358,189 @@ pub fn diff_objs(left: &mut ObjInfo, right: &mut ObjInfo, _diff_config: &DiffCon
358
358
) ?;
359
359
}
360
360
}
361
+ } else if left_section. kind == ObjSectionKind :: Data {
362
+ diff_data ( left_section, right_section) ;
361
363
}
362
364
}
363
365
}
364
366
Ok ( ( ) )
365
367
}
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