1
- mod code;
2
- mod data;
3
- pub mod display;
4
-
5
1
use std:: collections:: HashSet ;
6
2
7
3
use anyhow:: Result ;
8
4
9
5
use crate :: {
10
6
diff:: {
11
7
code:: { diff_code, no_diff_code} ,
12
- data:: { diff_bss_symbol, diff_data, no_diff_bss_symbol } ,
8
+ data:: { diff_bss_symbol, diff_data, diff_data_symbol , no_diff_symbol } ,
13
9
} ,
14
- obj:: { ObjInfo , ObjIns , ObjSectionKind , SymbolRef } ,
10
+ obj:: { ObjInfo , ObjIns , ObjSection , ObjSectionKind , ObjSymbol , SymbolRef } ,
15
11
} ;
16
12
13
+ mod code;
14
+ mod data;
15
+ pub mod display;
16
+
17
17
#[ derive( Debug , Copy , Clone , Default , Eq , PartialEq , serde:: Deserialize , serde:: Serialize ) ]
18
18
pub enum X86Formatter {
19
19
#[ default]
@@ -62,6 +62,7 @@ impl ObjSectionDiff {
62
62
63
63
#[ derive( Debug , Clone , Default ) ]
64
64
pub struct ObjSymbolDiff {
65
+ pub symbol_ref : SymbolRef ,
65
66
pub diff_symbol : Option < SymbolRef > ,
66
67
pub instructions : Vec < ObjInsDiff > ,
67
68
pub match_percent : Option < f32 > ,
@@ -142,10 +143,11 @@ impl ObjDiff {
142
143
sections : Vec :: with_capacity ( obj. sections . len ( ) ) ,
143
144
common : Vec :: with_capacity ( obj. common . len ( ) ) ,
144
145
} ;
145
- for section in & obj. sections {
146
+ for ( section_idx , section) in obj. sections . iter ( ) . enumerate ( ) {
146
147
let mut symbols = Vec :: with_capacity ( section. symbols . len ( ) ) ;
147
- for _ in & section. symbols {
148
+ for ( symbol_idx , _ ) in section. symbols . iter ( ) . enumerate ( ) {
148
149
symbols. push ( ObjSymbolDiff {
150
+ symbol_ref : SymbolRef { section_idx, symbol_idx } ,
149
151
diff_symbol : None ,
150
152
instructions : vec ! [ ] ,
151
153
match_percent : None ,
@@ -162,8 +164,9 @@ impl ObjDiff {
162
164
match_percent : None ,
163
165
} ) ;
164
166
}
165
- for _ in & obj. common {
167
+ for ( symbol_idx , _ ) in obj. common . iter ( ) . enumerate ( ) {
166
168
result. common . push ( ObjSymbolDiff {
169
+ symbol_ref : SymbolRef { section_idx : obj. sections . len ( ) , symbol_idx } ,
167
170
diff_symbol : None ,
168
171
instructions : vec ! [ ] ,
169
172
match_percent : None ,
@@ -184,12 +187,20 @@ impl ObjDiff {
184
187
185
188
#[ inline]
186
189
pub fn symbol_diff ( & self , symbol_ref : SymbolRef ) -> & ObjSymbolDiff {
187
- & self . section_diff ( symbol_ref. section_idx ) . symbols [ symbol_ref. symbol_idx ]
190
+ if symbol_ref. section_idx == self . sections . len ( ) {
191
+ & self . common [ symbol_ref. symbol_idx ]
192
+ } else {
193
+ & self . section_diff ( symbol_ref. section_idx ) . symbols [ symbol_ref. symbol_idx ]
194
+ }
188
195
}
189
196
190
197
#[ inline]
191
198
pub fn symbol_diff_mut ( & mut self , symbol_ref : SymbolRef ) -> & mut ObjSymbolDiff {
192
- & mut self . section_diff_mut ( symbol_ref. section_idx ) . symbols [ symbol_ref. symbol_idx ]
199
+ if symbol_ref. section_idx == self . sections . len ( ) {
200
+ & mut self . common [ symbol_ref. symbol_idx ]
201
+ } else {
202
+ & mut self . section_diff_mut ( symbol_ref. section_idx ) . symbols [ symbol_ref. symbol_idx ]
203
+ }
193
204
}
194
205
}
195
206
@@ -247,7 +258,14 @@ pub fn diff_objs(
247
258
}
248
259
}
249
260
ObjSectionKind :: Data => {
250
- // TODO diff data symbol
261
+ let ( left_diff, right_diff) = diff_data_symbol (
262
+ left_obj,
263
+ right_obj,
264
+ left_symbol_ref,
265
+ right_symbol_ref,
266
+ ) ?;
267
+ * left_out. symbol_diff_mut ( left_symbol_ref) = left_diff;
268
+ * right_out. symbol_diff_mut ( right_symbol_ref) = right_diff;
251
269
}
252
270
ObjSectionKind :: Bss => {
253
271
let ( left_diff, right_diff) = diff_bss_symbol (
@@ -268,10 +286,9 @@ pub fn diff_objs(
268
286
* left_out. symbol_diff_mut ( left_symbol_ref) =
269
287
no_diff_code ( left_obj, left_symbol_ref, config) ?;
270
288
}
271
- ObjSectionKind :: Data => { }
272
- ObjSectionKind :: Bss => {
289
+ ObjSectionKind :: Data | ObjSectionKind :: Bss => {
273
290
* left_out. symbol_diff_mut ( left_symbol_ref) =
274
- no_diff_bss_symbol ( left_obj, left_symbol_ref) ;
291
+ no_diff_symbol ( left_obj, left_symbol_ref) ;
275
292
}
276
293
}
277
294
}
@@ -282,10 +299,9 @@ pub fn diff_objs(
282
299
* right_out. symbol_diff_mut ( right_symbol_ref) =
283
300
no_diff_code ( right_obj, right_symbol_ref, config) ?;
284
301
}
285
- ObjSectionKind :: Data => { }
286
- ObjSectionKind :: Bss => {
302
+ ObjSectionKind :: Data | ObjSectionKind :: Bss => {
287
303
* right_out. symbol_diff_mut ( right_symbol_ref) =
288
- no_diff_bss_symbol ( right_obj, right_symbol_ref) ;
304
+ no_diff_symbol ( right_obj, right_symbol_ref) ;
289
305
}
290
306
}
291
307
}
@@ -357,8 +373,8 @@ fn matching_symbols(
357
373
for ( symbol_idx, symbol) in section. symbols . iter ( ) . enumerate ( ) {
358
374
let symbol_match = SymbolMatch {
359
375
left : Some ( SymbolRef { section_idx, symbol_idx } ) ,
360
- right : find_symbol ( right, & symbol. name , section. kind ) ,
361
- prev : find_symbol ( prev, & symbol. name , section. kind ) ,
376
+ right : find_symbol ( right, symbol, section) ,
377
+ prev : find_symbol ( prev, symbol, section) ,
362
378
section_kind : section. kind ,
363
379
} ;
364
380
matches. push ( symbol_match) ;
@@ -367,6 +383,18 @@ fn matching_symbols(
367
383
}
368
384
}
369
385
}
386
+ for ( symbol_idx, symbol) in left. common . iter ( ) . enumerate ( ) {
387
+ let symbol_match = SymbolMatch {
388
+ left : Some ( SymbolRef { section_idx : left. sections . len ( ) , symbol_idx } ) ,
389
+ right : find_common_symbol ( right, symbol) ,
390
+ prev : find_common_symbol ( prev, symbol) ,
391
+ section_kind : ObjSectionKind :: Bss ,
392
+ } ;
393
+ matches. push ( symbol_match) ;
394
+ if let Some ( right) = symbol_match. right {
395
+ right_used. insert ( right) ;
396
+ }
397
+ }
370
398
}
371
399
if let Some ( right) = right {
372
400
for ( section_idx, section) in right. sections . iter ( ) . enumerate ( ) {
@@ -378,29 +406,68 @@ fn matching_symbols(
378
406
matches. push ( SymbolMatch {
379
407
left : None ,
380
408
right : Some ( symbol_ref) ,
381
- prev : find_symbol ( prev, & symbol. name , section. kind ) ,
409
+ prev : find_symbol ( prev, symbol, section) ,
382
410
section_kind : section. kind ,
383
411
} ) ;
384
412
}
385
413
}
414
+ for ( symbol_idx, symbol) in right. common . iter ( ) . enumerate ( ) {
415
+ let symbol_ref = SymbolRef { section_idx : right. sections . len ( ) , symbol_idx } ;
416
+ if right_used. contains ( & symbol_ref) {
417
+ continue ;
418
+ }
419
+ matches. push ( SymbolMatch {
420
+ left : None ,
421
+ right : Some ( symbol_ref) ,
422
+ prev : find_common_symbol ( prev, symbol) ,
423
+ section_kind : ObjSectionKind :: Bss ,
424
+ } ) ;
425
+ }
386
426
}
387
427
Ok ( matches)
388
428
}
389
429
390
430
fn find_symbol (
391
431
obj : Option < & ObjInfo > ,
392
- name : & str ,
393
- section_kind : ObjSectionKind ,
432
+ in_symbol : & ObjSymbol ,
433
+ in_section : & ObjSection ,
394
434
) -> Option < SymbolRef > {
395
- for ( section_idx, section) in obj?. sections . iter ( ) . enumerate ( ) {
396
- if section. kind != section_kind {
435
+ let obj = obj?;
436
+ // Try to find an exact name match
437
+ for ( section_idx, section) in obj. sections . iter ( ) . enumerate ( ) {
438
+ if section. kind != in_section. kind {
397
439
continue ;
398
440
}
399
- let symbol_idx = match section. symbols . iter ( ) . position ( |symbol| symbol. name == name) {
400
- Some ( symbol_idx) => symbol_idx,
401
- None => continue ,
402
- } ;
403
- return Some ( SymbolRef { section_idx, symbol_idx } ) ;
441
+ if let Some ( symbol_idx) =
442
+ section. symbols . iter ( ) . position ( |symbol| symbol. name == in_symbol. name )
443
+ {
444
+ return Some ( SymbolRef { section_idx, symbol_idx } ) ;
445
+ }
446
+ }
447
+ // Match compiler-generated symbols against each other (e.g. @251 -> @60)
448
+ // If they are at the same address in the same section
449
+ if in_symbol. name . starts_with ( '@' )
450
+ && matches ! ( in_section. kind, ObjSectionKind :: Data | ObjSectionKind :: Bss )
451
+ {
452
+ if let Some ( ( section_idx, section) ) =
453
+ obj. sections . iter ( ) . enumerate ( ) . find ( |( _, s) | s. name == in_section. name )
454
+ {
455
+ if let Some ( symbol_idx) = section. symbols . iter ( ) . position ( |symbol| {
456
+ symbol. address == in_symbol. address && symbol. name . starts_with ( '@' )
457
+ } ) {
458
+ return Some ( SymbolRef { section_idx, symbol_idx } ) ;
459
+ }
460
+ }
461
+ }
462
+ None
463
+ }
464
+
465
+ fn find_common_symbol ( obj : Option < & ObjInfo > , in_symbol : & ObjSymbol ) -> Option < SymbolRef > {
466
+ let obj = obj?;
467
+ for ( symbol_idx, symbol) in obj. common . iter ( ) . enumerate ( ) {
468
+ if symbol. name == in_symbol. name {
469
+ return Some ( SymbolRef { section_idx : obj. sections . len ( ) , symbol_idx } ) ;
470
+ }
404
471
}
405
472
None
406
473
}
0 commit comments