@@ -575,47 +575,57 @@ fn matching_symbols(
575
575
& mut matches,
576
576
) ?;
577
577
}
578
- for ( symbol_idx, symbol) in left. symbols . iter ( ) . enumerate ( ) {
579
- if symbol. size == 0 || symbol. flags . contains ( SymbolFlag :: Ignored ) {
580
- continue ;
581
- }
582
- let section_kind = symbol_section_kind ( left, symbol) ;
583
- if section_kind == SectionKind :: Unknown {
584
- continue ;
585
- }
586
- if left_used. contains ( & symbol_idx) {
587
- continue ;
588
- }
589
- let symbol_match = SymbolMatch {
590
- left : Some ( symbol_idx) ,
591
- right : find_symbol ( right, left, symbol_idx, Some ( & right_used) ) ,
592
- prev : find_symbol ( prev, left, symbol_idx, None ) ,
593
- section_kind,
594
- } ;
595
- matches. push ( symbol_match) ;
596
- if let Some ( right) = symbol_match. right {
597
- right_used. insert ( right) ;
578
+ // Do two passes for nameless literals. The first only pairs up perfect matches to ensure
579
+ // those are correct first, while the second pass catches near matches.
580
+ for fuzzy_literals in [ false , true ] {
581
+ for ( symbol_idx, symbol) in left. symbols . iter ( ) . enumerate ( ) {
582
+ if symbol. size == 0 || symbol. flags . contains ( SymbolFlag :: Ignored ) {
583
+ continue ;
584
+ }
585
+ let section_kind = symbol_section_kind ( left, symbol) ;
586
+ if section_kind == SectionKind :: Unknown {
587
+ continue ;
588
+ }
589
+ if left_used. contains ( & symbol_idx) {
590
+ continue ;
591
+ }
592
+ let symbol_match = SymbolMatch {
593
+ left : Some ( symbol_idx) ,
594
+ right : find_symbol ( right, left, symbol_idx, Some ( & right_used) , fuzzy_literals) ,
595
+ prev : find_symbol ( prev, left, symbol_idx, None , fuzzy_literals) ,
596
+ section_kind,
597
+ } ;
598
+ matches. push ( symbol_match) ;
599
+ left_used. insert ( symbol_idx) ;
600
+ if let Some ( right) = symbol_match. right {
601
+ right_used. insert ( right) ;
602
+ }
598
603
}
599
604
}
600
605
}
601
606
if let Some ( right) = right {
602
- for ( symbol_idx, symbol) in right. symbols . iter ( ) . enumerate ( ) {
603
- if symbol. size == 0 || symbol. flags . contains ( SymbolFlag :: Ignored ) {
604
- continue ;
605
- }
606
- let section_kind = symbol_section_kind ( right, symbol) ;
607
- if section_kind == SectionKind :: Unknown {
608
- continue ;
609
- }
610
- if right_used. contains ( & symbol_idx) {
611
- continue ;
607
+ // Do two passes for nameless literals. The first only pairs up perfect matches to ensure
608
+ // those are correct first, while the second pass catches near matches.
609
+ for fuzzy_literals in [ false , true ] {
610
+ for ( symbol_idx, symbol) in right. symbols . iter ( ) . enumerate ( ) {
611
+ if symbol. size == 0 || symbol. flags . contains ( SymbolFlag :: Ignored ) {
612
+ continue ;
613
+ }
614
+ let section_kind = symbol_section_kind ( right, symbol) ;
615
+ if section_kind == SectionKind :: Unknown {
616
+ continue ;
617
+ }
618
+ if right_used. contains ( & symbol_idx) {
619
+ continue ;
620
+ }
621
+ matches. push ( SymbolMatch {
622
+ left : None ,
623
+ right : Some ( symbol_idx) ,
624
+ prev : find_symbol ( prev, right, symbol_idx, None , fuzzy_literals) ,
625
+ section_kind,
626
+ } ) ;
627
+ right_used. insert ( symbol_idx) ;
612
628
}
613
- matches. push ( SymbolMatch {
614
- left : None ,
615
- right : Some ( symbol_idx) ,
616
- prev : find_symbol ( prev, right, symbol_idx, None ) ,
617
- section_kind,
618
- } ) ;
619
629
}
620
630
}
621
631
Ok ( matches)
@@ -677,6 +687,7 @@ fn find_symbol(
677
687
in_obj : & Object ,
678
688
in_symbol_idx : usize ,
679
689
used : Option < & BTreeSet < usize > > ,
690
+ fuzzy_literals : bool ,
680
691
) -> Option < usize > {
681
692
let in_symbol = & in_obj. symbols [ in_symbol_idx] ;
682
693
let obj = obj?;
@@ -687,7 +698,8 @@ fn find_symbol(
687
698
if is_symbol_compiler_generated_literal ( in_symbol)
688
699
&& matches ! ( section_kind, SectionKind :: Data | SectionKind :: Bss )
689
700
{
690
- let mut matching_symbol_idx = None ;
701
+ let mut closest_match_symbol_idx = None ;
702
+ let mut closest_match_percent = 0.0 ;
691
703
for ( symbol_idx, symbol) in unmatched_symbols ( obj, used) {
692
704
let Some ( section_index) = symbol. section else {
693
705
continue ;
@@ -700,27 +712,35 @@ fn find_symbol(
700
712
}
701
713
match section_kind {
702
714
SectionKind :: Data => {
703
- // For data, pick the first symbol that has the exact matching bytes and relocations.
715
+ // For data, pick the first symbol with exactly matching bytes and relocations.
716
+ // If no symbols match exactly, and `fuzzy_literals` is true, pick the closest
717
+ // plausible match instead.
704
718
if let Ok ( ( left_diff, _right_diff) ) =
705
719
diff_data_symbol ( in_obj, obj, in_symbol_idx, symbol_idx)
706
720
&& let Some ( match_percent) = left_diff. match_percent
707
- && match_percent == 100.0
721
+ && ( match_percent == 100.0
722
+ || ( fuzzy_literals
723
+ && match_percent >= 50.0
724
+ && match_percent > closest_match_percent) )
708
725
{
709
- matching_symbol_idx = Some ( symbol_idx) ;
710
- break ;
726
+ closest_match_symbol_idx = Some ( symbol_idx) ;
727
+ closest_match_percent = match_percent;
728
+ if match_percent == 100.0 {
729
+ break ;
730
+ }
711
731
}
712
732
}
713
733
SectionKind :: Bss => {
714
734
// For BSS, pick the first symbol that has the exact matching size.
715
735
if in_symbol. size == symbol. size {
716
- matching_symbol_idx = Some ( symbol_idx) ;
736
+ closest_match_symbol_idx = Some ( symbol_idx) ;
717
737
break ;
718
738
}
719
739
}
720
740
_ => unreachable ! ( ) ,
721
741
}
722
742
}
723
- return matching_symbol_idx ;
743
+ return closest_match_symbol_idx ;
724
744
}
725
745
726
746
// Try to find an exact name match
0 commit comments