diff options
Diffstat (limited to 'lib/Transforms/Instrumentation/DataFlowSanitizer.cpp')
-rw-r--r-- | lib/Transforms/Instrumentation/DataFlowSanitizer.cpp | 116 |
1 files changed, 65 insertions, 51 deletions
diff --git a/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index 9b9e725cde..df1549d405 100644 --- a/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -50,13 +50,13 @@ #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/ValueTracking.h" -#include "llvm/IR/InlineAsm.h" #include "llvm/IR/IRBuilder.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/InstVisitor.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" -#include "llvm/InstVisitor.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" @@ -96,6 +96,22 @@ static cl::opt<bool> ClArgsABI( cl::desc("Use the argument ABI rather than the TLS ABI"), cl::Hidden); +// Controls whether the pass includes or ignores the labels of pointers in load +// instructions. +static cl::opt<bool> ClCombinePointerLabelsOnLoad( + "dfsan-combine-pointer-labels-on-load", + cl::desc("Combine the label of the pointer with the label of the data when " + "loading from memory."), + cl::Hidden, cl::init(true)); + +// Controls whether the pass includes or ignores the labels of pointers in +// stores instructions. +static cl::opt<bool> ClCombinePointerLabelsOnStore( + "dfsan-combine-pointer-labels-on-store", + cl::desc("Combine the label of the pointer with the label of the data when " + "storing in memory."), + cl::Hidden, cl::init(false)); + static cl::opt<bool> ClDebugNonzeroLabels( "dfsan-debug-nonzero-labels", cl::desc("Insert calls to __dfsan_nonzero_label on observing a parameter, " @@ -148,7 +164,7 @@ class DataFlowSanitizer : public ModulePass { WK_Custom }; - DataLayout *DL; + const DataLayout *DL; Module *Mod; LLVMContext *Ctx; IntegerType *ShadowTy; @@ -174,7 +190,7 @@ class DataFlowSanitizer : public ModulePass { Constant *DFSanSetLabelFn; Constant *DFSanNonzeroLabelFn; MDNode *ColdCallWeights; - OwningPtr<SpecialCaseList> ABIList; + std::unique_ptr<SpecialCaseList> ABIList; DenseMap<Value *, Function *> UnwrappedFnMap; AttributeSet ReadOnlyNoneAttrs; @@ -197,8 +213,8 @@ class DataFlowSanitizer : public ModulePass { DataFlowSanitizer(StringRef ABIListFile = StringRef(), void *(*getArgTLS)() = 0, void *(*getRetValTLS)() = 0); static char ID; - bool doInitialization(Module &M); - bool runOnModule(Module &M); + bool doInitialization(Module &M) override; + bool runOnModule(Module &M) override; }; struct DFSanFunction { @@ -327,9 +343,10 @@ FunctionType *DataFlowSanitizer::getCustomFunctionType(FunctionType *T) { } bool DataFlowSanitizer::doInitialization(Module &M) { - DL = getAnalysisIfAvailable<DataLayout>(); - if (!DL) + DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); + if (!DLP) return false; + DL = &DLP->getDataLayout(); Mod = &M; Ctx = &M.getContext(); @@ -505,6 +522,7 @@ bool DataFlowSanitizer::runOnModule(Module &M) { DFSanUnionLoadFn = Mod->getOrInsertFunction("__dfsan_union_load", DFSanUnionLoadFnTy); if (Function *F = dyn_cast<Function>(DFSanUnionLoadFn)) { + F->addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly); F->addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt); } DFSanUnimplementedFn = @@ -536,8 +554,7 @@ bool DataFlowSanitizer::runOnModule(Module &M) { ++i; // Don't stop on weak. We assume people aren't playing games with the // instrumentedness of overridden weak aliases. - if (Function *F = dyn_cast<Function>( - GA->resolveAliasedGlobal(/*stopOnWeak=*/false))) { + if (Function *F = dyn_cast<Function>(GA->getAliasedGlobal())) { bool GAInst = isInstrumented(GA), FInst = isInstrumented(F); if (GAInst && FInst) { addGlobalNamePrefix(GA); @@ -589,10 +606,10 @@ bool DataFlowSanitizer::runOnModule(Module &M) { } NewF->getBasicBlockList().splice(NewF->begin(), F.getBasicBlockList()); - for (Function::use_iterator ui = F.use_begin(), ue = F.use_end(); - ui != ue;) { - BlockAddress *BA = dyn_cast<BlockAddress>(ui.getUse().getUser()); - ++ui; + for (Function::user_iterator UI = F.user_begin(), UE = F.user_end(); + UI != UE;) { + BlockAddress *BA = dyn_cast<BlockAddress>(*UI); + ++UI; if (BA) { BA->replaceAllUsesWith( BlockAddress::get(NewF, BA->getBasicBlock())); @@ -718,10 +735,9 @@ bool DataFlowSanitizer::runOnModule(Module &M) { while (isa<PHINode>(Pos) || isa<AllocaInst>(Pos)) Pos = Pos->getNextNode(); IRBuilder<> IRB(Pos); - Instruction *NeInst = cast<Instruction>( - IRB.CreateICmpNE(*i, DFSF.DFS.ZeroShadow)); + Value *Ne = IRB.CreateICmpNE(*i, DFSF.DFS.ZeroShadow); BranchInst *BI = cast<BranchInst>(SplitBlockAndInsertIfThen( - NeInst, /*Unreachable=*/ false, ColdCallWeights)); + Ne, Pos, /*Unreachable=*/false, ColdCallWeights)); IRBuilder<> ThenIRB(BI); ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn); } @@ -821,26 +837,19 @@ Value *DataFlowSanitizer::combineShadows(Value *V1, Value *V2, IRBuilder<> IRB(Pos); BasicBlock *Head = Pos->getParent(); Value *Ne = IRB.CreateICmpNE(V1, V2); - Instruction *NeInst = dyn_cast<Instruction>(Ne); - if (NeInst) { - BranchInst *BI = cast<BranchInst>(SplitBlockAndInsertIfThen( - NeInst, /*Unreachable=*/ false, ColdCallWeights)); - IRBuilder<> ThenIRB(BI); - CallInst *Call = ThenIRB.CreateCall2(DFSanUnionFn, V1, V2); - Call->addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt); - Call->addAttribute(1, Attribute::ZExt); - Call->addAttribute(2, Attribute::ZExt); - - BasicBlock *Tail = BI->getSuccessor(0); - PHINode *Phi = PHINode::Create(ShadowTy, 2, "", Tail->begin()); - Phi->addIncoming(Call, Call->getParent()); - Phi->addIncoming(V1, Head); - Pos = Phi; - return Phi; - } else { - assert(0 && "todo"); - return 0; - } + BranchInst *BI = cast<BranchInst>(SplitBlockAndInsertIfThen( + Ne, Pos, /*Unreachable=*/false, ColdCallWeights)); + IRBuilder<> ThenIRB(BI); + CallInst *Call = ThenIRB.CreateCall2(DFSanUnionFn, V1, V2); + Call->addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt); + Call->addAttribute(1, Attribute::ZExt); + Call->addAttribute(2, Attribute::ZExt); + + BasicBlock *Tail = BI->getSuccessor(0); + PHINode *Phi = PHINode::Create(ShadowTy, 2, "", Tail->begin()); + Phi->addIncoming(Call, Call->getParent()); + Phi->addIncoming(V1, Head); + return Phi; } // A convenience function which folds the shadows of each of the operands @@ -978,14 +987,15 @@ void DFSanVisitor::visitLoadInst(LoadInst &LI) { Align = 1; } IRBuilder<> IRB(&LI); - Value *LoadedShadow = - DFSF.loadShadow(LI.getPointerOperand(), Size, Align, &LI); - Value *PtrShadow = DFSF.getShadow(LI.getPointerOperand()); - Value *CombinedShadow = DFSF.DFS.combineShadows(LoadedShadow, PtrShadow, &LI); - if (CombinedShadow != DFSF.DFS.ZeroShadow) - DFSF.NonZeroChecks.insert(CombinedShadow); - - DFSF.setShadow(&LI, CombinedShadow); + Value *Shadow = DFSF.loadShadow(LI.getPointerOperand(), Size, Align, &LI); + if (ClCombinePointerLabelsOnLoad) { + Value *PtrShadow = DFSF.getShadow(LI.getPointerOperand()); + Shadow = DFSF.DFS.combineShadows(Shadow, PtrShadow, &LI); + } + if (Shadow != DFSF.DFS.ZeroShadow) + DFSF.NonZeroChecks.insert(Shadow); + + DFSF.setShadow(&LI, Shadow); } void DFSanFunction::storeShadow(Value *Addr, uint64_t Size, uint64_t Align, @@ -1050,8 +1060,13 @@ void DFSanVisitor::visitStoreInst(StoreInst &SI) { } else { Align = 1; } - DFSF.storeShadow(SI.getPointerOperand(), Size, Align, - DFSF.getShadow(SI.getValueOperand()), &SI); + + Value* Shadow = DFSF.getShadow(SI.getValueOperand()); + if (ClCombinePointerLabelsOnStore) { + Value *PtrShadow = DFSF.getShadow(SI.getPointerOperand()); + Shadow = DFSF.DFS.combineShadows(Shadow, PtrShadow, &SI); + } + DFSF.storeShadow(SI.getPointerOperand(), Size, Align, Shadow, &SI); } void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) { @@ -1088,12 +1103,11 @@ void DFSanVisitor::visitInsertValueInst(InsertValueInst &I) { void DFSanVisitor::visitAllocaInst(AllocaInst &I) { bool AllLoadsStores = true; - for (Instruction::use_iterator i = I.use_begin(), e = I.use_end(); i != e; - ++i) { - if (isa<LoadInst>(*i)) + for (User *U : I.users()) { + if (isa<LoadInst>(U)) continue; - if (StoreInst *SI = dyn_cast<StoreInst>(*i)) { + if (StoreInst *SI = dyn_cast<StoreInst>(U)) { if (SI->getPointerOperand() == &I) continue; } |