[BOLT] Fix intermittent crash with instrumentation
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. Reviewed By: yota9 Differential Revision: https://reviews.llvm.org/D144806
This commit is contained in:
parent
4364e2429c
commit
fb28196a64
@ -110,6 +110,13 @@ private:
|
||||
return AnnotationInst;
|
||||
}
|
||||
|
||||
void removeAnnotationInst(MCInst &Inst) const {
|
||||
assert(getAnnotationInst(Inst) && "Expected annotation instruction.");
|
||||
Inst.erase(std::prev(Inst.end()));
|
||||
assert(!getAnnotationInst(Inst) &&
|
||||
"More than one annotation instruction detected.");
|
||||
}
|
||||
|
||||
void setAnnotationOpValue(MCInst &Inst, unsigned Index, int64_t Value,
|
||||
AllocatorIdTy AllocatorId = 0) {
|
||||
MCInst *AnnotationInst = getAnnotationInst(Inst);
|
||||
@ -163,6 +170,18 @@ protected:
|
||||
/// 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));
|
||||
removeAnnotationInst(SrcInst);
|
||||
}
|
||||
|
||||
public:
|
||||
class InstructionIterator {
|
||||
public:
|
||||
@ -1864,9 +1883,8 @@ public:
|
||||
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();
|
||||
}
|
||||
|
@ -298,7 +298,8 @@ void MCPlusBuilder::stripAnnotations(MCInst &Inst, bool KeepTC) {
|
||||
// Preserve TailCall annotation.
|
||||
auto IsTC = hasAnnotation(Inst, MCAnnotation::kTailCall);
|
||||
|
||||
Inst.erase(std::prev(Inst.end()));
|
||||
removeAnnotationInst(Inst);
|
||||
|
||||
if (KeepTC && IsTC)
|
||||
setTailCall(Inst);
|
||||
}
|
||||
|
@ -215,7 +215,7 @@ void Instrumentation::instrumentIndirectTarget(BinaryBasicBlock &BB,
|
||||
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);
|
||||
|
@ -3085,8 +3085,7 @@ public:
|
||||
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 @@ public:
|
||||
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user