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 visitBranchInst(BranchInst &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";
1287 std::string SearchStr =
".symver " + GVName +
",";
1288 size_t Pos =
Asm.find(SearchStr);
1289 if (Pos != std::string::npos) {
1290 Asm.replace(Pos, SearchStr.size(),
".symver " + GVName + Suffix +
",");
1291 Pos =
Asm.find(
'@');
1293 if (Pos == std::string::npos)
1296 Asm.replace(Pos, 1, Suffix +
"@");
1301void DataFlowSanitizer::buildExternWeakCheckIfNeeded(
IRBuilder<> &IRB,
1311 std::vector<Value *>
Args;
1314 IRB.
CreateCall(DFSanWrapperExternWeakNullFn, Args);
1319DataFlowSanitizer::buildWrapperFunction(Function *
F, StringRef NewFName,
1321 FunctionType *NewFT) {
1322 FunctionType *FT =
F->getFunctionType();
1324 NewFName,
F->getParent());
1327 NewFT->getReturnType(), NewF->
getAttributes().getRetAttrs()));
1330 if (
F->isVarArg()) {
1333 IRBuilder<>(BB).CreateGlobalString(
F->getName()),
"", BB);
1334 new UnreachableInst(*Ctx, BB);
1336 auto ArgIt = pointer_iterator<Argument *>(NewF->
arg_begin());
1337 std::vector<Value *>
Args(ArgIt, ArgIt + FT->getNumParams());
1340 if (FT->getReturnType()->isVoidTy())
1350void DataFlowSanitizer::initializeRuntimeFunctions(
Module &M) {
1351 LLVMContext &
C =
M.getContext();
1354 AL =
AL.addFnAttribute(
C, Attribute::NoUnwind);
1355 AL =
AL.addFnAttribute(
1357 AL =
AL.addRetAttribute(
C, Attribute::ZExt);
1359 Mod->getOrInsertFunction(
"__dfsan_union_load", DFSanUnionLoadFnTy, AL);
1363 AL =
AL.addFnAttribute(
C, Attribute::NoUnwind);
1364 AL =
AL.addFnAttribute(
1366 AL =
AL.addRetAttribute(
C, Attribute::ZExt);
1367 DFSanLoadLabelAndOriginFn =
Mod->getOrInsertFunction(
1368 "__dfsan_load_label_and_origin", DFSanLoadLabelAndOriginFnTy, AL);
1370 DFSanUnimplementedFn =
1371 Mod->getOrInsertFunction(
"__dfsan_unimplemented", DFSanUnimplementedFnTy);
1372 DFSanWrapperExternWeakNullFn =
Mod->getOrInsertFunction(
1373 "__dfsan_wrapper_extern_weak_null", DFSanWrapperExternWeakNullFnTy);
1376 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1377 AL =
AL.addParamAttribute(
M.getContext(), 1, Attribute::ZExt);
1379 Mod->getOrInsertFunction(
"__dfsan_set_label", DFSanSetLabelFnTy, AL);
1381 DFSanNonzeroLabelFn =
1382 Mod->getOrInsertFunction(
"__dfsan_nonzero_label", DFSanNonzeroLabelFnTy);
1383 DFSanVarargWrapperFn =
Mod->getOrInsertFunction(
"__dfsan_vararg_wrapper",
1384 DFSanVarargWrapperFnTy);
1387 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1388 AL =
AL.addRetAttribute(
M.getContext(), Attribute::ZExt);
1389 DFSanChainOriginFn =
Mod->getOrInsertFunction(
"__dfsan_chain_origin",
1390 DFSanChainOriginFnTy, AL);
1394 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1395 AL =
AL.addParamAttribute(
M.getContext(), 1, Attribute::ZExt);
1396 AL =
AL.addRetAttribute(
M.getContext(), Attribute::ZExt);
1397 DFSanChainOriginIfTaintedFn =
Mod->getOrInsertFunction(
1398 "__dfsan_chain_origin_if_tainted", DFSanChainOriginIfTaintedFnTy, AL);
1400 DFSanMemOriginTransferFn =
Mod->getOrInsertFunction(
1401 "__dfsan_mem_origin_transfer", DFSanMemOriginTransferFnTy);
1403 DFSanMemShadowOriginTransferFn =
Mod->getOrInsertFunction(
1404 "__dfsan_mem_shadow_origin_transfer", DFSanMemShadowOriginTransferFnTy);
1406 DFSanMemShadowOriginConditionalExchangeFn =
1407 Mod->getOrInsertFunction(
"__dfsan_mem_shadow_origin_conditional_exchange",
1408 DFSanMemShadowOriginConditionalExchangeFnTy);
1412 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1413 AL =
AL.addParamAttribute(
M.getContext(), 3, Attribute::ZExt);
1414 DFSanMaybeStoreOriginFn =
Mod->getOrInsertFunction(
1415 "__dfsan_maybe_store_origin", DFSanMaybeStoreOriginFnTy, AL);
1418 DFSanRuntimeFunctions.
insert(
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(
1457 DFSanMemShadowOriginConditionalExchangeFn.
getCallee()
1459 DFSanRuntimeFunctions.
insert(
1464void DataFlowSanitizer::initializeCallbackFunctions(
Module &M) {
1467 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1468 DFSanLoadCallbackFn =
Mod->getOrInsertFunction(
1469 "__dfsan_load_callback", DFSanLoadStoreCallbackFnTy, AL);
1473 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1474 DFSanStoreCallbackFn =
Mod->getOrInsertFunction(
1475 "__dfsan_store_callback", DFSanLoadStoreCallbackFnTy, AL);
1477 DFSanMemTransferCallbackFn =
Mod->getOrInsertFunction(
1478 "__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
1481 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1482 DFSanCmpCallbackFn =
Mod->getOrInsertFunction(
"__dfsan_cmp_callback",
1483 DFSanCmpCallbackFnTy, AL);
1487 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1488 DFSanConditionalCallbackFn =
Mod->getOrInsertFunction(
1489 "__dfsan_conditional_callback", DFSanConditionalCallbackFnTy, AL);
1493 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1494 DFSanConditionalCallbackOriginFn =
1495 Mod->getOrInsertFunction(
"__dfsan_conditional_callback_origin",
1496 DFSanConditionalCallbackOriginFnTy, AL);
1500 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1501 DFSanReachesFunctionCallbackFn =
1502 Mod->getOrInsertFunction(
"__dfsan_reaches_function_callback",
1503 DFSanReachesFunctionCallbackFnTy, AL);
1507 AL =
AL.addParamAttribute(
M.getContext(), 0, Attribute::ZExt);
1508 DFSanReachesFunctionCallbackOriginFn =
1509 Mod->getOrInsertFunction(
"__dfsan_reaches_function_callback_origin",
1510 DFSanReachesFunctionCallbackOriginFnTy, AL);
1514bool DataFlowSanitizer::runImpl(
1515 Module &M, llvm::function_ref<TargetLibraryInfo &(Function &)> GetTLI) {
1516 initializeModule(M);
1518 if (ABIList.isIn(M,
"skip"))
1521 const unsigned InitialGlobalSize =
M.global_size();
1522 const unsigned InitialModuleSize =
M.size();
1526 auto GetOrInsertGlobal = [
this, &
Changed](StringRef
Name,
1527 Type *Ty) -> Constant * {
1528 GlobalVariable *
G =
Mod->getOrInsertGlobal(Name, Ty);
1529 Changed |=
G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
1530 G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
1536 GetOrInsertGlobal(
"__dfsan_arg_tls",
1537 ArrayType::get(Type::getInt64Ty(*Ctx),
ArgTLSSize / 8));
1538 RetvalTLS = GetOrInsertGlobal(
1539 "__dfsan_retval_tls",
1541 ArgOriginTLSTy = ArrayType::get(OriginTy, NumOfElementsInArgOrgTLS);
1542 ArgOriginTLS = GetOrInsertGlobal(
"__dfsan_arg_origin_tls", ArgOriginTLSTy);
1543 RetvalOriginTLS = GetOrInsertGlobal(
"__dfsan_retval_origin_tls", OriginTy);
1545 (void)
Mod->getOrInsertGlobal(
"__dfsan_track_origins", OriginTy, [&] {
1547 return new GlobalVariable(
1548 M, OriginTy, true, GlobalValue::WeakODRLinkage,
1549 ConstantInt::getSigned(OriginTy,
1550 shouldTrackOrigins() ? ClTrackOrigins : 0),
1551 "__dfsan_track_origins");
1554 initializeCallbackFunctions(M);
1555 initializeRuntimeFunctions(M);
1557 std::vector<Function *> FnsToInstrument;
1558 SmallPtrSet<Function *, 2> FnsWithNativeABI;
1559 SmallPtrSet<Function *, 2> FnsWithForceZeroLabel;
1560 SmallPtrSet<Constant *, 1> PersonalityFns;
1561 for (Function &
F : M)
1562 if (!
F.isIntrinsic() && !DFSanRuntimeFunctions.
contains(&
F) &&
1563 !LibAtomicFunction(
F) &&
1564 !
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) {
1565 FnsToInstrument.push_back(&
F);
1566 if (
F.hasPersonalityFn())
1567 PersonalityFns.
insert(
F.getPersonalityFn()->stripPointerCasts());
1571 for (
auto *
C : PersonalityFns) {
1574 if (!isInstrumented(
F))
1588 bool GAInst = isInstrumented(&GA), FInst = isInstrumented(
F);
1589 if (GAInst && FInst) {
1590 addGlobalNameSuffix(&GA);
1591 }
else if (GAInst != FInst) {
1596 buildWrapperFunction(
F,
"", GA.
getLinkage(),
F->getFunctionType());
1600 FnsToInstrument.push_back(NewF);
1609 for (std::vector<Function *>::iterator FI = FnsToInstrument.begin(),
1610 FE = FnsToInstrument.end();
1613 FunctionType *FT =
F.getFunctionType();
1615 bool IsZeroArgsVoidRet = (FT->getNumParams() == 0 && !FT->isVarArg() &&
1616 FT->getReturnType()->isVoidTy());
1618 if (isInstrumented(&
F)) {
1619 if (isForceZeroLabels(&
F))
1620 FnsWithForceZeroLabel.
insert(&
F);
1625 addGlobalNameSuffix(&
F);
1626 }
else if (!IsZeroArgsVoidRet || getWrapperKind(&
F) == WK_Custom) {
1634 F.hasLocalLinkage() ?
F.getLinkage()
1637 Function *NewF = buildWrapperFunction(
1639 (shouldTrackOrigins() ? std::string(
"dfso$") : std::string(
"dfsw$")) +
1640 std::string(
F.getName()),
1641 WrapperLinkage, FT);
1661 auto IsNotCmpUse = [](
Use &
U) ->
bool {
1662 User *Usr =
U.getUser();
1665 if (
CE->getOpcode() == Instruction::ICmp) {
1670 if (
I->getOpcode() == Instruction::ICmp) {
1676 F.replaceUsesWithIf(NewF, IsNotCmpUse);
1678 UnwrappedFnMap[NewF] = &
F;
1681 if (!
F.isDeclaration()) {
1691 size_t N = FI - FnsToInstrument.begin(),
1692 Count = FE - FnsToInstrument.begin();
1693 FnsToInstrument.push_back(&
F);
1694 FI = FnsToInstrument.begin() +
N;
1695 FE = FnsToInstrument.begin() +
Count;
1699 }
else if (FT->isVarArg()) {
1700 UnwrappedFnMap[&
F] = &
F;
1705 for (Function *
F : FnsToInstrument) {
1706 if (!
F ||
F->isDeclaration())
1711 DFSanFunction DFSF(*
this,
F, FnsWithNativeABI.
count(
F),
1712 FnsWithForceZeroLabel.
count(
F), GetTLI(*
F));
1716 for (
auto &FArg :
F->args()) {
1718 Value *FArgShadow = DFSF.getShadow(&FArg);
1719 if (isZeroShadow(FArgShadow))
1722 Next = FArgShadowInst->getNextNode();
1724 if (shouldTrackOrigins()) {
1725 if (Instruction *Origin =
1729 if (
Next->comesBefore(OriginNext)) {
1735 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, *
Next, &FArg);
1743 for (BasicBlock *BB : BBList) {
1753 if (!DFSF.SkipInsts.
count(Inst))
1754 DFSanVisitor(DFSF).visit(Inst);
1765 for (DFSanFunction::PHIFixupElement &
P : DFSF.PHIFixups) {
1766 for (
unsigned Val = 0,
N =
P.Phi->getNumIncomingValues(); Val !=
N;
1768 P.ShadowPhi->setIncomingValue(
1769 Val, DFSF.getShadow(
P.Phi->getIncomingValue(Val)));
1771 P.OriginPhi->setIncomingValue(
1772 Val, DFSF.getOrigin(
P.Phi->getIncomingValue(Val)));
1781 for (
Value *V : DFSF.NonZeroChecks) {
1784 Pos = std::next(
I->getIterator());
1788 Pos = std::next(Pos->getIterator());
1790 Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(V, Pos);
1792 IRB.
CreateICmpNE(PrimitiveShadow, DFSF.DFS.ZeroPrimitiveShadow);
1794 Ne, Pos,
false, ColdCallWeights));
1796 ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn, {});
1801 return Changed || !FnsToInstrument.empty() ||
1802 M.global_size() != InitialGlobalSize ||
M.size() != InitialModuleSize;
1806 return IRB.
CreatePtrAdd(DFS.ArgTLS, ConstantInt::get(DFS.IntptrTy, ArgOffset),
1815Value *DFSanFunction::getRetvalOriginTLS() {
return DFS.RetvalOriginTLS; }
1819 ArgNo,
"_dfsarg_o");
1823 assert(DFS.shouldTrackOrigins());
1825 return DFS.ZeroOrigin;
1826 Value *&Origin = ValOriginMap[
V];
1830 return DFS.ZeroOrigin;
1831 if (
A->getArgNo() < DFS.NumOfElementsInArgOrgTLS) {
1832 Instruction *ArgOriginTLSPos = &*
F->getEntryBlock().begin();
1834 Value *ArgOriginPtr = getArgOriginTLS(
A->getArgNo(), IRB);
1835 Origin = IRB.
CreateLoad(DFS.OriginTy, ArgOriginPtr);
1838 Origin = DFS.ZeroOrigin;
1841 Origin = DFS.ZeroOrigin;
1847void DFSanFunction::setOrigin(Instruction *
I,
Value *Origin) {
1848 if (!DFS.shouldTrackOrigins())
1852 ValOriginMap[
I] = Origin;
1855Value *DFSanFunction::getShadowForTLSArgument(Argument *
A) {
1856 unsigned ArgOffset = 0;
1857 const DataLayout &
DL =
F->getDataLayout();
1858 for (
auto &FArg :
F->args()) {
1859 if (!FArg.getType()->isSized()) {
1865 unsigned Size =
DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
1878 Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
1883 return DFS.getZeroShadow(
A);
1888 return DFS.getZeroShadow(V);
1889 if (IsForceZeroLabels)
1890 return DFS.getZeroShadow(V);
1891 Value *&Shadow = ValShadowMap[
V];
1895 return DFS.getZeroShadow(V);
1896 Shadow = getShadowForTLSArgument(
A);
1897 NonZeroChecks.push_back(Shadow);
1899 Shadow = DFS.getZeroShadow(V);
1905void DFSanFunction::setShadow(Instruction *
I,
Value *Shadow) {
1907 ValShadowMap[
I] = Shadow;
1915 assert(Addr != RetvalTLS &&
"Reinstrumenting?");
1918 uint64_t AndMask = MapParams->AndMask;
1921 IRB.
CreateAnd(OffsetLong, ConstantInt::get(IntptrTy, ~AndMask));
1923 uint64_t XorMask = MapParams->XorMask;
1925 OffsetLong = IRB.
CreateXor(OffsetLong, ConstantInt::get(IntptrTy, XorMask));
1929std::pair<Value *, Value *>
1930DataFlowSanitizer::getShadowOriginAddress(
Value *Addr, Align InstAlignment,
1934 Value *ShadowOffset = getShadowOffset(Addr, IRB);
1935 Value *ShadowLong = ShadowOffset;
1936 uint64_t ShadowBase = MapParams->ShadowBase;
1937 if (ShadowBase != 0) {
1939 IRB.
CreateAdd(ShadowLong, ConstantInt::get(IntptrTy, ShadowBase));
1942 Value *OriginPtr =
nullptr;
1943 if (shouldTrackOrigins()) {
1944 Value *OriginLong = ShadowOffset;
1945 uint64_t OriginBase = MapParams->OriginBase;
1946 if (OriginBase != 0)
1948 IRB.
CreateAdd(OriginLong, ConstantInt::get(IntptrTy, OriginBase));
1954 OriginLong = IRB.
CreateAnd(OriginLong, ConstantInt::get(IntptrTy, ~Mask));
1958 return std::make_pair(ShadowPtr, OriginPtr);
1961Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1963 Value *ShadowOffset) {
1968Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1971 Value *ShadowAddr = getShadowOffset(Addr, IRB);
1972 uint64_t ShadowBase = MapParams->ShadowBase;
1973 if (ShadowBase != 0)
1975 IRB.
CreateAdd(ShadowAddr, ConstantInt::get(IntptrTy, ShadowBase));
1976 return getShadowAddress(Addr, Pos, ShadowAddr);
1981 Value *PrimitiveValue = combineShadows(V1, V2, Pos);
1982 return expandFromPrimitiveShadow(
T, PrimitiveValue, Pos);
1989 if (DFS.isZeroShadow(V1))
1990 return collapseToPrimitiveShadow(V2, Pos);
1991 if (DFS.isZeroShadow(V2))
1992 return collapseToPrimitiveShadow(V1, Pos);
1994 return collapseToPrimitiveShadow(V1, Pos);
1996 auto V1Elems = ShadowElements.
find(V1);
1997 auto V2Elems = ShadowElements.
find(V2);
1998 if (V1Elems != ShadowElements.
end() && V2Elems != ShadowElements.
end()) {
2000 return collapseToPrimitiveShadow(V1, Pos);
2003 return collapseToPrimitiveShadow(V2, Pos);
2005 }
else if (V1Elems != ShadowElements.
end()) {
2006 if (V1Elems->second.count(V2))
2007 return collapseToPrimitiveShadow(V1, Pos);
2008 }
else if (V2Elems != ShadowElements.
end()) {
2009 if (V2Elems->second.count(V1))
2010 return collapseToPrimitiveShadow(V2, Pos);
2013 auto Key = std::make_pair(V1, V2);
2016 CachedShadow &CCS = CachedShadows[
Key];
2017 if (CCS.Block && DT.
dominates(CCS.Block, Pos->getParent()))
2021 Value *PV1 = collapseToPrimitiveShadow(V1, Pos);
2022 Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
2025 CCS.Block = Pos->getParent();
2026 CCS.Shadow = IRB.
CreateOr(PV1, PV2);
2028 std::set<Value *> UnionElems;
2029 if (V1Elems != ShadowElements.
end()) {
2030 UnionElems = V1Elems->second;
2032 UnionElems.insert(V1);
2034 if (V2Elems != ShadowElements.
end()) {
2035 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
2037 UnionElems.insert(V2);
2039 ShadowElements[CCS.Shadow] = std::move(UnionElems);
2047Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
2049 return DFS.getZeroShadow(Inst);
2053 Shadow = combineShadows(Shadow, getShadow(Inst->
getOperand(
I)),
2056 return expandFromPrimitiveShadow(Inst->
getType(), Shadow,
2060void DFSanVisitor::visitInstOperands(Instruction &
I) {
2061 Value *CombinedShadow = DFSF.combineOperandShadows(&
I);
2062 DFSF.setShadow(&
I, CombinedShadow);
2063 visitInstOperandOrigins(
I);
2066Value *DFSanFunction::combineOrigins(
const std::vector<Value *> &Shadows,
2067 const std::vector<Value *> &Origins,
2069 ConstantInt *Zero) {
2070 assert(Shadows.size() == Origins.size());
2071 size_t Size = Origins.size();
2073 return DFS.ZeroOrigin;
2074 Value *Origin =
nullptr;
2076 Zero = DFS.ZeroPrimitiveShadow;
2077 for (
size_t I = 0;
I !=
Size; ++
I) {
2078 Value *OpOrigin = Origins[
I];
2080 if (ConstOpOrigin && ConstOpOrigin->
isNullValue())
2086 Value *OpShadow = Shadows[
I];
2087 Value *PrimitiveShadow = collapseToPrimitiveShadow(OpShadow, Pos);
2092 return Origin ? Origin : DFS.ZeroOrigin;
2095Value *DFSanFunction::combineOperandOrigins(Instruction *Inst) {
2097 std::vector<Value *> Shadows(
Size);
2098 std::vector<Value *> Origins(
Size);
2099 for (
unsigned I = 0;
I !=
Size; ++
I) {
2103 return combineOrigins(Shadows, Origins, Inst->
getIterator());
2106void DFSanVisitor::visitInstOperandOrigins(Instruction &
I) {
2107 if (!DFSF.DFS.shouldTrackOrigins())
2109 Value *CombinedOrigin = DFSF.combineOperandOrigins(&
I);
2110 DFSF.setOrigin(&
I, CombinedOrigin);
2113Align DFSanFunction::getShadowAlign(Align InstAlignment) {
2115 return Align(Alignment.
value() * DFS.ShadowWidthBytes);
2118Align DFSanFunction::getOriginAlign(Align InstAlignment) {
2123bool DFSanFunction::isLookupTableConstant(
Value *
P) {
2125 if (GV->isConstant() && GV->
hasName())
2126 return DFS.CombineTaintLookupTableNames.
count(GV->
getName());
2131bool DFSanFunction::useCallbackLoadLabelAndOrigin(uint64_t
Size,
2132 Align InstAlignment) {
2156 Value **OriginAddr) {
2159 IRB.
CreateGEP(OriginTy, *OriginAddr, ConstantInt::get(IntptrTy, 1));
2163std::pair<Value *, Value *> DFSanFunction::loadShadowFast(
2164 Value *ShadowAddr,
Value *OriginAddr, uint64_t
Size, Align ShadowAlign,
2166 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2167 const uint64_t ShadowSize =
Size * DFS.ShadowWidthBytes;
2169 assert(
Size >= 4 &&
"Not large enough load size for fast path!");
2172 std::vector<Value *> Shadows;
2173 std::vector<Value *> Origins;
2186 Type *WideShadowTy =
2187 ShadowSize == 4 ? Type::getInt32Ty(*DFS.Ctx) :
Type::getInt64Ty(*DFS.Ctx);
2190 Value *CombinedWideShadow =
2194 const uint64_t BytesPerWideShadow = WideShadowBitWidth / DFS.ShadowWidthBits;
2196 auto AppendWideShadowAndOrigin = [&](
Value *WideShadow,
Value *Origin) {
2197 if (BytesPerWideShadow > 4) {
2198 assert(BytesPerWideShadow == 8);
2205 Value *WideShadowLo =
2206 F->getParent()->getDataLayout().isLittleEndian()
2209 ConstantInt::get(WideShadowTy, WideShadowBitWidth / 2))
2212 ConstantInt::get(WideShadowTy,
2213 (1 - (1 << (WideShadowBitWidth / 2)))
2214 << (WideShadowBitWidth / 2)));
2215 Shadows.push_back(WideShadow);
2216 Origins.push_back(DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr));
2218 Shadows.push_back(WideShadowLo);
2219 Origins.push_back(Origin);
2221 Shadows.push_back(WideShadow);
2222 Origins.push_back(Origin);
2226 if (ShouldTrackOrigins)
2227 AppendWideShadowAndOrigin(CombinedWideShadow, FirstOrigin);
2234 for (uint64_t ByteOfs = BytesPerWideShadow; ByteOfs <
Size;
2235 ByteOfs += BytesPerWideShadow) {
2236 ShadowAddr = IRB.
CreateGEP(WideShadowTy, ShadowAddr,
2237 ConstantInt::get(DFS.IntptrTy, 1));
2238 Value *NextWideShadow =
2240 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, NextWideShadow);
2241 if (ShouldTrackOrigins) {
2242 Value *NextOrigin = DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr);
2243 AppendWideShadowAndOrigin(NextWideShadow, NextOrigin);
2246 for (
unsigned Width = WideShadowBitWidth / 2; Width >= DFS.ShadowWidthBits;
2249 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, ShrShadow);
2251 return {IRB.
CreateTrunc(CombinedWideShadow, DFS.PrimitiveShadowTy),
2253 ? combineOrigins(Shadows, Origins, Pos,
2258std::pair<Value *, Value *> DFSanFunction::loadShadowOriginSansLoadTracking(
2260 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2264 const auto SI = AllocaShadowMap.
find(AI);
2265 if (SI != AllocaShadowMap.
end()) {
2268 const auto OI = AllocaOriginMap.
find(AI);
2269 assert(!ShouldTrackOrigins || OI != AllocaOriginMap.
end());
2270 return {ShadowLI, ShouldTrackOrigins
2277 SmallVector<const Value *, 2> Objs;
2279 bool AllConstants =
true;
2280 for (
const Value *Obj : Objs) {
2286 AllConstants =
false;
2290 return {DFS.ZeroPrimitiveShadow,
2291 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2294 return {DFS.ZeroPrimitiveShadow,
2295 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2299 if (ShouldTrackOrigins &&
2300 useCallbackLoadLabelAndOrigin(
Size, InstAlignment)) {
2303 IRB.
CreateCall(DFS.DFSanLoadLabelAndOriginFn,
2304 {Addr, ConstantInt::get(DFS.IntptrTy, Size)});
2307 DFS.PrimitiveShadowTy),
2312 Value *ShadowAddr, *OriginAddr;
2313 std::tie(ShadowAddr, OriginAddr) =
2314 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2316 const Align ShadowAlign = getShadowAlign(InstAlignment);
2317 const Align OriginAlign = getOriginAlign(InstAlignment);
2318 Value *Origin =
nullptr;
2319 if (ShouldTrackOrigins) {
2328 LoadInst *LI =
new LoadInst(DFS.PrimitiveShadowTy, ShadowAddr,
"", Pos);
2330 return {LI, Origin};
2334 Value *ShadowAddr1 = IRB.
CreateGEP(DFS.PrimitiveShadowTy, ShadowAddr,
2335 ConstantInt::get(DFS.IntptrTy, 1));
2340 return {combineShadows(Load, Load1, Pos), Origin};
2343 bool HasSizeForFastPath = DFS.hasLoadSizeForFastPath(
Size);
2345 if (HasSizeForFastPath)
2346 return loadShadowFast(ShadowAddr, OriginAddr,
Size, ShadowAlign,
2347 OriginAlign, Origin, Pos);
2351 DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
2353 return {FallbackCall, Origin};
2356std::pair<Value *, Value *>
2357DFSanFunction::loadShadowOrigin(
Value *Addr, uint64_t
Size, Align InstAlignment,
2359 Value *PrimitiveShadow, *Origin;
2360 std::tie(PrimitiveShadow, Origin) =
2361 loadShadowOriginSansLoadTracking(Addr,
Size, InstAlignment, Pos);
2362 if (DFS.shouldTrackOrigins()) {
2366 if (!ConstantShadow || !ConstantShadow->isZeroValue())
2367 Origin = updateOriginIfTainted(PrimitiveShadow, Origin, IRB);
2370 return {PrimitiveShadow, Origin};
2391 if (!V->getType()->isPointerTy())
2400 V =
GEP->getPointerOperand();
2403 if (!V->getType()->isPointerTy())
2408 }
while (Visited.
insert(V).second);
2413void DFSanVisitor::visitLoadInst(LoadInst &LI) {
2417 DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
2418 DFSF.setOrigin(&LI, DFSF.DFS.ZeroOrigin);
2433 Pos = std::next(Pos);
2435 std::vector<Value *> Shadows;
2436 std::vector<Value *> Origins;
2437 Value *PrimitiveShadow, *Origin;
2438 std::tie(PrimitiveShadow, Origin) =
2440 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2441 if (ShouldTrackOrigins) {
2442 Shadows.push_back(PrimitiveShadow);
2443 Origins.push_back(Origin);
2446 DFSF.isLookupTableConstant(
2449 PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, Pos);
2450 if (ShouldTrackOrigins) {
2451 Shadows.push_back(PtrShadow);
2455 if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
2456 DFSF.NonZeroChecks.push_back(PrimitiveShadow);
2459 DFSF.expandFromPrimitiveShadow(LI.
getType(), PrimitiveShadow, Pos);
2460 DFSF.setShadow(&LI, Shadow);
2462 if (ShouldTrackOrigins) {
2463 DFSF.setOrigin(&LI, DFSF.combineOrigins(Shadows, Origins, Pos));
2470 IRB.
CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr});
2475 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, LI, &LI);
2478Value *DFSanFunction::updateOriginIfTainted(
Value *Shadow,
Value *Origin,
2480 assert(DFS.shouldTrackOrigins());
2481 return IRB.
CreateCall(DFS.DFSanChainOriginIfTaintedFn, {Shadow, Origin});
2485 if (!DFS.shouldTrackOrigins())
2487 return IRB.
CreateCall(DFS.DFSanChainOriginFn, V);
2491 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2492 const DataLayout &
DL =
F->getDataLayout();
2493 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2494 if (IntptrSize == OriginSize)
2496 assert(IntptrSize == OriginSize * 2);
2502 Value *StoreOriginAddr,
2503 uint64_t StoreOriginSize, Align Alignment) {
2504 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2505 const DataLayout &
DL =
F->getDataLayout();
2506 const Align IntptrAlignment =
DL.getABITypeAlign(DFS.IntptrTy);
2507 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2509 assert(IntptrSize >= OriginSize);
2512 Align CurrentAlignment = Alignment;
2513 if (Alignment >= IntptrAlignment && IntptrSize > OriginSize) {
2514 Value *IntptrOrigin = originToIntptr(IRB, Origin);
2515 Value *IntptrStoreOriginPtr =
2517 for (
unsigned I = 0;
I < StoreOriginSize / IntptrSize; ++
I) {
2520 : IntptrStoreOriginPtr;
2522 Ofs += IntptrSize / OriginSize;
2523 CurrentAlignment = IntptrAlignment;
2527 for (
unsigned I = Ofs;
I < (StoreOriginSize + OriginSize - 1) / OriginSize;
2537 const Twine &Name) {
2538 Type *VTy =
V->getType();
2543 return IRB.
CreateICmpNE(V, ConstantInt::get(VTy, 0), Name);
2548 Value *StoreOriginAddr, Align InstAlignment) {
2551 const Align OriginAlignment = getOriginAlign(InstAlignment);
2552 Value *CollapsedShadow = collapseToPrimitiveShadow(Shadow, Pos);
2555 if (!ConstantShadow->isZeroValue())
2556 paintOrigin(IRB, updateOrigin(Origin, IRB), StoreOriginAddr,
Size,
2561 if (shouldInstrumentWithCall()) {
2563 DFS.DFSanMaybeStoreOriginFn,
2564 {CollapsedShadow, Addr, ConstantInt::get(DFS.IntptrTy, Size), Origin});
2566 Value *
Cmp = convertToBool(CollapsedShadow, IRB,
"_dfscmp");
2567 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
2569 Cmp, &*IRB.
GetInsertPoint(),
false, DFS.OriginStoreWeights, &DTU);
2571 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), StoreOriginAddr,
Size,
2577void DFSanFunction::storeZeroPrimitiveShadow(
Value *Addr, uint64_t
Size,
2581 IntegerType *ShadowTy =
2583 Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
2584 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
2590void DFSanFunction::storePrimitiveShadowOrigin(
Value *Addr, uint64_t
Size,
2591 Align InstAlignment,
2592 Value *PrimitiveShadow,
2595 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins() && Origin;
2598 const auto SI = AllocaShadowMap.
find(AI);
2599 if (SI != AllocaShadowMap.
end()) {
2605 if (ShouldTrackOrigins && !DFS.isZeroShadow(PrimitiveShadow)) {
2606 const auto OI = AllocaOriginMap.
find(AI);
2607 assert(OI != AllocaOriginMap.
end() && Origin);
2614 const Align ShadowAlign = getShadowAlign(InstAlignment);
2615 if (DFS.isZeroShadow(PrimitiveShadow)) {
2616 storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign, Pos);
2621 Value *ShadowAddr, *OriginAddr;
2622 std::tie(ShadowAddr, OriginAddr) =
2623 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2625 const unsigned ShadowVecSize = 8;
2626 assert(ShadowVecSize * DFS.ShadowWidthBits <= 128 &&
2627 "Shadow vector is too large!");
2630 uint64_t LeftSize =
Size;
2631 if (LeftSize >= ShadowVecSize) {
2635 for (
unsigned I = 0;
I != ShadowVecSize; ++
I) {
2637 ShadowVec, PrimitiveShadow,
2638 ConstantInt::get(Type::getInt32Ty(*DFS.Ctx),
I));
2641 Value *CurShadowVecAddr =
2644 LeftSize -= ShadowVecSize;
2646 }
while (LeftSize >= ShadowVecSize);
2649 while (LeftSize > 0) {
2650 Value *CurShadowAddr =
2657 if (ShouldTrackOrigins) {
2658 storeOrigin(Pos, Addr,
Size, PrimitiveShadow, Origin, OriginAddr,
2680void DFSanVisitor::visitStoreInst(StoreInst &SI) {
2681 auto &
DL =
SI.getDataLayout();
2682 Value *Val =
SI.getValueOperand();
2695 const bool ShouldTrackOrigins =
2696 DFSF.DFS.shouldTrackOrigins() && !
SI.isAtomic();
2697 std::vector<Value *> Shadows;
2698 std::vector<Value *> Origins;
2701 SI.isAtomic() ? DFSF.DFS.getZeroShadow(Val) : DFSF.getShadow(Val);
2703 if (ShouldTrackOrigins) {
2704 Shadows.push_back(Shadow);
2705 Origins.push_back(DFSF.getOrigin(Val));
2708 Value *PrimitiveShadow;
2710 Value *PtrShadow = DFSF.getShadow(
SI.getPointerOperand());
2711 if (ShouldTrackOrigins) {
2712 Shadows.push_back(PtrShadow);
2713 Origins.push_back(DFSF.getOrigin(
SI.getPointerOperand()));
2715 PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow,
SI.getIterator());
2717 PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow,
SI.getIterator());
2719 Value *Origin =
nullptr;
2720 if (ShouldTrackOrigins)
2721 Origin = DFSF.combineOrigins(Shadows, Origins,
SI.getIterator());
2722 DFSF.storePrimitiveShadowOrigin(
SI.getPointerOperand(),
Size,
SI.getAlign(),
2723 PrimitiveShadow, Origin,
SI.getIterator());
2726 Value *Addr =
SI.getPointerOperand();
2728 IRB.
CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr});
2733void DFSanVisitor::visitCASOrRMW(Align InstAlignment, Instruction &
I) {
2736 Value *Val =
I.getOperand(1);
2737 const auto &
DL =
I.getDataLayout();
2745 Value *Addr =
I.getOperand(0);
2746 const Align ShadowAlign = DFSF.getShadowAlign(InstAlignment);
2747 DFSF.storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign,
I.getIterator());
2748 DFSF.setShadow(&
I, DFSF.DFS.getZeroShadow(&
I));
2749 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2752void DFSanVisitor::visitAtomicRMWInst(AtomicRMWInst &
I) {
2753 visitCASOrRMW(
I.getAlign(),
I);
2759void DFSanVisitor::visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2760 visitCASOrRMW(
I.getAlign(),
I);
2766void DFSanVisitor::visitUnaryOperator(UnaryOperator &UO) {
2767 visitInstOperands(UO);
2770void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) {
2771 visitInstOperands(BO);
2774void DFSanVisitor::visitBitCastInst(BitCastInst &BCI) {
2781 visitInstOperands(BCI);
2784void DFSanVisitor::visitCastInst(CastInst &CI) { visitInstOperands(CI); }
2786void DFSanVisitor::visitCmpInst(CmpInst &CI) {
2787 visitInstOperands(CI);
2790 Value *CombinedShadow = DFSF.getShadow(&CI);
2792 IRB.
CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
2797void DFSanVisitor::visitLandingPadInst(LandingPadInst &LPI) {
2809 DFSF.setShadow(&LPI, DFSF.DFS.getZeroShadow(&LPI));
2810 DFSF.setOrigin(&LPI, DFSF.DFS.ZeroOrigin);
2813void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
2815 DFSF.isLookupTableConstant(
2817 visitInstOperands(GEPI);
2824 DFSF.setShadow(&GEPI, DFSF.getShadow(BasePointer));
2825 if (DFSF.DFS.shouldTrackOrigins())
2826 DFSF.setOrigin(&GEPI, DFSF.getOrigin(BasePointer));
2829void DFSanVisitor::visitExtractElementInst(ExtractElementInst &
I) {
2830 visitInstOperands(
I);
2833void DFSanVisitor::visitInsertElementInst(InsertElementInst &
I) {
2834 visitInstOperands(
I);
2837void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &
I) {
2838 visitInstOperands(
I);
2841void DFSanVisitor::visitExtractValueInst(ExtractValueInst &
I) {
2843 Value *Agg =
I.getAggregateOperand();
2844 Value *AggShadow = DFSF.getShadow(Agg);
2846 DFSF.setShadow(&
I, ResShadow);
2847 visitInstOperandOrigins(
I);
2850void DFSanVisitor::visitInsertValueInst(InsertValueInst &
I) {
2852 Value *AggShadow = DFSF.getShadow(
I.getAggregateOperand());
2853 Value *InsShadow = DFSF.getShadow(
I.getInsertedValueOperand());
2855 DFSF.setShadow(&
I, Res);
2856 visitInstOperandOrigins(
I);
2859void DFSanVisitor::visitAllocaInst(AllocaInst &
I) {
2860 bool AllLoadsStores =
true;
2861 for (User *U :
I.users()) {
2866 if (
SI->getPointerOperand() == &
I)
2870 AllLoadsStores =
false;
2873 if (AllLoadsStores) {
2875 DFSF.AllocaShadowMap[&
I] = IRB.
CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
2876 if (DFSF.DFS.shouldTrackOrigins()) {
2877 DFSF.AllocaOriginMap[&
I] =
2881 DFSF.setShadow(&
I, DFSF.DFS.ZeroPrimitiveShadow);
2882 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2885void DFSanVisitor::visitSelectInst(SelectInst &
I) {
2886 Value *CondShadow = DFSF.getShadow(
I.getCondition());
2887 Value *TrueShadow = DFSF.getShadow(
I.getTrueValue());
2888 Value *FalseShadow = DFSF.getShadow(
I.getFalseValue());
2889 Value *ShadowSel =
nullptr;
2890 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2891 std::vector<Value *> Shadows;
2892 std::vector<Value *> Origins;
2894 ShouldTrackOrigins ? DFSF.getOrigin(
I.getTrueValue()) :
nullptr;
2895 Value *FalseOrigin =
2896 ShouldTrackOrigins ? DFSF.getOrigin(
I.getFalseValue()) :
nullptr;
2898 DFSF.addConditionalCallbacksIfEnabled(
I,
I.getCondition());
2901 ShadowSel = DFSF.combineShadowsThenConvert(
I.getType(), TrueShadow,
2902 FalseShadow,
I.getIterator());
2903 if (ShouldTrackOrigins) {
2904 Shadows.push_back(TrueShadow);
2905 Shadows.push_back(FalseShadow);
2906 Origins.push_back(TrueOrigin);
2907 Origins.push_back(FalseOrigin);
2910 if (TrueShadow == FalseShadow) {
2911 ShadowSel = TrueShadow;
2912 if (ShouldTrackOrigins) {
2913 Shadows.push_back(TrueShadow);
2914 Origins.push_back(TrueOrigin);
2918 "",
I.getIterator());
2919 if (ShouldTrackOrigins) {
2920 Shadows.push_back(ShadowSel);
2922 FalseOrigin,
"",
I.getIterator()));
2927 I.getType(), CondShadow,
2928 ShadowSel,
I.getIterator())
2930 if (ShouldTrackOrigins) {
2932 Shadows.push_back(CondShadow);
2933 Origins.push_back(DFSF.getOrigin(
I.getCondition()));
2935 DFSF.setOrigin(&
I, DFSF.combineOrigins(Shadows, Origins,
I.getIterator()));
2939void DFSanVisitor::visitMemSetInst(MemSetInst &
I) {
2941 Value *ValShadow = DFSF.getShadow(
I.getValue());
2942 Value *ValOrigin = DFSF.DFS.shouldTrackOrigins()
2943 ? DFSF.getOrigin(
I.getValue())
2944 : DFSF.DFS.ZeroOrigin;
2946 {ValShadow, ValOrigin, I.getDest(),
2947 IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2950void DFSanVisitor::visitMemTransferInst(MemTransferInst &
I) {
2955 if (DFSF.DFS.shouldTrackOrigins()) {
2957 DFSF.DFS.DFSanMemOriginTransferFn,
2958 {I.getArgOperand(0), I.getArgOperand(1),
2959 IRB.CreateIntCast(I.getArgOperand(2), DFSF.DFS.IntptrTy, false)});
2962 Value *DestShadow = DFSF.DFS.getShadowAddress(
I.getDest(),
I.getIterator());
2963 Value *SrcShadow = DFSF.DFS.getShadowAddress(
I.getSource(),
I.getIterator());
2965 IRB.
CreateMul(
I.getLength(), ConstantInt::get(
I.getLength()->getType(),
2966 DFSF.DFS.ShadowWidthBytes));
2968 IRB.
CreateCall(
I.getFunctionType(),
I.getCalledOperand(),
2969 {DestShadow, SrcShadow, LenShadow, I.getVolatileCst()}));
2970 MTI->setDestAlignment(DFSF.getShadowAlign(
I.getDestAlign().valueOrOne()));
2971 MTI->setSourceAlignment(DFSF.getShadowAlign(
I.getSourceAlign().valueOrOne()));
2974 DFSF.DFS.DFSanMemTransferCallbackFn,
2975 {DestShadow, IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2979void DFSanVisitor::visitBranchInst(BranchInst &BR) {
2980 if (!
BR.isConditional())
2983 DFSF.addConditionalCallbacksIfEnabled(BR,
BR.getCondition());
2986void DFSanVisitor::visitSwitchInst(SwitchInst &SW) {
2987 DFSF.addConditionalCallbacksIfEnabled(SW, SW.
getCondition());
2993 RetVal =
I->getOperand(0);
2996 return I->isMustTailCall();
3001void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
3010 unsigned Size = getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
3016 if (DFSF.DFS.shouldTrackOrigins()) {
3023void DFSanVisitor::addShadowArguments(Function &
F, CallBase &CB,
3024 std::vector<Value *> &Args,
3026 FunctionType *FT =
F.getFunctionType();
3031 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
3033 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()));
3036 if (FT->isVarArg()) {
3037 auto *LabelVATy = ArrayType::get(DFSF.DFS.PrimitiveShadowTy,
3038 CB.
arg_size() - FT->getNumParams());
3039 auto *LabelVAAlloca =
3040 new AllocaInst(LabelVATy, getDataLayout().getAllocaAddrSpace(),
3043 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
3046 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()),
3054 if (!FT->getReturnType()->isVoidTy()) {
3055 if (!DFSF.LabelReturnAlloca) {
3056 DFSF.LabelReturnAlloca =
new AllocaInst(
3057 DFSF.DFS.PrimitiveShadowTy, getDataLayout().getAllocaAddrSpace(),
3060 Args.push_back(DFSF.LabelReturnAlloca);
3064void DFSanVisitor::addOriginArguments(Function &
F, CallBase &CB,
3065 std::vector<Value *> &Args,
3067 FunctionType *FT =
F.getFunctionType();
3072 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
3073 Args.push_back(DFSF.getOrigin(*
I));
3076 if (FT->isVarArg()) {
3078 ArrayType::get(DFSF.DFS.OriginTy, CB.
arg_size() - FT->getNumParams());
3079 auto *OriginVAAlloca =
3080 new AllocaInst(OriginVATy, getDataLayout().getAllocaAddrSpace(),
3083 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
3092 if (!FT->getReturnType()->isVoidTy()) {
3093 if (!DFSF.OriginReturnAlloca) {
3094 DFSF.OriginReturnAlloca =
new AllocaInst(
3095 DFSF.DFS.OriginTy, getDataLayout().getAllocaAddrSpace(),
3098 Args.push_back(DFSF.OriginReturnAlloca);
3102bool DFSanVisitor::visitWrappedCallBase(Function &
F, CallBase &CB) {
3104 switch (DFSF.DFS.getWrapperKind(&
F)) {
3105 case DataFlowSanitizer::WK_Warning:
3107 IRB.
CreateCall(DFSF.DFS.DFSanUnimplementedFn,
3109 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3110 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3111 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3113 case DataFlowSanitizer::WK_Discard:
3115 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3116 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3117 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3119 case DataFlowSanitizer::WK_Functional:
3121 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3122 visitInstOperands(CB);
3124 case DataFlowSanitizer::WK_Custom:
3132 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3133 FunctionType *FT =
F.getFunctionType();
3134 TransformedFunction CustomFn = DFSF.DFS.getCustomFunctionType(FT);
3135 std::string CustomFName = ShouldTrackOrigins ?
"__dfso_" :
"__dfsw_";
3136 CustomFName +=
F.getName();
3138 CustomFName, CustomFn.TransformedType);
3140 CustomFn->copyAttributesFrom(&
F);
3143 if (!FT->getReturnType()->isVoidTy()) {
3144 CustomFn->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
3148 std::vector<Value *>
Args;
3152 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N) {
3157 const unsigned ShadowArgStart =
Args.size();
3158 addShadowArguments(
F, CB, Args, IRB);
3161 const unsigned OriginArgStart =
Args.size();
3162 if (ShouldTrackOrigins)
3163 addOriginArguments(
F, CB, Args, IRB);
3168 CallInst *CustomCI = IRB.
CreateCall(CustomF, Args);
3176 for (
unsigned N = 0;
N < FT->getNumParams();
N++) {
3177 const unsigned ArgNo = ShadowArgStart +
N;
3179 DFSF.DFS.PrimitiveShadowTy)
3181 if (ShouldTrackOrigins) {
3182 const unsigned OriginArgNo = OriginArgStart +
N;
3190 if (!FT->getReturnType()->isVoidTy()) {
3191 LoadInst *LabelLoad =
3192 IRB.
CreateLoad(DFSF.DFS.PrimitiveShadowTy, DFSF.LabelReturnAlloca);
3193 DFSF.setShadow(CustomCI,
3194 DFSF.expandFromPrimitiveShadow(
3195 FT->getReturnType(), LabelLoad, CB.
getIterator()));
3196 if (ShouldTrackOrigins) {
3197 LoadInst *OriginLoad =
3198 IRB.
CreateLoad(DFSF.DFS.OriginTy, DFSF.OriginReturnAlloca);
3199 DFSF.setOrigin(CustomCI, OriginLoad);
3211 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3212 uint32_t OrderingTable[NumOrderings] = {};
3214 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3215 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3216 OrderingTable[(int)AtomicOrderingCABI::consume] =
3217 (
int)AtomicOrderingCABI::acquire;
3218 OrderingTable[(int)AtomicOrderingCABI::release] =
3219 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
3220 (int)AtomicOrderingCABI::acq_rel;
3221 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3222 (
int)AtomicOrderingCABI::seq_cst;
3227void DFSanVisitor::visitLibAtomicLoad(CallBase &CB) {
3238 Value *NewOrdering =
3243 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3249 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3250 {DstPtr, SrcPtr, NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3254 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3255 uint32_t OrderingTable[NumOrderings] = {};
3257 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3258 OrderingTable[(
int)AtomicOrderingCABI::release] =
3259 (int)AtomicOrderingCABI::release;
3260 OrderingTable[(int)AtomicOrderingCABI::consume] =
3261 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3262 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
3263 (
int)AtomicOrderingCABI::acq_rel;
3264 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3265 (
int)AtomicOrderingCABI::seq_cst;
3270void DFSanVisitor::visitLibAtomicStore(CallBase &CB) {
3278 Value *NewOrdering =
3286 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3287 {DstPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3290void DFSanVisitor::visitLibAtomicExchange(CallBase &CB) {
3306 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3307 {DstPtr, TargetPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3311 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3312 {TargetPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3315void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
3329 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3331 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3335 NextIRB.CreateCall(DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
3336 {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false),
3337 TargetPtr, ExpectedPtr, DesiredPtr,
3338 NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3341void DFSanVisitor::visitCallBase(CallBase &CB) {
3344 visitInstOperands(CB);
3359 case LibFunc_atomic_load:
3361 llvm::errs() <<
"DFSAN -- cannot instrument invoke of libatomic load. "
3365 visitLibAtomicLoad(CB);
3367 case LibFunc_atomic_store:
3368 visitLibAtomicStore(CB);
3376 if (
F &&
F->hasName() && !
F->isVarArg()) {
3377 if (
F->getName() ==
"__atomic_exchange") {
3378 visitLibAtomicExchange(CB);
3381 if (
F->getName() ==
"__atomic_compare_exchange") {
3382 visitLibAtomicCompareExchange(CB);
3387 DenseMap<Value *, Function *>::iterator UnwrappedFnIt =
3389 if (UnwrappedFnIt != DFSF.DFS.UnwrappedFnMap.end())
3390 if (visitWrappedCallBase(*UnwrappedFnIt->second, CB))
3395 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3397 const DataLayout &
DL = getDataLayout();
3400 unsigned ArgOffset = 0;
3401 for (
unsigned I = 0,
N = FT->getNumParams();
I !=
N; ++
I) {
3402 if (ShouldTrackOrigins) {
3405 if (
I < DFSF.DFS.NumOfElementsInArgOrgTLS &&
3406 !DFSF.DFS.isZeroShadow(ArgShadow))
3408 DFSF.getArgOriginTLS(
I, IRB));
3412 DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(
I)));
3418 DFSF.getArgTLS(FT->getParamType(
I), ArgOffset, IRB),
3426 if (
II->getNormalDest()->getSinglePredecessor()) {
3427 Next = &
II->getNormalDest()->front();
3444 unsigned Size =
DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
3447 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3449 LoadInst *LI = NextIRB.CreateAlignedLoad(
3450 DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.
getType(), NextIRB),
3452 DFSF.SkipInsts.
insert(LI);
3453 DFSF.setShadow(&CB, LI);
3454 DFSF.NonZeroChecks.push_back(LI);
3457 if (ShouldTrackOrigins) {
3458 LoadInst *LI = NextIRB.CreateLoad(DFSF.DFS.OriginTy,
3459 DFSF.getRetvalOriginTLS(),
"_dfsret_o");
3460 DFSF.SkipInsts.
insert(LI);
3461 DFSF.setOrigin(&CB, LI);
3464 DFSF.addReachesFunctionCallbacksIfEnabled(NextIRB, CB, &CB);
3468void DFSanVisitor::visitPHINode(PHINode &PN) {
3469 Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
3475 for (BasicBlock *BB : PN.
blocks())
3478 DFSF.setShadow(&PN, ShadowPN);
3480 PHINode *OriginPN =
nullptr;
3481 if (DFSF.DFS.shouldTrackOrigins()) {
3485 for (BasicBlock *BB : PN.
blocks())
3487 DFSF.setOrigin(&PN, OriginPN);
3490 DFSF.PHIFixups.push_back({&PN, ShadowPN, OriginPN});
3503 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")
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.
static bool runImpl(Function &F, const TargetLowering &TLI, const LibcallLoweringInfo &Libcalls, AssumptionCache *AC)
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.
ArrayRef - 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.
LLVM_ABI 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
LLVM_ABI 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.
const std::string & getModuleInlineAsm() const
Get any module-scope inline assembly blocks.
void setModuleInlineAsm(StringRef Asm)
Set the module-scope inline assembly blocks.
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
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.
StringRef - 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.
FunctionAddr VTableAddr Value
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.
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)
FunctionAddr VTableAddr Count
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.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
FunctionAddr VTableAddr Next
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.
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.