107 using namespace llvm;
129 "dfsan-preserve-alignment",
142 cl::desc(
"File listing native ABI functions and how the pass treats them"),
149 cl::desc(
"Use the argument ABI rather than the TLS ABI"),
155 "dfsan-combine-pointer-labels-on-load",
156 cl::desc(
"Combine the label of the pointer with the label of the data when " 157 "loading from memory."),
163 "dfsan-combine-pointer-labels-on-store",
164 cl::desc(
"Combine the label of the pointer with the label of the data when " 165 "storing in memory."),
169 "dfsan-debug-nonzero-labels",
170 cl::desc(
"Insert calls to __dfsan_nonzero_label on observing a parameter, " 171 "load or return with a nonzero label"),
185 "dfsan-event-callbacks",
186 cl::desc(
"Insert calls to __dfsan_*_callback functions on data events."),
192 "dfsan-fast-16-labels",
193 cl::desc(
"Use more efficient instrumentation, limiting the number of " 199 "dfsan-track-select-control-flow",
200 cl::desc(
"Propagate labels from condition values of select instructions " 206 Type *GType =
G.getValueType();
208 if (
StructType *SGType = dyn_cast<StructType>(GType)) {
209 if (!SGType->isLiteral())
210 return SGType->getName();
212 return "<unknown type>";
218 std::unique_ptr<SpecialCaseList> SCL;
221 DFSanABIList() =
default;
228 return isIn(*
F.getParent(), Category) ||
229 SCL->inSection(
"dataflow",
"fun",
F.getName(), Category);
241 return SCL->inSection(
"dataflow",
"fun", GA.
getName(), Category);
243 return SCL->inSection(
"dataflow",
"global", GA.
getName(), Category) ||
250 return SCL->inSection(
"dataflow",
"src",
M.getModuleIdentifier(), Category);
257 struct TransformedFunction {
260 std::vector<unsigned> ArgumentIndexMapping)
261 : OriginalType(OriginalType),
262 TransformedType(TransformedType),
263 ArgumentIndexMapping(ArgumentIndexMapping) {}
266 TransformedFunction(
const TransformedFunction&) =
delete;
267 TransformedFunction&
operator=(
const TransformedFunction&) =
delete;
270 TransformedFunction(TransformedFunction&&) =
default;
271 TransformedFunction&
operator=(TransformedFunction&&) =
default;
284 std::vector<unsigned> ArgumentIndexMapping;
291 const TransformedFunction& TransformedFunction,
295 std::vector<llvm::AttributeSet> ArgumentAttributes(
296 TransformedFunction.TransformedType->getNumParams());
301 for (
unsigned i=0, ie = TransformedFunction.ArgumentIndexMapping.size();
303 unsigned TransformedIndex = TransformedFunction.ArgumentIndexMapping[i];
308 for (
unsigned i = TransformedFunction.OriginalType->getNumParams(),
320 class DataFlowSanitizer {
321 friend struct DFSanFunction;
322 friend class DFSanVisitor;
324 enum { ShadowWidthBits = 16, ShadowWidthBytes = ShadowWidthBits / 8 };
327 enum InstrumentedABI {
397 DFSanABIList ABIList;
400 bool DFSanRuntimeShadowMask =
false;
408 InstrumentedABI getInstrumentedABI();
415 void initializeCallbackFunctions(
Module &M);
416 void initializeRuntimeFunctions(
Module &M);
422 bool shouldTrackFieldsAndIndices();
437 bool isZeroShadow(
Value *V);
452 DataFlowSanitizer(
const std::vector<std::string> &ABIListFiles);
457 struct DFSanFunction {
458 DataFlowSanitizer &
DFS;
461 DataFlowSanitizer::InstrumentedABI IA;
466 std::vector<std::pair<PHINode *, PHINode *>> PHIFixups;
468 std::vector<Value *> NonZeroChecks;
471 struct CachedShadow {
484 DFSanFunction(DataFlowSanitizer &
DFS,
Function *
F,
bool IsNativeABI)
485 :
DFS(
DFS),
F(
F), IA(
DFS.getInstrumentedABI()), IsNativeABI(IsNativeABI) {
489 AvoidNewBlocks =
F->size() > 1000;
534 template <
class AggregateType>
535 Value *collapseAggregateShadow(AggregateType *AT,
Value *Shadow,
544 class DFSanVisitor :
public InstVisitor<DFSanVisitor> {
548 DFSanVisitor(DFSanFunction &DFSF) : DFSF(DFSF) {}
551 return DFSF.F->getParent()->getDataLayout();
561 void visitCmpInst(
CmpInst &CI);
567 void visitPHINode(
PHINode &PN);
581 DataFlowSanitizer::DataFlowSanitizer(
582 const std::vector<std::string> &ABIListFiles) {
583 std::vector<std::string> AllABIListFiles(
std::move(ABIListFiles));
592 ArgTypes.
append(
T->getNumParams(), PrimitiveShadowTy);
594 ArgTypes.push_back(PrimitiveShadowPtrTy);
595 Type *RetType =
T->getReturnType();
605 ArgTypes.append(
T->param_begin(),
T->param_end());
606 ArgTypes.append(
T->getNumParams(), PrimitiveShadowTy);
607 Type *RetType =
T->getReturnType();
609 ArgTypes.push_back(PrimitiveShadowPtrTy);
613 TransformedFunction DataFlowSanitizer::getCustomFunctionType(
FunctionType *
T) {
620 std::vector<unsigned> ArgumentIndexMapping;
621 for (
unsigned i = 0, ie =
T->getNumParams(); i != ie; ++i) {
622 Type* param_type =
T->getParamType(i);
624 if (isa<PointerType>(param_type) && (FT = dyn_cast<FunctionType>(
625 cast<PointerType>(param_type)->getElementType()))) {
626 ArgumentIndexMapping.push_back(ArgTypes.
size());
627 ArgTypes.
push_back(getTrampolineFunctionType(FT)->getPointerTo());
630 ArgumentIndexMapping.push_back(ArgTypes.
size());
634 for (
unsigned i = 0,
e =
T->getNumParams(); i !=
e; ++i)
637 ArgTypes.
push_back(PrimitiveShadowPtrTy);
638 Type *RetType =
T->getReturnType();
640 ArgTypes.
push_back(PrimitiveShadowPtrTy);
641 return TransformedFunction(
643 ArgumentIndexMapping);
646 bool DataFlowSanitizer::isZeroShadow(
Value *V) {
647 if (!shouldTrackFieldsAndIndices())
648 return ZeroPrimitiveShadow == V;
651 if (!isa<ArrayType>(
T) && !isa<StructType>(
T)) {
652 if (
const ConstantInt *CI = dyn_cast<ConstantInt>(V))
657 return isa<ConstantAggregateZero>(V);
660 bool DataFlowSanitizer::shouldTrackFieldsAndIndices() {
661 return getInstrumentedABI() == DataFlowSanitizer::IA_TLS &&
ClFast16Labels;
664 Constant *DataFlowSanitizer::getZeroShadow(
Type *OrigTy) {
665 if (!shouldTrackFieldsAndIndices())
666 return ZeroPrimitiveShadow;
668 if (!isa<ArrayType>(OrigTy) && !isa<StructType>(OrigTy))
669 return ZeroPrimitiveShadow;
670 Type *ShadowTy = getShadowTy(OrigTy);
675 return getZeroShadow(V->
getType());
681 if (!isa<ArrayType>(SubShadowTy) && !isa<StructType>(SubShadowTy))
684 if (
ArrayType *AT = dyn_cast<ArrayType>(SubShadowTy)) {
685 for (
unsigned Idx = 0; Idx < AT->getNumElements(); Idx++) {
688 Shadow, Indices, AT->getElementType(), PrimitiveShadow, IRB);
694 if (
StructType *
ST = dyn_cast<StructType>(SubShadowTy)) {
695 for (
unsigned Idx = 0; Idx <
ST->getNumElements(); Idx++) {
698 Shadow, Indices,
ST->getElementType(Idx), PrimitiveShadow, IRB);
706 Value *DFSanFunction::expandFromPrimitiveShadow(
Type *
T,
Value *PrimitiveShadow,
708 Type *ShadowTy =
DFS.getShadowTy(
T);
710 if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
711 return PrimitiveShadow;
713 if (
DFS.isZeroShadow(PrimitiveShadow))
714 return DFS.getZeroShadow(ShadowTy);
720 PrimitiveShadow, IRB);
723 CachedCollapsedShadows[Shadow] = PrimitiveShadow;
727 template <
class AggregateType>
728 Value *DFSanFunction::collapseAggregateShadow(AggregateType *AT,
Value *Shadow,
730 if (!AT->getNumElements())
731 return DFS.ZeroPrimitiveShadow;
734 Value *Aggregator = collapseToPrimitiveShadow(FirstItem, IRB);
736 for (
unsigned Idx = 1; Idx < AT->getNumElements(); Idx++) {
738 Value *ShadowInner = collapseToPrimitiveShadow(ShadowItem, IRB);
739 Aggregator = IRB.
CreateOr(Aggregator, ShadowInner);
744 Value *DFSanFunction::collapseToPrimitiveShadow(
Value *Shadow,
747 if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
749 if (
ArrayType *AT = dyn_cast<ArrayType>(ShadowTy))
750 return collapseAggregateShadow<>(AT, Shadow, IRB);
752 return collapseAggregateShadow<>(
ST, Shadow, IRB);
756 Value *DFSanFunction::collapseToPrimitiveShadow(
Value *Shadow,
759 if (!isa<ArrayType>(ShadowTy) && !isa<StructType>(ShadowTy))
762 assert(
DFS.shouldTrackFieldsAndIndices());
765 Value *&CS = CachedCollapsedShadows[Shadow];
770 Value *PrimitiveShadow = collapseToPrimitiveShadow(Shadow, IRB);
772 CS = PrimitiveShadow;
773 return PrimitiveShadow;
776 Type *DataFlowSanitizer::getShadowTy(
Type *OrigTy) {
777 if (!shouldTrackFieldsAndIndices())
778 return PrimitiveShadowTy;
781 return PrimitiveShadowTy;
782 if (isa<IntegerType>(OrigTy))
783 return PrimitiveShadowTy;
784 if (isa<VectorType>(OrigTy))
785 return PrimitiveShadowTy;
786 if (
ArrayType *AT = dyn_cast<ArrayType>(OrigTy))
788 AT->getNumElements());
791 for (
unsigned I = 0,
N =
ST->getNumElements();
I <
N; ++
I)
795 return PrimitiveShadowTy;
798 Type *DataFlowSanitizer::getShadowTy(
Value *V) {
799 return getShadowTy(V->
getType());
803 Triple TargetTriple(
M.getTargetTriple());
805 bool IsMIPS64 = TargetTriple.isMIPS64();
812 Ctx = &
M.getContext();
816 IntptrTy =
DL.getIntPtrType(*Ctx);
825 DFSanRuntimeShadowMask =
true;
829 Type *DFSanUnionArgs[2] = {PrimitiveShadowTy, PrimitiveShadowTy};
832 Type *DFSanUnionLoadArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
840 DFSanSetLabelArgs,
false);
841 DFSanNonzeroLabelFnTy =
845 DFSanCmpCallbackFnTy =
848 Type *DFSanLoadStoreCallbackArgs[2] = {PrimitiveShadowTy, Int8Ptr};
849 DFSanLoadStoreCallbackFnTy =
852 Type *DFSanMemTransferCallbackArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
853 DFSanMemTransferCallbackFnTy =
861 bool DataFlowSanitizer::isInstrumented(
const Function *
F) {
862 return !ABIList.isIn(*
F,
"uninstrumented");
865 bool DataFlowSanitizer::isInstrumented(
const GlobalAlias *GA) {
866 return !ABIList.isIn(*GA,
"uninstrumented");
869 DataFlowSanitizer::InstrumentedABI DataFlowSanitizer::getInstrumentedABI() {
873 DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(
Function *
F) {
874 if (ABIList.isIn(*
F,
"functional"))
875 return WK_Functional;
876 if (ABIList.isIn(*
F,
"discard"))
878 if (ABIList.isIn(*
F,
"custom"))
884 void DataFlowSanitizer::addGlobalNamePrefix(
GlobalValue *GV) {
885 std::string GVName = std::string(GV->
getName()),
Prefix =
"dfs$";
894 std::string SearchStr =
".symver " + GVName +
",";
895 size_t Pos =
Asm.find(SearchStr);
896 if (Pos != std::string::npos) {
897 Asm.replace(Pos, SearchStr.size(),
909 NewFName,
F->getParent());
920 IRBuilder<>(BB).CreateGlobalStringPtr(
F->getName()),
"",
924 std::vector<Value *>
Args;
927 Args.push_back(&*ai);
942 Function *
F = dyn_cast<Function>(
C.getCallee());
943 if (
F &&
F->isDeclaration()) {
946 std::vector<Value *>
Args;
949 Args.push_back(&*AI);
959 DFSanFunction DFSF(*
this,
F,
true);
961 for (
unsigned N = FT->
getNumParams();
N != 0; ++ValAI, ++ShadowAI, --
N) {
963 DFSF.expandFromPrimitiveShadow(ValAI->
getType(), &*ShadowAI, CI);
964 DFSF.ValShadowMap[&*ValAI] = Shadow;
966 DFSanVisitor(DFSF).visitCallInst(*CI);
968 Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(
969 DFSF.getShadow(RI->getReturnValue()), RI);
970 new StoreInst(PrimitiveShadow, &*std::prev(
F->arg_end()), RI);
974 return cast<Constant>(
C.getCallee());
978 void DataFlowSanitizer::initializeRuntimeFunctions(
Module &M) {
982 Attribute::NoUnwind);
984 Attribute::ReadNone);
987 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
988 AL =
AL.addParamAttribute(
M.getContext(), 1, Attribute::ZExt);
990 Mod->getOrInsertFunction(
"__dfsan_union", DFSanUnionFnTy,
AL);
995 Attribute::NoUnwind);
997 Attribute::ReadNone);
1000 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1001 AL =
AL.addParamAttribute(
M.getContext(), 1, Attribute::ZExt);
1002 DFSanCheckedUnionFn =
1003 Mod->getOrInsertFunction(
"dfsan_union", DFSanUnionFnTy,
AL);
1008 Attribute::NoUnwind);
1010 Attribute::ReadOnly);
1014 Mod->getOrInsertFunction(
"__dfsan_union_load", DFSanUnionLoadFnTy,
AL);
1019 Attribute::NoUnwind);
1021 Attribute::ReadOnly);
1024 DFSanUnionLoadFast16LabelsFn =
Mod->getOrInsertFunction(
1025 "__dfsan_union_load_fast16labels", DFSanUnionLoadFnTy,
AL);
1027 DFSanUnimplementedFn =
1028 Mod->getOrInsertFunction(
"__dfsan_unimplemented", DFSanUnimplementedFnTy);
1031 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1033 Mod->getOrInsertFunction(
"__dfsan_set_label", DFSanSetLabelFnTy,
AL);
1035 DFSanNonzeroLabelFn =
1036 Mod->getOrInsertFunction(
"__dfsan_nonzero_label", DFSanNonzeroLabelFnTy);
1037 DFSanVarargWrapperFn =
Mod->getOrInsertFunction(
"__dfsan_vararg_wrapper",
1038 DFSanVarargWrapperFnTy);
1042 void DataFlowSanitizer::initializeCallbackFunctions(
Module &M) {
1043 DFSanLoadCallbackFn =
Mod->getOrInsertFunction(
"__dfsan_load_callback",
1044 DFSanLoadStoreCallbackFnTy);
1045 DFSanStoreCallbackFn =
Mod->getOrInsertFunction(
"__dfsan_store_callback",
1046 DFSanLoadStoreCallbackFnTy);
1047 DFSanMemTransferCallbackFn =
Mod->getOrInsertFunction(
1048 "__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
1049 DFSanCmpCallbackFn =
1050 Mod->getOrInsertFunction(
"__dfsan_cmp_callback", DFSanCmpCallbackFnTy);
1056 if (ABIList.isIn(M,
"skip"))
1059 const unsigned InitialGlobalSize =
M.global_size();
1060 const unsigned InitialModuleSize =
M.size();
1062 bool Changed =
false;
1065 ArgTLS =
Mod->getOrInsertGlobal(
"__dfsan_arg_tls", ArgTLSTy);
1072 RetvalTLS =
Mod->getOrInsertGlobal(
"__dfsan_retval_tls", RetvalTLSTy);
1078 ExternalShadowMask =
1081 initializeCallbackFunctions(M);
1082 initializeRuntimeFunctions(M);
1084 std::vector<Function *> FnsToInstrument;
1087 if (!i.isIntrinsic() &&
1088 &i != DFSanUnionFn.getCallee()->stripPointerCasts() &&
1089 &i != DFSanCheckedUnionFn.getCallee()->stripPointerCasts() &&
1090 &i != DFSanUnionLoadFn.getCallee()->stripPointerCasts() &&
1091 &i != DFSanUnionLoadFast16LabelsFn.getCallee()->stripPointerCasts() &&
1092 &i != DFSanUnimplementedFn.getCallee()->stripPointerCasts() &&
1093 &i != DFSanSetLabelFn.getCallee()->stripPointerCasts() &&
1094 &i != DFSanNonzeroLabelFn.getCallee()->stripPointerCasts() &&
1095 &i != DFSanVarargWrapperFn.getCallee()->stripPointerCasts() &&
1096 &i != DFSanLoadCallbackFn.getCallee()->stripPointerCasts() &&
1097 &i != DFSanStoreCallbackFn.getCallee()->stripPointerCasts() &&
1098 &i != DFSanMemTransferCallbackFn.getCallee()->stripPointerCasts() &&
1099 &i != DFSanCmpCallbackFn.getCallee()->stripPointerCasts())
1100 FnsToInstrument.push_back(&i);
1111 bool GAInst = isInstrumented(GA), FInst = isInstrumented(
F);
1112 if (GAInst && FInst) {
1113 addGlobalNamePrefix(GA);
1114 }
else if (GAInst != FInst) {
1119 buildWrapperFunction(
F,
"", GA->
getLinkage(),
F->getFunctionType());
1123 FnsToInstrument.push_back(NewF);
1128 ReadOnlyNoneAttrs.addAttribute(Attribute::ReadOnly)
1129 .addAttribute(Attribute::ReadNone);
1133 for (std::vector<Function *>::iterator i = FnsToInstrument.begin(),
1134 e = FnsToInstrument.end();
1142 if (isInstrumented(&
F)) {
1145 if (getInstrumentedABI() == IA_Args && !IsZeroArgsVoidRet) {
1148 F.getAddressSpace(),
"", &
M);
1155 FArgEnd =
F.arg_end();
1156 FArg != FArgEnd; ++FArg, ++NewFArg) {
1157 FArg->replaceAllUsesWith(&*NewFArg);
1171 F.replaceAllUsesWith(
1174 F.eraseFromParent();
1176 addGlobalNamePrefix(NewF);
1178 addGlobalNamePrefix(&
F);
1180 }
else if (!IsZeroArgsVoidRet || getWrapperKind(&
F) == WK_Custom) {
1185 ? getArgsFunctionType(FT)
1195 Function *NewF = buildWrapperFunction(
1196 &
F, std::string(
"dfsw$") + std::string(
F.getName()),
1197 wrapperLinkage, NewFT);
1198 if (getInstrumentedABI() == IA_TLS)
1201 Value *WrappedFnCst =
1203 F.replaceAllUsesWith(WrappedFnCst);
1205 UnwrappedFnMap[WrappedFnCst] = &
F;
1208 if (!
F.isDeclaration()) {
1218 size_t N = i - FnsToInstrument.begin(),
1219 Count =
e - FnsToInstrument.begin();
1220 FnsToInstrument.push_back(&
F);
1221 i = FnsToInstrument.begin() +
N;
1222 e = FnsToInstrument.begin() + Count;
1227 UnwrappedFnMap[&
F] = &
F;
1232 for (
Function *i : FnsToInstrument) {
1233 if (!i || i->isDeclaration())
1238 DFSanFunction DFSF(*
this, i, FnsWithNativeABI.
count(i));
1254 if (!DFSF.SkipInsts.count(Inst))
1255 DFSanVisitor(DFSF).visit(Inst);
1266 for (
std::vector<std::pair<PHINode *, PHINode *>>::iterator
1267 i = DFSF.PHIFixups.begin(),
1268 e = DFSF.PHIFixups.end();
1270 for (
unsigned val = 0, n = i->first->getNumIncomingValues(); val != n;
1272 i->second->setIncomingValue(
1273 val, DFSF.getShadow(i->first->getIncomingValue(val)));
1282 for (
Value *V : DFSF.NonZeroChecks) {
1285 Pos =
I->getNextNode();
1287 Pos = &DFSF.F->getEntryBlock().front();
1288 while (isa<PHINode>(Pos) || isa<AllocaInst>(Pos))
1291 Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(V, Pos);
1293 IRB.
CreateICmpNE(PrimitiveShadow, DFSF.DFS.ZeroPrimitiveShadow);
1295 Ne, Pos,
false, ColdCallWeights));
1297 ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn, {});
1302 return Changed || !FnsToInstrument.empty() ||
1303 M.global_size() != InitialGlobalSize ||
M.size() != InitialModuleSize;
1319 Value *DFSanFunction::getShadowForTLSArgument(
Argument *A) {
1320 unsigned ArgOffset = 0;
1322 for (
auto &FArg :
F->args()) {
1323 if (!FArg.getType()->isSized()) {
1329 unsigned Size =
DL.getTypeAllocSize(
DFS.getShadowTy(&FArg));
1342 Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
1347 return DFS.getZeroShadow(A);
1351 if (!isa<Argument>(V) && !isa<Instruction>(V))
1352 return DFS.getZeroShadow(V);
1353 Value *&Shadow = ValShadowMap[V];
1355 if (
Argument *A = dyn_cast<Argument>(V)) {
1357 return DFS.getZeroShadow(V);
1359 case DataFlowSanitizer::IA_TLS: {
1360 Shadow = getShadowForTLSArgument(A);
1363 case DataFlowSanitizer::IA_Args: {
1364 unsigned ArgIdx =
A->getArgNo() +
F->arg_size() / 2;
1373 NonZeroChecks.push_back(Shadow);
1375 Shadow =
DFS.getZeroShadow(V);
1383 assert(
DFS.shouldTrackFieldsAndIndices() ||
1385 ValShadowMap[
I] = Shadow;
1389 assert(
Addr != RetvalTLS &&
"Reinstrumenting?");
1391 Value *ShadowPtrMaskValue;
1392 if (DFSanRuntimeShadowMask)
1393 ShadowPtrMaskValue = IRB.
CreateLoad(IntptrTy, ExternalShadowMask);
1395 ShadowPtrMaskValue = ShadowPtrMask;
1401 PrimitiveShadowPtrTy);
1406 Value *PrimitiveValue = combineShadows(V1,
V2, Pos);
1407 return expandFromPrimitiveShadow(
T, PrimitiveValue, Pos);
1413 if (
DFS.isZeroShadow(V1))
1414 return collapseToPrimitiveShadow(
V2, Pos);
1415 if (
DFS.isZeroShadow(
V2))
1416 return collapseToPrimitiveShadow(V1, Pos);
1418 return collapseToPrimitiveShadow(V1, Pos);
1420 auto V1Elems = ShadowElements.
find(V1);
1421 auto V2Elems = ShadowElements.
find(
V2);
1422 if (V1Elems != ShadowElements.
end() && V2Elems != ShadowElements.
end()) {
1423 if (std::includes(V1Elems->second.begin(), V1Elems->second.end(),
1424 V2Elems->second.begin(), V2Elems->second.end())) {
1425 return collapseToPrimitiveShadow(V1, Pos);
1426 }
else if (std::includes(V2Elems->second.begin(), V2Elems->second.end(),
1427 V1Elems->second.begin(), V1Elems->second.end())) {
1428 return collapseToPrimitiveShadow(
V2, Pos);
1430 }
else if (V1Elems != ShadowElements.
end()) {
1431 if (V1Elems->second.count(
V2))
1432 return collapseToPrimitiveShadow(V1, Pos);
1433 }
else if (V2Elems != ShadowElements.
end()) {
1434 if (V2Elems->second.count(V1))
1435 return collapseToPrimitiveShadow(
V2, Pos);
1438 auto Key = std::make_pair(V1,
V2);
1441 CachedShadow &CCS = CachedShadows[
Key];
1446 Value *PV1 = collapseToPrimitiveShadow(V1, Pos);
1447 Value *PV2 = collapseToPrimitiveShadow(
V2, Pos);
1452 CCS.Shadow = IRB.
CreateOr(PV1, PV2);
1453 }
else if (AvoidNewBlocks) {
1456 Call->addParamAttr(0, Attribute::ZExt);
1457 Call->addParamAttr(1, Attribute::ZExt);
1465 Ne, Pos,
false,
DFS.ColdCallWeights, &DT));
1469 Call->addParamAttr(0, Attribute::ZExt);
1470 Call->addParamAttr(1, Attribute::ZExt);
1482 std::set<Value *> UnionElems;
1483 if (V1Elems != ShadowElements.
end()) {
1484 UnionElems = V1Elems->second;
1486 UnionElems.insert(V1);
1488 if (V2Elems != ShadowElements.
end()) {
1489 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
1491 UnionElems.insert(
V2);
1493 ShadowElements[CCS.Shadow] =
std::move(UnionElems);
1503 return DFS.getZeroShadow(Inst);
1507 Shadow = combineShadows(Shadow, getShadow(Inst->
getOperand(i)), Inst);
1509 return expandFromPrimitiveShadow(Inst->
getType(), Shadow, Inst);
1513 Value *CombinedShadow = DFSF.combineOperandShadows(&
I);
1514 DFSF.setShadow(&
I, CombinedShadow);
1515 return CombinedShadow;
1524 const auto i = AllocaShadowMap.
find(AI);
1525 if (i != AllocaShadowMap.
end()) {
1534 bool AllConstants =
true;
1535 for (
const Value *Obj : Objs) {
1536 if (isa<Function>(Obj) || isa<BlockAddress>(Obj))
1538 if (isa<GlobalVariable>(Obj) && cast<GlobalVariable>(Obj)->
isConstant())
1541 AllConstants =
false;
1545 return DFS.ZeroPrimitiveShadow;
1550 return DFS.ZeroPrimitiveShadow;
1560 return combineShadows(
1574 Value *CombinedWideShadow =
1576 for (uint64_t Ofs = 64 /
DFS.ShadowWidthBits; Ofs !=
Size;
1577 Ofs += 64 /
DFS.ShadowWidthBits) {
1580 Value *NextWideShadow =
1582 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, NextWideShadow);
1586 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, ShrShadow);
1588 return IRB.
CreateTrunc(CombinedWideShadow,
DFS.PrimitiveShadowTy);
1590 if (!AvoidNewBlocks &&
Size % (64 /
DFS.ShadowWidthBits) == 0) {
1596 CallInst *FallbackCall = FallbackIRB.CreateCall(
1597 DFS.DFSanUnionLoadFn,
1598 {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
1618 std::vector<DomTreeNode *> Children(OldNode->begin(), OldNode->end());
1621 for (
auto Child : Children)
1633 for (uint64_t Ofs = 64 /
DFS.ShadowWidthBits; Ofs !=
Size;
1634 Ofs += 64 /
DFS.ShadowWidthBits) {
1640 Value *NextWideShadow = NextIRB.CreateAlignedLoad(NextIRB.getInt64Ty(),
1641 WideAddr, ShadowAlign);
1642 ShadowsEq = NextIRB.CreateICmpEQ(WideShadow, NextWideShadow);
1644 LastBr = NextIRB.CreateCondBr(ShadowsEq, FallbackBB, FallbackBB);
1648 FallbackIRB.CreateBr(
Tail);
1662 return FallbackCall;
1665 void DFSanVisitor::visitLoadInst(
LoadInst &LI) {
1669 DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
1674 Value *PrimitiveShadow =
1678 PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, &LI);
1680 if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
1681 DFSF.NonZeroChecks.push_back(PrimitiveShadow);
1684 DFSF.expandFromPrimitiveShadow(LI.
getType(), PrimitiveShadow, &LI);
1685 DFSF.setShadow(&LI, Shadow);
1689 IRB.
CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr8});
1693 void DFSanFunction::storePrimitiveShadow(
Value *
Addr, uint64_t
Size,
1695 Value *PrimitiveShadow,
1698 const auto i = AllocaShadowMap.
find(AI);
1699 if (i != AllocaShadowMap.
end()) {
1706 const Align ShadowAlign(Alignment.
value() *
DFS.ShadowWidthBytes);
1709 if (
DFS.isZeroShadow(PrimitiveShadow)) {
1713 Value *ExtShadowAddr =
1719 const unsigned ShadowVecSize = 128 /
DFS.ShadowWidthBits;
1721 if (
Size >= ShadowVecSize) {
1725 for (
unsigned i = 0; i != ShadowVecSize; ++i) {
1727 ShadowVec, PrimitiveShadow,
1730 Value *ShadowVecAddr =
1733 Value *CurShadowVecAddr =
1736 Size -= ShadowVecSize;
1738 }
while (
Size >= ShadowVecSize);
1742 Value *CurShadowAddr =
1750 void DFSanVisitor::visitStoreInst(
StoreInst &
SI) {
1751 auto &
DL =
SI.getModule()->getDataLayout();
1752 uint64_t
Size =
DL.getTypeStoreSize(
SI.getValueOperand()->getType());
1758 Value* Shadow = DFSF.getShadow(
SI.getValueOperand());
1759 Value *PrimitiveShadow;
1761 Value *PtrShadow = DFSF.getShadow(
SI.getPointerOperand());
1762 PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow, &
SI);
1764 PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow, &
SI);
1766 DFSF.storePrimitiveShadow(
SI.getPointerOperand(),
Size, Alignment,
1767 PrimitiveShadow, &
SI);
1771 IRB.
CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr8});
1776 visitOperandShadowInst(UO);
1780 visitOperandShadowInst(BO);
1783 void DFSanVisitor::visitCastInst(
CastInst &CI) { visitOperandShadowInst(CI); }
1785 void DFSanVisitor::visitCmpInst(
CmpInst &CI) {
1786 Value *CombinedShadow = visitOperandShadowInst(CI);
1789 IRB.
CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
1794 visitOperandShadowInst(GEPI);
1798 visitOperandShadowInst(
I);
1802 visitOperandShadowInst(
I);
1806 visitOperandShadowInst(
I);
1810 if (!DFSF.DFS.shouldTrackFieldsAndIndices()) {
1811 visitOperandShadowInst(
I);
1816 Value *Agg =
I.getAggregateOperand();
1817 Value *AggShadow = DFSF.getShadow(Agg);
1819 DFSF.setShadow(&
I, ResShadow);
1823 if (!DFSF.DFS.shouldTrackFieldsAndIndices()) {
1824 visitOperandShadowInst(
I);
1829 Value *AggShadow = DFSF.getShadow(
I.getAggregateOperand());
1830 Value *InsShadow = DFSF.getShadow(
I.getInsertedValueOperand());
1832 DFSF.setShadow(&
I, Res);
1835 void DFSanVisitor::visitAllocaInst(
AllocaInst &
I) {
1836 bool AllLoadsStores =
true;
1837 for (
User *U :
I.users()) {
1838 if (isa<LoadInst>(U))
1842 if (
SI->getPointerOperand() == &
I)
1846 AllLoadsStores =
false;
1849 if (AllLoadsStores) {
1851 DFSF.AllocaShadowMap[&
I] = IRB.
CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
1853 DFSF.setShadow(&
I, DFSF.DFS.ZeroPrimitiveShadow);
1856 void DFSanVisitor::visitSelectInst(
SelectInst &
I) {
1857 Value *CondShadow = DFSF.getShadow(
I.getCondition());
1858 Value *TrueShadow = DFSF.getShadow(
I.getTrueValue());
1859 Value *FalseShadow = DFSF.getShadow(
I.getFalseValue());
1860 Value *ShadowSel =
nullptr;
1862 if (isa<VectorType>(
I.getCondition()->getType())) {
1863 ShadowSel = DFSF.combineShadowsThenConvert(
I.getType(), TrueShadow,
1866 if (TrueShadow == FalseShadow) {
1867 ShadowSel = TrueShadow;
1874 ? DFSF.combineShadowsThenConvert(
1875 I.getType(), CondShadow, ShadowSel, &
I)
1879 void DFSanVisitor::visitMemSetInst(
MemSetInst &
I) {
1881 Value *ValShadow = DFSF.getShadow(
I.getValue());
1883 {ValShadow, IRB.CreateBitCast(I.getDest(), Type::getInt8PtrTy(
1885 IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
1890 Value *RawDestShadow = DFSF.DFS.getShadowAddress(
I.getDest(), &
I);
1891 Value *SrcShadow = DFSF.DFS.getShadowAddress(
I.getSource(), &
I);
1894 DFSF.DFS.ShadowWidthBytes));
1898 auto *MTI = cast<MemTransferInst>(
1899 IRB.
CreateCall(
I.getFunctionType(),
I.getCalledOperand(),
1900 {DestShadow, SrcShadow, LenShadow,
I.getVolatileCst()}));
1902 MTI->setDestAlignment(
I.getDestAlign() * DFSF.DFS.ShadowWidthBytes);
1903 MTI->setSourceAlignment(
I.getSourceAlign() * DFSF.DFS.ShadowWidthBytes);
1905 MTI->setDestAlignment(
Align(DFSF.DFS.ShadowWidthBytes));
1906 MTI->setSourceAlignment(
Align(DFSF.DFS.ShadowWidthBytes));
1909 IRB.
CreateCall(DFSF.DFS.DFSanMemTransferCallbackFn,
1910 {RawDestShadow, I.getLength()});
1914 void DFSanVisitor::visitReturnInst(
ReturnInst &RI) {
1917 case DataFlowSanitizer::IA_TLS: {
1920 Type *RT = DFSF.F->getFunctionType()->getReturnType();
1922 getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
1931 case DataFlowSanitizer::IA_Args: {
1933 Type *RT = DFSF.F->getFunctionType()->getReturnType();
1945 void DFSanVisitor::visitCallBase(
CallBase &CB) {
1948 visitOperandShadowInst(CB);
1954 if (
F == DFSF.DFS.DFSanVarargWrapperFn.getCallee()->stripPointerCasts())
1961 if (i != DFSF.DFS.UnwrappedFnMap.end()) {
1963 switch (DFSF.DFS.getWrapperKind(
F)) {
1964 case DataFlowSanitizer::WK_Warning:
1966 IRB.
CreateCall(DFSF.DFS.DFSanUnimplementedFn,
1968 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
1970 case DataFlowSanitizer::WK_Discard:
1972 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
1974 case DataFlowSanitizer::WK_Functional:
1976 visitOperandShadowInst(CB);
1978 case DataFlowSanitizer::WK_Custom:
1982 if (
CallInst *CI = dyn_cast<CallInst>(&CB)) {
1984 TransformedFunction CustomFn = DFSF.DFS.getCustomFunctionType(FT);
1985 std::string CustomFName =
"__dfsw_";
1986 CustomFName +=
F->getName();
1988 CustomFName, CustomFn.TransformedType);
1990 CustomFn->copyAttributesFrom(
F);
1995 DFSF.DFS.ReadOnlyNoneAttrs);
1999 std::vector<Value *>
Args;
2002 for (
unsigned n = FT->
getNumParams(); n != 0; ++i, --n) {
2003 Type *
T = (*i)->getType();
2005 if (isa<PointerType>(
T) &&
2006 (ParamFT = dyn_cast<FunctionType>(
2007 cast<PointerType>(
T)->getElementType()))) {
2008 std::string TName =
"dfst";
2011 TName +=
F->getName();
2012 Constant *
T = DFSF.DFS.getOrBuildTrampolineFunction(ParamFT, TName);
2022 const unsigned ShadowArgStart =
Args.size();
2023 for (
unsigned n = FT->
getNumParams(); n != 0; ++i, --n)
2025 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*i), &CB));
2031 LabelVATy, getDataLayout().getAllocaAddrSpace(),
2032 "labelva", &DFSF.F->getEntryBlock().front());
2034 for (
unsigned n = 0; i != CB.
arg_end(); ++i, ++n) {
2037 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*i), &CB),
2045 if (!DFSF.LabelReturnAlloca) {
2046 DFSF.LabelReturnAlloca =
2048 getDataLayout().getAllocaAddrSpace(),
2049 "labelreturn", &DFSF.F->getEntryBlock().front());
2051 Args.push_back(DFSF.LabelReturnAlloca);
2059 CustomCI->
setAttributes(TransformFunctionAttributes(CustomFn,
2066 const unsigned ArgNo = ShadowArgStart + n;
2068 DFSF.DFS.PrimitiveShadowTy)
2074 DFSF.LabelReturnAlloca);
2075 DFSF.setShadow(CustomCI, DFSF.expandFromPrimitiveShadow(
2088 if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
2089 unsigned ArgOffset = 0;
2108 if (
InvokeInst *II = dyn_cast<InvokeInst>(&CB)) {
2109 if (II->getNormalDest()->getSinglePredecessor()) {
2110 Next = &II->getNormalDest()->front();
2113 SplitEdge(II->getParent(), II->getNormalDest(), &DFSF.DT);
2114 Next = &NewBB->
front();
2121 if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) {
2124 unsigned Size =
DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
2127 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
2129 LoadInst *LI = NextIRB.CreateAlignedLoad(
2130 DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.
getType(), NextIRB),
2132 DFSF.SkipInsts.insert(LI);
2133 DFSF.setShadow(&CB, LI);
2134 DFSF.NonZeroChecks.push_back(LI);
2141 if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_Args) {
2142 FunctionType *NewFT = DFSF.DFS.getArgsFunctionType(FT);
2145 std::vector<Value *>
Args;
2148 for (
unsigned n = FT->
getNumParams(); n != 0; ++i, --n)
2152 for (
unsigned n = FT->
getNumParams(); n != 0; ++i, --n)
2153 Args.push_back(DFSF.getShadow(*i));
2160 new AllocaInst(VarArgArrayTy, getDataLayout().getAllocaAddrSpace(),
2161 "", &DFSF.F->getEntryBlock().front());
2163 for (
unsigned n = 0; i !=
E; ++i, ++n) {
2172 if (
InvokeInst *II = dyn_cast<InvokeInst>(&CB)) {
2173 NewCB = IRB.
CreateInvoke(NewFT, Func, II->getNormalDest(),
2174 II->getUnwindDest(),
Args);
2185 DFSF.SkipInsts.insert(ExVal);
2187 DFSF.SkipInsts.insert(ExShadow);
2188 DFSF.setShadow(ExVal, ExShadow);
2189 DFSF.NonZeroChecks.push_back(ExShadow);
2198 void DFSanVisitor::visitPHINode(
PHINode &PN) {
2199 Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
2210 DFSF.PHIFixups.push_back(std::make_pair(&PN, ShadowPN));
2211 DFSF.setShadow(&PN, ShadowPN);
2215 class DataFlowSanitizerLegacyPass :
public ModulePass {
2217 std::vector<std::string> ABIListFiles;
2222 DataFlowSanitizerLegacyPass(
2223 const std::vector<std::string> &ABIListFiles = std::vector<std::string>())
2226 bool runOnModule(
Module &M)
override {
2227 return DataFlowSanitizer(ABIListFiles).runImpl(M);
2235 "DataFlowSanitizer: dynamic data flow analysis.",
false,
false)
2239 return new DataFlowSanitizerLegacyPass(ABIListFiles);
2244 if (DataFlowSanitizer(ABIListFiles).
runImpl(M)) {
Return a value (possibly void), from a function.
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
SymbolTableList< Instruction >::iterator 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)
InvokeInst * CreateInvoke(FunctionType *Ty, Value *Callee, BasicBlock *NormalDest, BasicBlock *UnwindDest, ArrayRef< Value * > Args, ArrayRef< OperandBundleDef > OpBundles, const Twine &Name="")
Create an invoke instruction.
static const unsigned kArgTLSSize
A parsed version of the target data layout string in and methods for querying it.
static Value * expandFromPrimitiveShadowRecursive(Value *Shadow, SmallVector< unsigned, 4 > &Indices, Type *SubShadowTy, Value *PrimitiveShadow, IRBuilder<> &IRB)
void ReplaceInstWithInst(BasicBlock::InstListType &BIL, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
This class is the base class for the comparison instructions.
static bool runImpl(Function &F, TargetLibraryInfo &TLI, DominatorTree &DT)
This is the entry point for all transforms.
static bool isConstant(const MachineInstr &MI)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
This class represents an incoming formal argument to a Function.
Base class for instruction visitors.
IntrusiveRefCntPtr< FileSystem > getRealFileSystem()
Gets an vfs::FileSystem for the 'real' file system, as seen by the operating system.
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
void setAlignment(Align Align)
Type * getParamType(unsigned i) const
Parameter type accessors.
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
A Module instance is used to store all the information related to an LLVM module.
const char kDFSanExternShadowPtrMask[]
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Implements a dense probed hash-table based set.
void push_back(const T &Elt)
static ConstantAggregateZero * get(Type *Ty)
void recalculate(ParentType &Func)
recalculate - compute a dominator tree for the given function
This class represents a function call, abstracting a target machine's calling convention.
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
This instruction constructs a fixed permutation of two input vectors.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", Instruction *InsertBefore=nullptr, Instruction *MDFrom=nullptr)
LLVMContext & getContext() const
All values hold a context through their type.
bool isTerminator() const
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
This class wraps the llvm.memset intrinsic.
BasicBlock * getSuccessor(unsigned i) const
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))
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
An instruction for reading from memory.
static IntegerType * getInt64Ty(LLVMContext &C)
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
ModulePass * createDataFlowSanitizerLegacyPassPass(const std::vector< std::string > &ABIListFiles=std::vector< std::string >())
void addAttribute(unsigned i, Attribute::AttrKind Kind)
adds the attribute to the list of attributes.
static PointerType * getInt64PtrTy(LLVMContext &C, unsigned AS=0)
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
block_iterator block_end()
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
Value * getArgOperand(unsigned i) const
static cl::opt< bool > ClArgsABI("dfsan-args-abi", cl::desc("Use the argument ABI rather than the TLS ABI"), cl::Hidden)
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
The address of a basic block.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
This class represents the LLVM 'select' instruction.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights, DominatorTree *DT, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
This is the base class for all instructions that perform data casts.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Class to represent struct types.
This file contains the simple types necessary to represent the attributes associated with functions a...
AttributeSet getRetAttributes() const
The attributes for the ret value are returned.
static cl::opt< bool > ClFast16Labels("dfsan-fast-16-labels", cl::desc("Use more efficient instrumentation, limiting the number of " "labels to 16."), cl::Hidden, cl::init(false))
void setModuleInlineAsm(StringRef Asm)
Set the module-scope inline assembly blocks.
void setName(const Twine &Name)
Change the name of the value.
block_iterator block_begin()
Class to represent function types.
Type * getType() const
All values are typed, get the type of this value.
LLVM_NODISCARD AttributeList removeAttributes(LLVMContext &C, unsigned Index, const AttrBuilder &AttrsToRemove) const
Remove the specified attributes at the specified index from this attribute list.
ArchType getArch() const
getArch - Get the parsed architecture type of this triple.
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
Value * getCalledOperand() const
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Class to represent array types.
AttributeSet getParamAttributes(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, LoopInfo *LI=nullptr, unsigned MaxLookup=6)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
BasicBlock * getBasicBlock() const
const GlobalObject * getBaseObject() const
An instruction for storing to memory.
LinkageTypes getLinkage() const
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
uint64_t value() const
This is a hole in the type system and should not be abused.
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.
Value * getOperand(unsigned i) const
Class to represent pointers.
static const Align kShadowTLSAlignment
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static const unsigned kRetvalTLSSize
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
iterator find(const_arg_type_t< KeyT > Val)
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
bool isVoidTy() const
Return true if this is 'void'.
Constant * CreateGlobalStringPtr(StringRef Str, const Twine &Name="", unsigned AddressSpace=0, Module *M=nullptr)
Same as CreateGlobalString, but return a pointer with "i8*" type instead of a pointer to array of i8.
Value * CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx, const Twine &Name="")
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Same, but only replaced by something equivalent.
initializer< Ty > init(const Ty &Val)
This instruction inserts a single (scalar) element into a VectorType value.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
A set of analyses that are preserved following a run of a transformation pass.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
unsigned arg_size() const
LLVM Basic Block Representation.
Value * CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name="")
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.
Conditional or Unconditional Branch instruction.
static BlockAddress * get(Function *F, BasicBlock *BB)
Return a BlockAddress for the specified function and basic block.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
This function has undefined behavior.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
bool isInlineAsm() const
Check if this call is an inline asm statement.
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< bool > ClEventCallbacks("dfsan-event-callbacks", cl::desc("Insert calls to __dfsan_*_callback functions on data events."), cl::Hidden, cl::init(false))
const Instruction & front() const
FunctionType * getFunctionType() const
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
static Type * getVoidTy(LLVMContext &C)
void splice(iterator where, iplist_impl &L2)
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)
bool dominates(const Value *Def, const Use &U) const
Return true if value Def dominates use U, in the sense that Def is available at U,...
void setCallingConv(CallingConv::ID CC)
Value * getPointerOperand()
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
self_iterator getIterator()
static std::unique_ptr< SpecialCaseList > createOrDie(const std::vector< std::string > &Paths, llvm::vfs::FileSystem &FS)
Parses the special case list entries from files.
Class to represent integer types.
BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="", bool Before=false)
Split the basic block into two basic blocks at the specified instruction.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
Tail - This calling convention attemps to make calls as fast as possible while guaranteeing that tail...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This struct is a compact representation of a valid (non-zero power of two) alignment.
Triple - Helper class for working with autoconf configuration names.
void setSuccessor(unsigned idx, BasicBlock *NewSucc)
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Iterator for intrusive lists based on ilist_node.
unsigned getNumOperands() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the generic address space (address sp...
This is the shared class of boolean and integer constants.
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Module.h This file contains the declarations for the Module class.
Type * getReturnType() const
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
unsigned getNumIncomingValues() const
Return the number of incoming edges.
AttributeList getAttributes() const
Return the parameter attributes for this call.
void setOperand(unsigned i, Value *Val)
The access may modify the value stored in memory.
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))
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
unsigned getNumAttrSets() const
LinkageTypes
An enumeration for the kinds of linkage for global values.
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Defines the virtual file system interface vfs::FileSystem.
void removeAttributes(unsigned i, const AttrBuilder &Attrs)
removes the attributes from the list of attributes.
This class wraps the llvm.memcpy/memmove intrinsics.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
static IntegerType * getInt32Ty(LLVMContext &C)
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))
Value * CreateGEP(Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
CallingConv::ID getCallingConv() const
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
StringRef getName() const
Return a constant reference to the value's name.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation.
static cl::opt< bool > ClTrackSelectControlFlow("dfsan-track-select-control-flow", cl::desc("Propagate labels from condition values of select instructions " "to results."), cl::Hidden, cl::init(true))
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
user_iterator_impl< User > user_iterator
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
Type * getValueType() const
const BasicBlockListType & getBasicBlockList() const
Get the underlying elements of the Function...
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Align getAlign() const
Return the alignment of the access that is being performed.
static StringRef GetGlobalTypeString(const GlobalValue &G)
const std::string & getModuleInlineAsm() const
Get any module-scope inline assembly blocks.
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
iterator_range< df_iterator< T > > depth_first(const T &G)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Root & operator=(Root &&)=delete
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Value * CreateConstGEP2_32(Type *Ty, Value *Ptr, unsigned Idx0, unsigned Idx1, const Twine &Name="")
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
AttrBuilder typeIncompatible(Type *Ty)
Which attributes cannot be applied to a type.
AttributeSet getFnAttributes() const
The function attributes are returned.
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
StringRef - Represent a constant reference to a string, i.e.
INITIALIZE_PASS(DataFlowSanitizerLegacyPass, "dfsan", "DataFlowSanitizer: dynamic data flow analysis.", false, false) ModulePass *llvm
A container for analyses that lazily runs them and caches their results.
Value * CreateStructGEP(Type *Ty, Value *Ptr, unsigned Idx, const Twine &Name="")
This header defines various interfaces for pass management in LLVM.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
PointerType * getType() const
Global values are always pointers.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute >> Attrs)
Create an AttributeList with the specified parameters in it.
const BasicBlock * getParent() const
an instruction to allocate memory on the stack
This instruction inserts a struct field of array element value into an aggregate value.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL