@@ -579,6 +579,21 @@ bool BinaryContext::analyzeJumpTable(const uint64_t Address,
579
579
TrimmedSize = EntriesAsAddress->size ();
580
580
};
581
581
582
+ auto printEntryDiagnostics = [&](raw_ostream &OS,
583
+ const BinaryFunction *TargetBF) {
584
+ OS << " FAIL: function doesn't contain this address\n " ;
585
+ if (!TargetBF)
586
+ return ;
587
+ OS << " ! function containing this address: " << *TargetBF << ' \n ' ;
588
+ if (!TargetBF->isFragment ())
589
+ return ;
590
+ OS << " ! is a fragment with parents: " ;
591
+ ListSeparator LS;
592
+ for (BinaryFunction *Parent : TargetBF->ParentFragments )
593
+ OS << LS << *Parent;
594
+ OS << ' \n ' ;
595
+ };
596
+
582
597
ErrorOr<const BinarySection &> Section = getSectionForAddress (Address);
583
598
if (!Section)
584
599
return false ;
@@ -646,25 +661,8 @@ bool BinaryContext::analyzeJumpTable(const uint64_t Address,
646
661
647
662
// Function or one of its fragments.
648
663
const BinaryFunction *TargetBF = getBinaryFunctionContainingAddress (Value);
649
- const bool DoesBelongToFunction =
650
- BF.containsAddress (Value) ||
651
- (TargetBF && areRelatedFragments (TargetBF, &BF));
652
- if (!DoesBelongToFunction) {
653
- LLVM_DEBUG ({
654
- if (!BF.containsAddress (Value)) {
655
- dbgs () << " FAIL: function doesn't contain this address\n " ;
656
- if (TargetBF) {
657
- dbgs () << " ! function containing this address: "
658
- << TargetBF->getPrintName () << ' \n ' ;
659
- if (TargetBF->isFragment ()) {
660
- dbgs () << " ! is a fragment" ;
661
- for (BinaryFunction *Parent : TargetBF->ParentFragments )
662
- dbgs () << " , parent: " << Parent->getPrintName ();
663
- dbgs () << ' \n ' ;
664
- }
665
- }
666
- }
667
- });
664
+ if (!TargetBF || !areRelatedFragments (TargetBF, &BF)) {
665
+ LLVM_DEBUG (printEntryDiagnostics (dbgs (), TargetBF));
668
666
break ;
669
667
}
670
668
@@ -703,10 +701,7 @@ void BinaryContext::populateJumpTables() {
703
701
++JTI) {
704
702
JumpTable *JT = JTI->second ;
705
703
706
- bool NonSimpleParent = false ;
707
- for (BinaryFunction *BF : JT->Parents )
708
- NonSimpleParent |= !BF->isSimple ();
709
- if (NonSimpleParent)
704
+ if (!llvm::all_of (JT->Parents , std::mem_fn (&BinaryFunction::isSimple)))
710
705
continue ;
711
706
712
707
uint64_t NextJTAddress = 0 ;
@@ -840,33 +835,25 @@ BinaryContext::getOrCreateJumpTable(BinaryFunction &Function, uint64_t Address,
840
835
assert (JT->Type == Type && " jump table types have to match" );
841
836
assert (Address == JT->getAddress () && " unexpected non-empty jump table" );
842
837
843
- // Prevent associating a jump table to a specific fragment twice.
844
- if (!llvm::is_contained (JT->Parents , &Function)) {
845
- assert (llvm::all_of (JT->Parents ,
846
- [&](const BinaryFunction *BF) {
847
- return areRelatedFragments (&Function, BF);
848
- }) &&
849
- " cannot re-use jump table of a different function" );
850
- // Duplicate the entry for the parent function for easy access
851
- JT->Parents .push_back (&Function);
852
- if (opts::Verbosity > 2 ) {
853
- this ->outs () << " BOLT-INFO: Multiple fragments access same jump table: "
854
- << JT->Parents [0 ]->getPrintName () << " ; "
855
- << Function.getPrintName () << " \n " ;
856
- JT->print (this ->outs ());
857
- }
858
- Function.JumpTables .emplace (Address, JT);
859
- for (BinaryFunction *Parent : JT->Parents )
860
- Parent->setHasIndirectTargetToSplitFragment (true );
861
- }
838
+ if (llvm::is_contained (JT->Parents , &Function))
839
+ return JT->getFirstLabel ();
862
840
863
- bool IsJumpTableParent = false ;
864
- (void )IsJumpTableParent;
865
- for (BinaryFunction *Frag : JT->Parents )
866
- if (Frag == &Function)
867
- IsJumpTableParent = true ;
868
- assert (IsJumpTableParent &&
841
+ // Prevent associating a jump table to a specific fragment twice.
842
+ auto isSibling = std::bind (&BinaryContext::areRelatedFragments, this ,
843
+ &Function, std::placeholders::_1);
844
+ assert (llvm::all_of (JT->Parents , isSibling) &&
869
845
" cannot re-use jump table of a different function" );
846
+ if (opts::Verbosity > 2 ) {
847
+ this ->outs () << " BOLT-INFO: multiple fragments access the same jump table"
848
+ << " : " << *JT->Parents [0 ] << " ; " << Function << ' \n ' ;
849
+ JT->print (this ->outs ());
850
+ }
851
+ if (JT->Parents .size () == 1 )
852
+ JT->Parents .front ()->setHasIndirectTargetToSplitFragment (true );
853
+ Function.setHasIndirectTargetToSplitFragment (true );
854
+ // Duplicate the entry for the parent function for easy access
855
+ JT->Parents .push_back (&Function);
856
+ Function.JumpTables .emplace (Address, JT);
870
857
return JT->getFirstLabel ();
871
858
}
872
859
0 commit comments