Index: llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -389,12 +389,6 @@ } 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 @@ } 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 @@ 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 @@ } 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 @@ 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()); Index: llvm/trunk/test/Instrumentation/DataFlowSanitizer/abilist.ll =================================================================== --- llvm/trunk/test/Instrumentation/DataFlowSanitizer/abilist.ll +++ llvm/trunk/test/Instrumentation/DataFlowSanitizer/abilist.ll @@ -12,8 +12,21 @@ ret i32 %c } +; CHECK: define i32 (i32, i32)* @discardg(i32) +; CHECK: %[[CALL:.*]] = call { i32 (i32, i32)*, i16 } @"dfs$g"(i32 %0, i16 0) +; CHECK: %[[XVAL:.*]] = extractvalue { i32 (i32, i32)*, i16 } %[[CALL]], 0 +; CHECK: ret {{.*}} %[[XVAL]] +@discardg = alias i32 (i32, i32)* (i32)* @g + declare void @custom1(i32 %a, i32 %b) +; CHECK: define linkonce_odr { i32, i16 } @"dfsw$custom2"(i32, i32, i16, i16) +; CHECK: %[[LABELRETURN2:.*]] = alloca i16 +; CHECK: %[[RV:.*]] = call i32 @__dfsw_custom2 +; CHECK: %[[RVSHADOW:.*]] = load i16* %[[LABELRETURN2]] +; CHECK: insertvalue {{.*}}[[RV]], 0 +; CHECK: insertvalue {{.*}}[[RVSHADOW]], 1 +; CHECK: ret { i32, i16 } declare i32 @custom2(i32 %a, i32 %b) declare void @custom3(i32 %a, ...) @@ -25,7 +38,9 @@ declare i32 @cb(i32) ; CHECK: @"dfs$f" -define void @f() { +define void @f(i32 %x) { + ; CHECK: %[[LABELVA2:.*]] = alloca [2 x i16] + ; CHECK: %[[LABELVA1:.*]] = alloca [2 x i16] ; CHECK: %[[LABELRETURN:.*]] = alloca i16 ; CHECK: call void @__dfsw_custom1(i32 1, i32 2, i16 0, i16 0) @@ -37,29 +52,22 @@ ; CHECK: call void @__dfsw_customcb({{.*}} @"dfst0$customcb", i8* bitcast ({{.*}} @"dfs$cb" to i8*), i16 0) call void @customcb(i32 (i32)* @cb) - ; CHECK: call void (i32, ...)* @__dfsw_custom3(i32 1, i32 2, i32 3, i16 0, i16 0, i16 0) - call void (i32, ...)* @custom3(i32 1, i32 2, i32 3) - - ; CHECK: call i32 (i32, ...)* @__dfsw_custom4(i32 1, i32 2, i32 3, i16 0, i16 0, i16 0, i16* %[[LABELRETURN]]) + ; CHECK: %[[LABELVA1_0:.*]] = getelementptr inbounds [2 x i16]* %[[LABELVA1]], i32 0, i32 0 + ; CHECK: store i16 0, i16* %[[LABELVA1_0]] + ; CHECK: %[[LABELVA1_1:.*]] = getelementptr inbounds [2 x i16]* %[[LABELVA1]], i32 0, i32 1 + ; CHECK: store i16 %{{.*}}, i16* %[[LABELVA1_1]] + ; CHECK: %[[LABELVA1_0A:.*]] = getelementptr inbounds [2 x i16]* %[[LABELVA1]], i32 0, i32 0 + ; CHECK: call void (i32, i16, i16*, ...)* @__dfsw_custom3(i32 1, i16 0, i16* %[[LABELVA1_0A]], i32 2, i32 %{{.*}}) + call void (i32, ...)* @custom3(i32 1, i32 2, i32 %x) + + ; CHECK: %[[LABELVA2_0:.*]] = getelementptr inbounds [2 x i16]* %[[LABELVA2]], i32 0, i32 0 + ; CHECK: %[[LABELVA2_0A:.*]] = getelementptr inbounds [2 x i16]* %[[LABELVA2]], i32 0, i32 0 + ; CHECK: call i32 (i32, i16, i16*, i16*, ...)* @__dfsw_custom4(i32 1, i16 0, i16* %[[LABELVA2_0A]], i16* %[[LABELRETURN]], i32 2, i32 3) call i32 (i32, ...)* @custom4(i32 1, i32 2, i32 3) ret void } -; CHECK: define i32 (i32, i32)* @discardg(i32) -; CHECK: %[[CALL:.*]] = call { i32 (i32, i32)*, i16 } @"dfs$g"(i32 %0, i16 0) -; CHECK: %[[XVAL:.*]] = extractvalue { i32 (i32, i32)*, i16 } %[[CALL]], 0 -; CHECK: ret {{.*}} %[[XVAL]] -@discardg = alias i32 (i32, i32)* (i32)* @g - -; CHECK: define linkonce_odr { i32, i16 } @"dfsw$custom2"(i32, i32, i16, i16) -; CHECK: %[[LABELRETURN2:.*]] = alloca i16 -; CHECK: %[[RV:.*]] = call i32 @__dfsw_custom2 -; CHECK: %[[RVSHADOW:.*]] = load i16* %[[LABELRETURN2]] -; CHECK: insertvalue {{.*}}[[RV]], 0 -; CHECK: insertvalue {{.*}}[[RVSHADOW]], 1 -; CHECK: ret { i32, i16 } - ; CHECK: @"dfs$g" define i32 (i32, i32)* @g(i32) { ; CHECK: ret {{.*}} @"dfsw$custom2" @@ -75,8 +83,8 @@ ; CHECK: declare void @__dfsw_custom1(i32, i32, i16, i16) ; CHECK: declare i32 @__dfsw_custom2(i32, i32, i16, i16, i16*) -; CHECK: declare void @__dfsw_custom3(i32, ...) -; CHECK: declare i32 @__dfsw_custom4(i32, ...) +; CHECK: declare void @__dfsw_custom3(i32, i16, i16*, ...) +; CHECK: declare i32 @__dfsw_custom4(i32, i16, i16*, i16*, ...) ; CHECK-LABEL: define linkonce_odr i32 @"dfst0$customcb"(i32 (i32)*, i32, i16, i16*) ; CHECK: %[[BC:.*]] = bitcast i32 (i32)* %0 to { i32, i16 } (i32, i16)* @@ -85,3 +93,4 @@ ; CHECK: %[[XVAL1:.*]] = extractvalue { i32, i16 } %[[CALL]], 1 ; CHECK: store i16 %[[XVAL1]], i16* %3 ; CHECK: ret i32 %[[XVAL0]] +