summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2014-10-30 13:22:57 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2014-10-30 13:22:57 +0000
commitdd3486ece1c0e6669e8c1f9fa5849310d613b38a (patch)
treeea659e4e541b465b16e3de634858aa902f5f8271 /llvm/lib
parent3f4062902a6a4aa0812dbcc61355449e7cd5c6a2 (diff)
downloadbcm5719-llvm-dd3486ece1c0e6669e8c1f9fa5849310d613b38a.tar.gz
bcm5719-llvm-dd3486ece1c0e6669e8c1f9fa5849310d613b38a.zip
[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
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp31
1 files changed, 22 insertions, 9 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index cb84fd67266..fa8257f3834 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<Type *, 4> 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<Value *> 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<PointerType>(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());
OpenPOWER on IntegriCloud