82 "dfsan-preserve-alignment",
95 cl::desc(
"File listing native ABI functions and how the pass treats them"),
102 cl::desc(
"Use the argument ABI rather than the TLS ABI"),
108 "dfsan-combine-pointer-labels-on-load",
109 cl::desc(
"Combine the label of the pointer with the label of the data when "
110 "loading from memory."),
116 "dfsan-combine-pointer-labels-on-store",
117 cl::desc(
"Combine the label of the pointer with the label of the data when "
118 "storing in memory."),
122 "dfsan-debug-nonzero-labels",
123 cl::desc(
"Insert calls to __dfsan_nonzero_label on observing a parameter, "
124 "load or return with a nonzero label"),
133 if (
StructType *SGType = dyn_cast<StructType>(GType)) {
134 if (!SGType->isLiteral())
135 return SGType->getName();
137 return "<unknown type>";
141 std::unique_ptr<SpecialCaseList> SCL;
146 void set(std::unique_ptr<SpecialCaseList>
List) { SCL = std::move(List); }
152 SCL->inSection(
"fun", F.
getName(), Category);
164 return SCL->inSection(
"fun", GA.
getName(), Category);
166 return SCL->inSection(
"global", GA.
getName(), Category) ||
167 SCL->inSection(
"type", GetGlobalTypeString(GA), Category);
177 friend struct DFSanFunction;
178 friend class DFSanVisitor;
185 enum InstrumentedABI {
230 void *(*GetArgTLSPtr)();
231 void *(*GetRetvalTLSPtr)();
248 DFSanABIList ABIList;
254 bool isInstrumented(
const Function *F);
259 InstrumentedABI getInstrumentedABI();
260 WrapperKind getWrapperKind(
Function *F);
269 const std::vector<std::string> &ABIListFiles = std::vector<std::string>(),
270 void *(*getArgTLS)() =
nullptr,
void *(*getRetValTLS)() =
nullptr);
272 bool doInitialization(
Module &M)
override;
273 bool runOnModule(
Module &M)
override;
276 struct DFSanFunction {
277 DataFlowSanitizer &DFS;
280 DataFlowSanitizer::InstrumentedABI IA;
287 std::vector<std::pair<PHINode *, PHINode *> > PHIFixups;
289 std::vector<Value *> NonZeroChecks;
292 struct CachedCombinedShadow {
297 CachedCombinedShadows;
300 DFSanFunction(DataFlowSanitizer &DFS,
Function *F,
bool IsNativeABI)
301 : DFS(DFS), F(F), IA(DFS.getInstrumentedABI()),
302 IsNativeABI(IsNativeABI), ArgTLSPtr(nullptr), RetvalTLSPtr(nullptr),
303 LabelReturnAlloca(nullptr) {
307 AvoidNewBlocks = F->
size() > 1000;
309 Value *getArgTLSPtr();
311 Value *getRetvalTLS();
318 void storeShadow(
Value *Addr, uint64_t Size, uint64_t
Align,
Value *Shadow,
322 class DFSanVisitor :
public InstVisitor<DFSanVisitor> {
325 DFSanVisitor(DFSanFunction &DFSF) : DFSF(DFSF) {}
331 void visitCmpInst(
CmpInst &CI);
337 void visitPHINode(
PHINode &PN);
353 "DataFlowSanitizer: dynamic data flow analysis.",
false,
false)
357 void *(*getArgTLS)(),
358 void *(*getRetValTLS)()) {
359 return new DataFlowSanitizer(ABIListFiles, getArgTLS, getRetValTLS);
362 DataFlowSanitizer::DataFlowSanitizer(
363 const std::vector<std::string> &ABIListFiles,
void *(*getArgTLS)(),
364 void *(*getRetValTLS)())
365 :
ModulePass(
ID), GetArgTLSPtr(getArgTLS), GetRetvalTLSPtr(getRetValTLS) {
366 std::vector<std::string> AllABIListFiles(std::move(ABIListFiles));
367 AllABIListFiles.insert(AllABIListFiles.end(),
ClABIListFiles.begin(),
369 ABIList.set(SpecialCaseList::createOrDie(AllABIListFiles));
376 ArgTypes.push_back(ShadowPtrTy);
379 RetType = StructType::get(RetType, ShadowTy, (
Type *)
nullptr);
380 return FunctionType::get(RetType, ArgTypes, T->
isVarArg());
391 ArgTypes.push_back(ShadowPtrTy);
392 return FunctionType::get(T->
getReturnType(), ArgTypes,
false);
401 *i)->getElementType()))) {
402 ArgTypes.
push_back(getTrampolineFunctionType(FT)->getPointerTo());
403 ArgTypes.
push_back(Type::getInt8PtrTy(*Ctx));
408 for (
unsigned i = 0, e = T->
getNumParams(); i != e; ++i)
418 bool DataFlowSanitizer::doInitialization(
Module &M) {
428 ShadowTy = IntegerType::get(*Ctx, ShadowWidth);
429 ShadowPtrTy = PointerType::getUnqual(ShadowTy);
431 ZeroShadow = ConstantInt::getSigned(ShadowTy, 0);
432 ShadowPtrMul = ConstantInt::getSigned(IntptrTy, ShadowWidth / 8);
434 ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0x700000000000LL);
436 ShadowPtrMask = ConstantInt::getSigned(IntptrTy, ~0xF000000000LL);
440 Type *DFSanUnionArgs[2] = { ShadowTy, ShadowTy };
442 FunctionType::get(ShadowTy, DFSanUnionArgs,
false);
443 Type *DFSanUnionLoadArgs[2] = { ShadowPtrTy, IntptrTy };
445 FunctionType::get(ShadowTy, DFSanUnionLoadArgs,
false);
446 DFSanUnimplementedFnTy = FunctionType::get(
447 Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx),
false);
448 Type *DFSanSetLabelArgs[3] = { ShadowTy, Type::getInt8PtrTy(*Ctx), IntptrTy };
449 DFSanSetLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx),
450 DFSanSetLabelArgs,
false);
451 DFSanNonzeroLabelFnTy = FunctionType::get(
452 Type::getVoidTy(*Ctx),
None,
false);
453 DFSanVarargWrapperFnTy = FunctionType::get(
454 Type::getVoidTy(*Ctx), Type::getInt8PtrTy(*Ctx),
false);
457 Type *ArgTLSTy = ArrayType::get(ShadowTy, 64);
459 GetArgTLS = ConstantExpr::getIntToPtr(
460 ConstantInt::get(IntptrTy, uintptr_t(GetArgTLSPtr)),
461 PointerType::getUnqual(
462 FunctionType::get(PointerType::getUnqual(ArgTLSTy),
465 if (GetRetvalTLSPtr) {
467 GetRetvalTLS = ConstantExpr::getIntToPtr(
468 ConstantInt::get(IntptrTy, uintptr_t(GetRetvalTLSPtr)),
469 PointerType::getUnqual(
470 FunctionType::get(PointerType::getUnqual(ShadowTy),
478 bool DataFlowSanitizer::isInstrumented(
const Function *F) {
479 return !ABIList.isIn(*F,
"uninstrumented");
482 bool DataFlowSanitizer::isInstrumented(
const GlobalAlias *GA) {
483 return !ABIList.isIn(*GA,
"uninstrumented");
486 DataFlowSanitizer::InstrumentedABI DataFlowSanitizer::getInstrumentedABI() {
490 DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(
Function *F) {
491 if (ABIList.isIn(*F,
"functional"))
492 return WK_Functional;
493 if (ABIList.isIn(*F,
"discard"))
495 if (ABIList.isIn(*F,
"custom"))
501 void DataFlowSanitizer::addGlobalNamePrefix(
GlobalValue *GV) {
511 std::string SearchStr =
".symver " + GVName +
",";
512 size_t Pos = Asm.find(SearchStr);
513 if (Pos != std::string::npos) {
514 Asm.replace(Pos, SearchStr.size(),
525 Function *NewF = Function::Create(NewFT, NewFLink, NewFName,
529 AttributeSet::ReturnIndex,
530 AttributeSet::get(F->
getContext(), AttributeSet::ReturnIndex,
533 BasicBlock *BB = BasicBlock::Create(*Ctx,
"entry", NewF);
536 AttributeSet::FunctionIndex,
537 AttributeSet().addAttribute(*Ctx, AttributeSet::FunctionIndex,
539 CallInst::Create(DFSanVarargWrapperFn,
544 std::vector<Value *> Args;
547 Args.push_back(&*ai);
548 CallInst *CI = CallInst::Create(F, Args,
"", BB);
550 ReturnInst::Create(*Ctx, BB);
552 ReturnInst::Create(*Ctx, CI, BB);
561 Constant *
C = Mod->getOrInsertFunction(FName, FTT);
564 F->
setLinkage(GlobalValue::LinkOnceODRLinkage);
565 BasicBlock *BB = BasicBlock::Create(*Ctx,
"entry", F);
566 std::vector<Value *> Args;
569 Args.push_back(&*AI);
574 RI = ReturnInst::Create(*Ctx, BB);
576 RI = ReturnInst::Create(*Ctx, CI, BB);
578 DFSanFunction DFSF(*
this, F,
true);
580 for (
unsigned N = FT->
getNumParams();
N != 0; ++ValAI, ++ShadowAI, --
N)
581 DFSF.ValShadowMap[ValAI] = ShadowAI;
582 DFSanVisitor(DFSF).visitCallInst(*CI);
584 new StoreInst(DFSF.getShadow(RI->getReturnValue()),
591 bool DataFlowSanitizer::runOnModule(
Module &M) {
592 if (ABIList.isIn(M,
"skip"))
598 Type *ArgTLSTy = ArrayType::get(ShadowTy, 64);
599 ArgTLS = Mod->getOrInsertGlobal(
"__dfsan_arg_tls", ArgTLSTy);
603 if (!GetRetvalTLSPtr) {
604 RetvalTLS = Mod->getOrInsertGlobal(
"__dfsan_retval_tls", ShadowTy);
609 DFSanUnionFn = Mod->getOrInsertFunction(
"__dfsan_union", DFSanUnionFnTy);
610 if (
Function *F = dyn_cast<Function>(DFSanUnionFn)) {
611 F->
addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
612 F->
addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
613 F->
addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
617 DFSanCheckedUnionFn = Mod->getOrInsertFunction(
"dfsan_union", DFSanUnionFnTy);
618 if (
Function *F = dyn_cast<Function>(DFSanCheckedUnionFn)) {
619 F->
addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
620 F->
addAttribute(AttributeSet::FunctionIndex, Attribute::ReadNone);
621 F->
addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
626 Mod->getOrInsertFunction(
"__dfsan_union_load", DFSanUnionLoadFnTy);
627 if (
Function *F = dyn_cast<Function>(DFSanUnionLoadFn)) {
628 F->
addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind);
629 F->
addAttribute(AttributeSet::FunctionIndex, Attribute::ReadOnly);
630 F->
addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
632 DFSanUnimplementedFn =
633 Mod->getOrInsertFunction(
"__dfsan_unimplemented", DFSanUnimplementedFnTy);
635 Mod->getOrInsertFunction(
"__dfsan_set_label", DFSanSetLabelFnTy);
636 if (
Function *F = dyn_cast<Function>(DFSanSetLabelFn)) {
639 DFSanNonzeroLabelFn =
640 Mod->getOrInsertFunction(
"__dfsan_nonzero_label", DFSanNonzeroLabelFnTy);
641 DFSanVarargWrapperFn = Mod->getOrInsertFunction(
"__dfsan_vararg_wrapper",
642 DFSanVarargWrapperFnTy);
644 std::vector<Function *> FnsToInstrument;
647 if (!i->isIntrinsic() &&
649 i != DFSanCheckedUnionFn &&
650 i != DFSanUnionLoadFn &&
651 i != DFSanUnimplementedFn &&
652 i != DFSanSetLabelFn &&
653 i != DFSanNonzeroLabelFn &&
654 i != DFSanVarargWrapperFn)
655 FnsToInstrument.push_back(&*i);
666 bool GAInst = isInstrumented(GA), FInst = isInstrumented(F);
667 if (GAInst && FInst) {
668 addGlobalNamePrefix(GA);
669 }
else if (GAInst != FInst) {
678 FnsToInstrument.push_back(NewF);
685 ReadOnlyNoneAttrs = AttributeSet::get(*Ctx, AttributeSet::FunctionIndex, B);
689 for (std::vector<Function *>::iterator i = FnsToInstrument.begin(),
690 e = FnsToInstrument.end();
698 if (isInstrumented(&F)) {
701 if (getInstrumentedABI() == IA_Args && !IsZeroArgsVoidRet) {
706 AttributeSet::ReturnIndex,
707 AttributeSet::get(NewF->
getContext(), AttributeSet::ReturnIndex,
712 FArg != FArgEnd; ++FArg, ++NewFArg) {
713 FArg->replaceAllUsesWith(NewFArg);
728 ConstantExpr::getBitCast(NewF, PointerType::getUnqual(FT)));
732 addGlobalNamePrefix(NewF);
734 addGlobalNamePrefix(&F);
736 }
else if (!IsZeroArgsVoidRet || getWrapperKind(&F) == WK_Custom) {
741 ? getArgsFunctionType(FT)
743 Function *NewF = buildWrapperFunction(
744 &F, std::string(
"dfsw$") + std::string(F.
getName()),
745 GlobalValue::LinkOnceODRLinkage, NewFT);
746 if (getInstrumentedABI() == IA_TLS)
749 Value *WrappedFnCst =
750 ConstantExpr::getBitCast(NewF, PointerType::getUnqual(FT));
754 auto DI = FunctionDIs.find(&F);
755 if (DI != FunctionDIs.end())
756 DI->second->replaceFunction(&F);
758 UnwrappedFnMap[WrappedFnCst] = &
F;
766 FnsWithNativeABI.
insert(&F);
771 size_t N = i - FnsToInstrument.begin(),
772 Count = e - FnsToInstrument.begin();
773 FnsToInstrument.push_back(&F);
774 i = FnsToInstrument.begin() +
N;
775 e = FnsToInstrument.begin() + Count;
780 UnwrappedFnMap[&
F] = &
F;
785 for (std::vector<Function *>::iterator i = FnsToInstrument.begin(),
786 e = FnsToInstrument.end();
788 if (!*i || (*i)->isDeclaration())
793 DFSanFunction DFSF(*
this, *i, FnsWithNativeABI.
count(*i));
811 bool IsTerminator = isa<TerminatorInst>(Inst);
812 if (!DFSF.SkipInsts.count(Inst))
813 DFSanVisitor(DFSF).visit(Inst);
824 for (std::vector<std::pair<PHINode *, PHINode *> >::iterator
825 i = DFSF.PHIFixups.begin(),
826 e = DFSF.PHIFixups.end();
828 for (
unsigned val = 0, n = i->first->getNumIncomingValues(); val != n;
830 i->second->setIncomingValue(
831 val, DFSF.getShadow(i->first->getIncomingValue(val)));
840 for (
Value *V : DFSF.NonZeroChecks) {
843 Pos =
I->getNextNode();
845 Pos = DFSF.F->getEntryBlock().begin();
846 while (isa<PHINode>(Pos) || isa<AllocaInst>(Pos))
849 Value *Ne = IRB.CreateICmpNE(V, DFSF.DFS.ZeroShadow);
851 Ne, Pos,
false, ColdCallWeights));
853 ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn, {});
861 Value *DFSanFunction::getArgTLSPtr() {
865 return ArgTLSPtr = DFS.ArgTLS;
868 return ArgTLSPtr = IRB.
CreateCall(DFS.GetArgTLS, {});
871 Value *DFSanFunction::getRetvalTLS() {
875 return RetvalTLSPtr = DFS.RetvalTLS;
878 return RetvalTLSPtr = IRB.
CreateCall(DFS.GetRetvalTLS, {});
883 return IRB.CreateConstGEP2_64(getArgTLSPtr(), 0, Idx);
887 if (!isa<Argument>(V) && !isa<Instruction>(V))
888 return DFS.ZeroShadow;
889 Value *&Shadow = ValShadowMap[V];
891 if (
Argument *
A = dyn_cast<Argument>(V)) {
893 return DFS.ZeroShadow;
895 case DataFlowSanitizer::IA_TLS: {
896 Value *ArgTLSPtr = getArgTLSPtr();
899 : cast<Instruction>(ArgTLSPtr)->getNextNode();
901 Shadow = IRB.CreateLoad(getArgTLS(
A->getArgNo(), ArgTLSPos));
904 case DataFlowSanitizer::IA_Args: {
910 assert(Shadow->
getType() == DFS.ShadowTy);
914 NonZeroChecks.push_back(Shadow);
916 Shadow = DFS.ZeroShadow;
923 assert(!ValShadowMap.count(I));
924 assert(Shadow->
getType() == DFS.ShadowTy);
925 ValShadowMap[
I] = Shadow;
929 assert(Addr != RetvalTLS &&
"Reinstrumenting?");
931 return IRB.CreateIntToPtr(
933 IRB.CreateAnd(IRB.CreatePtrToInt(Addr, IntptrTy), ShadowPtrMask),
941 if (V1 == DFS.ZeroShadow)
943 if (V2 == DFS.ZeroShadow)
948 auto V1Elems = ShadowElements.find(V1);
949 auto V2Elems = ShadowElements.find(V2);
950 if (V1Elems != ShadowElements.end() && V2Elems != ShadowElements.end()) {
951 if (std::includes(V1Elems->second.begin(), V1Elems->second.end(),
952 V2Elems->second.begin(), V2Elems->second.end())) {
954 }
else if (std::includes(V2Elems->second.begin(), V2Elems->second.end(),
955 V1Elems->second.begin(), V1Elems->second.end())) {
958 }
else if (V1Elems != ShadowElements.end()) {
959 if (V1Elems->second.count(V2))
961 }
else if (V2Elems != ShadowElements.end()) {
962 if (V2Elems->second.count(V1))
966 auto Key = std::make_pair(V1, V2);
969 CachedCombinedShadow &CCS = CachedCombinedShadows[Key];
970 if (CCS.Block && DT.dominates(CCS.Block, Pos->
getParent()))
974 if (AvoidNewBlocks) {
975 CallInst *
Call = IRB.CreateCall(DFS.DFSanCheckedUnionFn, {V1, V2});
976 Call->
addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
984 Value *Ne = IRB.CreateICmpNE(V1, V2);
986 Ne, Pos,
false, DFS.ColdCallWeights, &DT));
988 CallInst *Call = ThenIRB.CreateCall(DFS.DFSanUnionFn, {V1, V2});
989 Call->
addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
994 PHINode *Phi = PHINode::Create(DFS.ShadowTy, 2,
"", Tail->
begin());
1002 std::set<Value *> UnionElems;
1003 if (V1Elems != ShadowElements.end()) {
1004 UnionElems = V1Elems->second;
1006 UnionElems.insert(V1);
1008 if (V2Elems != ShadowElements.end()) {
1009 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
1011 UnionElems.insert(V2);
1013 ShadowElements[CCS.Shadow] = std::move(UnionElems);
1023 return DFS.ZeroShadow;
1027 Shadow = combineShadows(Shadow, getShadow(Inst->
getOperand(i)), Inst);
1032 void DFSanVisitor::visitOperandShadowInst(
Instruction &I) {
1033 Value *CombinedShadow = DFSF.combineOperandShadows(&I);
1034 DFSF.setShadow(&I, CombinedShadow);
1039 Value *DFSanFunction::loadShadow(
Value *Addr, uint64_t Size, uint64_t
Align,
1041 if (
AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
1043 AllocaShadowMap.find(AI);
1044 if (i != AllocaShadowMap.end()) {
1046 return IRB.CreateLoad(i->second);
1050 uint64_t ShadowAlign = Align * DFS.ShadowWidth / 8;
1053 bool AllConstants =
true;
1056 if (isa<Function>(*i) || isa<BlockAddress>(*i))
1058 if (isa<GlobalVariable>(*i) && cast<GlobalVariable>(*i)->isConstant())
1061 AllConstants =
false;
1065 return DFS.ZeroShadow;
1067 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
1070 return DFS.ZeroShadow;
1078 Value *ShadowAddr1 = IRB.CreateGEP(DFS.ShadowTy, ShadowAddr,
1079 ConstantInt::get(DFS.IntptrTy, 1));
1080 return combineShadows(IRB.CreateAlignedLoad(ShadowAddr, ShadowAlign),
1081 IRB.CreateAlignedLoad(ShadowAddr1, ShadowAlign), Pos);
1084 if (!AvoidNewBlocks && Size % (64 / DFS.ShadowWidth) == 0) {
1088 BasicBlock *FallbackBB = BasicBlock::Create(*DFS.Ctx,
"", F);
1090 CallInst *FallbackCall = FallbackIRB.CreateCall(
1091 DFS.DFSanUnionLoadFn,
1092 {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
1093 FallbackCall->
addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
1099 IRB.CreateBitCast(ShadowAddr, Type::getInt64PtrTy(*DFS.Ctx));
1100 Value *WideShadow = IRB.CreateAlignedLoad(WideAddr, ShadowAlign);
1101 Value *TruncShadow = IRB.CreateTrunc(WideShadow, DFS.ShadowTy);
1102 Value *ShlShadow = IRB.CreateShl(WideShadow, DFS.ShadowWidth);
1103 Value *ShrShadow = IRB.CreateLShr(WideShadow, 64 - DFS.ShadowWidth);
1104 Value *RotShadow = IRB.CreateOr(ShlShadow, ShrShadow);
1105 Value *ShadowsEq = IRB.CreateICmpEQ(WideShadow, RotShadow);
1111 std::vector<DomTreeNode *> Children(OldNode->begin(), OldNode->end());
1113 DomTreeNode *NewNode = DT.addNewBlock(Tail, Head);
1114 for (
auto Child : Children)
1115 DT.changeImmediateDominator(Child, NewNode);
1122 BranchInst *LastBr = BranchInst::Create(FallbackBB, FallbackBB, ShadowsEq);
1124 DT.addNewBlock(FallbackBB, Head);
1126 for (uint64_t Ofs = 64 / DFS.ShadowWidth; Ofs != Size;
1127 Ofs += 64 / DFS.ShadowWidth) {
1128 BasicBlock *NextBB = BasicBlock::Create(*DFS.Ctx,
"", F);
1129 DT.addNewBlock(NextBB, LastBr->
getParent());
1131 WideAddr = NextIRB.CreateGEP(Type::getInt64Ty(*DFS.Ctx), WideAddr,
1132 ConstantInt::get(DFS.IntptrTy, 1));
1133 Value *NextWideShadow = NextIRB.CreateAlignedLoad(WideAddr, ShadowAlign);
1134 ShadowsEq = NextIRB.CreateICmpEQ(WideShadow, NextWideShadow);
1136 LastBr = NextIRB.CreateCondBr(ShadowsEq, FallbackBB, FallbackBB);
1140 FallbackIRB.CreateBr(Tail);
1141 PHINode *Shadow = PHINode::Create(DFS.ShadowTy, 2,
"", &Tail->
front());
1148 CallInst *FallbackCall = IRB.CreateCall(
1149 DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
1150 FallbackCall->
addAttribute(AttributeSet::ReturnIndex, Attribute::ZExt);
1151 return FallbackCall;
1154 void DFSanVisitor::visitLoadInst(
LoadInst &LI) {
1158 DFSF.setShadow(&LI, DFSF.DFS.ZeroShadow);
1174 Shadow = DFSF.combineShadows(Shadow, PtrShadow, &LI);
1176 if (Shadow != DFSF.DFS.ZeroShadow)
1177 DFSF.NonZeroChecks.push_back(Shadow);
1179 DFSF.setShadow(&LI, Shadow);
1182 void DFSanFunction::storeShadow(
Value *Addr, uint64_t Size, uint64_t Align,
1184 if (
AllocaInst *AI = dyn_cast<AllocaInst>(Addr)) {
1186 AllocaShadowMap.find(AI);
1187 if (i != AllocaShadowMap.end()) {
1189 IRB.CreateStore(Shadow, i->second);
1194 uint64_t ShadowAlign = Align * DFS.ShadowWidth / 8;
1196 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
1197 if (Shadow == DFS.ZeroShadow) {
1198 IntegerType *ShadowTy = IntegerType::get(*DFS.Ctx, Size * DFS.ShadowWidth);
1199 Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
1200 Value *ExtShadowAddr =
1201 IRB.CreateBitCast(ShadowAddr, PointerType::getUnqual(ShadowTy));
1202 IRB.CreateAlignedStore(ExtZeroShadow, ExtShadowAddr, ShadowAlign);
1206 const unsigned ShadowVecSize = 128 / DFS.ShadowWidth;
1207 uint64_t Offset = 0;
1208 if (Size >= ShadowVecSize) {
1209 VectorType *ShadowVecTy = VectorType::get(DFS.ShadowTy, ShadowVecSize);
1210 Value *ShadowVec = UndefValue::get(ShadowVecTy);
1211 for (
unsigned i = 0; i != ShadowVecSize; ++i) {
1212 ShadowVec = IRB.CreateInsertElement(
1213 ShadowVec, Shadow, ConstantInt::get(Type::getInt32Ty(*DFS.Ctx), i));
1215 Value *ShadowVecAddr =
1216 IRB.CreateBitCast(ShadowAddr, PointerType::getUnqual(ShadowVecTy));
1218 Value *CurShadowVecAddr =
1219 IRB.CreateConstGEP1_32(ShadowVecTy, ShadowVecAddr, Offset);
1220 IRB.CreateAlignedStore(ShadowVec, CurShadowVecAddr, ShadowAlign);
1221 Size -= ShadowVecSize;
1223 }
while (Size >= ShadowVecSize);
1224 Offset *= ShadowVecSize;
1227 Value *CurShadowAddr =
1228 IRB.CreateConstGEP1_32(DFS.ShadowTy, ShadowAddr, Offset);
1229 IRB.CreateAlignedStore(Shadow, CurShadowAddr, ShadowAlign);
1235 void DFSanVisitor::visitStoreInst(
StoreInst &
SI) {
1253 Shadow = DFSF.combineShadows(Shadow, PtrShadow, &SI);
1259 visitOperandShadowInst(BO);
1262 void DFSanVisitor::visitCastInst(
CastInst &CI) { visitOperandShadowInst(CI); }
1264 void DFSanVisitor::visitCmpInst(
CmpInst &CI) { visitOperandShadowInst(CI); }
1267 visitOperandShadowInst(GEPI);
1271 visitOperandShadowInst(I);
1275 visitOperandShadowInst(I);
1279 visitOperandShadowInst(I);
1283 visitOperandShadowInst(I);
1287 visitOperandShadowInst(I);
1290 void DFSanVisitor::visitAllocaInst(
AllocaInst &I) {
1291 bool AllLoadsStores =
true;
1293 if (isa<LoadInst>(U))
1296 if (
StoreInst *SI = dyn_cast<StoreInst>(U)) {
1301 AllLoadsStores =
false;
1304 if (AllLoadsStores) {
1306 DFSF.AllocaShadowMap[&
I] = IRB.CreateAlloca(DFSF.DFS.ShadowTy);
1308 DFSF.setShadow(&I, DFSF.DFS.ZeroShadow);
1311 void DFSanVisitor::visitSelectInst(
SelectInst &I) {
1319 DFSF.combineShadows(
1320 CondShadow, DFSF.combineShadows(TrueShadow, FalseShadow, &I), &
I));
1323 if (TrueShadow == FalseShadow) {
1324 ShadowSel = TrueShadow;
1327 SelectInst::Create(I.
getCondition(), TrueShadow, FalseShadow,
"", &
I);
1329 DFSF.setShadow(&I, DFSF.combineShadows(CondShadow, ShadowSel, &I));
1333 void DFSanVisitor::visitMemSetInst(
MemSetInst &I) {
1336 IRB.CreateCall(DFSF.DFS.DFSanSetLabelFn,
1337 {ValShadow, IRB.CreateBitCast(I.
getDest(), Type::getInt8PtrTy(
1339 IRB.CreateZExtOrTrunc(I.
getLength(), DFSF.DFS.IntptrTy)});
1344 Value *DestShadow = DFSF.DFS.getShadowAddress(I.
getDest(), &
I);
1346 Value *LenShadow = IRB.CreateMul(
1353 DFSF.DFS.ShadowWidth / 8));
1356 DFSF.DFS.ShadowWidth / 8);
1358 Type *Int8Ptr = Type::getInt8PtrTy(*DFSF.DFS.Ctx);
1359 DestShadow = IRB.CreateBitCast(DestShadow, Int8Ptr);
1360 SrcShadow = IRB.CreateBitCast(SrcShadow, Int8Ptr);
1361 IRB.CreateCall(I.
getCalledValue(), {DestShadow, SrcShadow, LenShadow,
1365 void DFSanVisitor::visitReturnInst(
ReturnInst &RI) {
1368 case DataFlowSanitizer::IA_TLS: {
1371 IRB.CreateStore(S, DFSF.getRetvalTLS());
1374 case DataFlowSanitizer::IA_Args: {
1376 Type *RT = DFSF.F->getFunctionType()->getReturnType();
1378 IRB.CreateInsertValue(UndefValue::get(RT), RI.
getReturnValue(), 0);
1380 IRB.CreateInsertValue(InsVal, DFSF.getShadow(RI.
getReturnValue()), 1);
1388 void DFSanVisitor::visitCallSite(
CallSite CS) {
1397 if (F == DFSF.DFS.DFSanVarargWrapperFn)
1400 assert(!(cast<FunctionType>(
1408 if (i != DFSF.DFS.UnwrappedFnMap.end()) {
1410 switch (DFSF.DFS.getWrapperKind(F)) {
1411 case DataFlowSanitizer::WK_Warning: {
1413 IRB.CreateCall(DFSF.DFS.DFSanUnimplementedFn,
1414 IRB.CreateGlobalStringPtr(F->
getName()));
1418 case DataFlowSanitizer::WK_Discard: {
1423 case DataFlowSanitizer::WK_Functional: {
1428 case DataFlowSanitizer::WK_Custom: {
1434 FunctionType *CustomFT = DFSF.DFS.getCustomFunctionType(FT);
1435 std::string CustomFName =
"__dfsw_";
1438 DFSF.DFS.Mod->getOrInsertFunction(CustomFName, CustomFT);
1439 if (
Function *CustomFn = dyn_cast<Function>(CustomF)) {
1440 CustomFn->copyAttributesFrom(F);
1444 CustomFn->removeAttributes(AttributeSet::FunctionIndex,
1445 DFSF.DFS.ReadOnlyNoneAttrs);
1449 std::vector<Value *> Args;
1451 CallSite::arg_iterator i = CS.
arg_begin();
1452 for (
unsigned n = FT->
getNumParams(); n != 0; ++i, --n) {
1453 Type *T = (*i)->getType();
1455 if (isa<PointerType>(T) &&
1456 (ParamFT = dyn_cast<FunctionType>(
1457 cast<PointerType>(T)->getElementType()))) {
1458 std::string TName =
"dfst";
1462 Constant *T = DFSF.DFS.getOrBuildTrampolineFunction(ParamFT, TName);
1465 IRB.CreateBitCast(*i, Type::getInt8PtrTy(*DFSF.DFS.Ctx)));
1472 for (
unsigned n = FT->
getNumParams(); n != 0; ++i, --n)
1473 Args.push_back(DFSF.getShadow(*i));
1476 auto *LabelVATy = ArrayType::get(DFSF.DFS.ShadowTy,
1478 auto *LabelVAAlloca =
new AllocaInst(LabelVATy,
"labelva",
1479 DFSF.F->getEntryBlock().begin());
1481 for (
unsigned n = 0; i != CS.
arg_end(); ++i, ++n) {
1482 auto LabelVAPtr = IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, n);
1483 IRB.CreateStore(DFSF.getShadow(*i), LabelVAPtr);
1486 Args.push_back(IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, 0));
1490 if (!DFSF.LabelReturnAlloca) {
1491 DFSF.LabelReturnAlloca =
1492 new AllocaInst(DFSF.DFS.ShadowTy,
"labelreturn",
1493 DFSF.F->getEntryBlock().begin());
1495 Args.push_back(DFSF.LabelReturnAlloca);
1501 CallInst *CustomCI = IRB.CreateCall(CustomF, Args);
1506 LoadInst *LabelLoad = IRB.CreateLoad(DFSF.LabelReturnAlloca);
1507 DFSF.setShadow(CustomCI, LabelLoad);
1521 if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
1522 for (
unsigned i = 0, n = FT->
getNumParams(); i != n; ++i) {
1523 IRB.CreateStore(DFSF.getShadow(CS.
getArgument(i)),
1531 if (II->getNormalDest()->getSinglePredecessor()) {
1532 Next = II->getNormalDest()->begin();
1535 SplitEdge(II->getParent(), II->getNormalDest(), &DFSF.DT);
1536 Next = NewBB->
begin();
1539 Next = CS->getNextNode();
1542 if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
1544 LoadInst *LI = NextIRB.CreateLoad(DFSF.getRetvalTLS());
1545 DFSF.SkipInsts.insert(LI);
1547 DFSF.NonZeroChecks.push_back(LI);
1553 if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_Args) {
1554 FunctionType *NewFT = DFSF.DFS.getArgsFunctionType(FT);
1556 IRB.CreateBitCast(CS.
getCalledValue(), PointerType::getUnqual(NewFT));
1557 std::vector<Value *> Args;
1560 for (
unsigned n = FT->
getNumParams(); n != 0; ++i, --n)
1564 for (
unsigned n = FT->
getNumParams(); n != 0; ++i, --n)
1565 Args.push_back(DFSF.getShadow(*i));
1569 ArrayType *VarArgArrayTy = ArrayType::get(DFSF.DFS.ShadowTy, VarArgSize);
1571 new AllocaInst(VarArgArrayTy,
"", DFSF.F->getEntryBlock().begin());
1572 Args.push_back(IRB.CreateConstGEP2_32(VarArgArrayTy, VarArgShadow, 0, 0));
1573 for (
unsigned n = 0; i != e; ++i, ++n) {
1576 IRB.CreateConstGEP2_32(VarArgArrayTy, VarArgShadow, 0, n));
1583 NewCS = IRB.CreateInvoke(Func, II->getNormalDest(), II->getUnwindDest(),
1586 NewCS = IRB.CreateCall(Func, Args);
1590 *DFSF.DFS.Ctx, AttributeSet::ReturnIndex,
1596 DFSF.SkipInsts.insert(ExVal);
1599 DFSF.SkipInsts.insert(ExShadow);
1600 DFSF.setShadow(ExVal, ExShadow);
1601 DFSF.NonZeroChecks.push_back(ExShadow);
1610 void DFSanVisitor::visitPHINode(
PHINode &PN) {
1615 Value *UndefShadow = UndefValue::get(DFSF.DFS.ShadowTy);
1621 DFSF.PHIFixups.push_back(std::make_pair(&PN, ShadowPN));
1622 DFSF.setShadow(&PN, ShadowPN);
ReturnInst - Return a value (possibly void), from a function.
Value * getValueOperand()
const Value * getCalledValue() const
getCalledValue - Get a pointer to the function that is invoked by this instruction.
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
static cl::list< std::string > ClABIListFiles("dfsan-abilist", cl::desc("File listing native ABI functions and how the pass treats them"), cl::Hidden)
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
LinkageTypes getLinkage() const
IntegerType * getType() const
getType - Specialize the getType() method to always return an IntegerType, which reduces the amount o...
void ReplaceInstWithInst(BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Instruction *I)
ReplaceInstWithInst - Replace the instruction specified by BI with the instruction specified by I...
This class is the base class for the comparison instructions.
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - Add an incoming value to the end of the PHI list
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
LLVM Argument representation.
Base class for instruction visitors.
ValTy * getArgument(unsigned ArgNo) const
A Module instance is used to store all the information related to an LLVM module. ...
unsigned getNumParams() const
getNumParams - Return the number of fixed parameters this function type requires. ...
InstrTy * getInstruction() const
ConstantInt * getAlignmentCst() const
Value * getValue() const
get* - Return the arguments to the instruction.
DenseSet - This implements a dense probed hash-table based set.
unsigned getNumOperands() const
Type::subtype_iterator param_iterator
CallInst - This class represents a function call, abstracting a target machine's calling convention...
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
TerminatorInst * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr)
SplitBlockAndInsertIfThen - Split the containing block at the specified instruction - everything befo...
ShuffleVectorInst - This instruction constructs a fixed permutation of two input vectors.
MemSetInst - This class wraps the llvm.memset intrinsic.
void setAttributes(const AttributeSet &PAL)
const Instruction & front() const
LoadInst - an instruction for reading from memory.
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
void GetUnderlyingObjects(Value *V, SmallVectorImpl< Value * > &Objects, const DataLayout &DL, LoopInfo *LI=nullptr, unsigned MaxLookup=6)
This method is similar to GetUnderlyingObject except that it can look through phi and select instruct...
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
Type * getPointerElementType() const
StringRef getName() const
Return a constant reference to the value's name.
block_iterator block_end()
iterator begin()
Instruction iterator methods.
void setCallingConv(CallingConv::ID CC)
static cl::opt< bool > ClArgsABI("dfsan-args-abi", cl::desc("Use the argument ABI rather than the TLS ABI"), cl::Hidden)
BlockAddress - The address of a basic block.
SelectInst - This class represents the LLVM 'select' instruction.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
This is the base class for all instructions that perform data casts.
NodeTy * getNextNode()
Get the next node, or 0 for the list tail.
StructType - Class to represent struct types.
param_iterator param_end() const
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
void setThreadLocalMode(ThreadLocalMode Val)
void setModuleInlineAsm(StringRef Asm)
Set the module-scope inline assembly blocks.
void setName(const Twine &Name)
Change the name of the value.
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
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))
block_iterator block_begin()
FunctionType - Class to represent function types.
ValTy * getCalledValue() const
getCalledValue - Return the pointer to function that is being called.
ArrayType - Class to represent array types.
BasicBlock * getSuccessor(unsigned i) const
Base class for the actual dominator tree node.
static std::string utostr(uint64_t X, bool isNeg=false)
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
StoreInst - an instruction for storing to memory.
void setCallingConv(CallingConv::ID CC)
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
void removeAttributes(unsigned i, AttributeSet attr)
removes the attributes from the list of attributes.
void takeName(Value *V)
Transfer the name from V to this value.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Type * getElementType() const
void addAttribute(unsigned i, Attribute::AttrKind attr)
addAttribute - adds the attribute to the list of attributes.
PointerType - Class to represent pointers.
unsigned getNumIncomingValues() const
getNumIncomingValues - Return the number of incoming edges
GetElementPtrInst - an instruction for type-safe pointer arithmetic to access elements of arrays and ...
initializer< Ty > init(const Ty &Val)
InsertElementInst - This instruction inserts a single (scalar) element into a VectorType value...
unsigned getAlignment() const
getAlignment - Return the alignment of the access that is being performed
alias_iterator alias_end()
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
BranchInst - Conditional or Unconditional Branch instruction.
FunTy * getCalledFunction() const
getCalledFunction - Return the function being called if this is a direct call, otherwise return null ...
size_type LLVM_ATTRIBUTE_UNUSED_RESULT size() const
UnreachableInst - This function has undefined behavior.
This is an important base class in LLVM.
const Value * getCondition() const
param_iterator param_begin() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
ConstantInt * getVolatileCst() const
void copyAttributesFrom(const GlobalValue *Src) override
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Value * getOperand(unsigned i) const
Value * getPointerOperand()
Class to represent integer types.
void setAlignment(unsigned Align)
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
CallInst * CreateCall(Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="")
PointerType * getPointerTo(unsigned AddrSpace=0)
getPointerTo - Return a pointer to the current type.
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
const Value * getTrueValue() const
Triple - Helper class for working with autoconf configuration names.
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
const std::string & getModuleInlineAsm() const
Get any module-scope inline assembly blocks.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space...
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
const BasicBlockListType & getBasicBlockList() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
Value * getDest() const
getDest - This is just like getRawDest, but it strips off any cast instructions that feed it...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
static cl::opt< bool > ClDebugNonzeroLabels("dfsan-debug-nonzero-labels", cl::desc("Insert calls to __dfsan_nonzero_label on observing a parameter, ""load or return with a nonzero label"), cl::Hidden)
Value * getLength() const
alias_iterator alias_begin()
unsigned arg_size() const
BasicBlock * getBasicBlock() const
const BasicBlock & getEntryBlock() const
static cl::opt< AlignMode > Align(cl::desc("Load/store alignment support"), cl::Hidden, cl::init(NoStrictAlign), cl::values(clEnumValN(StrictAlign,"aarch64-strict-align","Disallow all unaligned memory accesses"), clEnumValN(NoStrictAlign,"aarch64-no-strict-align","Allow unaligned memory accesses"), clEnumValEnd))
void setLinkage(LinkageTypes LT)
void splice(iterator where, iplist &L2)
void setOperand(unsigned i, Value *Val)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static cl::opt< bool > ClPreserveAlignment("dfsan-preserve-alignment", cl::desc("respect alignment requirements provided by input IR"), cl::Hidden, cl::init(false))
AttributeSet removeAttributes(LLVMContext &C, unsigned Index, AttributeSet Attrs) const
Remove the specified attributes at the specified index from this attribute list.
VectorType - Class to represent vector types.
void eraseFromParent() override
eraseFromParent - This method unlinks 'this' from the containing module and deletes it...
LinkageTypes
An enumeration for the kinds of linkage for global values.
INITIALIZE_PASS(DataFlowSanitizer,"dfsan","DataFlowSanitizer: dynamic data flow analysis.", false, false) ModulePass *llvm
void addAttribute(unsigned i, Attribute::AttrKind attr)
adds the attribute to the list of attributes.
iterator_range< user_iterator > users()
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
void eraseFromParent() override
eraseFromParent - This method unlinks 'this' from the containing module and deletes it...
const AttributeSet & getAttributes() const
getAttributes - Return the parameter attributes for this call.
Value * getSource() const
getSource - This is just like getRawSource, but it strips off any cast instructions that feed it...
PointerType * getType() const
Global values are always pointers.
MemTransferInst - This class wraps the llvm.memcpy/memmove intrinsics.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
void setCalledFunction(Value *V)
setCalledFunction - Set the callee to the specified value.
unsigned getAlignment() const
getAlignment - Return the alignment of the access that is being performed
AttrBuilder typeIncompatible(const Type *Ty)
Which attributes cannot be applied to a type.
CallingConv::ID getCallingConv() const
getCallingConv/setCallingConv - get or set the calling convention of the call.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
FunctionType * getFunctionType() const
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
const AttributeSet & getAttributes() const
getAttributes/setAttributes - get or set the parameter attributes of the call.
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
Type * getType() const
getType - Return the type of the instruction that generated this call site
iterator_range< df_iterator< T > > depth_first(const T &G)
void setAttributes(const AttributeSet &Attrs)
setAttributes - Set the parameter attributes for this call.
Type * getReturnType() const
const GlobalObject * getBaseObject() const
user_iterator user_begin()
DenseMap< const Function *, DISubprogram * > makeSubprogramMap(const Module &M)
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
const ArgumentListType & getArgumentList() const
Get the underlying elements of the Function...
ModulePass * createDataFlowSanitizerPass(const std::vector< std::string > &ABIListFiles=std::vector< std::string >(), void *(*getArgTLS)()=nullptr, void *(*getRetValTLS)()=nullptr)
InvokeInst - Invoke instruction.
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
SplitEdge - Split the edge connecting specified block.
IterTy arg_begin() const
arg_begin/arg_end - Return iterators corresponding to the actual argument list for a call site...
C - The default llvm calling convention, compatible with C.
const Value * getFalseValue() const
StringRef - Represent a constant reference to a string, i.e.
bool removeUnreachableBlocks(Function &F)
Remove all blocks that can not be reached from the function's entry.
CallingConv::ID getCallingConv() const
getCallingConv/setCallingConv - Get or set the calling convention of this function call...
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))
bool isVarArg() const
isVarArg - Return true if this function takes a variable number of arguments.
Value * getPointerOperand()
const BasicBlock * getParent() const
LLVMContext & getContext() const
Get the global data context.
bool isVoidTy() const
isVoidTy - Return true if this is 'void'.
AllocaInst - an instruction to allocate memory on the stack.
InsertValueInst - This instruction inserts a struct field of array element value into an aggregate va...