[llvm] [BOLT] Correctly handle entry point at FDE boundaries (PR #176173)

Paschalis Mpeis via llvm-commits llvm-commits at lists.llvm.org
Tue Jun 30 06:24:19 PDT 2026


================
@@ -2067,6 +2068,152 @@ void RewriteInstance::disassemblePLT() {
   }
 }
 
+namespace {
+
+/// True when the predecessor body ends at its FDE boundary, so trailing bytes
+/// are outside both symtab size and unwind info:
+///   (1) __BOLT_FDE_FUNC* (FDE with no symtab entry), or
+///   (2) a normal symbol whose size equals its FDE address range.
+bool isCFIBoundedTailPredecessor(const BinaryFunction &BF,
+                                 const CFIReaderWriter &CFI) {
+  if (BF.getOneName().starts_with("__BOLT_FDE_FUNC"))
+    return true;
+  auto FDEI = CFI.getFDEs().find(BF.getAddress());
+  if (FDEI == CFI.getFDEs().end())
+    return false;
+  return FDEI->second->getAddressRange() == BF.getSize();
+}
+
+bool hasDataMarkerAt(DenseMap<uint64_t, MarkerSymType> &MarkerSyms,
+                     uint64_t Address) {
+  auto It = MarkerSyms.find(Address);
+  return It != MarkerSyms.end() && It->second == MarkerSymType::DATA;
+}
+
+/// AArch64 padding / filler instructions that may appear in slack but are not
+/// standalone callable functions.
+static bool isAArch64TailPaddingInst(const BinaryContext &BC,
+                                     const MCInst &Inst) {
+  if (BC.MIB->isNoop(Inst) || BC.MIB->isTrap(Inst))
+    return true;
+  return false;
+}
+
+/// True if the decoded tail looks like real callable code, not padding.
+static bool isValidAArch64UnmarkedTail(const BinaryContext &BC,
+                                       ArrayRef<MCInst> Insts) {
+  if (Insts.empty())
+    return false;
+
+  bool HasExecutable = false;
+  for (const MCInst &Inst : Insts) {
+    if (!isAArch64TailPaddingInst(BC, Inst))
+      HasExecutable = true;
+  }
+  if (!HasExecutable)
+    return false;
+
+  // Expect a callable snippet; inlined tails end with ret.
+  return BC.MIB->isReturn(Insts.back());
+}
+
+/// Disassemble a prefix of [TailStart, TailStart + TrailingExtent) and return
+/// its length. Any remaining bytes in the range must be zero padding.
+/// Returns 0 if the region is not valid unmarked code.
+static uint64_t
+measureAArch64UnmarkedTail(BinaryContext &BC, const BinaryFunction &Pred,
+                           DenseMap<uint64_t, MarkerSymType> &MarkerSyms,
+                           uint64_t TailStart, uint64_t TrailingExtent) {
+  // Pred was registered from an executable section during symbol/FDE discovery.
+  BinarySection &Section = *Pred.getOriginSection();
+
+  // adjustFunctionBoundaries() set Pred->MaxSize so [Pred, Pred+MaxSize) fits
+  // in the section and stops at the next symbol/function.
+  if (!Section.containsRange(TailStart, TrailingExtent))
+    return 0;
+
+  StringRef Contents = Section.getContents();
+  const uint64_t SectionOffset = TailStart - Section.getAddress();
+  const uint8_t *Bytes =
+      reinterpret_cast<const uint8_t *>(Contents.data()) + SectionOffset;
+
+  SmallVector<MCInst, 4> Insts;
+  uint64_t CodeLen = 0;
+  while (CodeLen < TrailingExtent) {
+    if (hasDataMarkerAt(MarkerSyms, TailStart + CodeLen))
+      return 0;
+    if (Pred.isInConstantIsland(TailStart + CodeLen))
+      return 0;
----------------
paschalis-mpeis wrote:

It might be worth mentioning the cases we bail out in the commit message.

https://github.com/llvm/llvm-project/pull/176173


More information about the llvm-commits mailing list