X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTransforms%2FInstrumentation%2FDataFlowSanitizer.cpp;h=cb84fd672667e457cea0ceb616aa8ba347843257;hp=f79b203952868dc087a1dc1bfdfe50ba27a94e60;hb=e376441786f994d7d3f27817e163d226d31b641e;hpb=7b96c4919a33cd13fad2fd99c85e60cac51838e2 diff --git a/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index f79b2039528..cb84fd67266 100644 --- a/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -51,6 +51,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/ValueTracking.h" #include "llvm/IR/Dominators.h" +#include "llvm/IR/DebugInfo.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/InstVisitor.h" @@ -139,7 +140,7 @@ class DFSanABIList { std::unique_ptr SCL; public: - DFSanABIList(std::unique_ptr SCL) : SCL(std::move(SCL)) {} + DFSanABIList(std::unique_ptr SCL) : SCL(std::move(SCL)) {} /// Returns whether either this function or its source file are listed in the /// given category. @@ -243,6 +244,7 @@ class DataFlowSanitizer : public ModulePass { DFSanABIList ABIList; DenseMap UnwrappedFnMap; AttributeSet ReadOnlyNoneAttrs; + DenseMap FunctionDIs; Value *getShadowAddress(Value *Addr, Instruction *Pos); bool isInstrumented(const Function *F); @@ -387,7 +389,12 @@ FunctionType *DataFlowSanitizer::getTrampolineFunctionType(FunctionType *T) { } FunctionType *DataFlowSanitizer::getCustomFunctionType(FunctionType *T) { - assert(!T->isVarArg()); + if (T->isVarArg()) { + // The labels are passed after all the arguments so there is no need to + // adjust the function type. + return T; + } + llvm::SmallVector ArgTypes; for (FunctionType::param_iterator i = T->param_begin(), e = T->param_end(); i != e; ++i) { @@ -476,7 +483,7 @@ DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(Function *F) { return WK_Functional; if (ABIList.isIn(*F, "discard")) return WK_Discard; - if (ABIList.isIn(*F, "custom") && !F->isVarArg()) + if (ABIList.isIn(*F, "custom")) return WK_Custom; return WK_Warning; @@ -568,6 +575,8 @@ bool DataFlowSanitizer::runOnModule(Module &M) { if (ABIList.isIn(M, "skip")) return false; + FunctionDIs = makeSubprogramMap(M); + if (!GetArgTLSPtr) { Type *ArgTLSTy = ArrayType::get(ShadowTy, 64); ArgTLS = Mod->getOrInsertGlobal("__dfsan_arg_tls", ArgTLSTy); @@ -704,11 +713,6 @@ bool DataFlowSanitizer::runOnModule(Module &M) { } else { addGlobalNamePrefix(&F); } - // Hopefully, nobody will try to indirectly call a vararg - // function... yet. - } else if (FT->isVarArg()) { - UnwrappedFnMap[&F] = &F; - *i = nullptr; } else if (!IsZeroArgsVoidRet || getWrapperKind(&F) == WK_Custom) { // Build a wrapper function for F. The wrapper simply calls F, and is // added to FnsToInstrument so that any instrumentation according to its @@ -725,6 +729,12 @@ bool DataFlowSanitizer::runOnModule(Module &M) { Value *WrappedFnCst = ConstantExpr::getBitCast(NewF, PointerType::getUnqual(FT)); F.replaceAllUsesWith(WrappedFnCst); + + // Patch the pointer to LLVM function in debug info descriptor. + auto DI = FunctionDIs.find(&F); + if (DI != FunctionDIs.end()) + DI->second.replaceFunction(&F); + UnwrappedFnMap[WrappedFnCst] = &F; *i = NewF; @@ -744,6 +754,11 @@ bool DataFlowSanitizer::runOnModule(Module &M) { i = FnsToInstrument.begin() + N; e = FnsToInstrument.begin() + Count; } + // Hopefully, nobody will try to indirectly call a vararg + // function... yet. + } else if (FT->isVarArg()) { + UnwrappedFnMap[&F] = &F; + *i = nullptr; } } @@ -1352,6 +1367,10 @@ void DFSanVisitor::visitCallSite(CallSite CS) { return; } + assert(!(cast( + CS.getCalledValue()->getType()->getPointerElementType())->isVarArg() && + dyn_cast(CS.getInstruction()))); + IRBuilder<> IRB(CS.getInstruction()); DenseMap::iterator i = @@ -1400,7 +1419,7 @@ void DFSanVisitor::visitCallSite(CallSite CS) { std::vector Args; CallSite::arg_iterator i = CS.arg_begin(); - for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) { + for (unsigned n = CS.arg_size(); n != 0; ++i, --n) { Type *T = (*i)->getType(); FunctionType *ParamFT; if (isa(T) && @@ -1420,7 +1439,7 @@ void DFSanVisitor::visitCallSite(CallSite CS) { } i = CS.arg_begin(); - for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) + for (unsigned n = CS.arg_size(); n != 0; ++i, --n) Args.push_back(DFSF.getShadow(*i)); if (!FT->getReturnType()->isVoidTy()) {