From dd3486ece1c0e6669e8c1f9fa5849310d613b38a Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 30 Oct 2014 13:22:57 +0000 Subject: [dfsan] New calling convention for custom functions with variadic arguments. Summary: The previous calling convention prevented custom functions from being able to access argument labels unless it knew how many variadic arguments there were, and of which type. This restriction made it impossible to correctly model functions in the printf family, as it is legal to pass more arguments than required to those functions. We now pass arguments in the following order: non-vararg arguments labels for non-vararg arguments [if vararg function, pointer to array of labels for vararg arguments] [if non-void function, pointer to label for return value] vararg arguments Differential Revision: http://reviews.llvm.org/D6028 llvm-svn: 220906 --- .../Instrumentation/DataFlowSanitizer.cpp | 31 +++++++++++++++------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp') diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp index cb84fd6..fa8257f 100644 --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -389,12 +389,6 @@ FunctionType *DataFlowSanitizer::getTrampolineFunctionType(FunctionType *T) { } FunctionType *DataFlowSanitizer::getCustomFunctionType(FunctionType *T) { - 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) { @@ -409,10 +403,12 @@ FunctionType *DataFlowSanitizer::getCustomFunctionType(FunctionType *T) { } for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) ArgTypes.push_back(ShadowTy); + if (T->isVarArg()) + ArgTypes.push_back(ShadowPtrTy); Type *RetType = T->getReturnType(); if (!RetType->isVoidTy()) ArgTypes.push_back(ShadowPtrTy); - return FunctionType::get(T->getReturnType(), ArgTypes, false); + return FunctionType::get(T->getReturnType(), ArgTypes, T->isVarArg()); } bool DataFlowSanitizer::doInitialization(Module &M) { @@ -1419,7 +1415,7 @@ void DFSanVisitor::visitCallSite(CallSite CS) { std::vector Args; CallSite::arg_iterator i = CS.arg_begin(); - for (unsigned n = CS.arg_size(); n != 0; ++i, --n) { + for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) { Type *T = (*i)->getType(); FunctionType *ParamFT; if (isa(T) && @@ -1439,9 +1435,23 @@ void DFSanVisitor::visitCallSite(CallSite CS) { } i = CS.arg_begin(); - for (unsigned n = CS.arg_size(); n != 0; ++i, --n) + for (unsigned n = FT->getNumParams(); n != 0; ++i, --n) Args.push_back(DFSF.getShadow(*i)); + if (FT->isVarArg()) { + auto LabelVAAlloca = + new AllocaInst(ArrayType::get(DFSF.DFS.ShadowTy, + CS.arg_size() - FT->getNumParams()), + "labelva", DFSF.F->getEntryBlock().begin()); + + for (unsigned n = 0; i != CS.arg_end(); ++i, ++n) { + auto LabelVAPtr = IRB.CreateStructGEP(LabelVAAlloca, n); + IRB.CreateStore(DFSF.getShadow(*i), LabelVAPtr); + } + + Args.push_back(IRB.CreateStructGEP(LabelVAAlloca, 0)); + } + if (!FT->getReturnType()->isVoidTy()) { if (!DFSF.LabelReturnAlloca) { DFSF.LabelReturnAlloca = @@ -1451,6 +1461,9 @@ void DFSanVisitor::visitCallSite(CallSite CS) { Args.push_back(DFSF.LabelReturnAlloca); } + for (i = CS.arg_begin() + FT->getNumParams(); i != CS.arg_end(); ++i) + Args.push_back(*i); + CallInst *CustomCI = IRB.CreateCall(CustomF, Args); CustomCI->setCallingConv(CI->getCallingConv()); CustomCI->setAttributes(CI->getAttributes()); -- cgit v1.1