[PATCH] D144806: [BOLT] Fix intermittent crash with instrumentation

Maksim Panchenko via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 25 21:35:44 PST 2023


maksfb created this revision.
maksfb added reviewers: yota9, Amir, ayermolo, rafauler, yavtuk, treapster.
Herald added a subscriber: pengfei.
Herald added a project: All.
maksfb requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

When createInstrumentedIndirectCall() was invoked for tail calls, we
attached annotation instruction twice to the new call instruction.
First in createDirectCall(), and then again while copying over the
metadata operands.

As a result, the annotations were not properly stripped for such calls
before the call to freeAnnotations() in LowerAnnotations pass. That lead
to use-after-free while restoring the offsets with setOffset() call.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D144806

Files:
  bolt/include/bolt/Core/MCPlusBuilder.h
  bolt/lib/Core/MCPlusBuilder.cpp
  bolt/lib/Passes/Instrumentation.cpp
  bolt/lib/Target/X86/X86MCPlusBuilder.cpp


Index: bolt/lib/Target/X86/X86MCPlusBuilder.cpp
===================================================================
--- bolt/lib/Target/X86/X86MCPlusBuilder.cpp
+++ bolt/lib/Target/X86/X86MCPlusBuilder.cpp
@@ -3085,8 +3085,7 @@
     Inst.addOperand(MCOperand::createReg(X86::NoRegister)); // AddrSegmentReg
   }
 
-  InstructionListType createInstrumentedIndirectCall(const MCInst &CallInst,
-                                                     bool TailCall,
+  InstructionListType createInstrumentedIndirectCall(MCInst &&CallInst,
                                                      MCSymbol *HandlerFuncAddr,
                                                      int CallSiteID,
                                                      MCContext *Ctx) override {
@@ -3137,14 +3136,13 @@
     createLoadImmediate(Insts.back(), TempReg, CallSiteID);
     Insts.emplace_back();
     createPushRegister(Insts.back(), TempReg, 8);
-    Insts.emplace_back();
-    createDirectCall(Insts.back(), HandlerFuncAddr, Ctx,
-                     /*TailCall=*/TailCall);
-    // Carry over metadata
-    for (int I = MCPlus::getNumPrimeOperands(CallInst),
-             E = CallInst.getNumOperands();
-         I != E; ++I)
-      Insts.back().addOperand(CallInst.getOperand(I));
+
+    MCInst &NewCallInst = Insts.emplace_back();
+    createDirectCall(NewCallInst, HandlerFuncAddr, Ctx, isTailCall(CallInst));
+
+    // Carry over metadata including tail call marker if present.
+    stripAnnotations(NewCallInst);
+    moveAnnotations(std::move(CallInst), NewCallInst);
 
     return Insts;
   }
Index: bolt/lib/Passes/Instrumentation.cpp
===================================================================
--- bolt/lib/Passes/Instrumentation.cpp
+++ bolt/lib/Passes/Instrumentation.cpp
@@ -215,7 +215,7 @@
   BinaryContext &BC = FromFunction.getBinaryContext();
   bool IsTailCall = BC.MIB->isTailCall(*Iter);
   InstructionListType CounterInstrs = BC.MIB->createInstrumentedIndirectCall(
-      *Iter, IsTailCall,
+      std::move(*Iter),
       IsTailCall ? IndTailCallHandlerExitBBFunction->getSymbol()
                  : IndCallHandlerExitBBFunction->getSymbol(),
       IndCallSiteID, &*BC.Ctx);
Index: bolt/lib/Core/MCPlusBuilder.cpp
===================================================================
--- bolt/lib/Core/MCPlusBuilder.cpp
+++ bolt/lib/Core/MCPlusBuilder.cpp
@@ -299,6 +299,9 @@
   auto IsTC = hasAnnotation(Inst, MCAnnotation::kTailCall);
 
   Inst.erase(std::prev(Inst.end()));
+  assert(!getAnnotationInst(Inst) &&
+         "More than one annotation instruction detected.");
+
   if (KeepTC && IsTC)
     setTailCall(Inst);
 }
Index: bolt/include/bolt/Core/MCPlusBuilder.h
===================================================================
--- bolt/include/bolt/Core/MCPlusBuilder.h
+++ bolt/include/bolt/Core/MCPlusBuilder.h
@@ -163,6 +163,18 @@
   /// MCPlusBuilder classes must use convert/lower/create* interfaces instead.
   void setTailCall(MCInst &Inst);
 
+  /// Transfer annotations from \p SrcInst to \p DstInst.
+  void moveAnnotations(MCInst &&SrcInst, MCInst &DstInst) const {
+    assert(!getAnnotationInst(DstInst) &&
+           "Destination instruction should not have annotations.");
+    const MCInst *AnnotationInst = getAnnotationInst(SrcInst);
+    if (!AnnotationInst)
+      return;
+
+    DstInst.addOperand(MCOperand::createInst(AnnotationInst));
+    SrcInst.erase(std::prev(SrcInst.end()));
+  }
+
 public:
   class InstructionIterator {
   public:
@@ -1864,9 +1876,8 @@
   void stripAnnotations(MCInst &Inst, bool KeepTC = false);
 
   virtual InstructionListType
-  createInstrumentedIndirectCall(const MCInst &CallInst, bool TailCall,
-                                 MCSymbol *HandlerFuncAddr, int CallSiteID,
-                                 MCContext *Ctx) {
+  createInstrumentedIndirectCall(MCInst &&CallInst, MCSymbol *HandlerFuncAddr,
+                                 int CallSiteID, MCContext *Ctx) {
     llvm_unreachable("not implemented");
     return InstructionListType();
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D144806.500495.patch
Type: text/x-patch
Size: 4044 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230226/4a2562a0/attachment.bin>


More information about the llvm-commits mailing list