139 "dfsan-preserve-alignment",
161 cl::desc(
"File listing native ABI functions and how the pass treats them"),
167 "dfsan-combine-pointer-labels-on-load",
168 cl::desc(
"Combine the label of the pointer with the label of the data when "
169 "loading from memory."),
175 "dfsan-combine-pointer-labels-on-store",
176 cl::desc(
"Combine the label of the pointer with the label of the data when "
177 "storing in memory."),
182 "dfsan-combine-offset-labels-on-gep",
184 "Combine the label of the offset with the label of the pointer when "
185 "doing pointer arithmetic."),
189 "dfsan-combine-taint-lookup-table",
191 "When dfsan-combine-offset-labels-on-gep and/or "
192 "dfsan-combine-pointer-labels-on-load are false, this flag can "
193 "be used to re-enable combining offset and/or pointer taint when "
194 "loading specific constant global variables (i.e. lookup tables)."),
198 "dfsan-debug-nonzero-labels",
199 cl::desc(
"Insert calls to __dfsan_nonzero_label on observing a parameter, "
200 "load or return with a nonzero label"),
214 "dfsan-event-callbacks",
215 cl::desc(
"Insert calls to __dfsan_*_callback functions on data events."),
222 "dfsan-conditional-callbacks",
230 "dfsan-reaches-function-callbacks",
231 cl::desc(
"Insert calls to callback functions on data reaching a function."),
236 "dfsan-track-select-control-flow",
237 cl::desc(
"Propagate labels from condition values of select instructions "
243 "dfsan-instrument-with-call-threshold",
244 cl::desc(
"If the function being instrumented requires more than "
245 "this number of origin stores, use callbacks instead of "
246 "inline checks (-1 means never use callbacks)."),
255 cl::desc(
"Track origins of labels"),
259 "dfsan-ignore-personality-routine",
260 cl::desc(
"If a personality routine is marked uninstrumented from the ABI "
261 "list, do not create a wrapper for it."),
265 "dfsan-add-global-name-suffix",
271 Type *GType =
G.getValueType();
274 if (!SGType->isLiteral())
275 return SGType->getName();
277 return "<unknown type>";
286struct MemoryMapParams {
332 std::unique_ptr<SpecialCaseList> SCL;
335 DFSanABIList() =
default;
337 void set(std::unique_ptr<SpecialCaseList>
List) { SCL = std::move(
List); }
341 bool isIn(
const Function &
F, StringRef Category)
const {
342 return isIn(*
F.getParent(), Category) ||
343 SCL->inSection(
"dataflow",
"fun",
F.getName(), Category);
350 bool isIn(
const GlobalAlias &GA, StringRef Category)
const {
355 return SCL->inSection(
"dataflow",
"fun", GA.
getName(), Category);
357 return SCL->inSection(
"dataflow",
"global", GA.
getName(), Category) ||
363 bool isIn(
const Module &M, StringRef Category)
const {
364 return SCL->inSection(
"dataflow",
"src",
M.getModuleIdentifier(), Category);
371struct TransformedFunction {
372 TransformedFunction(FunctionType *OriginalType, FunctionType *TransformedType,
373 const std::vector<unsigned> &ArgumentIndexMapping)
374 : OriginalType(OriginalType), TransformedType(TransformedType),
375 ArgumentIndexMapping(ArgumentIndexMapping) {}
378 TransformedFunction(
const TransformedFunction &) =
delete;
379 TransformedFunction &operator=(
const TransformedFunction &) =
delete;
382 TransformedFunction(TransformedFunction &&) =
default;
383 TransformedFunction &operator=(TransformedFunction &&) =
default;
386 FunctionType *OriginalType;
389 FunctionType *TransformedType;
396 std::vector<unsigned> ArgumentIndexMapping;
403transformFunctionAttributes(
const TransformedFunction &TransformedFunction,
407 std::vector<llvm::AttributeSet> ArgumentAttributes(
408 TransformedFunction.TransformedType->getNumParams());
413 for (
unsigned I = 0, IE = TransformedFunction.ArgumentIndexMapping.size();
415 unsigned TransformedIndex = TransformedFunction.ArgumentIndexMapping[
I];
416 ArgumentAttributes[TransformedIndex] = CallSiteAttrs.getParamAttrs(
I);
420 for (
unsigned I = TransformedFunction.OriginalType->getNumParams(),
421 IE = CallSiteAttrs.getNumAttrSets();
423 ArgumentAttributes.push_back(CallSiteAttrs.getParamAttrs(
I));
426 return AttributeList::get(Ctx, CallSiteAttrs.getFnAttrs(),
427 CallSiteAttrs.getRetAttrs(),
431class DataFlowSanitizer {
432 friend struct DFSanFunction;
433 friend class DFSanVisitor;
435 enum { ShadowWidthBits = 8, ShadowWidthBytes = ShadowWidthBits / 8 };
437 enum { OriginWidthBits = 32, OriginWidthBytes = OriginWidthBits / 8 };
465 IntegerType *OriginTy;
467 ConstantInt *ZeroOrigin;
469 IntegerType *PrimitiveShadowTy;
471 IntegerType *IntptrTy;
472 ConstantInt *ZeroPrimitiveShadow;
478 FunctionType *DFSanUnionLoadFnTy;
479 FunctionType *DFSanLoadLabelAndOriginFnTy;
480 FunctionType *DFSanUnimplementedFnTy;
481 FunctionType *DFSanWrapperExternWeakNullFnTy;
482 FunctionType *DFSanSetLabelFnTy;
483 FunctionType *DFSanNonzeroLabelFnTy;
484 FunctionType *DFSanVarargWrapperFnTy;
485 FunctionType *DFSanConditionalCallbackFnTy;
486 FunctionType *DFSanConditionalCallbackOriginFnTy;
487 FunctionType *DFSanReachesFunctionCallbackFnTy;
488 FunctionType *DFSanReachesFunctionCallbackOriginFnTy;
489 FunctionType *DFSanCmpCallbackFnTy;
490 FunctionType *DFSanLoadStoreCallbackFnTy;
491 FunctionType *DFSanMemTransferCallbackFnTy;
492 FunctionType *DFSanChainOriginFnTy;
493 FunctionType *DFSanChainOriginIfTaintedFnTy;
494 FunctionType *DFSanMemOriginTransferFnTy;
495 FunctionType *DFSanMemShadowOriginTransferFnTy;
496 FunctionType *DFSanMemShadowOriginConditionalExchangeFnTy;
497 FunctionType *DFSanMaybeStoreOriginFnTy;
498 FunctionCallee DFSanUnionLoadFn;
499 FunctionCallee DFSanLoadLabelAndOriginFn;
500 FunctionCallee DFSanUnimplementedFn;
501 FunctionCallee DFSanWrapperExternWeakNullFn;
502 FunctionCallee DFSanSetLabelFn;
503 FunctionCallee DFSanNonzeroLabelFn;
504 FunctionCallee DFSanVarargWrapperFn;
505 FunctionCallee DFSanLoadCallbackFn;
506 FunctionCallee DFSanStoreCallbackFn;
507 FunctionCallee DFSanMemTransferCallbackFn;
508 FunctionCallee DFSanConditionalCallbackFn;
509 FunctionCallee DFSanConditionalCallbackOriginFn;
510 FunctionCallee DFSanReachesFunctionCallbackFn;
511 FunctionCallee DFSanReachesFunctionCallbackOriginFn;
512 FunctionCallee DFSanCmpCallbackFn;
513 FunctionCallee DFSanChainOriginFn;
514 FunctionCallee DFSanChainOriginIfTaintedFn;
515 FunctionCallee DFSanMemOriginTransferFn;
516 FunctionCallee DFSanMemShadowOriginTransferFn;
517 FunctionCallee DFSanMemShadowOriginConditionalExchangeFn;
518 FunctionCallee DFSanMaybeStoreOriginFn;
519 SmallPtrSet<Value *, 16> DFSanRuntimeFunctions;
520 MDNode *ColdCallWeights;
521 MDNode *OriginStoreWeights;
522 DFSanABIList ABIList;
523 DenseMap<Value *, Function *> UnwrappedFnMap;
524 AttributeMask ReadOnlyNoneAttrs;
525 StringSet<> CombineTaintLookupTableNames;
529 const MemoryMapParams *MapParams;
534 Value *ShadowOffset);
535 std::pair<Value *, Value *> getShadowOriginAddress(
Value *Addr,
538 bool isInstrumented(
const Function *
F);
539 bool isInstrumented(
const GlobalAlias *GA);
540 bool isForceZeroLabels(
const Function *
F);
541 TransformedFunction getCustomFunctionType(FunctionType *
T);
542 WrapperKind getWrapperKind(Function *
F);
543 void addGlobalNameSuffix(GlobalValue *GV);
544 void buildExternWeakCheckIfNeeded(
IRBuilder<> &IRB, Function *
F);
545 Function *buildWrapperFunction(Function *
F, StringRef NewFName,
547 FunctionType *NewFT);
548 void initializeCallbackFunctions(
Module &M);
549 void initializeRuntimeFunctions(
Module &M);
550 bool initializeModule(
Module &M);
559 bool hasLoadSizeForFastPath(uint64_t
Size);
562 bool shouldTrackOrigins();
574 bool isZeroShadow(
Value *V);
585 const uint64_t NumOfElementsInArgOrgTLS =
ArgTLSSize / OriginWidthBytes;
588 DataFlowSanitizer(
const std::vector<std::string> &ABIListFiles,
589 IntrusiveRefCntPtr<vfs::FileSystem> FS);
592 llvm::function_ref<TargetLibraryInfo &(Function &)> GetTLI);
595struct DFSanFunction {
596 DataFlowSanitizer &DFS;
600 bool IsForceZeroLabels;
601 TargetLibraryInfo &TLI;
602 AllocaInst *LabelReturnAlloca =
nullptr;
603 AllocaInst *OriginReturnAlloca =
nullptr;
604 DenseMap<Value *, Value *> ValShadowMap;
605 DenseMap<Value *, Value *> ValOriginMap;
606 DenseMap<AllocaInst *, AllocaInst *> AllocaShadowMap;
607 DenseMap<AllocaInst *, AllocaInst *> AllocaOriginMap;
609 struct PHIFixupElement {
614 std::vector<PHIFixupElement> PHIFixups;
616 DenseSet<Instruction *> SkipInsts;
617 std::vector<Value *> NonZeroChecks;
619 struct CachedShadow {
624 DenseMap<std::pair<Value *, Value *>, CachedShadow> CachedShadows;
629 DenseMap<Value *, Value *> CachedCollapsedShadows;
630 DenseMap<Value *, std::set<Value *>> ShadowElements;
632 DFSanFunction(DataFlowSanitizer &DFS, Function *F,
bool IsNativeABI,
633 bool IsForceZeroLabels, TargetLibraryInfo &TLI)
634 : DFS(DFS), F(F), IsNativeABI(IsNativeABI),
635 IsForceZeroLabels(IsForceZeroLabels), TLI(TLI) {
653 Value *getRetvalOriginTLS();
656 void setOrigin(Instruction *
I,
Value *Origin);
658 Value *combineOperandOrigins(Instruction *Inst);
665 Value *combineOrigins(
const std::vector<Value *> &Shadows,
666 const std::vector<Value *> &Origins,
670 void setShadow(Instruction *
I,
Value *Shadow);
678 Value *combineOperandShadows(Instruction *Inst);
687 std::pair<Value *, Value *> loadShadowOrigin(
Value *Addr, uint64_t
Size,
691 void storePrimitiveShadowOrigin(
Value *Addr, uint64_t
Size,
692 Align InstAlignment,
Value *PrimitiveShadow,
711 void storeZeroPrimitiveShadow(
Value *Addr, uint64_t
Size, Align ShadowAlign,
714 Align getShadowAlign(Align InstAlignment);
718 void addConditionalCallbacksIfEnabled(Instruction &
I,
Value *Condition);
722 void addReachesFunctionCallbacksIfEnabled(
IRBuilder<> &IRB, Instruction &
I,
725 bool isLookupTableConstant(
Value *
P);
730 template <
class AggregateType>
731 Value *collapseAggregateShadow(AggregateType *AT,
Value *Shadow,
737 Value *getShadowForTLSArgument(Argument *
A);
740 std::pair<Value *, Value *>
741 loadShadowFast(
Value *ShadowAddr,
Value *OriginAddr, uint64_t
Size,
742 Align ShadowAlign, Align OriginAlign,
Value *FirstOrigin,
745 Align getOriginAlign(Align InstAlignment);
756 bool useCallbackLoadLabelAndOrigin(uint64_t
Size, Align InstAlignment);
772 uint64_t StoreOriginSize, Align Alignment);
781 Align InstAlignment);
786 bool shouldInstrumentWithCall();
792 std::pair<Value *, Value *>
793 loadShadowOriginSansLoadTracking(
Value *Addr, uint64_t
Size,
796 int NumOriginStores = 0;
799class DFSanVisitor :
public InstVisitor<DFSanVisitor> {
803 DFSanVisitor(DFSanFunction &DFSF) : DFSF(DFSF) {}
805 const DataLayout &getDataLayout()
const {
806 return DFSF.F->getDataLayout();
810 void visitInstOperands(Instruction &
I);
812 void visitUnaryOperator(UnaryOperator &UO);
813 void visitBinaryOperator(BinaryOperator &BO);
814 void visitBitCastInst(BitCastInst &BCI);
815 void visitCastInst(CastInst &CI);
816 void visitCmpInst(CmpInst &CI);
817 void visitLandingPadInst(LandingPadInst &LPI);
818 void visitGetElementPtrInst(GetElementPtrInst &GEPI);
819 void visitLoadInst(LoadInst &LI);
820 void visitStoreInst(StoreInst &SI);
821 void visitAtomicRMWInst(AtomicRMWInst &
I);
822 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I);
823 void visitReturnInst(ReturnInst &RI);
824 void visitLibAtomicLoad(CallBase &CB);
825 void visitLibAtomicStore(CallBase &CB);
826 void visitLibAtomicExchange(CallBase &CB);
827 void visitLibAtomicCompareExchange(CallBase &CB);
828 void visitCallBase(CallBase &CB);
829 void visitPHINode(PHINode &PN);
830 void visitExtractElementInst(ExtractElementInst &
I);
831 void visitInsertElementInst(InsertElementInst &
I);
832 void visitShuffleVectorInst(ShuffleVectorInst &
I);
833 void visitExtractValueInst(ExtractValueInst &
I);
834 void visitInsertValueInst(InsertValueInst &
I);
835 void visitAllocaInst(AllocaInst &
I);
836 void visitSelectInst(SelectInst &
I);
837 void visitMemSetInst(MemSetInst &
I);
838 void visitMemTransferInst(MemTransferInst &
I);
839 void visitCondBrInst(CondBrInst &BR);
840 void visitSwitchInst(SwitchInst &SW);
843 void visitCASOrRMW(Align InstAlignment, Instruction &
I);
846 bool visitWrappedCallBase(Function &
F, CallBase &CB);
849 void visitInstOperandOrigins(Instruction &
I);
851 void addShadowArguments(Function &
F, CallBase &CB, std::vector<Value *> &Args,
854 void addOriginArguments(Function &
F, CallBase &CB, std::vector<Value *> &Args,
861bool LibAtomicFunction(
const Function &
F) {
867 if (!
F.hasName() ||
F.isVarArg())
869 switch (
F.arg_size()) {
871 return F.getName() ==
"__atomic_load" ||
F.getName() ==
"__atomic_store";
873 return F.getName() ==
"__atomic_exchange";
875 return F.getName() ==
"__atomic_compare_exchange";
883DataFlowSanitizer::DataFlowSanitizer(
884 const std::vector<std::string> &ABIListFiles,
886 std::vector<std::string> AllABIListFiles(std::move(ABIListFiles));
893TransformedFunction DataFlowSanitizer::getCustomFunctionType(FunctionType *
T) {
900 std::vector<unsigned> ArgumentIndexMapping;
901 for (
unsigned I = 0,
E =
T->getNumParams();
I !=
E; ++
I) {
902 Type *ParamType =
T->getParamType(
I);
903 ArgumentIndexMapping.push_back(ArgTypes.
size());
906 for (
unsigned I = 0,
E =
T->getNumParams();
I !=
E; ++
I)
909 ArgTypes.
push_back(PrimitiveShadowPtrTy);
910 Type *RetType =
T->getReturnType();
912 ArgTypes.
push_back(PrimitiveShadowPtrTy);
914 if (shouldTrackOrigins()) {
915 for (
unsigned I = 0,
E =
T->getNumParams();
I !=
E; ++
I)
923 return TransformedFunction(
924 T, FunctionType::get(
T->getReturnType(), ArgTypes,
T->isVarArg()),
925 ArgumentIndexMapping);
928bool DataFlowSanitizer::isZeroShadow(
Value *V) {
939bool DataFlowSanitizer::hasLoadSizeForFastPath(uint64_t
Size) {
940 uint64_t ShadowSize =
Size * ShadowWidthBytes;
941 return ShadowSize % 8 == 0 || ShadowSize == 4;
944bool DataFlowSanitizer::shouldTrackOrigins() {
946 return ShouldTrackOrigins;
949Constant *DataFlowSanitizer::getZeroShadow(
Type *OrigTy) {
951 return ZeroPrimitiveShadow;
952 Type *ShadowTy = getShadowTy(OrigTy);
957 return getZeroShadow(
V->getType());
967 for (
unsigned Idx = 0; Idx < AT->getNumElements(); Idx++) {
970 Shadow, Indices, AT->getElementType(), PrimitiveShadow, IRB);
977 for (
unsigned Idx = 0; Idx < ST->getNumElements(); Idx++) {
980 Shadow, Indices, ST->getElementType(Idx), PrimitiveShadow, IRB);
988bool DFSanFunction::shouldInstrumentWithCall() {
993Value *DFSanFunction::expandFromPrimitiveShadow(
Type *
T,
Value *PrimitiveShadow,
995 Type *ShadowTy = DFS.getShadowTy(
T);
998 return PrimitiveShadow;
1000 if (DFS.isZeroShadow(PrimitiveShadow))
1001 return DFS.getZeroShadow(ShadowTy);
1004 SmallVector<unsigned, 4> Indices;
1007 PrimitiveShadow, IRB);
1010 CachedCollapsedShadows[Shadow] = PrimitiveShadow;
1014template <
class AggregateType>
1015Value *DFSanFunction::collapseAggregateShadow(AggregateType *AT,
Value *Shadow,
1017 if (!AT->getNumElements())
1018 return DFS.ZeroPrimitiveShadow;
1021 Value *Aggregator = collapseToPrimitiveShadow(FirstItem, IRB);
1023 for (
unsigned Idx = 1; Idx < AT->getNumElements(); Idx++) {
1025 Value *ShadowInner = collapseToPrimitiveShadow(ShadowItem, IRB);
1026 Aggregator = IRB.
CreateOr(Aggregator, ShadowInner);
1031Value *DFSanFunction::collapseToPrimitiveShadow(
Value *Shadow,
1037 return collapseAggregateShadow<>(AT, Shadow, IRB);
1039 return collapseAggregateShadow<>(ST, Shadow, IRB);
1043Value *DFSanFunction::collapseToPrimitiveShadow(
Value *Shadow,
1050 Value *&CS = CachedCollapsedShadows[Shadow];
1055 Value *PrimitiveShadow = collapseToPrimitiveShadow(Shadow, IRB);
1057 CS = PrimitiveShadow;
1058 return PrimitiveShadow;
1061void DFSanFunction::addConditionalCallbacksIfEnabled(Instruction &
I,
1067 Value *CondShadow = getShadow(Condition);
1069 if (DFS.shouldTrackOrigins()) {
1070 Value *CondOrigin = getOrigin(Condition);
1071 CI = IRB.
CreateCall(DFS.DFSanConditionalCallbackOriginFn,
1072 {CondShadow, CondOrigin});
1074 CI = IRB.
CreateCall(DFS.DFSanConditionalCallbackFn, {CondShadow});
1079void DFSanFunction::addReachesFunctionCallbacksIfEnabled(
IRBuilder<> &IRB,
1085 const DebugLoc &dbgloc =
I.getDebugLoc();
1086 Value *DataShadow = collapseToPrimitiveShadow(getShadow(
Data), IRB);
1087 ConstantInt *CILine;
1090 if (dbgloc.
get() ==
nullptr) {
1091 CILine = llvm::ConstantInt::get(
I.getContext(), llvm::APInt(32, 0));
1093 I.getFunction()->getParent()->getSourceFileName());
1095 CILine = llvm::ConstantInt::get(
I.getContext(),
1096 llvm::APInt(32, dbgloc.
getLine()));
1104 std::vector<Value *>
args;
1106 if (DFS.shouldTrackOrigins()) {
1108 args = { DataShadow, DataOrigin, FilePathPtr, CILine, FunctionNamePtr };
1109 CB = IRB.
CreateCall(DFS.DFSanReachesFunctionCallbackOriginFn,
args);
1111 args = { DataShadow, FilePathPtr, CILine, FunctionNamePtr };
1118Type *DataFlowSanitizer::getShadowTy(
Type *OrigTy) {
1120 return PrimitiveShadowTy;
1122 return PrimitiveShadowTy;
1124 return PrimitiveShadowTy;
1126 return ArrayType::get(getShadowTy(AT->getElementType()),
1127 AT->getNumElements());
1130 for (
unsigned I = 0,
N =
ST->getNumElements();
I <
N; ++
I)
1131 Elements.push_back(getShadowTy(
ST->getElementType(
I)));
1134 return PrimitiveShadowTy;
1137Type *DataFlowSanitizer::getShadowTy(
Value *V) {
1138 return getShadowTy(
V->getType());
1141bool DataFlowSanitizer::initializeModule(
Module &M) {
1142 Triple TargetTriple(
M.getTargetTriple());
1143 const DataLayout &
DL =
M.getDataLayout();
1147 switch (TargetTriple.getArch()) {
1165 Ctx = &
M.getContext();
1166 Int8Ptr = PointerType::getUnqual(*Ctx);
1168 OriginPtrTy = PointerType::getUnqual(*Ctx);
1170 PrimitiveShadowPtrTy = PointerType::getUnqual(*Ctx);
1171 IntptrTy =
DL.getIntPtrType(*Ctx);
1175 Type *DFSanUnionLoadArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
1176 DFSanUnionLoadFnTy = FunctionType::get(PrimitiveShadowTy, DFSanUnionLoadArgs,
1178 Type *DFSanLoadLabelAndOriginArgs[2] = {Int8Ptr, IntptrTy};
1179 DFSanLoadLabelAndOriginFnTy =
1182 DFSanUnimplementedFnTy = FunctionType::get(
1183 Type::getVoidTy(*Ctx), PointerType::getUnqual(*Ctx),
false);
1184 Type *DFSanWrapperExternWeakNullArgs[2] = {Int8Ptr, Int8Ptr};
1185 DFSanWrapperExternWeakNullFnTy =
1186 FunctionType::get(Type::getVoidTy(*Ctx), DFSanWrapperExternWeakNullArgs,
1188 Type *DFSanSetLabelArgs[4] = {PrimitiveShadowTy, OriginTy,
1189 PointerType::getUnqual(*Ctx), IntptrTy};
1190 DFSanSetLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx),
1191 DFSanSetLabelArgs,
false);
1192 DFSanNonzeroLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx), {},
1194 DFSanVarargWrapperFnTy = FunctionType::get(
1195 Type::getVoidTy(*Ctx), PointerType::getUnqual(*Ctx),
false);
1196 DFSanConditionalCallbackFnTy =
1197 FunctionType::get(Type::getVoidTy(*Ctx), PrimitiveShadowTy,
1199 Type *DFSanConditionalCallbackOriginArgs[2] = {PrimitiveShadowTy, OriginTy};
1200 DFSanConditionalCallbackOriginFnTy = FunctionType::get(
1201 Type::getVoidTy(*Ctx), DFSanConditionalCallbackOriginArgs,
1203 Type *DFSanReachesFunctionCallbackArgs[4] = {PrimitiveShadowTy, Int8Ptr,
1205 DFSanReachesFunctionCallbackFnTy =
1206 FunctionType::get(Type::getVoidTy(*Ctx), DFSanReachesFunctionCallbackArgs,
1208 Type *DFSanReachesFunctionCallbackOriginArgs[5] = {
1209 PrimitiveShadowTy, OriginTy, Int8Ptr, OriginTy, Int8Ptr};
1210 DFSanReachesFunctionCallbackOriginFnTy = FunctionType::get(
1211 Type::getVoidTy(*Ctx), DFSanReachesFunctionCallbackOriginArgs,
1213 DFSanCmpCallbackFnTy =
1214 FunctionType::get(Type::getVoidTy(*Ctx), PrimitiveShadowTy,
1216 DFSanChainOriginFnTy =
1217 FunctionType::get(OriginTy, OriginTy,
false);
1218 Type *DFSanChainOriginIfTaintedArgs[2] = {PrimitiveShadowTy, OriginTy};
1219 DFSanChainOriginIfTaintedFnTy = FunctionType::get(
1220 OriginTy, DFSanChainOriginIfTaintedArgs,
false);
1222 Int8Ptr, IntptrTy, OriginTy};
1223 DFSanMaybeStoreOriginFnTy = FunctionType::get(
1224 Type::getVoidTy(*Ctx), DFSanMaybeStoreOriginArgs,
false);
1225 Type *DFSanMemOriginTransferArgs[3] = {Int8Ptr, Int8Ptr, IntptrTy};
1226 DFSanMemOriginTransferFnTy = FunctionType::get(
1227 Type::getVoidTy(*Ctx), DFSanMemOriginTransferArgs,
false);
1228 Type *DFSanMemShadowOriginTransferArgs[3] = {Int8Ptr, Int8Ptr, IntptrTy};
1229 DFSanMemShadowOriginTransferFnTy =
1230 FunctionType::get(Type::getVoidTy(*Ctx), DFSanMemShadowOriginTransferArgs,
1232 Type *DFSanMemShadowOriginConditionalExchangeArgs[5] = {
1234 DFSanMemShadowOriginConditionalExchangeFnTy = FunctionType::get(
1235 Type::getVoidTy(*Ctx), DFSanMemShadowOriginConditionalExchangeArgs,
1237 Type *DFSanLoadStoreCallbackArgs[2] = {PrimitiveShadowTy, Int8Ptr};
1238 DFSanLoadStoreCallbackFnTy =
1239 FunctionType::get(Type::getVoidTy(*Ctx), DFSanLoadStoreCallbackArgs,
1241 Type *DFSanMemTransferCallbackArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
1242 DFSanMemTransferCallbackFnTy =
1243 FunctionType::get(Type::getVoidTy(*Ctx), DFSanMemTransferCallbackArgs,
1246 ColdCallWeights = MDBuilder(*Ctx).createUnlikelyBranchWeights();
1247 OriginStoreWeights = MDBuilder(*Ctx).createUnlikelyBranchWeights();
1251bool DataFlowSanitizer::isInstrumented(
const Function *
F) {
1252 return !ABIList.isIn(*
F,
"uninstrumented");
1255bool DataFlowSanitizer::isInstrumented(
const GlobalAlias *GA) {
1256 return !ABIList.isIn(*GA,
"uninstrumented");
1259bool DataFlowSanitizer::isForceZeroLabels(
const Function *
F) {
1260 return ABIList.isIn(*
F,
"force_zero_labels");
1263DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(Function *
F) {
1264 if (ABIList.isIn(*
F,
"functional"))
1265 return WK_Functional;
1266 if (ABIList.isIn(*
F,
"discard"))
1268 if (ABIList.isIn(*
F,
"custom"))
1274void DataFlowSanitizer::addGlobalNameSuffix(GlobalValue *GV) {
1278 std::string GVName = std::string(GV->
getName()), Suffix =
".dfsan";
1286 for (Module::GlobalAsmFragment &Frag :
1288 std::string SearchStr =
".symver " + GVName +
",";
1289 size_t Pos = Frag.Asm.find(SearchStr);
1290 if (Pos != std::string::npos) {
1291 Frag.Asm.replace(Pos, SearchStr.size(),
1292 ".symver " + GVName + Suffix +
",");
1293 Pos = Frag.Asm.find(
'@');
1295 if (Pos == std::string::npos)
1298 Frag.Asm.replace(Pos, 1, Suffix +
"@");
1303void DataFlowSanitizer::buildExternWeakCheckIfNeeded(
IRBuilder<> &IRB,
1313 std::vector<Value *>
Args;
1316 IRB.
CreateCall(DFSanWrapperExternWeakNullFn, Args);
1321DataFlowSanitizer::buildWrapperFunction(Function *
F, StringRef NewFName,
1323 FunctionType *NewFT) {
1324 FunctionType *FT =
F->getFunctionType();
1326 NewFName,
F->getParent());
1329 NewFT->getReturnType(), NewF->
getAttributes().getRetAttrs()));
1332 if (
F->isVarArg()) {
1335 IRBuilder<>(BB).CreateGlobalString(
F->getName()),
"", BB);
1336 new UnreachableInst(*Ctx, BB);
1338 auto ArgIt = pointer_iterator<Argument *>(NewF->
arg_begin());
1339 std::vector<Value *>
Args(ArgIt, ArgIt + FT->getNumParams());
1342 if (FT->getReturnType()->isVoidTy())
1352void DataFlowSanitizer::initializeRuntimeFunctions(
Module &M) {
1353 LLVMContext &
C =
M.getContext();
1356 AL =
AL.addFnAttribute(
C, Attribute::NoUnwind);
1357 AL =
AL.addFnAttribute(
1359 AL =
AL.addRetAttribute(
C, Attribute::ZExt);
1361 Mod->getOrInsertFunction(
"__dfsan_union_load", DFSanUnionLoadFnTy, AL);
1365 AL =
AL.addFnAttribute(
C, Attribute::NoUnwind);
1366 AL =
AL.addFnAttribute(
1368 AL =
AL.addRetAttribute(
C, Attribute::ZExt);
1369 DFSanLoadLabelAndOriginFn =
Mod->getOrInsertFunction(
1370 "__dfsan_load_label_and_origin", DFSanLoadLabelAndOriginFnTy, AL);
1372 DFSanUnimplementedFn =
1373 Mod->getOrInsertFunction(
"__dfsan_unimplemented", DFSanUnimplementedFnTy);
1374 DFSanWrapperExternWeakNullFn =
Mod->getOrInsertFunction(
1375 "__dfsan_wrapper_extern_weak_null", DFSanWrapperExternWeakNullFnTy);
1378 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1379 AL =
AL.addParamAttribute(
M.getContext(), 1, Attribute::ZExt);
1381 Mod->getOrInsertFunction(
"__dfsan_set_label", DFSanSetLabelFnTy, AL);
1383 DFSanNonzeroLabelFn =
1384 Mod->getOrInsertFunction(
"__dfsan_nonzero_label", DFSanNonzeroLabelFnTy);
1385 DFSanVarargWrapperFn =
Mod->getOrInsertFunction(
"__dfsan_vararg_wrapper",
1386 DFSanVarargWrapperFnTy);
1389 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1390 AL =
AL.addRetAttribute(
M.getContext(), Attribute::ZExt);
1391 DFSanChainOriginFn =
Mod->getOrInsertFunction(
"__dfsan_chain_origin",
1392 DFSanChainOriginFnTy, AL);
1396 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1397 AL =
AL.addParamAttribute(
M.getContext(), 1, Attribute::ZExt);
1398 AL =
AL.addRetAttribute(
M.getContext(), Attribute::ZExt);
1399 DFSanChainOriginIfTaintedFn =
Mod->getOrInsertFunction(
1400 "__dfsan_chain_origin_if_tainted", DFSanChainOriginIfTaintedFnTy, AL);
1402 DFSanMemOriginTransferFn =
Mod->getOrInsertFunction(
1403 "__dfsan_mem_origin_transfer", DFSanMemOriginTransferFnTy);
1405 DFSanMemShadowOriginTransferFn =
Mod->getOrInsertFunction(
1406 "__dfsan_mem_shadow_origin_transfer", DFSanMemShadowOriginTransferFnTy);
1408 DFSanMemShadowOriginConditionalExchangeFn =
1409 Mod->getOrInsertFunction(
"__dfsan_mem_shadow_origin_conditional_exchange",
1410 DFSanMemShadowOriginConditionalExchangeFnTy);
1414 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1415 AL =
AL.addParamAttribute(
M.getContext(), 3, Attribute::ZExt);
1416 DFSanMaybeStoreOriginFn =
Mod->getOrInsertFunction(
1417 "__dfsan_maybe_store_origin", DFSanMaybeStoreOriginFnTy, AL);
1420 DFSanRuntimeFunctions.
insert(
1422 DFSanRuntimeFunctions.
insert(
1424 DFSanRuntimeFunctions.
insert(
1426 DFSanRuntimeFunctions.
insert(
1428 DFSanRuntimeFunctions.
insert(
1430 DFSanRuntimeFunctions.
insert(
1432 DFSanRuntimeFunctions.
insert(
1434 DFSanRuntimeFunctions.
insert(
1436 DFSanRuntimeFunctions.
insert(
1438 DFSanRuntimeFunctions.
insert(
1440 DFSanRuntimeFunctions.
insert(
1442 DFSanRuntimeFunctions.
insert(
1444 DFSanRuntimeFunctions.
insert(
1446 DFSanRuntimeFunctions.
insert(
1448 DFSanRuntimeFunctions.
insert(
1450 DFSanRuntimeFunctions.
insert(
1452 DFSanRuntimeFunctions.
insert(
1454 DFSanRuntimeFunctions.
insert(
1456 DFSanRuntimeFunctions.
insert(
1458 DFSanRuntimeFunctions.
insert(
1459 DFSanMemShadowOriginConditionalExchangeFn.
getCallee()
1461 DFSanRuntimeFunctions.
insert(
1466void DataFlowSanitizer::initializeCallbackFunctions(
Module &M) {
1469 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1470 DFSanLoadCallbackFn =
Mod->getOrInsertFunction(
1471 "__dfsan_load_callback", DFSanLoadStoreCallbackFnTy, AL);
1475 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1476 DFSanStoreCallbackFn =
Mod->getOrInsertFunction(
1477 "__dfsan_store_callback", DFSanLoadStoreCallbackFnTy, AL);
1479 DFSanMemTransferCallbackFn =
Mod->getOrInsertFunction(
1480 "__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
1483 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1484 DFSanCmpCallbackFn =
Mod->getOrInsertFunction(
"__dfsan_cmp_callback",
1485 DFSanCmpCallbackFnTy, AL);
1489 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1490 DFSanConditionalCallbackFn =
Mod->getOrInsertFunction(
1491 "__dfsan_conditional_callback", DFSanConditionalCallbackFnTy, AL);
1495 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1496 DFSanConditionalCallbackOriginFn =
1497 Mod->getOrInsertFunction(
"__dfsan_conditional_callback_origin",
1498 DFSanConditionalCallbackOriginFnTy, AL);
1502 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1503 DFSanReachesFunctionCallbackFn =
1504 Mod->getOrInsertFunction(
"__dfsan_reaches_function_callback",
1505 DFSanReachesFunctionCallbackFnTy, AL);
1509 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1510 DFSanReachesFunctionCallbackOriginFn =
1511 Mod->getOrInsertFunction(
"__dfsan_reaches_function_callback_origin",
1512 DFSanReachesFunctionCallbackOriginFnTy, AL);
1516bool DataFlowSanitizer::runImpl(
1517 Module &M, llvm::function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
1518 initializeModule(M);
1520 if (ABIList.isIn(M,
"skip"))
1523 const unsigned InitialGlobalSize =
M.global_size();
1524 const unsigned InitialModuleSize =
M.size();
1528 auto GetOrInsertGlobal = [
this, &
Changed](StringRef
Name,
1529 Type *Ty) -> Constant * {
1530 GlobalVariable *
G =
Mod->getOrInsertGlobal(Name, Ty);
1531 Changed |=
G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
1532 G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
1538 GetOrInsertGlobal(
"__dfsan_arg_tls",
1539 ArrayType::get(Type::getInt64Ty(*Ctx),
ArgTLSSize / 8));
1540 RetvalTLS = GetOrInsertGlobal(
1541 "__dfsan_retval_tls",
1543 ArgOriginTLSTy = ArrayType::get(OriginTy, NumOfElementsInArgOrgTLS);
1544 ArgOriginTLS = GetOrInsertGlobal(
"__dfsan_arg_origin_tls", ArgOriginTLSTy);
1545 RetvalOriginTLS = GetOrInsertGlobal(
"__dfsan_retval_origin_tls", OriginTy);
1547 (void)
Mod->getOrInsertGlobal(
"__dfsan_track_origins", OriginTy, [&] {
1549 return new GlobalVariable(
1550 M, OriginTy, true, GlobalValue::WeakODRLinkage,
1551 ConstantInt::getSigned(OriginTy,
1552 shouldTrackOrigins() ? ClTrackOrigins : 0),
1553 "__dfsan_track_origins");
1556 initializeCallbackFunctions(M);
1557 initializeRuntimeFunctions(M);
1559 std::vector<Function *> FnsToInstrument;
1560 SmallPtrSet<Function *, 2> FnsWithNativeABI;
1561 SmallPtrSet<Function *, 2> FnsWithForceZeroLabel;
1562 SmallPtrSet<Constant *, 1> PersonalityFns;
1563 for (Function &
F : M)
1564 if (!
F.isIntrinsic() && !DFSanRuntimeFunctions.
contains(&
F) &&
1565 !LibAtomicFunction(
F) &&
1566 !
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) {
1567 FnsToInstrument.push_back(&
F);
1568 if (
F.hasPersonalityFn())
1569 PersonalityFns.
insert(
F.getPersonalityFn()->stripPointerCasts());
1573 for (
auto *
C : PersonalityFns) {
1576 if (!isInstrumented(
F))
1590 bool GAInst = isInstrumented(&GA), FInst = isInstrumented(
F);
1591 if (GAInst && FInst) {
1592 addGlobalNameSuffix(&GA);
1593 }
else if (GAInst != FInst) {
1598 buildWrapperFunction(
F,
"", GA.
getLinkage(),
F->getFunctionType());
1602 FnsToInstrument.push_back(NewF);
1611 for (std::vector<Function *>::iterator FI = FnsToInstrument.begin(),
1612 FE = FnsToInstrument.end();
1615 FunctionType *FT =
F.getFunctionType();
1617 bool IsZeroArgsVoidRet = (FT->getNumParams() == 0 && !FT->isVarArg() &&
1618 FT->getReturnType()->isVoidTy());
1620 if (isInstrumented(&
F)) {
1621 if (isForceZeroLabels(&
F))
1622 FnsWithForceZeroLabel.
insert(&
F);
1627 addGlobalNameSuffix(&
F);
1628 }
else if (!IsZeroArgsVoidRet || getWrapperKind(&
F) == WK_Custom) {
1636 F.hasLocalLinkage() ?
F.getLinkage()
1639 Function *NewF = buildWrapperFunction(
1641 (shouldTrackOrigins() ? std::string(
"dfso$") : std::string(
"dfsw$")) +
1642 std::string(
F.getName()),
1643 WrapperLinkage, FT);
1663 auto IsNotCmpUse = [](
Use &
U) ->
bool {
1664 User *Usr =
U.getUser();
1667 if (
CE->getOpcode() == Instruction::ICmp) {
1672 if (
I->getOpcode() == Instruction::ICmp) {
1678 F.replaceUsesWithIf(NewF, IsNotCmpUse);
1680 UnwrappedFnMap[NewF] = &
F;
1683 if (!
F.isDeclaration()) {
1693 size_t N = FI - FnsToInstrument.begin(),
1694 Count = FE - FnsToInstrument.begin();
1695 FnsToInstrument.push_back(&
F);
1696 FI = FnsToInstrument.begin() +
N;
1697 FE = FnsToInstrument.begin() +
Count;
1701 }
else if (FT->isVarArg()) {
1702 UnwrappedFnMap[&
F] = &
F;
1707 for (Function *
F : FnsToInstrument) {
1708 if (!
F ||
F->isDeclaration())
1713 DFSanFunction DFSF(*
this,
F, FnsWithNativeABI.
count(
F),
1714 FnsWithForceZeroLabel.
count(
F), GetTLI(*
F));
1718 for (
auto &FArg :
F->args()) {
1720 Value *FArgShadow = DFSF.getShadow(&FArg);
1721 if (isZeroShadow(FArgShadow))
1724 Next = FArgShadowInst->getNextNode();
1726 if (shouldTrackOrigins()) {
1727 if (Instruction *Origin =
1731 if (
Next->comesBefore(OriginNext)) {
1737 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, *
Next, &FArg);
1745 for (BasicBlock *BB : BBList) {
1755 if (!DFSF.SkipInsts.
count(Inst))
1756 DFSanVisitor(DFSF).visit(Inst);
1767 for (DFSanFunction::PHIFixupElement &
P : DFSF.PHIFixups) {
1768 for (
unsigned Val = 0,
N =
P.Phi->getNumIncomingValues(); Val !=
N;
1770 P.ShadowPhi->setIncomingValue(
1771 Val, DFSF.getShadow(
P.Phi->getIncomingValue(Val)));
1773 P.OriginPhi->setIncomingValue(
1774 Val, DFSF.getOrigin(
P.Phi->getIncomingValue(Val)));
1783 for (
Value *V : DFSF.NonZeroChecks) {
1786 Pos = std::next(
I->getIterator());
1790 Pos = std::next(Pos->getIterator());
1792 Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(V, Pos);
1794 IRB.
CreateICmpNE(PrimitiveShadow, DFSF.DFS.ZeroPrimitiveShadow);
1796 Ne, Pos,
false, ColdCallWeights));
1798 ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn, {});
1803 return Changed || !FnsToInstrument.empty() ||
1804 M.global_size() != InitialGlobalSize ||
M.size() != InitialModuleSize;
1808 return IRB.
CreatePtrAdd(DFS.ArgTLS, ConstantInt::get(DFS.IntptrTy, ArgOffset),
1817Value *DFSanFunction::getRetvalOriginTLS() {
return DFS.RetvalOriginTLS; }
1821 ArgNo,
"_dfsarg_o");
1825 assert(DFS.shouldTrackOrigins());
1827 return DFS.ZeroOrigin;
1828 Value *&Origin = ValOriginMap[
V];
1832 return DFS.ZeroOrigin;
1833 if (
A->getArgNo() < DFS.NumOfElementsInArgOrgTLS) {
1834 Instruction *ArgOriginTLSPos = &*
F->getEntryBlock().begin();
1836 Value *ArgOriginPtr = getArgOriginTLS(
A->getArgNo(), IRB);
1837 Origin = IRB.
CreateLoad(DFS.OriginTy, ArgOriginPtr);
1840 Origin = DFS.ZeroOrigin;
1843 Origin = DFS.ZeroOrigin;
1849void DFSanFunction::setOrigin(Instruction *
I,
Value *Origin) {
1850 if (!DFS.shouldTrackOrigins())
1854 ValOriginMap[
I] = Origin;
1857Value *DFSanFunction::getShadowForTLSArgument(Argument *
A) {
1858 unsigned ArgOffset = 0;
1859 const DataLayout &
DL =
F->getDataLayout();
1860 for (
auto &FArg :
F->args()) {
1861 if (!FArg.getType()->isSized()) {
1867 unsigned Size =
DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
1880 Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
1885 return DFS.getZeroShadow(
A);
1890 return DFS.getZeroShadow(V);
1891 if (IsForceZeroLabels)
1892 return DFS.getZeroShadow(V);
1893 Value *&Shadow = ValShadowMap[
V];
1897 return DFS.getZeroShadow(V);
1898 Shadow = getShadowForTLSArgument(
A);
1899 NonZeroChecks.push_back(Shadow);
1901 Shadow = DFS.getZeroShadow(V);
1907void DFSanFunction::setShadow(Instruction *
I,
Value *Shadow) {
1909 ValShadowMap[
I] = Shadow;
1917 assert(Addr != RetvalTLS &&
"Reinstrumenting?");
1920 uint64_t AndMask = MapParams->AndMask;
1923 IRB.
CreateAnd(OffsetLong, ConstantInt::get(IntptrTy, ~AndMask));
1925 uint64_t XorMask = MapParams->XorMask;
1927 OffsetLong = IRB.
CreateXor(OffsetLong, ConstantInt::get(IntptrTy, XorMask));
1931std::pair<Value *, Value *>
1932DataFlowSanitizer::getShadowOriginAddress(
Value *Addr, Align InstAlignment,
1936 Value *ShadowOffset = getShadowOffset(Addr, IRB);
1937 Value *ShadowLong = ShadowOffset;
1938 uint64_t ShadowBase = MapParams->ShadowBase;
1939 if (ShadowBase != 0) {
1941 IRB.
CreateAdd(ShadowLong, ConstantInt::get(IntptrTy, ShadowBase));
1944 Value *OriginPtr =
nullptr;
1945 if (shouldTrackOrigins()) {
1946 Value *OriginLong = ShadowOffset;
1947 uint64_t OriginBase = MapParams->OriginBase;
1948 if (OriginBase != 0)
1950 IRB.
CreateAdd(OriginLong, ConstantInt::get(IntptrTy, OriginBase));
1956 OriginLong = IRB.
CreateAnd(OriginLong, ConstantInt::get(IntptrTy, ~Mask));
1960 return std::make_pair(ShadowPtr, OriginPtr);
1963Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1965 Value *ShadowOffset) {
1970Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1973 Value *ShadowAddr = getShadowOffset(Addr, IRB);
1974 uint64_t ShadowBase = MapParams->ShadowBase;
1975 if (ShadowBase != 0)
1977 IRB.
CreateAdd(ShadowAddr, ConstantInt::get(IntptrTy, ShadowBase));
1978 return getShadowAddress(Addr, Pos, ShadowAddr);
1983 Value *PrimitiveValue = combineShadows(
V1, V2, Pos);
1984 return expandFromPrimitiveShadow(
T, PrimitiveValue, Pos);
1991 if (DFS.isZeroShadow(
V1))
1992 return collapseToPrimitiveShadow(V2, Pos);
1993 if (DFS.isZeroShadow(V2))
1994 return collapseToPrimitiveShadow(
V1, Pos);
1996 return collapseToPrimitiveShadow(
V1, Pos);
1998 auto V1Elems = ShadowElements.
find(
V1);
1999 auto V2Elems = ShadowElements.
find(V2);
2000 if (V1Elems != ShadowElements.
end() && V2Elems != ShadowElements.
end()) {
2002 return collapseToPrimitiveShadow(
V1, Pos);
2005 return collapseToPrimitiveShadow(V2, Pos);
2007 }
else if (V1Elems != ShadowElements.
end()) {
2008 if (V1Elems->second.count(V2))
2009 return collapseToPrimitiveShadow(
V1, Pos);
2010 }
else if (V2Elems != ShadowElements.
end()) {
2011 if (V2Elems->second.count(
V1))
2012 return collapseToPrimitiveShadow(V2, Pos);
2015 auto Key = std::make_pair(
V1, V2);
2018 CachedShadow &CCS = CachedShadows[
Key];
2019 if (CCS.Block && DT.
dominates(CCS.Block, Pos->getParent()))
2023 Value *PV1 = collapseToPrimitiveShadow(
V1, Pos);
2024 Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
2027 CCS.Block = Pos->getParent();
2028 CCS.Shadow = IRB.
CreateOr(PV1, PV2);
2030 std::set<Value *> UnionElems;
2031 if (V1Elems != ShadowElements.
end()) {
2032 UnionElems = V1Elems->second;
2034 UnionElems.insert(
V1);
2036 if (V2Elems != ShadowElements.
end()) {
2037 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
2039 UnionElems.insert(V2);
2041 ShadowElements[CCS.Shadow] = std::move(UnionElems);
2049Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
2051 return DFS.getZeroShadow(Inst);
2055 Shadow = combineShadows(Shadow, getShadow(Inst->
getOperand(
I)),
2058 return expandFromPrimitiveShadow(Inst->
getType(), Shadow,
2062void DFSanVisitor::visitInstOperands(Instruction &
I) {
2063 Value *CombinedShadow = DFSF.combineOperandShadows(&
I);
2064 DFSF.setShadow(&
I, CombinedShadow);
2065 visitInstOperandOrigins(
I);
2068Value *DFSanFunction::combineOrigins(
const std::vector<Value *> &Shadows,
2069 const std::vector<Value *> &Origins,
2071 ConstantInt *Zero) {
2072 assert(Shadows.size() == Origins.size());
2073 size_t Size = Origins.size();
2075 return DFS.ZeroOrigin;
2076 Value *Origin =
nullptr;
2078 Zero = DFS.ZeroPrimitiveShadow;
2079 for (
size_t I = 0;
I !=
Size; ++
I) {
2080 Value *OpOrigin = Origins[
I];
2082 if (ConstOpOrigin && ConstOpOrigin->
isNullValue())
2088 Value *OpShadow = Shadows[
I];
2089 Value *PrimitiveShadow = collapseToPrimitiveShadow(OpShadow, Pos);
2094 return Origin ? Origin : DFS.ZeroOrigin;
2097Value *DFSanFunction::combineOperandOrigins(Instruction *Inst) {
2099 std::vector<Value *> Shadows(
Size);
2100 std::vector<Value *> Origins(
Size);
2101 for (
unsigned I = 0;
I !=
Size; ++
I) {
2105 return combineOrigins(Shadows, Origins, Inst->
getIterator());
2108void DFSanVisitor::visitInstOperandOrigins(Instruction &
I) {
2109 if (!DFSF.DFS.shouldTrackOrigins())
2111 Value *CombinedOrigin = DFSF.combineOperandOrigins(&
I);
2112 DFSF.setOrigin(&
I, CombinedOrigin);
2115Align DFSanFunction::getShadowAlign(Align InstAlignment) {
2117 return Align(Alignment.
value() * DFS.ShadowWidthBytes);
2120Align DFSanFunction::getOriginAlign(Align InstAlignment) {
2125bool DFSanFunction::isLookupTableConstant(
Value *
P) {
2127 if (GV->isConstant() && GV->
hasName())
2128 return DFS.CombineTaintLookupTableNames.
count(GV->
getName());
2133bool DFSanFunction::useCallbackLoadLabelAndOrigin(uint64_t
Size,
2134 Align InstAlignment) {
2158 Value **OriginAddr) {
2161 IRB.
CreateGEP(OriginTy, *OriginAddr, ConstantInt::get(IntptrTy, 1));
2165std::pair<Value *, Value *> DFSanFunction::loadShadowFast(
2166 Value *ShadowAddr,
Value *OriginAddr, uint64_t
Size, Align ShadowAlign,
2168 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2169 const uint64_t ShadowSize =
Size * DFS.ShadowWidthBytes;
2171 assert(
Size >= 4 &&
"Not large enough load size for fast path!");
2174 std::vector<Value *> Shadows;
2175 std::vector<Value *> Origins;
2188 Type *WideShadowTy =
2189 ShadowSize == 4 ? Type::getInt32Ty(*DFS.Ctx) :
Type::getInt64Ty(*DFS.Ctx);
2192 Value *CombinedWideShadow =
2196 const uint64_t BytesPerWideShadow = WideShadowBitWidth / DFS.ShadowWidthBits;
2198 auto AppendWideShadowAndOrigin = [&](
Value *WideShadow,
Value *Origin) {
2199 if (BytesPerWideShadow > 4) {
2200 assert(BytesPerWideShadow == 8);
2207 Value *WideShadowLo =
2208 F->getParent()->getDataLayout().isLittleEndian()
2211 ConstantInt::get(WideShadowTy, WideShadowBitWidth / 2))
2214 ConstantInt::get(WideShadowTy,
2215 (1 - (1 << (WideShadowBitWidth / 2)))
2216 << (WideShadowBitWidth / 2)));
2217 Shadows.push_back(WideShadow);
2218 Origins.push_back(DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr));
2220 Shadows.push_back(WideShadowLo);
2221 Origins.push_back(Origin);
2223 Shadows.push_back(WideShadow);
2224 Origins.push_back(Origin);
2228 if (ShouldTrackOrigins)
2229 AppendWideShadowAndOrigin(CombinedWideShadow, FirstOrigin);
2236 for (uint64_t ByteOfs = BytesPerWideShadow; ByteOfs <
Size;
2237 ByteOfs += BytesPerWideShadow) {
2238 ShadowAddr = IRB.
CreateGEP(WideShadowTy, ShadowAddr,
2239 ConstantInt::get(DFS.IntptrTy, 1));
2240 Value *NextWideShadow =
2242 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, NextWideShadow);
2243 if (ShouldTrackOrigins) {
2244 Value *NextOrigin = DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr);
2245 AppendWideShadowAndOrigin(NextWideShadow, NextOrigin);
2248 for (
unsigned Width = WideShadowBitWidth / 2; Width >= DFS.ShadowWidthBits;
2251 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, ShrShadow);
2253 return {IRB.
CreateTrunc(CombinedWideShadow, DFS.PrimitiveShadowTy),
2255 ? combineOrigins(Shadows, Origins, Pos,
2260std::pair<Value *, Value *> DFSanFunction::loadShadowOriginSansLoadTracking(
2262 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2266 const auto SI = AllocaShadowMap.
find(AI);
2267 if (SI != AllocaShadowMap.
end()) {
2270 const auto OI = AllocaOriginMap.
find(AI);
2271 assert(!ShouldTrackOrigins || OI != AllocaOriginMap.
end());
2272 return {ShadowLI, ShouldTrackOrigins
2279 SmallVector<const Value *, 2> Objs;
2281 bool AllConstants =
true;
2282 for (
const Value *Obj : Objs) {
2288 AllConstants =
false;
2292 return {DFS.ZeroPrimitiveShadow,
2293 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2296 return {DFS.ZeroPrimitiveShadow,
2297 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2301 if (ShouldTrackOrigins &&
2302 useCallbackLoadLabelAndOrigin(
Size, InstAlignment)) {
2305 IRB.
CreateCall(DFS.DFSanLoadLabelAndOriginFn,
2306 {Addr, ConstantInt::get(DFS.IntptrTy, Size)});
2309 DFS.PrimitiveShadowTy),
2314 Value *ShadowAddr, *OriginAddr;
2315 std::tie(ShadowAddr, OriginAddr) =
2316 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2318 const Align ShadowAlign = getShadowAlign(InstAlignment);
2319 const Align OriginAlign = getOriginAlign(InstAlignment);
2320 Value *Origin =
nullptr;
2321 if (ShouldTrackOrigins) {
2330 LoadInst *LI =
new LoadInst(DFS.PrimitiveShadowTy, ShadowAddr,
"", Pos);
2332 return {LI, Origin};
2336 Value *ShadowAddr1 = IRB.
CreateGEP(DFS.PrimitiveShadowTy, ShadowAddr,
2337 ConstantInt::get(DFS.IntptrTy, 1));
2342 return {combineShadows(Load, Load1, Pos), Origin};
2345 bool HasSizeForFastPath = DFS.hasLoadSizeForFastPath(
Size);
2347 if (HasSizeForFastPath)
2348 return loadShadowFast(ShadowAddr, OriginAddr,
Size, ShadowAlign,
2349 OriginAlign, Origin, Pos);
2353 DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
2355 return {FallbackCall, Origin};
2358std::pair<Value *, Value *>
2359DFSanFunction::loadShadowOrigin(
Value *Addr, uint64_t
Size, Align InstAlignment,
2361 Value *PrimitiveShadow, *Origin;
2362 std::tie(PrimitiveShadow, Origin) =
2363 loadShadowOriginSansLoadTracking(Addr,
Size, InstAlignment, Pos);
2364 if (DFS.shouldTrackOrigins()) {
2368 if (!ConstantShadow || !ConstantShadow->isNullValue())
2369 Origin = updateOriginIfTainted(PrimitiveShadow, Origin, IRB);
2372 return {PrimitiveShadow, Origin};
2393 if (!V->getType()->isPointerTy())
2402 V =
GEP->getPointerOperand();
2405 if (!V->getType()->isPointerTy())
2410 }
while (Visited.
insert(V).second);
2415void DFSanVisitor::visitLoadInst(LoadInst &LI) {
2419 DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
2420 DFSF.setOrigin(&LI, DFSF.DFS.ZeroOrigin);
2435 Pos = std::next(Pos);
2437 std::vector<Value *> Shadows;
2438 std::vector<Value *> Origins;
2439 Value *PrimitiveShadow, *Origin;
2440 std::tie(PrimitiveShadow, Origin) =
2442 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2443 if (ShouldTrackOrigins) {
2444 Shadows.push_back(PrimitiveShadow);
2445 Origins.push_back(Origin);
2448 DFSF.isLookupTableConstant(
2451 PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, Pos);
2452 if (ShouldTrackOrigins) {
2453 Shadows.push_back(PtrShadow);
2457 if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
2458 DFSF.NonZeroChecks.push_back(PrimitiveShadow);
2461 DFSF.expandFromPrimitiveShadow(LI.
getType(), PrimitiveShadow, Pos);
2462 DFSF.setShadow(&LI, Shadow);
2464 if (ShouldTrackOrigins) {
2465 DFSF.setOrigin(&LI, DFSF.combineOrigins(Shadows, Origins, Pos));
2472 IRB.
CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr});
2477 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, LI, &LI);
2480Value *DFSanFunction::updateOriginIfTainted(
Value *Shadow,
Value *Origin,
2482 assert(DFS.shouldTrackOrigins());
2483 return IRB.
CreateCall(DFS.DFSanChainOriginIfTaintedFn, {Shadow, Origin});
2487 if (!DFS.shouldTrackOrigins())
2489 return IRB.
CreateCall(DFS.DFSanChainOriginFn, V);
2493 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2494 const DataLayout &
DL =
F->getDataLayout();
2495 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2496 if (IntptrSize == OriginSize)
2498 assert(IntptrSize == OriginSize * 2);
2504 Value *StoreOriginAddr,
2505 uint64_t StoreOriginSize, Align Alignment) {
2506 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2507 const DataLayout &
DL =
F->getDataLayout();
2508 const Align IntptrAlignment =
DL.getABITypeAlign(DFS.IntptrTy);
2509 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2511 assert(IntptrSize >= OriginSize);
2514 Align CurrentAlignment = Alignment;
2515 if (Alignment >= IntptrAlignment && IntptrSize > OriginSize) {
2516 Value *IntptrOrigin = originToIntptr(IRB, Origin);
2517 Value *IntptrStoreOriginPtr =
2519 for (
unsigned I = 0;
I < StoreOriginSize / IntptrSize; ++
I) {
2522 : IntptrStoreOriginPtr;
2524 Ofs += IntptrSize / OriginSize;
2525 CurrentAlignment = IntptrAlignment;
2529 for (
unsigned I = Ofs;
I < (StoreOriginSize + OriginSize - 1) / OriginSize;
2539 const Twine &Name) {
2540 Type *VTy =
V->getType();
2545 return IRB.
CreateICmpNE(V, ConstantInt::get(VTy, 0), Name);
2550 Value *StoreOriginAddr, Align InstAlignment) {
2553 const Align OriginAlignment = getOriginAlign(InstAlignment);
2554 Value *CollapsedShadow = collapseToPrimitiveShadow(Shadow, Pos);
2557 if (!ConstantShadow->isNullValue())
2558 paintOrigin(IRB, updateOrigin(Origin, IRB), StoreOriginAddr,
Size,
2563 if (shouldInstrumentWithCall()) {
2565 DFS.DFSanMaybeStoreOriginFn,
2566 {CollapsedShadow, Addr, ConstantInt::get(DFS.IntptrTy, Size), Origin});
2568 Value *
Cmp = convertToBool(CollapsedShadow, IRB,
"_dfscmp");
2569 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
2571 Cmp, &*IRB.
GetInsertPoint(),
false, DFS.OriginStoreWeights, &DTU);
2573 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), StoreOriginAddr,
Size,
2579void DFSanFunction::storeZeroPrimitiveShadow(
Value *Addr, uint64_t
Size,
2583 IntegerType *ShadowTy =
2585 Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
2586 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
2592void DFSanFunction::storePrimitiveShadowOrigin(
Value *Addr, uint64_t
Size,
2593 Align InstAlignment,
2594 Value *PrimitiveShadow,
2597 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins() && Origin;
2600 const auto SI = AllocaShadowMap.
find(AI);
2601 if (SI != AllocaShadowMap.
end()) {
2607 if (ShouldTrackOrigins && !DFS.isZeroShadow(PrimitiveShadow)) {
2608 const auto OI = AllocaOriginMap.
find(AI);
2609 assert(OI != AllocaOriginMap.
end() && Origin);
2616 const Align ShadowAlign = getShadowAlign(InstAlignment);
2617 if (DFS.isZeroShadow(PrimitiveShadow)) {
2618 storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign, Pos);
2623 Value *ShadowAddr, *OriginAddr;
2624 std::tie(ShadowAddr, OriginAddr) =
2625 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2627 const unsigned ShadowVecSize = 8;
2628 assert(ShadowVecSize * DFS.ShadowWidthBits <= 128 &&
2629 "Shadow vector is too large!");
2632 uint64_t LeftSize =
Size;
2633 if (LeftSize >= ShadowVecSize) {
2637 for (
unsigned I = 0;
I != ShadowVecSize; ++
I) {
2639 ShadowVec, PrimitiveShadow,
2640 ConstantInt::get(Type::getInt32Ty(*DFS.Ctx),
I));
2643 Value *CurShadowVecAddr =
2646 LeftSize -= ShadowVecSize;
2648 }
while (LeftSize >= ShadowVecSize);
2651 while (LeftSize > 0) {
2652 Value *CurShadowAddr =
2659 if (ShouldTrackOrigins) {
2660 storeOrigin(Pos, Addr,
Size, PrimitiveShadow, Origin, OriginAddr,
2682void DFSanVisitor::visitStoreInst(StoreInst &SI) {
2683 auto &
DL =
SI.getDataLayout();
2684 Value *Val =
SI.getValueOperand();
2697 const bool ShouldTrackOrigins =
2698 DFSF.DFS.shouldTrackOrigins() && !
SI.isAtomic();
2699 std::vector<Value *> Shadows;
2700 std::vector<Value *> Origins;
2703 SI.isAtomic() ? DFSF.DFS.getZeroShadow(Val) : DFSF.getShadow(Val);
2705 if (ShouldTrackOrigins) {
2706 Shadows.push_back(Shadow);
2707 Origins.push_back(DFSF.getOrigin(Val));
2710 Value *PrimitiveShadow;
2712 Value *PtrShadow = DFSF.getShadow(
SI.getPointerOperand());
2713 if (ShouldTrackOrigins) {
2714 Shadows.push_back(PtrShadow);
2715 Origins.push_back(DFSF.getOrigin(
SI.getPointerOperand()));
2717 PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow,
SI.getIterator());
2719 PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow,
SI.getIterator());
2721 Value *Origin =
nullptr;
2722 if (ShouldTrackOrigins)
2723 Origin = DFSF.combineOrigins(Shadows, Origins,
SI.getIterator());
2724 DFSF.storePrimitiveShadowOrigin(
SI.getPointerOperand(),
Size,
SI.getAlign(),
2725 PrimitiveShadow, Origin,
SI.getIterator());
2728 Value *Addr =
SI.getPointerOperand();
2730 IRB.
CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr});
2735void DFSanVisitor::visitCASOrRMW(Align InstAlignment, Instruction &
I) {
2738 Value *Val =
I.getOperand(1);
2739 const auto &
DL =
I.getDataLayout();
2747 Value *Addr =
I.getOperand(0);
2748 const Align ShadowAlign = DFSF.getShadowAlign(InstAlignment);
2749 DFSF.storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign,
I.getIterator());
2750 DFSF.setShadow(&
I, DFSF.DFS.getZeroShadow(&
I));
2751 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2754void DFSanVisitor::visitAtomicRMWInst(AtomicRMWInst &
I) {
2755 visitCASOrRMW(
I.getAlign(),
I);
2761void DFSanVisitor::visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2762 visitCASOrRMW(
I.getAlign(),
I);
2768void DFSanVisitor::visitUnaryOperator(UnaryOperator &UO) {
2769 visitInstOperands(UO);
2772void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) {
2773 visitInstOperands(BO);
2776void DFSanVisitor::visitBitCastInst(BitCastInst &BCI) {
2783 visitInstOperands(BCI);
2786void DFSanVisitor::visitCastInst(CastInst &CI) { visitInstOperands(CI); }
2788void DFSanVisitor::visitCmpInst(CmpInst &CI) {
2789 visitInstOperands(CI);
2792 Value *CombinedShadow = DFSF.getShadow(&CI);
2794 IRB.
CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
2799void DFSanVisitor::visitLandingPadInst(LandingPadInst &LPI) {
2811 DFSF.setShadow(&LPI, DFSF.DFS.getZeroShadow(&LPI));
2812 DFSF.setOrigin(&LPI, DFSF.DFS.ZeroOrigin);
2815void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
2817 DFSF.isLookupTableConstant(
2819 visitInstOperands(GEPI);
2826 DFSF.setShadow(&GEPI, DFSF.getShadow(BasePointer));
2827 if (DFSF.DFS.shouldTrackOrigins())
2828 DFSF.setOrigin(&GEPI, DFSF.getOrigin(BasePointer));
2831void DFSanVisitor::visitExtractElementInst(ExtractElementInst &
I) {
2832 visitInstOperands(
I);
2835void DFSanVisitor::visitInsertElementInst(InsertElementInst &
I) {
2836 visitInstOperands(
I);
2839void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &
I) {
2840 visitInstOperands(
I);
2843void DFSanVisitor::visitExtractValueInst(ExtractValueInst &
I) {
2845 Value *Agg =
I.getAggregateOperand();
2846 Value *AggShadow = DFSF.getShadow(Agg);
2848 DFSF.setShadow(&
I, ResShadow);
2849 visitInstOperandOrigins(
I);
2852void DFSanVisitor::visitInsertValueInst(InsertValueInst &
I) {
2854 Value *AggShadow = DFSF.getShadow(
I.getAggregateOperand());
2855 Value *InsShadow = DFSF.getShadow(
I.getInsertedValueOperand());
2857 DFSF.setShadow(&
I, Res);
2858 visitInstOperandOrigins(
I);
2861void DFSanVisitor::visitAllocaInst(AllocaInst &
I) {
2862 bool AllLoadsStores =
true;
2863 for (User *U :
I.users()) {
2868 if (
SI->getPointerOperand() == &
I)
2872 AllLoadsStores =
false;
2875 if (AllLoadsStores) {
2877 DFSF.AllocaShadowMap[&
I] = IRB.
CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
2878 if (DFSF.DFS.shouldTrackOrigins()) {
2879 DFSF.AllocaOriginMap[&
I] =
2883 DFSF.setShadow(&
I, DFSF.DFS.ZeroPrimitiveShadow);
2884 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2887void DFSanVisitor::visitSelectInst(SelectInst &
I) {
2888 Value *CondShadow = DFSF.getShadow(
I.getCondition());
2889 Value *TrueShadow = DFSF.getShadow(
I.getTrueValue());
2890 Value *FalseShadow = DFSF.getShadow(
I.getFalseValue());
2891 Value *ShadowSel =
nullptr;
2892 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2893 std::vector<Value *> Shadows;
2894 std::vector<Value *> Origins;
2896 ShouldTrackOrigins ? DFSF.getOrigin(
I.getTrueValue()) :
nullptr;
2897 Value *FalseOrigin =
2898 ShouldTrackOrigins ? DFSF.getOrigin(
I.getFalseValue()) :
nullptr;
2900 DFSF.addConditionalCallbacksIfEnabled(
I,
I.getCondition());
2903 ShadowSel = DFSF.combineShadowsThenConvert(
I.getType(), TrueShadow,
2904 FalseShadow,
I.getIterator());
2905 if (ShouldTrackOrigins) {
2906 Shadows.push_back(TrueShadow);
2907 Shadows.push_back(FalseShadow);
2908 Origins.push_back(TrueOrigin);
2909 Origins.push_back(FalseOrigin);
2912 if (TrueShadow == FalseShadow) {
2913 ShadowSel = TrueShadow;
2914 if (ShouldTrackOrigins) {
2915 Shadows.push_back(TrueShadow);
2916 Origins.push_back(TrueOrigin);
2920 "",
I.getIterator());
2921 if (ShouldTrackOrigins) {
2922 Shadows.push_back(ShadowSel);
2924 FalseOrigin,
"",
I.getIterator()));
2929 I.getType(), CondShadow,
2930 ShadowSel,
I.getIterator())
2932 if (ShouldTrackOrigins) {
2934 Shadows.push_back(CondShadow);
2935 Origins.push_back(DFSF.getOrigin(
I.getCondition()));
2937 DFSF.setOrigin(&
I, DFSF.combineOrigins(Shadows, Origins,
I.getIterator()));
2941void DFSanVisitor::visitMemSetInst(MemSetInst &
I) {
2943 Value *ValShadow = DFSF.getShadow(
I.getValue());
2944 Value *ValOrigin = DFSF.DFS.shouldTrackOrigins()
2945 ? DFSF.getOrigin(
I.getValue())
2946 : DFSF.DFS.ZeroOrigin;
2948 {ValShadow, ValOrigin, I.getDest(),
2949 IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2952void DFSanVisitor::visitMemTransferInst(MemTransferInst &
I) {
2957 if (DFSF.DFS.shouldTrackOrigins()) {
2959 DFSF.DFS.DFSanMemOriginTransferFn,
2960 {I.getArgOperand(0), I.getArgOperand(1),
2961 IRB.CreateIntCast(I.getArgOperand(2), DFSF.DFS.IntptrTy, false)});
2964 Value *DestShadow = DFSF.DFS.getShadowAddress(
I.getDest(),
I.getIterator());
2965 Value *SrcShadow = DFSF.DFS.getShadowAddress(
I.getSource(),
I.getIterator());
2967 IRB.
CreateMul(
I.getLength(), ConstantInt::get(
I.getLength()->getType(),
2968 DFSF.DFS.ShadowWidthBytes));
2970 IRB.
CreateCall(
I.getFunctionType(),
I.getCalledOperand(),
2971 {DestShadow, SrcShadow, LenShadow, I.getVolatileCst()}));
2972 MTI->setDestAlignment(DFSF.getShadowAlign(
I.getDestAlign().valueOrOne()));
2973 MTI->setSourceAlignment(DFSF.getShadowAlign(
I.getSourceAlign().valueOrOne()));
2976 DFSF.DFS.DFSanMemTransferCallbackFn,
2977 {DestShadow, IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2981void DFSanVisitor::visitCondBrInst(CondBrInst &BR) {
2982 DFSF.addConditionalCallbacksIfEnabled(BR,
BR.getCondition());
2985void DFSanVisitor::visitSwitchInst(SwitchInst &SW) {
2986 DFSF.addConditionalCallbacksIfEnabled(SW, SW.
getCondition());
2992 RetVal =
I->getOperand(0);
2995 return I->isMustTailCall();
3000void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
3009 unsigned Size = getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
3015 if (DFSF.DFS.shouldTrackOrigins()) {
3022void DFSanVisitor::addShadowArguments(Function &
F, CallBase &CB,
3023 std::vector<Value *> &Args,
3025 FunctionType *FT =
F.getFunctionType();
3030 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
3032 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()));
3035 if (FT->isVarArg()) {
3036 auto *LabelVATy = ArrayType::get(DFSF.DFS.PrimitiveShadowTy,
3037 CB.
arg_size() - FT->getNumParams());
3038 auto *LabelVAAlloca =
3039 new AllocaInst(LabelVATy, getDataLayout().getAllocaAddrSpace(),
3042 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
3045 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()),
3053 if (!FT->getReturnType()->isVoidTy()) {
3054 if (!DFSF.LabelReturnAlloca) {
3055 DFSF.LabelReturnAlloca =
new AllocaInst(
3056 DFSF.DFS.PrimitiveShadowTy, getDataLayout().getAllocaAddrSpace(),
3059 Args.push_back(DFSF.LabelReturnAlloca);
3063void DFSanVisitor::addOriginArguments(Function &
F, CallBase &CB,
3064 std::vector<Value *> &Args,
3066 FunctionType *FT =
F.getFunctionType();
3071 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
3072 Args.push_back(DFSF.getOrigin(*
I));
3075 if (FT->isVarArg()) {
3077 ArrayType::get(DFSF.DFS.OriginTy, CB.
arg_size() - FT->getNumParams());
3078 auto *OriginVAAlloca =
3079 new AllocaInst(OriginVATy, getDataLayout().getAllocaAddrSpace(),
3082 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
3091 if (!FT->getReturnType()->isVoidTy()) {
3092 if (!DFSF.OriginReturnAlloca) {
3093 DFSF.OriginReturnAlloca =
new AllocaInst(
3094 DFSF.DFS.OriginTy, getDataLayout().getAllocaAddrSpace(),
3097 Args.push_back(DFSF.OriginReturnAlloca);
3101bool DFSanVisitor::visitWrappedCallBase(Function &
F, CallBase &CB) {
3103 switch (DFSF.DFS.getWrapperKind(&
F)) {
3104 case DataFlowSanitizer::WK_Warning:
3106 IRB.
CreateCall(DFSF.DFS.DFSanUnimplementedFn,
3108 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3109 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3110 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3112 case DataFlowSanitizer::WK_Discard:
3114 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3115 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3116 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3118 case DataFlowSanitizer::WK_Functional:
3120 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3121 visitInstOperands(CB);
3123 case DataFlowSanitizer::WK_Custom:
3131 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3132 FunctionType *FT =
F.getFunctionType();
3133 TransformedFunction CustomFn = DFSF.DFS.getCustomFunctionType(FT);
3134 std::string CustomFName = ShouldTrackOrigins ?
"__dfso_" :
"__dfsw_";
3135 CustomFName +=
F.getName();
3137 CustomFName, CustomFn.TransformedType);
3139 CustomFn->copyAttributesFrom(&
F);
3142 if (!FT->getReturnType()->isVoidTy()) {
3143 CustomFn->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
3147 std::vector<Value *>
Args;
3151 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N) {
3156 const unsigned ShadowArgStart =
Args.size();
3157 addShadowArguments(
F, CB, Args, IRB);
3160 const unsigned OriginArgStart =
Args.size();
3161 if (ShouldTrackOrigins)
3162 addOriginArguments(
F, CB, Args, IRB);
3167 CallInst *CustomCI = IRB.
CreateCall(CustomF, Args);
3175 for (
unsigned N = 0;
N < FT->getNumParams();
N++) {
3176 const unsigned ArgNo = ShadowArgStart +
N;
3178 DFSF.DFS.PrimitiveShadowTy)
3180 if (ShouldTrackOrigins) {
3181 const unsigned OriginArgNo = OriginArgStart +
N;
3189 if (!FT->getReturnType()->isVoidTy()) {
3190 LoadInst *LabelLoad =
3191 IRB.
CreateLoad(DFSF.DFS.PrimitiveShadowTy, DFSF.LabelReturnAlloca);
3192 DFSF.setShadow(CustomCI,
3193 DFSF.expandFromPrimitiveShadow(
3194 FT->getReturnType(), LabelLoad, CB.
getIterator()));
3195 if (ShouldTrackOrigins) {
3196 LoadInst *OriginLoad =
3197 IRB.
CreateLoad(DFSF.DFS.OriginTy, DFSF.OriginReturnAlloca);
3198 DFSF.setOrigin(CustomCI, OriginLoad);
3210 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3211 uint32_t OrderingTable[NumOrderings] = {};
3213 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3214 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3215 OrderingTable[(int)AtomicOrderingCABI::consume] =
3216 (
int)AtomicOrderingCABI::acquire;
3217 OrderingTable[(int)AtomicOrderingCABI::release] =
3218 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
3219 (int)AtomicOrderingCABI::acq_rel;
3220 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3221 (
int)AtomicOrderingCABI::seq_cst;
3226void DFSanVisitor::visitLibAtomicLoad(CallBase &CB) {
3237 Value *NewOrdering =
3242 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3248 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3249 {DstPtr, SrcPtr, NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3253 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3254 uint32_t OrderingTable[NumOrderings] = {};
3256 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3257 OrderingTable[(
int)AtomicOrderingCABI::release] =
3258 (int)AtomicOrderingCABI::release;
3259 OrderingTable[(int)AtomicOrderingCABI::consume] =
3260 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3261 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
3262 (
int)AtomicOrderingCABI::acq_rel;
3263 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3264 (
int)AtomicOrderingCABI::seq_cst;
3269void DFSanVisitor::visitLibAtomicStore(CallBase &CB) {
3277 Value *NewOrdering =
3285 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3286 {DstPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3289void DFSanVisitor::visitLibAtomicExchange(CallBase &CB) {
3305 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3306 {DstPtr, TargetPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3310 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3311 {TargetPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3314void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
3328 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3330 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3334 NextIRB.CreateCall(DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
3335 {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false),
3336 TargetPtr, ExpectedPtr, DesiredPtr,
3337 NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3340void DFSanVisitor::visitCallBase(CallBase &CB) {
3343 visitInstOperands(CB);
3358 case LibFunc_atomic_load:
3360 llvm::errs() <<
"DFSAN -- cannot instrument invoke of libatomic load. "
3364 visitLibAtomicLoad(CB);
3366 case LibFunc_atomic_store:
3367 visitLibAtomicStore(CB);
3375 if (
F &&
F->hasName() && !
F->isVarArg()) {
3376 if (
F->getName() ==
"__atomic_exchange") {
3377 visitLibAtomicExchange(CB);
3380 if (
F->getName() ==
"__atomic_compare_exchange") {
3381 visitLibAtomicCompareExchange(CB);
3387 if (UnwrappedFnIt != DFSF.DFS.UnwrappedFnMap.end())
3388 if (visitWrappedCallBase(*UnwrappedFnIt->second, CB))
3393 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3395 const DataLayout &
DL = getDataLayout();
3398 unsigned ArgOffset = 0;
3399 for (
unsigned I = 0,
N = FT->getNumParams();
I !=
N; ++
I) {
3400 if (ShouldTrackOrigins) {
3403 if (
I < DFSF.DFS.NumOfElementsInArgOrgTLS &&
3404 !DFSF.DFS.isZeroShadow(ArgShadow))
3406 DFSF.getArgOriginTLS(
I, IRB));
3410 DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(
I)));
3416 DFSF.getArgTLS(FT->getParamType(
I), ArgOffset, IRB),
3424 if (
II->getNormalDest()->getSinglePredecessor()) {
3425 Next = &
II->getNormalDest()->front();
3442 unsigned Size =
DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
3445 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3447 LoadInst *LI = NextIRB.CreateAlignedLoad(
3448 DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.
getType(), NextIRB),
3450 DFSF.SkipInsts.
insert(LI);
3451 DFSF.setShadow(&CB, LI);
3452 DFSF.NonZeroChecks.push_back(LI);
3455 if (ShouldTrackOrigins) {
3456 LoadInst *LI = NextIRB.CreateLoad(DFSF.DFS.OriginTy,
3457 DFSF.getRetvalOriginTLS(),
"_dfsret_o");
3458 DFSF.SkipInsts.
insert(LI);
3459 DFSF.setOrigin(&CB, LI);
3462 DFSF.addReachesFunctionCallbacksIfEnabled(NextIRB, CB, &CB);
3466void DFSanVisitor::visitPHINode(PHINode &PN) {
3467 Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
3473 for (BasicBlock *BB : PN.
blocks())
3476 DFSF.setShadow(&PN, ShadowPN);
3478 PHINode *OriginPN =
nullptr;
3479 if (DFSF.DFS.shouldTrackOrigins()) {
3483 for (BasicBlock *BB : PN.
blocks())
3485 DFSF.setOrigin(&PN, OriginPN);
3488 DFSF.PHIFixups.push_back({&PN, ShadowPN, OriginPN});
3501 if (!DataFlowSanitizer(ABIListFiles, FS).
runImpl(M, GetTLI))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isConstant(const MachineInstr &MI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static bool runImpl(MachineFunction &MF)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const MemoryMapParams Linux_LoongArch64_MemoryMapParams
const MemoryMapParams Linux_X86_64_MemoryMapParams
static cl::opt< bool > ClAddGlobalNameSuffix("dfsan-add-global-name-suffix", cl::desc("Whether to add .dfsan suffix to global names"), cl::Hidden, cl::init(true))
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))
static cl::list< std::string > ClCombineTaintLookupTables("dfsan-combine-taint-lookup-table", cl::desc("When dfsan-combine-offset-labels-on-gep and/or " "dfsan-combine-pointer-labels-on-load are false, this flag can " "be used to re-enable combining offset and/or pointer taint when " "loading specific constant global variables (i.e. lookup tables)."), cl::Hidden)
static const Align MinOriginAlignment
static cl::opt< int > ClTrackOrigins("dfsan-track-origins", cl::desc("Track origins of labels"), cl::Hidden, cl::init(0))
static cl::list< std::string > ClABIListFiles("dfsan-abilist", cl::desc("File listing native ABI functions and how the pass treats them"), cl::Hidden)
static cl::opt< bool > ClReachesFunctionCallbacks("dfsan-reaches-function-callbacks", cl::desc("Insert calls to callback functions on data reaching a function."), cl::Hidden, cl::init(false))
static Value * expandFromPrimitiveShadowRecursive(Value *Shadow, SmallVector< unsigned, 4 > &Indices, Type *SubShadowTy, Value *PrimitiveShadow, IRBuilder<> &IRB)
static cl::opt< int > ClInstrumentWithCallThreshold("dfsan-instrument-with-call-threshold", cl::desc("If the function being instrumented requires more than " "this number of origin stores, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(3500))
static cl::opt< bool > ClPreserveAlignment("dfsan-preserve-alignment", cl::desc("respect alignment requirements provided by input IR"), cl::Hidden, cl::init(false))
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)
static cl::opt< bool > ClCombineOffsetLabelsOnGEP("dfsan-combine-offset-labels-on-gep", cl::desc("Combine the label of the offset with the label of the pointer when " "doing pointer arithmetic."), cl::Hidden, cl::init(true))
static cl::opt< bool > ClIgnorePersonalityRoutine("dfsan-ignore-personality-routine", cl::desc("If a personality routine is marked uninstrumented from the ABI " "list, do not create a wrapper for it."), cl::Hidden, cl::init(false))
static const Align ShadowTLSAlignment
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_S390X_MemoryMapParams
static AtomicOrdering addAcquireOrdering(AtomicOrdering AO)
Value * StripPointerGEPsAndCasts(Value *V)
const MemoryMapParams Linux_AArch64_MemoryMapParams
static cl::opt< bool > ClConditionalCallbacks("dfsan-conditional-callbacks", cl::desc("Insert calls to callback functions on conditionals."), cl::Hidden, cl::init(false))
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))
static StringRef getGlobalTypeString(const GlobalValue &G)
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))
static const unsigned ArgTLSSize
static const unsigned RetvalTLSSize
static bool isAMustTailRetVal(Value *RetVal)
static cl::opt< bool > ClEventCallbacks("dfsan-event-callbacks", cl::desc("Insert calls to __dfsan_*_callback functions on data events."), cl::Hidden, cl::init(false))
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
This is the interface for a simple mod/ref and alias analysis over globals.
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
Machine Check Debug Module
uint64_t IntrinsicInst * II
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
FunctionAnalysisManager FAM
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
StringSet - A set-like wrapper for the StringMap.
Defines the virtual file system interface vfs::FileSystem.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
iterator begin()
Instruction iterator methods.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Instruction & front() const
InstListType::iterator iterator
Instruction iterators...
bool isInlineAsm() const
Check if this call is an inline asm statement.
void setCallingConv(CallingConv::ID CC)
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
CallingConv::ID getCallingConv() const
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Value * getCalledOperand() const
void setAttributes(AttributeList A)
Set the attributes for this call.
void addRetAttr(Attribute::AttrKind Kind)
Adds the attribute to the return value.
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
FunctionType * getFunctionType() const
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned arg_size() const
AttributeList getAttributes() const
Return the attributes for this call.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
void setCalledFunction(Function *Fn)
Sets the function called, including updating the function type.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
bool isMustTailCall() const
static LLVM_ABI ConstantAggregateZero * get(Type *Ty)
static LLVM_ABI Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
static ConstantInt * getSigned(IntegerType *Ty, int64_t V, bool ImplicitTrunc=false)
Return a ConstantInt with the specified value for the specified type.
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI unsigned getLine() const
DILocation * get() const
Get the underlying DILocation.
iterator find(const_arg_type_t< KeyT > Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Type * getReturnType() const
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
const BasicBlock & getEntryBlock() const
FunctionType * getFunctionType() const
Returns the FunctionType for me.
void removeFnAttrs(const AttributeMask &Attrs)
AttributeList getAttributes() const
Return the attribute list for this Function.
void removeFnAttr(Attribute::AttrKind Kind)
Remove function attributes from this function.
void removeRetAttrs(const AttributeMask &Attrs)
removes the attributes from the return value list of attributes.
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
Value * getPointerOperand()
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
LLVM_ABI const GlobalObject * getAliaseeObject() const
static bool isExternalWeakLinkage(LinkageTypes Linkage)
LinkageTypes getLinkage() const
Module * getParent()
Get the module that this global value is contained inside of...
LinkageTypes
An enumeration for the kinds of linkage for global values.
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Type * getValueType() const
Analysis pass providing a never-invalidated alias analysis result.
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
LLVM_ABI Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
BasicBlock::iterator GetInsertPoint() const
Value * CreateStructGEP(Type *Ty, Value *Ptr, unsigned Idx, const Twine &Name="")
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
LLVMContext & getContext() const
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateConstInBoundsGEP2_64(Type *Ty, Value *Ptr, uint64_t Idx0, uint64_t Idx1, const Twine &Name="")
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
LLVM_ABI GlobalVariable * CreateGlobalString(StringRef Str, const Twine &Name="", unsigned AddressSpace=0, Module *M=nullptr, bool AddNull=true)
Make a new global variable with initializer type i8*.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Base class for instruction visitors.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
bool isTerminator() const
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this instruction belongs to.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
This is an important class for using LLVM in a threaded context.
void setAlignment(Align Align)
Value * getPointerOperand()
void setOrdering(AtomicOrdering Ordering)
Sets the ordering constraint of this load instruction.
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
Align getAlign() const
Return the alignment of the access that is being performed.
static MemoryEffectsBase readOnly()
A Module instance is used to store all the information related to an LLVM module.
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
ArrayRef< GlobalAsmFragment > getModuleInlineAsm() const
Get any module-scope inline assembly blocks.
unsigned getOpcode() const
Return the opcode for this Instruction or ConstantExpr.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
iterator_range< const_block_iterator > blocks() const
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static LLVM_ABI std::unique_ptr< SpecialCaseList > createOrDie(const std::vector< std::string > &Paths, llvm::vfs::FileSystem &FS)
Parses the special case list entries from files.
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Represent a constant reference to a string, i.e.
void insert_range(Range &&R)
Class to represent struct types.
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Value * getCondition() const
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getIntegerBitWidth() const
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
const ParentTy * getParent() const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ C
The default llvm calling convention, compatible with C.
@ BR
Control flow instructions. These all have token chains.
@ BasicBlock
Various leaf nodes.
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
bool includes(R1 &&Range1, R2 &&Range2)
Provide wrappers to std::includes which take ranges instead of having to pass begin/end explicitly.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
iterator_range< df_iterator< T > > depth_first(const T &G)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
LLVM_ABI 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...
LLVM_ABI void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=MaxLookupSearchDepth)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.