diff options
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp')
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp | 307 |
1 files changed, 185 insertions, 122 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index cf9a6a321c7a3..2846319007318 100644 --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -59,7 +59,6 @@ #include "llvm/IR/Argument.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" -#include "llvm/IR/CallSite.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" @@ -162,10 +161,25 @@ static cl::opt<bool> ClDebugNonzeroLabels( "load or return with a nonzero label"), cl::Hidden); +// Experimental feature that inserts callbacks for certain data events. +// Currently callbacks are only inserted for loads, stores, memory transfers +// (i.e. memcpy and memmove), and comparisons. +// +// If this flag is set to true, the user must provide definitions for the +// following callback functions: +// void __dfsan_load_callback(dfsan_label Label); +// void __dfsan_store_callback(dfsan_label Label); +// void __dfsan_mem_transfer_callback(dfsan_label *Start, size_t Len); +// void __dfsan_cmp_callback(dfsan_label CombinedLabel); +static cl::opt<bool> ClEventCallbacks( + "dfsan-event-callbacks", + cl::desc("Insert calls to __dfsan_*_callback functions on data events."), + cl::Hidden, cl::init(false)); + static StringRef GetGlobalTypeString(const GlobalValue &G) { // Types of GlobalVariables are always pointer types. Type *GType = G.getValueType(); - // For now we support blacklisting struct types only. + // For now we support excluding struct types only. if (StructType *SGType = dyn_cast<StructType>(GType)) { if (!SGType->isLiteral()) return SGType->getName(); @@ -282,9 +296,7 @@ class DataFlowSanitizer : public ModulePass { friend struct DFSanFunction; friend class DFSanVisitor; - enum { - ShadowWidth = 16 - }; + enum { ShadowWidthBits = 16, ShadowWidthBytes = ShadowWidthBits / 8 }; /// Which ABI should be used for instrumented functions? enum InstrumentedABI { @@ -345,6 +357,8 @@ class DataFlowSanitizer : public ModulePass { FunctionType *DFSanSetLabelFnTy; FunctionType *DFSanNonzeroLabelFnTy; FunctionType *DFSanVarargWrapperFnTy; + FunctionType *DFSanLoadStoreCmpCallbackFnTy; + FunctionType *DFSanMemTransferCallbackFnTy; FunctionCallee DFSanUnionFn; FunctionCallee DFSanCheckedUnionFn; FunctionCallee DFSanUnionLoadFn; @@ -352,6 +366,10 @@ class DataFlowSanitizer : public ModulePass { FunctionCallee DFSanSetLabelFn; FunctionCallee DFSanNonzeroLabelFn; FunctionCallee DFSanVarargWrapperFn; + FunctionCallee DFSanLoadCallbackFn; + FunctionCallee DFSanStoreCallbackFn; + FunctionCallee DFSanMemTransferCallbackFn; + FunctionCallee DFSanCmpCallbackFn; MDNode *ColdCallWeights; DFSanABIList ABIList; DenseMap<Value *, Function *> UnwrappedFnMap; @@ -371,6 +389,8 @@ class DataFlowSanitizer : public ModulePass { GlobalValue::LinkageTypes NewFLink, FunctionType *NewFT); Constant *getOrBuildTrampolineFunction(FunctionType *FT, StringRef FName); + void initializeCallbackFunctions(Module &M); + void initializeRuntimeFunctions(Module &M); public: static char ID; @@ -424,7 +444,7 @@ struct DFSanFunction { Value *combineOperandShadows(Instruction *Inst); Value *loadShadow(Value *ShadowAddr, uint64_t Size, uint64_t Align, Instruction *Pos); - void storeShadow(Value *Addr, uint64_t Size, uint64_t Align, Value *Shadow, + void storeShadow(Value *Addr, uint64_t Size, Align Alignment, Value *Shadow, Instruction *Pos); }; @@ -438,7 +458,10 @@ public: return DFSF.F->getParent()->getDataLayout(); } - void visitOperandShadowInst(Instruction &I); + // Combines shadow values for all of I's operands. Returns the combined shadow + // value. + Value *visitOperandShadowInst(Instruction &I); + void visitUnaryOperator(UnaryOperator &UO); void visitBinaryOperator(BinaryOperator &BO); void visitCastInst(CastInst &CI); @@ -447,7 +470,7 @@ public: void visitLoadInst(LoadInst &LI); void visitStoreInst(StoreInst &SI); void visitReturnInst(ReturnInst &RI); - void visitCallSite(CallSite CS); + void visitCallBase(CallBase &CB); void visitPHINode(PHINode &PN); void visitExtractElementInst(ExtractElementInst &I); void visitInsertElementInst(InsertElementInst &I); @@ -553,11 +576,11 @@ bool DataFlowSanitizer::doInitialization(Module &M) { Mod = &M; Ctx = &M.getContext(); - ShadowTy = IntegerType::get(*Ctx, ShadowWidth); + ShadowTy = IntegerType::get(*Ctx, ShadowWidthBits); ShadowPtrTy = PointerType::getUnqual(ShadowTy); IntptrTy = DL.getIntPtrType(*Ctx); ZeroShadow = ConstantInt::getSigned(ShadowTy, 0); - ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidth / 8); + ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidthBytes); if (IsX86_64) ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x700000000000LL); else if (IsMIPS64) @@ -583,6 +606,12 @@ bool DataFlowSanitizer::doInitialization(Module &M) { Type::getVoidTy(*Ctx), None, /*isVarArg=*/false); DFSanVarargWrapperFnTy = FunctionType::get( Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx), /*isVarArg=*/false); + DFSanLoadStoreCmpCallbackFnTy = + FunctionType::get(Type::getVoidTy(*Ctx), ShadowTy, /*isVarArg=*/false); + Type *DFSanMemTransferCallbackArgs[2] = {ShadowPtrTy, IntptrTy}; + DFSanMemTransferCallbackFnTy = + FunctionType::get(Type::getVoidTy(*Ctx), DFSanMemTransferCallbackArgs, + /*isVarArg=*/false); if (GetArgTLSPtr) { Type *ArgTLSTy = ArrayType::get(ShadowTy, 64); @@ -628,7 +657,7 @@ DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(Function *F) { } void DataFlowSanitizer::addGlobalNamePrefix(GlobalValue *GV) { - std::string GVName = GV->getName(), Prefix = "dfs$"; + std::string GVName = std::string(GV->getName()), Prefix = "dfs$"; GV->setName(Prefix + GVName); // Try to change the name of the function in module inline asm. We only do @@ -713,25 +742,8 @@ Constant *DataFlowSanitizer::getOrBuildTrampolineFunction(FunctionType *FT, return cast<Constant>(C.getCallee()); } -bool DataFlowSanitizer::runOnModule(Module &M) { - if (ABIList.isIn(M, "skip")) - return false; - - if (!GetArgTLSPtr) { - Type *ArgTLSTy = ArrayType::get(ShadowTy, 64); - ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy); - if (GlobalVariable *G = dyn_cast<GlobalVariable>(ArgTLS)) - G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel); - } - if (!GetRetvalTLSPtr) { - RetvalTLS = Mod->getOrInsertGlobal("__dfsan_retval_tls", ShadowTy); - if (GlobalVariable *G = dyn_cast<GlobalVariable>(RetvalTLS)) - G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel); - } - - ExternalShadowMask = - Mod->getOrInsertGlobal(kDFSanExternShadowPtrMask, IntptrTy); - +// Initialize DataFlowSanitizer runtime functions and declare them in the module +void DataFlowSanitizer::initializeRuntimeFunctions(Module &M) { { AttributeList AL; AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex, @@ -745,7 +757,6 @@ bool DataFlowSanitizer::runOnModule(Module &M) { DFSanUnionFn = Mod->getOrInsertFunction("__dfsan_union", DFSanUnionFnTy, AL); } - { AttributeList AL; AL = AL.addAttribute(M.getContext(), AttributeList::FunctionIndex, @@ -782,6 +793,50 @@ bool DataFlowSanitizer::runOnModule(Module &M) { Mod->getOrInsertFunction("__dfsan_nonzero_label", DFSanNonzeroLabelFnTy); DFSanVarargWrapperFn = Mod->getOrInsertFunction("__dfsan_vararg_wrapper", DFSanVarargWrapperFnTy); +} + +// Initializes event callback functions and declare them in the module +void DataFlowSanitizer::initializeCallbackFunctions(Module &M) { + DFSanLoadCallbackFn = Mod->getOrInsertFunction("__dfsan_load_callback", + DFSanLoadStoreCmpCallbackFnTy); + DFSanStoreCallbackFn = Mod->getOrInsertFunction( + "__dfsan_store_callback", DFSanLoadStoreCmpCallbackFnTy); + DFSanMemTransferCallbackFn = Mod->getOrInsertFunction( + "__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy); + DFSanCmpCallbackFn = Mod->getOrInsertFunction("__dfsan_cmp_callback", + DFSanLoadStoreCmpCallbackFnTy); +} + +bool DataFlowSanitizer::runOnModule(Module &M) { + if (ABIList.isIn(M, "skip")) + return false; + + const unsigned InitialGlobalSize = M.global_size(); + const unsigned InitialModuleSize = M.size(); + + bool Changed = false; + + if (!GetArgTLSPtr) { + Type *ArgTLSTy = ArrayType::get(ShadowTy, 64); + ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy); + if (GlobalVariable *G = dyn_cast<GlobalVariable>(ArgTLS)) { + Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel; + G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel); + } + } + if (!GetRetvalTLSPtr) { + RetvalTLS = Mod->getOrInsertGlobal("__dfsan_retval_tls", ShadowTy); + if (GlobalVariable *G = dyn_cast<GlobalVariable>(RetvalTLS)) { + Changed |= G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel; + G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel); + } + } + + ExternalShadowMask = + Mod->getOrInsertGlobal(kDFSanExternShadowPtrMask, IntptrTy); + + initializeCallbackFunctions(M); + initializeRuntimeFunctions(M); std::vector<Function *> FnsToInstrument; SmallPtrSet<Function *, 2> FnsWithNativeABI; @@ -793,7 +848,11 @@ bool DataFlowSanitizer::runOnModule(Module &M) { &i != DFSanUnimplementedFn.getCallee()->stripPointerCasts() && &i != DFSanSetLabelFn.getCallee()->stripPointerCasts() && &i != DFSanNonzeroLabelFn.getCallee()->stripPointerCasts() && - &i != DFSanVarargWrapperFn.getCallee()->stripPointerCasts()) + &i != DFSanVarargWrapperFn.getCallee()->stripPointerCasts() && + &i != DFSanLoadCallbackFn.getCallee()->stripPointerCasts() && + &i != DFSanStoreCallbackFn.getCallee()->stripPointerCasts() && + &i != DFSanMemTransferCallbackFn.getCallee()->stripPointerCasts() && + &i != DFSanCmpCallbackFn.getCallee()->stripPointerCasts()) FnsToInstrument.push_back(&i); } @@ -994,7 +1053,8 @@ bool DataFlowSanitizer::runOnModule(Module &M) { } } - return false; + return Changed || !FnsToInstrument.empty() || + M.global_size() != InitialGlobalSize || M.size() != InitialModuleSize; } Value *DFSanFunction::getArgTLSPtr() { @@ -1177,9 +1237,10 @@ Value *DFSanFunction::combineOperandShadows(Instruction *Inst) { return Shadow; } -void DFSanVisitor::visitOperandShadowInst(Instruction &I) { +Value *DFSanVisitor::visitOperandShadowInst(Instruction &I) { Value *CombinedShadow = DFSF.combineOperandShadows(&I); DFSF.setShadow(&I, CombinedShadow); + return CombinedShadow; } // Generates IR to load shadow corresponding to bytes [Addr, Addr+Size), where @@ -1194,7 +1255,7 @@ Value *DFSanFunction::loadShadow(Value *Addr, uint64_t Size, uint64_t Align, } } - uint64_t ShadowAlign = Align * DFS.ShadowWidth / 8; + const llvm::Align ShadowAlign(Align * DFS.ShadowWidthBytes); SmallVector<const Value *, 2> Objs; GetUnderlyingObjects(Addr, Objs, Pos->getModule()->getDataLayout()); bool AllConstants = true; @@ -1216,7 +1277,7 @@ Value *DFSanFunction::loadShadow(Value *Addr, uint64_t Size, uint64_t Align, return DFS.ZeroShadow; case 1: { LoadInst *LI = new LoadInst(DFS.ShadowTy, ShadowAddr, "", Pos); - LI->setAlignment(MaybeAlign(ShadowAlign)); + LI->setAlignment(ShadowAlign); return LI; } case 2: { @@ -1228,7 +1289,7 @@ Value *DFSanFunction::loadShadow(Value *Addr, uint64_t Size, uint64_t Align, IRB.CreateAlignedLoad(DFS.ShadowTy, ShadowAddr1, ShadowAlign), Pos); } } - if (!AvoidNewBlocks && Size % (64 / DFS.ShadowWidth) == 0) { + if (!AvoidNewBlocks && Size % (64 / DFS.ShadowWidthBits) == 0) { // Fast path for the common case where each byte has identical shadow: load // shadow 64 bits at a time, fall out to a __dfsan_union_load call if any // shadow is non-equal. @@ -1240,15 +1301,15 @@ Value *DFSanFunction::loadShadow(Value *Addr, uint64_t Size, uint64_t Align, FallbackCall->addAttribute(AttributeList::ReturnIndex, Attribute::ZExt); // Compare each of the shadows stored in the loaded 64 bits to each other, - // by computing (WideShadow rotl ShadowWidth) == WideShadow. + // by computing (WideShadow rotl ShadowWidthBits) == WideShadow. IRBuilder<> IRB(Pos); Value *WideAddr = IRB.CreateBitCast(ShadowAddr, Type::getInt64PtrTy(*DFS.Ctx)); Value *WideShadow = IRB.CreateAlignedLoad(IRB.getInt64Ty(), WideAddr, ShadowAlign); Value *TruncShadow = IRB.CreateTrunc(WideShadow, DFS.ShadowTy); - Value *ShlShadow = IRB.CreateShl(WideShadow, DFS.ShadowWidth); - Value *ShrShadow = IRB.CreateLShr(WideShadow, 64 - DFS.ShadowWidth); + Value *ShlShadow = IRB.CreateShl(WideShadow, DFS.ShadowWidthBits); + Value *ShrShadow = IRB.CreateLShr(WideShadow, 64 - DFS.ShadowWidthBits); Value *RotShadow = IRB.CreateOr(ShlShadow, ShrShadow); Value *ShadowsEq = IRB.CreateICmpEQ(WideShadow, RotShadow); @@ -1271,8 +1332,8 @@ Value *DFSanFunction::loadShadow(Value *Addr, uint64_t Size, uint64_t Align, ReplaceInstWithInst(Head->getTerminator(), LastBr); DT.addNewBlock(FallbackBB, Head); - for (uint64_t Ofs = 64 / DFS.ShadowWidth; Ofs != Size; - Ofs += 64 / DFS.ShadowWidth) { + for (uint64_t Ofs = 64 / DFS.ShadowWidthBits; Ofs != Size; + Ofs += 64 / DFS.ShadowWidthBits) { BasicBlock *NextBB = BasicBlock::Create(*DFS.Ctx, "", F); DT.addNewBlock(NextBB, LastBr->getParent()); IRBuilder<> NextIRB(NextBB); @@ -1308,16 +1369,9 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) { return; } - uint64_t Align; - if (ClPreserveAlignment) { - Align = LI.getAlignment(); - if (Align == 0) - Align = DL.getABITypeAlignment(LI.getType()); - } else { - Align = 1; - } - IRBuilder<> IRB(&LI); - Value *Shadow = DFSF.loadShadow(LI.getPointerOperand(), Size, Align, &LI); + Align Alignment = ClPreserveAlignment ? LI.getAlign() : Align(1); + Value *Shadow = + DFSF.loadShadow(LI.getPointerOperand(), Size, Alignment.value(), &LI); if (ClCombinePointerLabelsOnLoad) { Value *PtrShadow = DFSF.getShadow(LI.getPointerOperand()); Shadow = DFSF.combineShadows(Shadow, PtrShadow, &LI); @@ -1326,9 +1380,13 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) { DFSF.NonZeroChecks.push_back(Shadow); DFSF.setShadow(&LI, Shadow); + if (ClEventCallbacks) { + IRBuilder<> IRB(&LI); + IRB.CreateCall(DFSF.DFS.DFSanLoadCallbackFn, Shadow); + } } -void DFSanFunction::storeShadow(Value *Addr, uint64_t Size, uint64_t Align, +void DFSanFunction::storeShadow(Value *Addr, uint64_t Size, Align Alignment, Value *Shadow, Instruction *Pos) { if (AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) { const auto i = AllocaShadowMap.find(AI); @@ -1339,11 +1397,12 @@ void DFSanFunction::storeShadow(Value *Addr, uint64_t Size, uint64_t Align, } } - uint64_t ShadowAlign = Align * DFS.ShadowWidth / 8; + const Align ShadowAlign(Alignment.value() * DFS.ShadowWidthBytes); IRBuilder<> IRB(Pos); Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos); if (Shadow == DFS.ZeroShadow) { - IntegerType *ShadowTy = IntegerType::get(*DFS.Ctx, Size * DFS.ShadowWidth); + IntegerType *ShadowTy = + IntegerType::get(*DFS.Ctx, Size * DFS.ShadowWidthBits); Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0); Value *ExtShadowAddr = IRB.CreateBitCast(ShadowAddr, PointerType::getUnqual(ShadowTy)); @@ -1351,10 +1410,10 @@ void DFSanFunction::storeShadow(Value *Addr, uint64_t Size, uint64_t Align, return; } - const unsigned ShadowVecSize = 128 / DFS.ShadowWidth; + const unsigned ShadowVecSize = 128 / DFS.ShadowWidthBits; uint64_t Offset = 0; if (Size >= ShadowVecSize) { - VectorType *ShadowVecTy = VectorType::get(DFS.ShadowTy, ShadowVecSize); + auto *ShadowVecTy = FixedVectorType::get(DFS.ShadowTy, ShadowVecSize); Value *ShadowVec = UndefValue::get(ShadowVecTy); for (unsigned i = 0; i != ShadowVecSize; ++i) { ShadowVec = IRB.CreateInsertElement( @@ -1386,21 +1445,18 @@ void DFSanVisitor::visitStoreInst(StoreInst &SI) { if (Size == 0) return; - uint64_t Align; - if (ClPreserveAlignment) { - Align = SI.getAlignment(); - if (Align == 0) - Align = DL.getABITypeAlignment(SI.getValueOperand()->getType()); - } else { - Align = 1; - } + const Align Alignment = ClPreserveAlignment ? SI.getAlign() : Align(1); Value* Shadow = DFSF.getShadow(SI.getValueOperand()); if (ClCombinePointerLabelsOnStore) { Value *PtrShadow = DFSF.getShadow(SI.getPointerOperand()); Shadow = DFSF.combineShadows(Shadow, PtrShadow, &SI); } - DFSF.storeShadow(SI.getPointerOperand(), Size, Align, Shadow, &SI); + DFSF.storeShadow(SI.getPointerOperand(), Size, Alignment, Shadow, &SI); + if (ClEventCallbacks) { + IRBuilder<> IRB(&SI); + IRB.CreateCall(DFSF.DFS.DFSanStoreCallbackFn, Shadow); + } } void DFSanVisitor::visitUnaryOperator(UnaryOperator &UO) { @@ -1413,7 +1469,13 @@ void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) { void DFSanVisitor::visitCastInst(CastInst &CI) { visitOperandShadowInst(CI); } -void DFSanVisitor::visitCmpInst(CmpInst &CI) { visitOperandShadowInst(CI); } +void DFSanVisitor::visitCmpInst(CmpInst &CI) { + Value *CombinedShadow = visitOperandShadowInst(CI); + if (ClEventCallbacks) { + IRBuilder<> IRB(&CI); + IRB.CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow); + } +} void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) { visitOperandShadowInst(GEPI); @@ -1493,23 +1555,27 @@ void DFSanVisitor::visitMemSetInst(MemSetInst &I) { void DFSanVisitor::visitMemTransferInst(MemTransferInst &I) { IRBuilder<> IRB(&I); - Value *DestShadow = DFSF.DFS.getShadowAddress(I.getDest(), &I); + Value *RawDestShadow = DFSF.DFS.getShadowAddress(I.getDest(), &I); Value *SrcShadow = DFSF.DFS.getShadowAddress(I.getSource(), &I); - Value *LenShadow = IRB.CreateMul( - I.getLength(), - ConstantInt::get(I.getLength()->getType(), DFSF.DFS.ShadowWidth / 8)); + Value *LenShadow = + IRB.CreateMul(I.getLength(), ConstantInt::get(I.getLength()->getType(), + DFSF.DFS.ShadowWidthBytes)); Type *Int8Ptr = Type::getInt8PtrTy(*DFSF.DFS.Ctx); - DestShadow = IRB.CreateBitCast(DestShadow, Int8Ptr); + Value *DestShadow = IRB.CreateBitCast(RawDestShadow, Int8Ptr); SrcShadow = IRB.CreateBitCast(SrcShadow, Int8Ptr); auto *MTI = cast<MemTransferInst>( - IRB.CreateCall(I.getFunctionType(), I.getCalledValue(), + IRB.CreateCall(I.getFunctionType(), I.getCalledOperand(), {DestShadow, SrcShadow, LenShadow, I.getVolatileCst()})); if (ClPreserveAlignment) { - MTI->setDestAlignment(I.getDestAlignment() * (DFSF.DFS.ShadowWidth / 8)); - MTI->setSourceAlignment(I.getSourceAlignment() * (DFSF.DFS.ShadowWidth / 8)); + MTI->setDestAlignment(I.getDestAlign() * DFSF.DFS.ShadowWidthBytes); + MTI->setSourceAlignment(I.getSourceAlign() * DFSF.DFS.ShadowWidthBytes); } else { - MTI->setDestAlignment(DFSF.DFS.ShadowWidth / 8); - MTI->setSourceAlignment(DFSF.DFS.ShadowWidth / 8); + MTI->setDestAlignment(Align(DFSF.DFS.ShadowWidthBytes)); + MTI->setSourceAlignment(Align(DFSF.DFS.ShadowWidthBytes)); + } + if (ClEventCallbacks) { + IRB.CreateCall(DFSF.DFS.DFSanMemTransferCallbackFn, + {RawDestShadow, I.getLength()}); } } @@ -1536,10 +1602,10 @@ void DFSanVisitor::visitReturnInst(ReturnInst &RI) { } } -void DFSanVisitor::visitCallSite(CallSite CS) { - Function *F = CS.getCalledFunction(); - if ((F && F->isIntrinsic()) || isa<InlineAsm>(CS.getCalledValue())) { - visitOperandShadowInst(*CS.getInstruction()); +void DFSanVisitor::visitCallBase(CallBase &CB) { + Function *F = CB.getCalledFunction(); + if ((F && F->isIntrinsic()) || CB.isInlineAsm()) { + visitOperandShadowInst(CB); return; } @@ -1548,32 +1614,32 @@ void DFSanVisitor::visitCallSite(CallSite CS) { if (F == DFSF.DFS.DFSanVarargWrapperFn.getCallee()->stripPointerCasts()) return; - IRBuilder<> IRB(CS.getInstruction()); + IRBuilder<> IRB(&CB); DenseMap<Value *, Function *>::iterator i = - DFSF.DFS.UnwrappedFnMap.find(CS.getCalledValue()); + DFSF.DFS.UnwrappedFnMap.find(CB.getCalledOperand()); if (i != DFSF.DFS.UnwrappedFnMap.end()) { Function *F = i->second; switch (DFSF.DFS.getWrapperKind(F)) { case DataFlowSanitizer::WK_Warning: - CS.setCalledFunction(F); + CB.setCalledFunction(F); IRB.CreateCall(DFSF.DFS.DFSanUnimplementedFn, IRB.CreateGlobalStringPtr(F->getName())); - DFSF.setShadow(CS.getInstruction(), DFSF.DFS.ZeroShadow); + DFSF.setShadow(&CB, DFSF.DFS.ZeroShadow); return; case DataFlowSanitizer::WK_Discard: - CS.setCalledFunction(F); - DFSF.setShadow(CS.getInstruction(), DFSF.DFS.ZeroShadow); + CB.setCalledFunction(F); + DFSF.setShadow(&CB, DFSF.DFS.ZeroShadow); return; case DataFlowSanitizer::WK_Functional: - CS.setCalledFunction(F); - visitOperandShadowInst(*CS.getInstruction()); + CB.setCalledFunction(F); + visitOperandShadowInst(CB); return; case DataFlowSanitizer::WK_Custom: // Don't try to handle invokes of custom functions, it's too complicated. // Instead, invoke the dfsw$ wrapper, which will in turn call the __dfsw_ // wrapper. - if (CallInst *CI = dyn_cast<CallInst>(CS.getInstruction())) { + if (CallInst *CI = dyn_cast<CallInst>(&CB)) { FunctionType *FT = F->getFunctionType(); TransformedFunction CustomFn = DFSF.DFS.getCustomFunctionType(FT); std::string CustomFName = "__dfsw_"; @@ -1592,7 +1658,7 @@ void DFSanVisitor::visitCallSite(CallSite CS) { std::vector<Value *> Args; - CallSite::arg_iterator i = CS.arg_begin(); + auto i = CB.arg_begin(); for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) { Type *T = (*i)->getType(); FunctionType *ParamFT; @@ -1612,19 +1678,19 @@ void DFSanVisitor::visitCallSite(CallSite CS) { } } - i = CS.arg_begin(); + i = CB.arg_begin(); const unsigned ShadowArgStart = Args.size(); for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) Args.push_back(DFSF.getShadow(*i)); if (FT->isVarArg()) { auto *LabelVATy = ArrayType::get(DFSF.DFS.ShadowTy, - CS.arg_size() - FT->getNumParams()); + CB.arg_size() - FT->getNumParams()); auto *LabelVAAlloca = new AllocaInst( LabelVATy, getDataLayout().getAllocaAddrSpace(), "labelva", &DFSF.F->getEntryBlock().front()); - for (unsigned n = 0; i != CS.arg_end(); ++i, ++n) { + for (unsigned n = 0; i != CB.arg_end(); ++i, ++n) { auto LabelVAPtr = IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, n); IRB.CreateStore(DFSF.getShadow(*i), LabelVAPtr); } @@ -1642,7 +1708,7 @@ void DFSanVisitor::visitCallSite(CallSite CS) { Args.push_back(DFSF.LabelReturnAlloca); } - for (i = CS.arg_begin() + FT->getNumParams(); i != CS.arg_end(); ++i) + for (i = CB.arg_begin() + FT->getNumParams(); i != CB.arg_end(); ++i) Args.push_back(*i); CallInst *CustomCI = IRB.CreateCall(CustomF, Args); @@ -1673,18 +1739,17 @@ void DFSanVisitor::visitCallSite(CallSite CS) { } } - FunctionType *FT = cast<FunctionType>( - CS.getCalledValue()->getType()->getPointerElementType()); + FunctionType *FT = CB.getFunctionType(); if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) { for (unsigned i = 0, n = FT->getNumParams(); i != n; ++i) { - IRB.CreateStore(DFSF.getShadow(CS.getArgument(i)), - DFSF.getArgTLS(i, CS.getInstruction())); + IRB.CreateStore(DFSF.getShadow(CB.getArgOperand(i)), + DFSF.getArgTLS(i, &CB)); } } Instruction *Next = nullptr; - if (!CS.getType()->isVoidTy()) { - if (InvokeInst *II = dyn_cast<InvokeInst>(CS.getInstruction())) { + if (!CB.getType()->isVoidTy()) { + if (InvokeInst *II = dyn_cast<InvokeInst>(&CB)) { if (II->getNormalDest()->getSinglePredecessor()) { Next = &II->getNormalDest()->front(); } else { @@ -1693,15 +1758,15 @@ void DFSanVisitor::visitCallSite(CallSite CS) { Next = &NewBB->front(); } } else { - assert(CS->getIterator() != CS->getParent()->end()); - Next = CS->getNextNode(); + assert(CB.getIterator() != CB.getParent()->end()); + Next = CB.getNextNode(); } if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) { IRBuilder<> NextIRB(Next); LoadInst *LI = NextIRB.CreateLoad(DFSF.DFS.ShadowTy, DFSF.getRetvalTLS()); DFSF.SkipInsts.insert(LI); - DFSF.setShadow(CS.getInstruction(), LI); + DFSF.setShadow(&CB, LI); DFSF.NonZeroChecks.push_back(LI); } } @@ -1711,25 +1776,25 @@ void DFSanVisitor::visitCallSite(CallSite CS) { if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_Args) { FunctionType *NewFT = DFSF.DFS.getArgsFunctionType(FT); Value *Func = - IRB.CreateBitCast(CS.getCalledValue(), PointerType::getUnqual(NewFT)); + IRB.CreateBitCast(CB.getCalledOperand(), PointerType::getUnqual(NewFT)); std::vector<Value *> Args; - CallSite::arg_iterator i = CS.arg_begin(), e = CS.arg_end(); + auto i = CB.arg_begin(), E = CB.arg_end(); for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) Args.push_back(*i); - i = CS.arg_begin(); + i = CB.arg_begin(); for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) Args.push_back(DFSF.getShadow(*i)); if (FT->isVarArg()) { - unsigned VarArgSize = CS.arg_size() - FT->getNumParams(); + unsigned VarArgSize = CB.arg_size() - FT->getNumParams(); ArrayType *VarArgArrayTy = ArrayType::get(DFSF.DFS.ShadowTy, VarArgSize); AllocaInst *VarArgShadow = new AllocaInst(VarArgArrayTy, getDataLayout().getAllocaAddrSpace(), "", &DFSF.F->getEntryBlock().front()); Args.push_back(IRB.CreateConstGEP2_32(VarArgArrayTy, VarArgShadow, 0, 0)); - for (unsigned n = 0; i != e; ++i, ++n) { + for (unsigned n = 0; i != E; ++i, ++n) { IRB.CreateStore( DFSF.getShadow(*i), IRB.CreateConstGEP2_32(VarArgArrayTy, VarArgShadow, 0, n)); @@ -1737,32 +1802,30 @@ void DFSanVisitor::visitCallSite(CallSite CS) { } } - CallSite NewCS; - if (InvokeInst *II = dyn_cast<InvokeInst>(CS.getInstruction())) { - NewCS = IRB.CreateInvoke(NewFT, Func, II->getNormalDest(), + CallBase *NewCB; + if (InvokeInst *II = dyn_cast<InvokeInst>(&CB)) { + NewCB = IRB.CreateInvoke(NewFT, Func, II->getNormalDest(), II->getUnwindDest(), Args); } else { - NewCS = IRB.CreateCall(NewFT, Func, Args); + NewCB = IRB.CreateCall(NewFT, Func, Args); } - NewCS.setCallingConv(CS.getCallingConv()); - NewCS.setAttributes(CS.getAttributes().removeAttributes( + NewCB->setCallingConv(CB.getCallingConv()); + NewCB->setAttributes(CB.getAttributes().removeAttributes( *DFSF.DFS.Ctx, AttributeList::ReturnIndex, - AttributeFuncs::typeIncompatible(NewCS.getInstruction()->getType()))); + AttributeFuncs::typeIncompatible(NewCB->getType()))); if (Next) { - ExtractValueInst *ExVal = - ExtractValueInst::Create(NewCS.getInstruction(), 0, "", Next); + ExtractValueInst *ExVal = ExtractValueInst::Create(NewCB, 0, "", Next); DFSF.SkipInsts.insert(ExVal); - ExtractValueInst *ExShadow = - ExtractValueInst::Create(NewCS.getInstruction(), 1, "", Next); + ExtractValueInst *ExShadow = ExtractValueInst::Create(NewCB, 1, "", Next); DFSF.SkipInsts.insert(ExShadow); DFSF.setShadow(ExVal, ExShadow); DFSF.NonZeroChecks.push_back(ExShadow); - CS.getInstruction()->replaceAllUsesWith(ExVal); + CB.replaceAllUsesWith(ExVal); } - CS.getInstruction()->eraseFromParent(); + CB.eraseFromParent(); } } |