@@ -579,6 +579,21 @@ bool BinaryContext::analyzeJumpTable(const uint64_t Address,
579579 TrimmedSize = EntriesAsAddress->size ();
580580 };
581581
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+
582597 ErrorOr<const BinarySection &> Section = getSectionForAddress (Address);
583598 if (!Section)
584599 return false ;
@@ -646,25 +661,9 @@ bool BinaryContext::analyzeJumpTable(const uint64_t Address,
646661
647662 // Function or one of its fragments.
648663 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));
666+ (void )printEntryDiagnostics;
668667 break ;
669668 }
670669
@@ -703,10 +702,7 @@ void BinaryContext::populateJumpTables() {
703702 ++JTI) {
704703 JumpTable *JT = JTI->second ;
705704
706- bool NonSimpleParent = false ;
707- for (BinaryFunction *BF : JT->Parents )
708- NonSimpleParent |= !BF->isSimple ();
709- if (NonSimpleParent)
705+ if (!llvm::all_of (JT->Parents , std::mem_fn (&BinaryFunction::isSimple)))
710706 continue ;
711707
712708 uint64_t NextJTAddress = 0 ;
@@ -840,33 +836,26 @@ BinaryContext::getOrCreateJumpTable(BinaryFunction &Function, uint64_t Address,
840836 assert (JT->Type == Type && " jump table types have to match" );
841837 assert (Address == JT->getAddress () && " unexpected non-empty jump table" );
842838
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- }
839+ if (llvm::is_contained (JT->Parents , &Function))
840+ return JT->getFirstLabel ();
862841
863- bool IsJumpTableParent = false ;
864- (void )IsJumpTableParent;
865- for (BinaryFunction *Frag : JT->Parents )
866- if (Frag == &Function)
867- IsJumpTableParent = true ;
868- assert (IsJumpTableParent &&
842+ // Prevent associating a jump table to a specific fragment twice.
843+ auto isSibling = std::bind (&BinaryContext::areRelatedFragments, this ,
844+ &Function, std::placeholders::_1);
845+ assert (llvm::all_of (JT->Parents , isSibling) &&
869846 " cannot re-use jump table of a different function" );
847+ (void )isSibling;
848+ if (opts::Verbosity > 2 ) {
849+ this ->outs () << " BOLT-INFO: multiple fragments access the same jump table"
850+ << " : " << *JT->Parents [0 ] << " ; " << Function << ' \n ' ;
851+ JT->print (this ->outs ());
852+ }
853+ if (JT->Parents .size () == 1 )
854+ JT->Parents .front ()->setHasIndirectTargetToSplitFragment (true );
855+ Function.setHasIndirectTargetToSplitFragment (true );
856+ // Duplicate the entry for the parent function for easy access
857+ JT->Parents .push_back (&Function);
858+ Function.JumpTables .emplace (Address, JT);
870859 return JT->getFirstLabel ();
871860 }
872861
0 commit comments