@@ -575,47 +575,57 @@ fn matching_symbols(
575575 & mut matches,
576576 ) ?;
577577 }
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+ }
598603 }
599604 }
600605 }
601606 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) ;
612628 }
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- } ) ;
619629 }
620630 }
621631 Ok ( matches)
@@ -677,6 +687,7 @@ fn find_symbol(
677687 in_obj : & Object ,
678688 in_symbol_idx : usize ,
679689 used : Option < & BTreeSet < usize > > ,
690+ fuzzy_literals : bool ,
680691) -> Option < usize > {
681692 let in_symbol = & in_obj. symbols [ in_symbol_idx] ;
682693 let obj = obj?;
@@ -687,7 +698,8 @@ fn find_symbol(
687698 if is_symbol_compiler_generated_literal ( in_symbol)
688699 && matches ! ( section_kind, SectionKind :: Data | SectionKind :: Bss )
689700 {
690- let mut matching_symbol_idx = None ;
701+ let mut closest_match_symbol_idx = None ;
702+ let mut closest_match_percent = 0.0 ;
691703 for ( symbol_idx, symbol) in unmatched_symbols ( obj, used) {
692704 let Some ( section_index) = symbol. section else {
693705 continue ;
@@ -700,27 +712,35 @@ fn find_symbol(
700712 }
701713 match section_kind {
702714 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.
704718 if let Ok ( ( left_diff, _right_diff) ) =
705719 diff_data_symbol ( in_obj, obj, in_symbol_idx, symbol_idx)
706720 && 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) )
708725 {
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+ }
711731 }
712732 }
713733 SectionKind :: Bss => {
714734 // For BSS, pick the first symbol that has the exact matching size.
715735 if in_symbol. size == symbol. size {
716- matching_symbol_idx = Some ( symbol_idx) ;
736+ closest_match_symbol_idx = Some ( symbol_idx) ;
717737 break ;
718738 }
719739 }
720740 _ => unreachable ! ( ) ,
721741 }
722742 }
723- return matching_symbol_idx ;
743+ return closest_match_symbol_idx ;
724744 }
725745
726746 // Try to find an exact name match
0 commit comments