diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -1860,6 +1860,40 @@ if (HasFixedIndirectBranch) return false; + // Validate that all data references to function offsets are claimed by + // recognized jump tables. Register externally referenced blocks as entry + // points. + if (!opts::StrictMode && hasInternalReference()) { + SmallPtrSet JTTargets; + for (const JumpTable *JT : llvm::make_second_range(JumpTables)) + JTTargets.insert(JT->Entries.begin(), JT->Entries.end()); + + bool UnclaimedReference = false; + for (uint64_t Destination : ExternallyReferencedOffsets) { + // Ignore __builtin_unreachable(). + if (Destination == getSize()) + continue; + + if (BinaryBasicBlock *BB = getBasicBlockAtOffset(Destination)) { + bool Found = JTTargets.contains(BB->getLabel()); + if (Found) + continue; + + if (opts::Verbosity >= 1) { + outs() << "BOLT-WARNING: unclaimed data to code reference (possibly " + << "an unrecognized jump table entry) to " << BB->getName() + << " in " << *this << ".\n"; + } + } else if (opts::Verbosity >= 1) { + outs() << "BOLT-WARNING: unknown data to code reference to offset " + << Twine::utohexstr(Destination) << " in " << *this << ".\n"; + } + UnclaimedReference = true; + } + if (UnclaimedReference) + return false; + } + if (HasUnknownControlFlow && !BC.HasRelocations) return false;