151 Type *GType =
G.getValueType();
154 if (!SGType->isLiteral())
155 return SGType->getName();
157 return "<unknown type>";
166struct MemoryMapParams {
212 std::unique_ptr<SpecialCaseList> SCL;
215 DFSanABIList() =
default;
217 void set(std::unique_ptr<SpecialCaseList>
List) { SCL = std::move(
List); }
221 bool isIn(
const Function &
F, StringRef Category)
const {
222 return isIn(*
F.getParent(), Category) ||
223 SCL->inSection(
"dataflow",
"fun",
F.getName(), Category);
230 bool isIn(
const GlobalAlias &GA, StringRef Category)
const {
235 return SCL->inSection(
"dataflow",
"fun", GA.
getName(), Category);
237 return SCL->inSection(
"dataflow",
"global", GA.
getName(), Category) ||
243 bool isIn(
const Module &M, StringRef Category)
const {
244 return SCL->inSection(
"dataflow",
"src",
M.getModuleIdentifier(), Category);
251struct TransformedFunction {
252 TransformedFunction(FunctionType *OriginalType, FunctionType *TransformedType,
253 const std::vector<unsigned> &ArgumentIndexMapping,
254 AttributeList &NewParamAttrs)
255 : OriginalType(OriginalType), TransformedType(TransformedType),
256 ArgumentIndexMapping(ArgumentIndexMapping),
257 NewParamAttrs(NewParamAttrs) {}
260 TransformedFunction(
const TransformedFunction &) =
delete;
261 TransformedFunction &operator=(
const TransformedFunction &) =
delete;
264 TransformedFunction(TransformedFunction &&) =
default;
265 TransformedFunction &operator=(TransformedFunction &&) =
default;
268 FunctionType *OriginalType;
271 FunctionType *TransformedType;
278 std::vector<unsigned> ArgumentIndexMapping;
282 AttributeList NewParamAttrs;
289transformFunctionAttributes(
const TransformedFunction &TransformedFunction,
293 std::vector<llvm::AttributeSet> ArgumentAttributes(
294 TransformedFunction.TransformedType->getNumParams());
299 for (
unsigned I = 0, IE = TransformedFunction.ArgumentIndexMapping.size();
301 unsigned TransformedIndex = TransformedFunction.ArgumentIndexMapping[
I];
302 ArgumentAttributes[TransformedIndex] = CallSiteAttrs.getParamAttrs(
I);
306 for (
unsigned I = TransformedFunction.OriginalType->getNumParams(),
307 IE = CallSiteAttrs.getNumAttrSets();
309 ArgumentAttributes.push_back(CallSiteAttrs.getParamAttrs(
I));
312 return AttributeList::get(Ctx, CallSiteAttrs.getFnAttrs(),
313 CallSiteAttrs.getRetAttrs(),
317class DataFlowSanitizer {
318 friend struct DFSanFunction;
319 friend class DFSanVisitor;
321 enum { ShadowWidthBits = 8, ShadowWidthBytes = ShadowWidthBits / 8 };
323 enum { OriginWidthBits = 32, OriginWidthBytes = OriginWidthBits / 8 };
348 const InstrumentationOptions &Opts;
352 IntegerType *OriginTy;
354 ConstantInt *ZeroOrigin;
356 IntegerType *PrimitiveShadowTy;
358 IntegerType *IntptrTy;
359 ConstantInt *ZeroPrimitiveShadow;
365 FunctionType *DFSanUnionLoadFnTy;
366 FunctionType *DFSanLoadLabelAndOriginFnTy;
367 FunctionType *DFSanUnimplementedFnTy;
368 FunctionType *DFSanWrapperExternWeakNullFnTy;
369 FunctionType *DFSanSetLabelFnTy;
370 FunctionType *DFSanNonzeroLabelFnTy;
371 FunctionType *DFSanVarargWrapperFnTy;
372 FunctionType *DFSanConditionalCallbackFnTy;
373 FunctionType *DFSanConditionalCallbackOriginFnTy;
374 FunctionType *DFSanReachesFunctionCallbackFnTy;
375 FunctionType *DFSanReachesFunctionCallbackOriginFnTy;
376 FunctionType *DFSanCmpCallbackFnTy;
377 FunctionType *DFSanLoadStoreCallbackFnTy;
378 FunctionType *DFSanMemTransferCallbackFnTy;
379 FunctionType *DFSanChainOriginFnTy;
380 FunctionType *DFSanChainOriginIfTaintedFnTy;
381 FunctionType *DFSanMemOriginTransferFnTy;
382 FunctionType *DFSanMemShadowOriginTransferFnTy;
383 FunctionType *DFSanMemShadowOriginConditionalExchangeFnTy;
384 FunctionType *DFSanMaybeStoreOriginFnTy;
385 FunctionCallee DFSanUnionLoadFn;
386 FunctionCallee DFSanLoadLabelAndOriginFn;
387 FunctionCallee DFSanUnimplementedFn;
388 FunctionCallee DFSanWrapperExternWeakNullFn;
389 FunctionCallee DFSanSetLabelFn;
390 FunctionCallee DFSanNonzeroLabelFn;
391 FunctionCallee DFSanVarargWrapperFn;
392 FunctionCallee DFSanLoadCallbackFn;
393 FunctionCallee DFSanStoreCallbackFn;
394 FunctionCallee DFSanMemTransferCallbackFn;
395 FunctionCallee DFSanConditionalCallbackFn;
396 FunctionCallee DFSanConditionalCallbackOriginFn;
397 FunctionCallee DFSanReachesFunctionCallbackFn;
398 FunctionCallee DFSanReachesFunctionCallbackOriginFn;
399 FunctionCallee DFSanCmpCallbackFn;
400 FunctionCallee DFSanChainOriginFn;
401 FunctionCallee DFSanChainOriginIfTaintedFn;
402 FunctionCallee DFSanMemOriginTransferFn;
403 FunctionCallee DFSanMemShadowOriginTransferFn;
404 FunctionCallee DFSanMemShadowOriginConditionalExchangeFn;
405 FunctionCallee DFSanMaybeStoreOriginFn;
406 SmallPtrSet<Value *, 16> DFSanRuntimeFunctions;
407 MDNode *ColdCallWeights;
408 MDNode *OriginStoreWeights;
409 DFSanABIList ABIList;
410 DenseMap<Value *, Function *> UnwrappedFnMap;
411 AttributeMask ReadOnlyNoneAttrs;
412 StringSet<> CombineTaintLookupTableNames;
416 const MemoryMapParams *MapParams;
421 Value *ShadowOffset);
422 std::pair<Value *, Value *> getShadowOriginAddress(
Value *Addr,
426 bool isInstrumented(
const GlobalAlias *GA);
427 bool isForceZeroLabels(
const Function *
F);
428 TransformedFunction getCustomFunctionType(FunctionType *
T,
429 TargetLibraryInfo &TLI);
431 void addGlobalNameSuffix(GlobalValue *GV);
435 FunctionType *NewFT);
436 void initializeCallbackFunctions(
Module &M);
437 void initializeRuntimeFunctions(
Module &M);
438 bool initializeModule(
Module &M);
450 bool shouldTrackOrigins();
462 bool isZeroShadow(
Value *V);
476 DataFlowSanitizer(
const InstrumentationOptions &Opts,
477 const std::vector<std::string> &ABIListFiles,
478 IntrusiveRefCntPtr<vfs::FileSystem> FS);
481 llvm::function_ref<TargetLibraryInfo &(
Function &)> GetTLI);
484struct DFSanFunction {
485 const InstrumentationOptions &Opts;
486 DataFlowSanitizer &DFS;
490 bool IsForceZeroLabels;
491 TargetLibraryInfo &TLI;
492 AllocaInst *LabelReturnAlloca =
nullptr;
493 AllocaInst *OriginReturnAlloca =
nullptr;
494 DenseMap<Value *, Value *> ValShadowMap;
495 DenseMap<Value *, Value *> ValOriginMap;
496 DenseMap<AllocaInst *, AllocaInst *> AllocaShadowMap;
497 DenseMap<AllocaInst *, AllocaInst *> AllocaOriginMap;
499 struct PHIFixupElement {
504 std::vector<PHIFixupElement> PHIFixups;
506 DenseSet<Instruction *> SkipInsts;
507 std::vector<Value *> NonZeroChecks;
509 struct CachedShadow {
514 DenseMap<std::pair<Value *, Value *>, CachedShadow> CachedShadows;
519 DenseMap<Value *, Value *> CachedCollapsedShadows;
520 DenseMap<Value *, std::set<Value *>> ShadowElements;
522 DFSanFunction(DataFlowSanitizer &DFS,
Function *F,
bool IsNativeABI,
523 bool IsForceZeroLabels, TargetLibraryInfo &TLI)
524 : Opts(DFS.Opts), DFS(DFS), F(F), IsNativeABI(IsNativeABI),
525 IsForceZeroLabels(IsForceZeroLabels), TLI(TLI) {
543 Value *getRetvalOriginTLS();
546 void setOrigin(Instruction *
I,
Value *Origin);
548 Value *combineOperandOrigins(Instruction *Inst);
555 Value *combineOrigins(
const std::vector<Value *> &Shadows,
556 const std::vector<Value *> &Origins,
560 void setShadow(Instruction *
I,
Value *Shadow);
568 Value *combineOperandShadows(Instruction *Inst);
582 Align InstAlignment,
Value *PrimitiveShadow,
604 Align getShadowAlign(Align InstAlignment);
608 void addConditionalCallbacksIfEnabled(Instruction &
I,
Value *Condition);
612 void addReachesFunctionCallbacksIfEnabled(
IRBuilder<> &IRB, Instruction &
I,
615 bool isLookupTableConstant(
Value *
P);
620 template <
class AggregateType>
621 Value *collapseAggregateShadow(AggregateType *AT,
Value *Shadow,
627 Value *getShadowForTLSArgument(Argument *
A);
630 std::pair<Value *, Value *>
632 Align ShadowAlign, Align OriginAlign,
Value *FirstOrigin,
635 Align getOriginAlign(Align InstAlignment);
646 bool useCallbackLoadLabelAndOrigin(
uint64_t Size, Align InstAlignment);
662 uint64_t StoreOriginSize, Align Alignment);
671 Align InstAlignment);
676 bool shouldInstrumentWithCall();
682 std::pair<Value *, Value *>
686 int NumOriginStores = 0;
689class DFSanVisitor :
public InstVisitor<DFSanVisitor> {
693 DFSanVisitor(DFSanFunction &DFSF) : DFSF(DFSF) {}
695 const DataLayout &getDataLayout()
const {
696 return DFSF.F->getDataLayout();
700 void visitInstOperands(Instruction &
I);
702 void visitUnaryOperator(UnaryOperator &UO);
703 void visitBinaryOperator(BinaryOperator &BO);
704 void visitBitCastInst(BitCastInst &BCI);
705 void visitCastInst(CastInst &CI);
706 void visitCmpInst(CmpInst &CI);
707 void visitLandingPadInst(LandingPadInst &LPI);
708 void visitGetElementPtrInst(GetElementPtrInst &GEPI);
709 void visitLoadInst(LoadInst &LI);
710 void visitStoreInst(StoreInst &SI);
711 void visitAtomicRMWInst(AtomicRMWInst &
I);
712 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I);
713 void visitReturnInst(ReturnInst &RI);
714 void visitLibAtomicLoad(CallBase &CB);
715 void visitLibAtomicStore(CallBase &CB);
716 void visitLibAtomicExchange(CallBase &CB);
717 void visitLibAtomicCompareExchange(CallBase &CB);
718 void visitCallBase(CallBase &CB);
719 void visitPHINode(PHINode &PN);
720 void visitExtractElementInst(ExtractElementInst &
I);
721 void visitInsertElementInst(InsertElementInst &
I);
722 void visitShuffleVectorInst(ShuffleVectorInst &
I);
723 void visitExtractValueInst(ExtractValueInst &
I);
724 void visitInsertValueInst(InsertValueInst &
I);
725 void visitAllocaInst(AllocaInst &
I);
726 void visitSelectInst(SelectInst &
I);
727 void visitMemSetInst(MemSetInst &
I);
728 void visitMemTransferInst(MemTransferInst &
I);
729 void visitCondBrInst(CondBrInst &BR);
730 void visitSwitchInst(SwitchInst &SW);
733 void visitCASOrRMW(Align InstAlignment, Instruction &
I);
736 bool visitWrappedCallBase(
Function &
F, CallBase &CB);
739 void visitInstOperandOrigins(Instruction &
I);
741 void addShadowArguments(
Function &
F, CallBase &CB, std::vector<Value *> &Args,
744 void addOriginArguments(
Function &
F, CallBase &CB, std::vector<Value *> &Args,
751bool LibAtomicFunction(
const Function &
F) {
757 if (!
F.hasName() ||
F.isVarArg())
759 switch (
F.arg_size()) {
761 return F.getName() ==
"__atomic_load" ||
F.getName() ==
"__atomic_store";
763 return F.getName() ==
"__atomic_exchange";
765 return F.getName() ==
"__atomic_compare_exchange";
773DataFlowSanitizer::DataFlowSanitizer(
774 const InstrumentationOptions &Opts,
775 const std::vector<std::string> &ABIListFiles,
778 std::vector<std::string> AllABIListFiles(std::move(ABIListFiles));
783 Opts.dfsan_combine_taint_lookup_table);
790 AttributeList NewParamAttrs;
791 Attribute::AttrKind ShadowParamExtAttr =
793 Attribute::AttrKind OriginParamExtAttr =
794 TLI.getExtAttrForI32Param(
false);
800 std::vector<unsigned> ArgumentIndexMapping;
801 for (
unsigned I = 0,
E =
T->getNumParams();
I !=
E; ++
I) {
802 Type *ParamType =
T->getParamType(
I);
803 ArgumentIndexMapping.push_back(ArgTypes.
size());
806 for (
unsigned I = 0,
E =
T->getNumParams();
I !=
E; ++
I) {
807 NewParamAttrs = NewParamAttrs.maybeAddParamAttribute(*Ctx, ArgTypes.
size(),
812 ArgTypes.
push_back(PrimitiveShadowPtrTy);
813 Type *RetType =
T->getReturnType();
815 ArgTypes.
push_back(PrimitiveShadowPtrTy);
817 if (shouldTrackOrigins()) {
818 for (
unsigned I = 0,
E =
T->getNumParams();
I !=
E; ++
I) {
819 NewParamAttrs = NewParamAttrs.maybeAddParamAttribute(
820 *Ctx, ArgTypes.
size(), OriginParamExtAttr);
829 return TransformedFunction(
830 T, FunctionType::get(
T->getReturnType(), ArgTypes,
T->isVarArg()),
831 ArgumentIndexMapping, NewParamAttrs);
834bool DataFlowSanitizer::isZeroShadow(
Value *V) {
845bool DataFlowSanitizer::hasLoadSizeForFastPath(
uint64_t Size) {
847 return ShadowSize % 8 == 0 || ShadowSize == 4;
850bool DataFlowSanitizer::shouldTrackOrigins() {
851 return Opts.dfsan_track_origins;
854Constant *DataFlowSanitizer::getZeroShadow(
Type *OrigTy) {
856 return ZeroPrimitiveShadow;
857 Type *ShadowTy = getShadowTy(OrigTy);
862 return getZeroShadow(
V->getType());
872 for (
unsigned Idx = 0; Idx < AT->getNumElements(); Idx++) {
875 Shadow, Indices, AT->getElementType(), PrimitiveShadow, IRB);
882 for (
unsigned Idx = 0; Idx < ST->getNumElements(); Idx++) {
885 Shadow, Indices, ST->getElementType(Idx), PrimitiveShadow, IRB);
893bool DFSanFunction::shouldInstrumentWithCall() {
894 return Opts.dfsan_instrument_with_call_threshold >= 0 &&
895 NumOriginStores >= Opts.dfsan_instrument_with_call_threshold;
898Value *DFSanFunction::expandFromPrimitiveShadow(
Type *
T,
Value *PrimitiveShadow,
900 Type *ShadowTy = DFS.getShadowTy(
T);
903 return PrimitiveShadow;
905 if (DFS.isZeroShadow(PrimitiveShadow))
906 return DFS.getZeroShadow(ShadowTy);
909 SmallVector<unsigned, 4> Indices;
912 PrimitiveShadow, IRB);
915 CachedCollapsedShadows[Shadow] = PrimitiveShadow;
919template <
class AggregateType>
920Value *DFSanFunction::collapseAggregateShadow(AggregateType *AT,
Value *Shadow,
922 if (!AT->getNumElements())
923 return DFS.ZeroPrimitiveShadow;
926 Value *Aggregator = collapseToPrimitiveShadow(FirstItem, IRB);
928 for (
unsigned Idx = 1;
Idx < AT->getNumElements();
Idx++) {
930 Value *ShadowInner = collapseToPrimitiveShadow(ShadowItem, IRB);
931 Aggregator = IRB.
CreateOr(Aggregator, ShadowInner);
936Value *DFSanFunction::collapseToPrimitiveShadow(
Value *Shadow,
942 return collapseAggregateShadow<>(AT, Shadow, IRB);
944 return collapseAggregateShadow<>(ST, Shadow, IRB);
948Value *DFSanFunction::collapseToPrimitiveShadow(
Value *Shadow,
955 Value *&CS = CachedCollapsedShadows[Shadow];
960 Value *PrimitiveShadow = collapseToPrimitiveShadow(Shadow, IRB);
962 CS = PrimitiveShadow;
963 return PrimitiveShadow;
966void DFSanFunction::addConditionalCallbacksIfEnabled(Instruction &
I,
968 if (!Opts.dfsan_conditional_callbacks) {
972 Value *CondShadow = getShadow(Condition);
974 if (DFS.shouldTrackOrigins()) {
975 Value *CondOrigin = getOrigin(Condition);
976 CI = IRB.
CreateCall(DFS.DFSanConditionalCallbackOriginFn,
977 {CondShadow, CondOrigin});
980 CI = IRB.
CreateCall(DFS.DFSanConditionalCallbackFn, {CondShadow});
985void DFSanFunction::addReachesFunctionCallbacksIfEnabled(
IRBuilder<> &IRB,
988 if (!Opts.dfsan_reaches_function_callbacks) {
991 const DebugLoc &dbgloc =
I.getDebugLoc();
992 Value *DataShadow = collapseToPrimitiveShadow(getShadow(
Data), IRB);
996 if (dbgloc.
get() ==
nullptr) {
997 CILine = llvm::ConstantInt::get(
I.getContext(), llvm::APInt(32, 0));
999 I.getFunction()->getParent()->getSourceFileName());
1001 CILine = llvm::ConstantInt::get(
I.getContext(),
1002 llvm::APInt(32, dbgloc.
getLine()));
1010 std::vector<Value *>
args;
1012 Attribute::AttrKind I32ParamExtAttr =
1013 TLI.getExtAttrForI32Param(
false);
1014 if (DFS.shouldTrackOrigins()) {
1016 args = { DataShadow, DataOrigin, FilePathPtr, CILine, FunctionNamePtr };
1017 CB = IRB.
CreateCall(DFS.DFSanReachesFunctionCallbackOriginFn,
args);
1021 args = { DataShadow, FilePathPtr, CILine, FunctionNamePtr };
1029Type *DataFlowSanitizer::getShadowTy(
Type *OrigTy) {
1031 return PrimitiveShadowTy;
1033 return PrimitiveShadowTy;
1035 return PrimitiveShadowTy;
1037 return ArrayType::get(getShadowTy(AT->getElementType()),
1038 AT->getNumElements());
1041 for (
unsigned I = 0,
N =
ST->getNumElements();
I <
N; ++
I)
1042 Elements.push_back(getShadowTy(
ST->getElementType(
I)));
1045 return PrimitiveShadowTy;
1048Type *DataFlowSanitizer::getShadowTy(
Value *V) {
1049 return getShadowTy(
V->getType());
1052bool DataFlowSanitizer::initializeModule(
Module &M) {
1053 Triple TargetTriple(
M.getTargetTriple());
1054 const DataLayout &
DL =
M.getDataLayout();
1058 switch (TargetTriple.getArch()) {
1076 Ctx = &
M.getContext();
1077 Int8Ptr = PointerType::getUnqual(*Ctx);
1079 OriginPtrTy = PointerType::getUnqual(*Ctx);
1081 PrimitiveShadowPtrTy = PointerType::getUnqual(*Ctx);
1082 IntptrTy =
DL.getIntPtrType(*Ctx);
1086 Type *DFSanUnionLoadArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
1087 DFSanUnionLoadFnTy = FunctionType::get(PrimitiveShadowTy, DFSanUnionLoadArgs,
1089 Type *DFSanLoadLabelAndOriginArgs[2] = {Int8Ptr, IntptrTy};
1090 DFSanLoadLabelAndOriginFnTy =
1093 DFSanUnimplementedFnTy = FunctionType::get(
1094 Type::getVoidTy(*Ctx), PointerType::getUnqual(*Ctx),
false);
1095 Type *DFSanWrapperExternWeakNullArgs[2] = {Int8Ptr, Int8Ptr};
1096 DFSanWrapperExternWeakNullFnTy =
1097 FunctionType::get(Type::getVoidTy(*Ctx), DFSanWrapperExternWeakNullArgs,
1099 Type *DFSanSetLabelArgs[4] = {PrimitiveShadowTy, OriginTy,
1100 PointerType::getUnqual(*Ctx), IntptrTy};
1101 DFSanSetLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx),
1102 DFSanSetLabelArgs,
false);
1103 DFSanNonzeroLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx), {},
1105 DFSanVarargWrapperFnTy = FunctionType::get(
1106 Type::getVoidTy(*Ctx), PointerType::getUnqual(*Ctx),
false);
1107 DFSanConditionalCallbackFnTy =
1108 FunctionType::get(Type::getVoidTy(*Ctx), PrimitiveShadowTy,
1110 Type *DFSanConditionalCallbackOriginArgs[2] = {PrimitiveShadowTy, OriginTy};
1111 DFSanConditionalCallbackOriginFnTy = FunctionType::get(
1112 Type::getVoidTy(*Ctx), DFSanConditionalCallbackOriginArgs,
1114 Type *DFSanReachesFunctionCallbackArgs[4] = {PrimitiveShadowTy, Int8Ptr,
1116 DFSanReachesFunctionCallbackFnTy =
1117 FunctionType::get(Type::getVoidTy(*Ctx), DFSanReachesFunctionCallbackArgs,
1119 Type *DFSanReachesFunctionCallbackOriginArgs[5] = {
1120 PrimitiveShadowTy, OriginTy, Int8Ptr, OriginTy, Int8Ptr};
1121 DFSanReachesFunctionCallbackOriginFnTy = FunctionType::get(
1122 Type::getVoidTy(*Ctx), DFSanReachesFunctionCallbackOriginArgs,
1124 DFSanCmpCallbackFnTy =
1125 FunctionType::get(Type::getVoidTy(*Ctx), PrimitiveShadowTy,
1127 DFSanChainOriginFnTy =
1128 FunctionType::get(OriginTy, OriginTy,
false);
1129 Type *DFSanChainOriginIfTaintedArgs[2] = {PrimitiveShadowTy, OriginTy};
1130 DFSanChainOriginIfTaintedFnTy = FunctionType::get(
1131 OriginTy, DFSanChainOriginIfTaintedArgs,
false);
1133 Int8Ptr, IntptrTy, OriginTy};
1134 DFSanMaybeStoreOriginFnTy = FunctionType::get(
1135 Type::getVoidTy(*Ctx), DFSanMaybeStoreOriginArgs,
false);
1136 Type *DFSanMemOriginTransferArgs[3] = {Int8Ptr, Int8Ptr, IntptrTy};
1137 DFSanMemOriginTransferFnTy = FunctionType::get(
1138 Type::getVoidTy(*Ctx), DFSanMemOriginTransferArgs,
false);
1139 Type *DFSanMemShadowOriginTransferArgs[3] = {Int8Ptr, Int8Ptr, IntptrTy};
1140 DFSanMemShadowOriginTransferFnTy =
1141 FunctionType::get(Type::getVoidTy(*Ctx), DFSanMemShadowOriginTransferArgs,
1143 Type *DFSanMemShadowOriginConditionalExchangeArgs[5] = {
1145 DFSanMemShadowOriginConditionalExchangeFnTy = FunctionType::get(
1146 Type::getVoidTy(*Ctx), DFSanMemShadowOriginConditionalExchangeArgs,
1148 Type *DFSanLoadStoreCallbackArgs[2] = {PrimitiveShadowTy, Int8Ptr};
1149 DFSanLoadStoreCallbackFnTy =
1150 FunctionType::get(Type::getVoidTy(*Ctx), DFSanLoadStoreCallbackArgs,
1152 Type *DFSanMemTransferCallbackArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
1153 DFSanMemTransferCallbackFnTy =
1154 FunctionType::get(Type::getVoidTy(*Ctx), DFSanMemTransferCallbackArgs,
1157 ColdCallWeights = MDBuilder(*Ctx).createUnlikelyBranchWeights();
1158 OriginStoreWeights = MDBuilder(*Ctx).createUnlikelyBranchWeights();
1162bool DataFlowSanitizer::isInstrumented(
const Function *
F) {
1163 return !ABIList.isIn(*
F,
"uninstrumented");
1166bool DataFlowSanitizer::isInstrumented(
const GlobalAlias *GA) {
1167 return !ABIList.isIn(*GA,
"uninstrumented");
1170bool DataFlowSanitizer::isForceZeroLabels(
const Function *
F) {
1171 return ABIList.isIn(*
F,
"force_zero_labels");
1174DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(
Function *
F) {
1175 if (ABIList.isIn(*
F,
"functional"))
1176 return WK_Functional;
1177 if (ABIList.isIn(*
F,
"discard"))
1179 if (ABIList.isIn(*
F,
"custom"))
1185void DataFlowSanitizer::addGlobalNameSuffix(GlobalValue *GV) {
1186 if (!Opts.dfsan_add_global_name_suffix)
1189 std::string GVName = std::string(GV->
getName()), Suffix =
".dfsan";
1197 for (Module::GlobalAsmFragment &Frag :
1199 std::string SearchStr =
".symver " + GVName +
",";
1200 size_t Pos = Frag.Asm.find(SearchStr);
1201 if (Pos != std::string::npos) {
1202 Frag.Asm.replace(Pos, SearchStr.size(),
1203 ".symver " + GVName + Suffix +
",");
1204 Pos = Frag.Asm.find(
'@');
1206 if (Pos == std::string::npos)
1209 Frag.Asm.replace(Pos, 1, Suffix +
"@");
1214void DataFlowSanitizer::buildExternWeakCheckIfNeeded(
IRBuilder<> &IRB,
1224 std::vector<Value *>
Args;
1227 IRB.
CreateCall(DFSanWrapperExternWeakNullFn, Args);
1232DataFlowSanitizer::buildWrapperFunction(
Function *
F, StringRef NewFName,
1234 FunctionType *NewFT) {
1235 FunctionType *FT =
F->getFunctionType();
1237 NewFName,
F->getParent());
1240 NewFT->getReturnType(), NewF->
getAttributes().getRetAttrs()));
1243 if (
F->isVarArg()) {
1246 IRBuilder<>(BB).CreateGlobalString(
F->getName()),
"", BB);
1247 new UnreachableInst(*Ctx, BB);
1249 auto ArgIt = pointer_iterator<Argument *>(NewF->
arg_begin());
1250 std::vector<Value *>
Args(ArgIt, ArgIt + FT->getNumParams());
1253 if (FT->getReturnType()->isVoidTy())
1263void DataFlowSanitizer::initializeRuntimeFunctions(
Module &M) {
1264 LLVMContext &
C =
M.getContext();
1265 Attribute::AttrKind I8ParamExtAttr =
1267 Attribute::AttrKind I32ParamExtAttr =
1268 TargetLibraryInfo::getExtAttrForI32Param(
M.getTargetTriple(),
1272 AL =
AL.addFnAttribute(
C, Attribute::NoUnwind);
1273 AL =
AL.addFnAttribute(
1275 AL =
AL.addRetAttribute(
C, Attribute::ZExt);
1277 Mod->getOrInsertFunction(
"__dfsan_union_load", DFSanUnionLoadFnTy, AL);
1281 AL =
AL.addFnAttribute(
C, Attribute::NoUnwind);
1282 AL =
AL.addFnAttribute(
1284 AL =
AL.addRetAttribute(
C, Attribute::ZExt);
1285 DFSanLoadLabelAndOriginFn =
Mod->getOrInsertFunction(
1286 "__dfsan_load_label_and_origin", DFSanLoadLabelAndOriginFnTy, AL);
1288 DFSanUnimplementedFn =
1289 Mod->getOrInsertFunction(
"__dfsan_unimplemented", DFSanUnimplementedFnTy);
1290 DFSanWrapperExternWeakNullFn =
Mod->getOrInsertFunction(
1291 "__dfsan_wrapper_extern_weak_null", DFSanWrapperExternWeakNullFnTy);
1294 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1295 AL =
AL.maybeAddParamAttribute(
M.getContext(), 1, I32ParamExtAttr);
1297 Mod->getOrInsertFunction(
"__dfsan_set_label", DFSanSetLabelFnTy, AL);
1299 DFSanNonzeroLabelFn =
1300 Mod->getOrInsertFunction(
"__dfsan_nonzero_label", DFSanNonzeroLabelFnTy);
1301 DFSanVarargWrapperFn =
Mod->getOrInsertFunction(
"__dfsan_vararg_wrapper",
1302 DFSanVarargWrapperFnTy);
1305 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I32ParamExtAttr);
1306 AL =
AL.addRetAttribute(
M.getContext(), Attribute::ZExt);
1307 DFSanChainOriginFn =
Mod->getOrInsertFunction(
"__dfsan_chain_origin",
1308 DFSanChainOriginFnTy, AL);
1312 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1313 AL =
AL.maybeAddParamAttribute(
M.getContext(), 1, I32ParamExtAttr);
1314 AL =
AL.addRetAttribute(
M.getContext(), Attribute::ZExt);
1315 DFSanChainOriginIfTaintedFn =
Mod->getOrInsertFunction(
1316 "__dfsan_chain_origin_if_tainted", DFSanChainOriginIfTaintedFnTy, AL);
1318 DFSanMemOriginTransferFn =
Mod->getOrInsertFunction(
1319 "__dfsan_mem_origin_transfer", DFSanMemOriginTransferFnTy);
1321 DFSanMemShadowOriginTransferFn =
Mod->getOrInsertFunction(
1322 "__dfsan_mem_shadow_origin_transfer", DFSanMemShadowOriginTransferFnTy);
1326 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1327 DFSanMemShadowOriginConditionalExchangeFn =
Mod->getOrInsertFunction(
1328 "__dfsan_mem_shadow_origin_conditional_exchange",
1329 DFSanMemShadowOriginConditionalExchangeFnTy, AL);
1334 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1335 AL =
AL.maybeAddParamAttribute(
M.getContext(), 3, I32ParamExtAttr);
1336 DFSanMaybeStoreOriginFn =
Mod->getOrInsertFunction(
1337 "__dfsan_maybe_store_origin", DFSanMaybeStoreOriginFnTy, AL);
1340 DFSanRuntimeFunctions.
insert(
1342 DFSanRuntimeFunctions.
insert(
1344 DFSanRuntimeFunctions.
insert(
1346 DFSanRuntimeFunctions.
insert(
1348 DFSanRuntimeFunctions.
insert(
1350 DFSanRuntimeFunctions.
insert(
1352 DFSanRuntimeFunctions.
insert(
1354 DFSanRuntimeFunctions.
insert(
1356 DFSanRuntimeFunctions.
insert(
1358 DFSanRuntimeFunctions.
insert(
1360 DFSanRuntimeFunctions.
insert(
1362 DFSanRuntimeFunctions.
insert(
1364 DFSanRuntimeFunctions.
insert(
1366 DFSanRuntimeFunctions.
insert(
1368 DFSanRuntimeFunctions.
insert(
1370 DFSanRuntimeFunctions.
insert(
1372 DFSanRuntimeFunctions.
insert(
1374 DFSanRuntimeFunctions.
insert(
1376 DFSanRuntimeFunctions.
insert(
1378 DFSanRuntimeFunctions.
insert(
1379 DFSanMemShadowOriginConditionalExchangeFn.
getCallee()
1381 DFSanRuntimeFunctions.
insert(
1386void DataFlowSanitizer::initializeCallbackFunctions(
Module &M) {
1387 Attribute::AttrKind I8ParamExtAttr =
1389 Attribute::AttrKind I32ParamExtAttr =
1390 TargetLibraryInfo::getExtAttrForI32Param(
M.getTargetTriple(),
1394 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1395 DFSanLoadCallbackFn =
Mod->getOrInsertFunction(
1396 "__dfsan_load_callback", DFSanLoadStoreCallbackFnTy, AL);
1400 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1401 DFSanStoreCallbackFn =
Mod->getOrInsertFunction(
1402 "__dfsan_store_callback", DFSanLoadStoreCallbackFnTy, AL);
1404 DFSanMemTransferCallbackFn =
Mod->getOrInsertFunction(
1405 "__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
1408 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1409 DFSanCmpCallbackFn =
Mod->getOrInsertFunction(
"__dfsan_cmp_callback",
1410 DFSanCmpCallbackFnTy, AL);
1414 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1415 DFSanConditionalCallbackFn =
Mod->getOrInsertFunction(
1416 "__dfsan_conditional_callback", DFSanConditionalCallbackFnTy, AL);
1420 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1421 AL =
AL.maybeAddParamAttribute(
M.getContext(), 1, I32ParamExtAttr);
1422 DFSanConditionalCallbackOriginFn =
1423 Mod->getOrInsertFunction(
"__dfsan_conditional_callback_origin",
1424 DFSanConditionalCallbackOriginFnTy, AL);
1428 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1429 AL =
AL.maybeAddParamAttribute(
M.getContext(), 2, I32ParamExtAttr);
1430 DFSanReachesFunctionCallbackFn =
1431 Mod->getOrInsertFunction(
"__dfsan_reaches_function_callback",
1432 DFSanReachesFunctionCallbackFnTy, AL);
1436 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1437 AL =
AL.maybeAddParamAttribute(
M.getContext(), 1, I32ParamExtAttr);
1438 AL =
AL.maybeAddParamAttribute(
M.getContext(), 3, I32ParamExtAttr);
1439 DFSanReachesFunctionCallbackOriginFn =
1440 Mod->getOrInsertFunction(
"__dfsan_reaches_function_callback_origin",
1441 DFSanReachesFunctionCallbackOriginFnTy, AL);
1445bool DataFlowSanitizer::runImpl(
1446 Module &M, llvm::function_ref<TargetLibraryInfo &(
Function &)> GetTLI) {
1447 initializeModule(M);
1449 if (ABIList.isIn(M,
"skip"))
1452 const unsigned InitialGlobalSize =
M.global_size();
1453 const unsigned InitialModuleSize =
M.size();
1457 auto GetOrInsertGlobal = [
this, &
Changed](StringRef
Name,
1458 Type *Ty) -> Constant * {
1459 GlobalVariable *
G =
Mod->getOrInsertGlobal(Name, Ty);
1460 Changed |=
G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
1461 G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
1467 GetOrInsertGlobal(
"__dfsan_arg_tls",
1468 ArrayType::get(Type::getInt64Ty(*Ctx),
ArgTLSSize / 8));
1469 RetvalTLS = GetOrInsertGlobal(
1470 "__dfsan_retval_tls",
1472 ArgOriginTLSTy = ArrayType::get(OriginTy, NumOfElementsInArgOrgTLS);
1473 ArgOriginTLS = GetOrInsertGlobal(
"__dfsan_arg_origin_tls", ArgOriginTLSTy);
1474 RetvalOriginTLS = GetOrInsertGlobal(
"__dfsan_retval_origin_tls", OriginTy);
1476 (void)
Mod->getOrInsertGlobal(
"__dfsan_track_origins", OriginTy, [&] {
1478 return new GlobalVariable(
1479 M, OriginTy, true, GlobalValue::WeakODRLinkage,
1480 ConstantInt::getSigned(OriginTy, Opts.dfsan_track_origins),
1481 "__dfsan_track_origins");
1484 initializeCallbackFunctions(M);
1485 initializeRuntimeFunctions(M);
1487 std::vector<Function *> FnsToInstrument;
1488 SmallPtrSet<Function *, 2> FnsWithNativeABI;
1489 SmallPtrSet<Function *, 2> FnsWithForceZeroLabel;
1490 SmallPtrSet<Constant *, 1> PersonalityFns;
1492 if (!
F.isIntrinsic() && !DFSanRuntimeFunctions.
contains(&
F) &&
1493 !LibAtomicFunction(
F) &&
1494 !
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) {
1495 FnsToInstrument.push_back(&
F);
1496 if (
F.hasPersonalityFn())
1497 PersonalityFns.
insert(
F.getPersonalityFn()->stripPointerCasts());
1500 if (Opts.dfsan_ignore_personality_routine) {
1501 for (
auto *
C : PersonalityFns) {
1504 if (!isInstrumented(
F))
1518 bool GAInst = isInstrumented(&GA), FInst = isInstrumented(
F);
1519 if (GAInst && FInst) {
1520 addGlobalNameSuffix(&GA);
1521 }
else if (GAInst != FInst) {
1526 buildWrapperFunction(
F,
"", GA.
getLinkage(),
F->getFunctionType());
1530 FnsToInstrument.push_back(NewF);
1539 for (std::vector<Function *>::iterator FI = FnsToInstrument.begin(),
1540 FE = FnsToInstrument.end();
1543 FunctionType *FT =
F.getFunctionType();
1545 bool IsZeroArgsVoidRet = (FT->getNumParams() == 0 && !FT->isVarArg() &&
1546 FT->getReturnType()->isVoidTy());
1548 if (isInstrumented(&
F)) {
1549 if (isForceZeroLabels(&
F))
1550 FnsWithForceZeroLabel.
insert(&
F);
1555 addGlobalNameSuffix(&
F);
1556 }
else if (!IsZeroArgsVoidRet || getWrapperKind(&
F) == WK_Custom) {
1564 F.hasLocalLinkage() ?
F.getLinkage()
1567 Function *NewF = buildWrapperFunction(
1569 (shouldTrackOrigins() ? std::string(
"dfso$") : std::string(
"dfsw$")) +
1570 std::string(
F.getName()),
1571 WrapperLinkage, FT);
1591 auto IsNotCmpUse = [](
Use &
U) ->
bool {
1592 User *Usr =
U.getUser();
1595 if (
CE->getOpcode() == Instruction::ICmp) {
1600 if (
I->getOpcode() == Instruction::ICmp) {
1606 F.replaceUsesWithIf(NewF, IsNotCmpUse);
1608 UnwrappedFnMap[NewF] = &
F;
1611 if (!
F.isDeclaration()) {
1621 size_t N = FI - FnsToInstrument.begin(),
1622 Count = FE - FnsToInstrument.begin();
1623 FnsToInstrument.push_back(&
F);
1624 FI = FnsToInstrument.begin() +
N;
1625 FE = FnsToInstrument.begin() +
Count;
1629 }
else if (FT->isVarArg()) {
1630 UnwrappedFnMap[&
F] = &
F;
1636 if (!
F ||
F->isDeclaration())
1641 DFSanFunction DFSF(*
this,
F, FnsWithNativeABI.
count(
F),
1642 FnsWithForceZeroLabel.
count(
F), GetTLI(*
F));
1647 if (Opts.dfsan_reaches_function_callbacks && !UnwrappedFnMap.
count(
F)) {
1649 Instruction *FirstOrigInst = &
F->getEntryBlock().front();
1652 for (
auto &FArg :
F->args()) {
1654 Value *FArgShadow = DFSF.getShadow(&FArg);
1655 if (isZeroShadow(FArgShadow))
1658 Next = FArgShadowInst->getNextNode();
1660 if (shouldTrackOrigins()) {
1661 if (Instruction *Origin =
1665 if (
Next->comesBefore(OriginNext)) {
1671 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, *
Next, &FArg);
1676 for (Instruction &
I :
F->getEntryBlock()) {
1677 if (&
I == FirstOrigInst)
1687 for (BasicBlock *BB : BBList) {
1697 if (!DFSF.SkipInsts.
count(Inst))
1698 DFSanVisitor(DFSF).visit(Inst);
1709 for (DFSanFunction::PHIFixupElement &
P : DFSF.PHIFixups) {
1710 for (
unsigned Val = 0,
N =
P.Phi->getNumIncomingValues(); Val !=
N;
1712 P.ShadowPhi->setIncomingValue(
1713 Val, DFSF.getShadow(
P.Phi->getIncomingValue(Val)));
1715 P.OriginPhi->setIncomingValue(
1716 Val, DFSF.getOrigin(
P.Phi->getIncomingValue(Val)));
1724 if (Opts.dfsan_debug_nonzero_labels) {
1725 for (
Value *V : DFSF.NonZeroChecks) {
1728 Pos = std::next(
I->getIterator());
1732 Pos = std::next(Pos->getIterator());
1734 Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(V, Pos);
1736 IRB.
CreateICmpNE(PrimitiveShadow, DFSF.DFS.ZeroPrimitiveShadow);
1738 Ne, Pos,
false, ColdCallWeights));
1740 ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn, {});
1746 M.global_size() != InitialGlobalSize ||
M.size() != InitialModuleSize;
1750 return IRB.
CreatePtrAdd(DFS.ArgTLS, ConstantInt::get(DFS.IntptrTy, ArgOffset),
1759Value *DFSanFunction::getRetvalOriginTLS() {
return DFS.RetvalOriginTLS; }
1763 ArgNo,
"_dfsarg_o");
1767 assert(DFS.shouldTrackOrigins());
1769 return DFS.ZeroOrigin;
1770 Value *&Origin = ValOriginMap[
V];
1774 return DFS.ZeroOrigin;
1775 if (
A->getArgNo() < DFS.NumOfElementsInArgOrgTLS) {
1776 Instruction *ArgOriginTLSPos = &*
F->getEntryBlock().begin();
1778 Value *ArgOriginPtr = getArgOriginTLS(
A->getArgNo(), IRB);
1779 Origin = IRB.
CreateLoad(DFS.OriginTy, ArgOriginPtr);
1782 Origin = DFS.ZeroOrigin;
1785 Origin = DFS.ZeroOrigin;
1791void DFSanFunction::setOrigin(Instruction *
I,
Value *Origin) {
1792 if (!DFS.shouldTrackOrigins())
1796 ValOriginMap[
I] = Origin;
1799Value *DFSanFunction::getShadowForTLSArgument(Argument *
A) {
1800 unsigned ArgOffset = 0;
1801 const DataLayout &
DL =
F->getDataLayout();
1802 for (
auto &FArg :
F->args()) {
1803 if (!FArg.getType()->isSized()) {
1809 unsigned Size =
DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
1822 Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
1827 return DFS.getZeroShadow(
A);
1832 return DFS.getZeroShadow(V);
1833 if (IsForceZeroLabels)
1834 return DFS.getZeroShadow(V);
1835 Value *&Shadow = ValShadowMap[
V];
1839 return DFS.getZeroShadow(V);
1840 Shadow = getShadowForTLSArgument(
A);
1841 NonZeroChecks.push_back(Shadow);
1843 Shadow = DFS.getZeroShadow(V);
1849void DFSanFunction::setShadow(Instruction *
I,
Value *Shadow) {
1851 ValShadowMap[
I] = Shadow;
1859 assert(Addr != RetvalTLS &&
"Reinstrumenting?");
1862 uint64_t AndMask = MapParams->AndMask;
1865 IRB.
CreateAnd(OffsetLong, ConstantInt::get(IntptrTy, ~AndMask));
1867 uint64_t XorMask = MapParams->XorMask;
1869 OffsetLong = IRB.
CreateXor(OffsetLong, ConstantInt::get(IntptrTy, XorMask));
1873std::pair<Value *, Value *>
1874DataFlowSanitizer::getShadowOriginAddress(
Value *Addr, Align InstAlignment,
1878 Value *ShadowOffset = getShadowOffset(Addr, IRB);
1879 Value *ShadowLong = ShadowOffset;
1880 uint64_t ShadowBase = MapParams->ShadowBase;
1881 if (ShadowBase != 0) {
1883 IRB.
CreateAdd(ShadowLong, ConstantInt::get(IntptrTy, ShadowBase));
1886 Value *OriginPtr =
nullptr;
1887 if (shouldTrackOrigins()) {
1888 Value *OriginLong = ShadowOffset;
1889 uint64_t OriginBase = MapParams->OriginBase;
1890 if (OriginBase != 0)
1892 IRB.
CreateAdd(OriginLong, ConstantInt::get(IntptrTy, OriginBase));
1898 OriginLong = IRB.
CreateAnd(OriginLong, ConstantInt::get(IntptrTy, ~Mask));
1902 return std::make_pair(ShadowPtr, OriginPtr);
1905Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1907 Value *ShadowOffset) {
1912Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1915 Value *ShadowAddr = getShadowOffset(Addr, IRB);
1916 uint64_t ShadowBase = MapParams->ShadowBase;
1917 if (ShadowBase != 0)
1919 IRB.
CreateAdd(ShadowAddr, ConstantInt::get(IntptrTy, ShadowBase));
1920 return getShadowAddress(Addr, Pos, ShadowAddr);
1925 Value *PrimitiveValue = combineShadows(
V1, V2, Pos);
1926 return expandFromPrimitiveShadow(
T, PrimitiveValue, Pos);
1933 if (DFS.isZeroShadow(
V1))
1934 return collapseToPrimitiveShadow(V2, Pos);
1935 if (DFS.isZeroShadow(V2))
1936 return collapseToPrimitiveShadow(
V1, Pos);
1938 return collapseToPrimitiveShadow(
V1, Pos);
1940 auto V1Elems = ShadowElements.
find(
V1);
1941 auto V2Elems = ShadowElements.
find(V2);
1942 if (V1Elems != ShadowElements.
end() && V2Elems != ShadowElements.
end()) {
1944 return collapseToPrimitiveShadow(
V1, Pos);
1947 return collapseToPrimitiveShadow(V2, Pos);
1949 }
else if (V1Elems != ShadowElements.
end()) {
1950 if (V1Elems->second.count(V2))
1951 return collapseToPrimitiveShadow(
V1, Pos);
1952 }
else if (V2Elems != ShadowElements.
end()) {
1953 if (V2Elems->second.count(
V1))
1954 return collapseToPrimitiveShadow(V2, Pos);
1957 auto Key = std::make_pair(
V1, V2);
1960 CachedShadow &CCS = CachedShadows[
Key];
1961 if (CCS.Block && DT.
dominates(CCS.Block, Pos->getParent()))
1965 Value *PV1 = collapseToPrimitiveShadow(
V1, Pos);
1966 Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
1969 CCS.Block = Pos->getParent();
1970 CCS.Shadow = IRB.
CreateOr(PV1, PV2);
1972 std::set<Value *> UnionElems;
1973 if (V1Elems != ShadowElements.
end()) {
1974 UnionElems = V1Elems->second;
1976 UnionElems.insert(
V1);
1978 if (V2Elems != ShadowElements.
end()) {
1979 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
1981 UnionElems.insert(V2);
1983 ShadowElements[CCS.Shadow] = std::move(UnionElems);
1991Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
1993 return DFS.getZeroShadow(Inst);
1997 Shadow = combineShadows(Shadow, getShadow(Inst->
getOperand(
I)),
2000 return expandFromPrimitiveShadow(Inst->
getType(), Shadow,
2004void DFSanVisitor::visitInstOperands(Instruction &
I) {
2005 Value *CombinedShadow = DFSF.combineOperandShadows(&
I);
2006 DFSF.setShadow(&
I, CombinedShadow);
2007 visitInstOperandOrigins(
I);
2010Value *DFSanFunction::combineOrigins(
const std::vector<Value *> &Shadows,
2011 const std::vector<Value *> &Origins,
2013 ConstantInt *Zero) {
2014 assert(Shadows.size() == Origins.size());
2015 size_t Size = Origins.size();
2017 return DFS.ZeroOrigin;
2018 Value *Origin =
nullptr;
2020 Zero = DFS.ZeroPrimitiveShadow;
2021 for (
size_t I = 0;
I !=
Size; ++
I) {
2022 Value *OpOrigin = Origins[
I];
2024 if (ConstOpOrigin && ConstOpOrigin->
isNullValue())
2030 Value *OpShadow = Shadows[
I];
2031 Value *PrimitiveShadow = collapseToPrimitiveShadow(OpShadow, Pos);
2036 return Origin ? Origin : DFS.ZeroOrigin;
2039Value *DFSanFunction::combineOperandOrigins(Instruction *Inst) {
2041 std::vector<Value *> Shadows(
Size);
2042 std::vector<Value *> Origins(
Size);
2043 for (
unsigned I = 0;
I !=
Size; ++
I) {
2047 return combineOrigins(Shadows, Origins, Inst->
getIterator());
2050void DFSanVisitor::visitInstOperandOrigins(Instruction &
I) {
2051 if (!DFSF.DFS.shouldTrackOrigins())
2053 Value *CombinedOrigin = DFSF.combineOperandOrigins(&
I);
2054 DFSF.setOrigin(&
I, CombinedOrigin);
2057Align DFSanFunction::getShadowAlign(Align InstAlignment) {
2059 Opts.dfsan_preserve_alignment ? InstAlignment :
Align(1);
2063Align DFSanFunction::getOriginAlign(Align InstAlignment) {
2068bool DFSanFunction::isLookupTableConstant(
Value *
P) {
2070 if (GV->isConstant() && GV->
hasName())
2071 return DFS.CombineTaintLookupTableNames.
count(GV->
getName());
2076bool DFSanFunction::useCallbackLoadLabelAndOrigin(
uint64_t Size,
2077 Align InstAlignment) {
2080 if (Opts.dfsan_track_origins == 2)
2101 Value **OriginAddr) {
2104 IRB.
CreateGEP(OriginTy, *OriginAddr, ConstantInt::get(IntptrTy, 1));
2108std::pair<Value *, Value *> DFSanFunction::loadShadowFast(
2111 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2112 const uint64_t ShadowSize =
Size * DFS.ShadowWidthBytes;
2114 assert(
Size >= 4 &&
"Not large enough load size for fast path!");
2117 std::vector<Value *> Shadows;
2118 std::vector<Value *> Origins;
2131 Type *WideShadowTy =
2132 ShadowSize == 4 ? Type::getInt32Ty(*DFS.Ctx) :
Type::getInt64Ty(*DFS.Ctx);
2135 Value *CombinedWideShadow =
2139 const uint64_t BytesPerWideShadow = WideShadowBitWidth / DFS.ShadowWidthBits;
2141 auto AppendWideShadowAndOrigin = [&](
Value *WideShadow,
Value *Origin) {
2142 if (BytesPerWideShadow > 4) {
2143 assert(BytesPerWideShadow == 8);
2150 Value *WideShadowLo =
2151 F->getDataLayout().isLittleEndian()
2154 ConstantInt::get(WideShadowTy, WideShadowBitWidth / 2))
2157 ConstantInt::get(WideShadowTy,
2158 ((1ULL << (WideShadowBitWidth / 2)) - 1)
2159 << (WideShadowBitWidth / 2)));
2160 Shadows.push_back(WideShadow);
2161 Origins.push_back(DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr));
2163 Shadows.push_back(WideShadowLo);
2164 Origins.push_back(Origin);
2166 Shadows.push_back(WideShadow);
2167 Origins.push_back(Origin);
2171 if (ShouldTrackOrigins)
2172 AppendWideShadowAndOrigin(CombinedWideShadow, FirstOrigin);
2179 for (
uint64_t ByteOfs = BytesPerWideShadow; ByteOfs <
Size;
2180 ByteOfs += BytesPerWideShadow) {
2181 ShadowAddr = IRB.
CreateGEP(WideShadowTy, ShadowAddr,
2182 ConstantInt::get(DFS.IntptrTy, 1));
2183 Value *NextWideShadow =
2185 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, NextWideShadow);
2186 if (ShouldTrackOrigins) {
2187 Value *NextOrigin = DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr);
2188 AppendWideShadowAndOrigin(NextWideShadow, NextOrigin);
2191 for (
unsigned Width = WideShadowBitWidth / 2; Width >= DFS.ShadowWidthBits;
2194 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, ShrShadow);
2196 return {IRB.
CreateTrunc(CombinedWideShadow, DFS.PrimitiveShadowTy),
2198 ? combineOrigins(Shadows, Origins, Pos,
2203std::pair<Value *, Value *> DFSanFunction::loadShadowOriginSansLoadTracking(
2205 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2209 const auto SI = AllocaShadowMap.
find(AI);
2210 if (SI != AllocaShadowMap.
end()) {
2213 const auto OI = AllocaOriginMap.
find(AI);
2214 assert(!ShouldTrackOrigins || OI != AllocaOriginMap.
end());
2215 return {ShadowLI, ShouldTrackOrigins
2222 SmallVector<const Value *, 2> Objs;
2224 bool AllConstants =
true;
2225 for (
const Value *Obj : Objs) {
2231 AllConstants =
false;
2235 return {DFS.ZeroPrimitiveShadow,
2236 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2239 return {DFS.ZeroPrimitiveShadow,
2240 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2244 if (ShouldTrackOrigins &&
2245 useCallbackLoadLabelAndOrigin(
Size, InstAlignment)) {
2248 IRB.
CreateCall(DFS.DFSanLoadLabelAndOriginFn,
2249 {Addr, ConstantInt::get(DFS.IntptrTy, Size)});
2252 DFS.PrimitiveShadowTy),
2257 Value *ShadowAddr, *OriginAddr;
2258 std::tie(ShadowAddr, OriginAddr) =
2259 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2261 const Align ShadowAlign = getShadowAlign(InstAlignment);
2262 const Align OriginAlign = getOriginAlign(InstAlignment);
2263 Value *Origin =
nullptr;
2264 if (ShouldTrackOrigins) {
2273 LoadInst *LI =
new LoadInst(DFS.PrimitiveShadowTy, ShadowAddr,
"", Pos);
2275 return {LI, Origin};
2279 Value *ShadowAddr1 = IRB.
CreateGEP(DFS.PrimitiveShadowTy, ShadowAddr,
2280 ConstantInt::get(DFS.IntptrTy, 1));
2285 return {combineShadows(
Load, Load1, Pos), Origin};
2288 bool HasSizeForFastPath = DFS.hasLoadSizeForFastPath(
Size);
2290 if (HasSizeForFastPath)
2291 return loadShadowFast(ShadowAddr, OriginAddr,
Size, ShadowAlign,
2292 OriginAlign, Origin, Pos);
2296 DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
2298 return {FallbackCall, Origin};
2301std::pair<Value *, Value *>
2304 Value *PrimitiveShadow, *Origin;
2305 std::tie(PrimitiveShadow, Origin) =
2306 loadShadowOriginSansLoadTracking(Addr,
Size, InstAlignment, Pos);
2307 if (DFS.shouldTrackOrigins()) {
2308 if (Opts.dfsan_track_origins == 2) {
2311 if (!ConstantShadow || !ConstantShadow->isNullValue())
2312 Origin = updateOriginIfTainted(PrimitiveShadow, Origin, IRB);
2315 return {PrimitiveShadow, Origin};
2336 if (!V->getType()->isPointerTy())
2345 V =
GEP->getPointerOperand();
2348 if (!V->getType()->isPointerTy())
2353 }
while (Visited.
insert(V).second);
2358void DFSanVisitor::visitLoadInst(LoadInst &LI) {
2362 DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
2363 DFSF.setOrigin(&LI, DFSF.DFS.ZeroOrigin);
2378 Pos = std::next(Pos);
2380 std::vector<Value *> Shadows;
2381 std::vector<Value *> Origins;
2382 Value *PrimitiveShadow, *Origin;
2383 std::tie(PrimitiveShadow, Origin) =
2385 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2386 if (ShouldTrackOrigins) {
2387 Shadows.push_back(PrimitiveShadow);
2388 Origins.push_back(Origin);
2390 if (DFSF.Opts.dfsan_combine_pointer_labels_on_load ||
2391 DFSF.isLookupTableConstant(
2394 PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, Pos);
2395 if (ShouldTrackOrigins) {
2396 Shadows.push_back(PtrShadow);
2400 if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
2401 DFSF.NonZeroChecks.push_back(PrimitiveShadow);
2404 DFSF.expandFromPrimitiveShadow(LI.
getType(), PrimitiveShadow, Pos);
2405 DFSF.setShadow(&LI, Shadow);
2407 if (ShouldTrackOrigins) {
2408 DFSF.setOrigin(&LI, DFSF.combineOrigins(Shadows, Origins, Pos));
2411 if (DFSF.Opts.dfsan_event_callbacks) {
2415 IRB.
CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr});
2420 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, LI, &LI);
2423Value *DFSanFunction::updateOriginIfTainted(
Value *Shadow,
Value *Origin,
2425 assert(DFS.shouldTrackOrigins());
2426 return IRB.
CreateCall(DFS.DFSanChainOriginIfTaintedFn, {Shadow, Origin});
2430 if (!DFS.shouldTrackOrigins())
2432 return IRB.
CreateCall(DFS.DFSanChainOriginFn, V);
2436 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2437 const DataLayout &
DL =
F->getDataLayout();
2438 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2439 if (IntptrSize == OriginSize)
2441 assert(IntptrSize == OriginSize * 2);
2447 Value *StoreOriginAddr,
2448 uint64_t StoreOriginSize, Align Alignment) {
2449 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2450 const DataLayout &
DL =
F->getDataLayout();
2451 const Align IntptrAlignment =
DL.getABITypeAlign(DFS.IntptrTy);
2452 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2454 assert(IntptrSize >= OriginSize);
2458 if (Alignment >= IntptrAlignment && IntptrSize > OriginSize) {
2459 Value *IntptrOrigin = originToIntptr(IRB, Origin);
2460 Value *IntptrStoreOriginPtr =
2462 for (
unsigned I = 0;
I < StoreOriginSize / IntptrSize; ++
I) {
2465 : IntptrStoreOriginPtr;
2467 Ofs += IntptrSize / OriginSize;
2468 CurrentAlignment = IntptrAlignment;
2472 for (
unsigned I = Ofs;
I < (StoreOriginSize + OriginSize - 1) / OriginSize;
2482 const Twine &Name) {
2483 Type *VTy =
V->getType();
2488 return IRB.
CreateICmpNE(V, ConstantInt::get(VTy, 0), Name);
2493 Value *StoreOriginAddr, Align InstAlignment) {
2496 const Align OriginAlignment = getOriginAlign(InstAlignment);
2497 Value *CollapsedShadow = collapseToPrimitiveShadow(Shadow, Pos);
2500 if (!ConstantShadow->isNullValue())
2501 paintOrigin(IRB, updateOrigin(Origin, IRB), StoreOriginAddr,
Size,
2506 if (shouldInstrumentWithCall()) {
2508 DFS.DFSanMaybeStoreOriginFn,
2509 {CollapsedShadow, Addr, ConstantInt::get(DFS.IntptrTy, Size), Origin});
2511 Value *
Cmp = convertToBool(CollapsedShadow, IRB,
"_dfscmp");
2512 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
2514 Cmp, &*IRB.
GetInsertPoint(),
false, DFS.OriginStoreWeights, &DTU);
2516 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), StoreOriginAddr,
Size,
2526 IntegerType *ShadowTy =
2528 Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
2529 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
2536 Align InstAlignment,
2537 Value *PrimitiveShadow,
2540 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins() && Origin;
2543 const auto SI = AllocaShadowMap.
find(AI);
2544 if (SI != AllocaShadowMap.
end()) {
2550 if (ShouldTrackOrigins && !DFS.isZeroShadow(PrimitiveShadow)) {
2551 const auto OI = AllocaOriginMap.
find(AI);
2552 assert(OI != AllocaOriginMap.
end() && Origin);
2559 const Align ShadowAlign = getShadowAlign(InstAlignment);
2560 if (DFS.isZeroShadow(PrimitiveShadow)) {
2561 storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign, Pos);
2566 Value *ShadowAddr, *OriginAddr;
2567 std::tie(ShadowAddr, OriginAddr) =
2568 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2570 const unsigned ShadowVecSize = 8;
2571 assert(ShadowVecSize * DFS.ShadowWidthBits <= 128 &&
2572 "Shadow vector is too large!");
2576 if (LeftSize >= ShadowVecSize) {
2580 for (
unsigned I = 0;
I != ShadowVecSize; ++
I) {
2582 ShadowVec, PrimitiveShadow,
2583 ConstantInt::get(Type::getInt32Ty(*DFS.Ctx),
I));
2586 Value *CurShadowVecAddr =
2589 LeftSize -= ShadowVecSize;
2591 }
while (LeftSize >= ShadowVecSize);
2594 while (LeftSize > 0) {
2595 Value *CurShadowAddr =
2602 if (ShouldTrackOrigins) {
2603 storeOrigin(Pos, Addr,
Size, PrimitiveShadow, Origin, OriginAddr,
2625void DFSanVisitor::visitStoreInst(StoreInst &SI) {
2626 auto &
DL =
SI.getDataLayout();
2627 Value *Val =
SI.getValueOperand();
2640 const bool ShouldTrackOrigins =
2641 DFSF.DFS.shouldTrackOrigins() && !
SI.isAtomic();
2642 std::vector<Value *> Shadows;
2643 std::vector<Value *> Origins;
2646 SI.isAtomic() ? DFSF.DFS.getZeroShadow(Val) : DFSF.getShadow(Val);
2648 if (ShouldTrackOrigins) {
2649 Shadows.push_back(Shadow);
2650 Origins.push_back(DFSF.getOrigin(Val));
2653 Value *PrimitiveShadow;
2654 if (DFSF.Opts.dfsan_combine_pointer_labels_on_store) {
2655 Value *PtrShadow = DFSF.getShadow(
SI.getPointerOperand());
2656 if (ShouldTrackOrigins) {
2657 Shadows.push_back(PtrShadow);
2658 Origins.push_back(DFSF.getOrigin(
SI.getPointerOperand()));
2660 PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow,
SI.getIterator());
2662 PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow,
SI.getIterator());
2664 Value *Origin =
nullptr;
2665 if (ShouldTrackOrigins)
2666 Origin = DFSF.combineOrigins(Shadows, Origins,
SI.getIterator());
2667 DFSF.storePrimitiveShadowOrigin(
SI.getPointerOperand(),
Size,
SI.getAlign(),
2668 PrimitiveShadow, Origin,
SI.getIterator());
2669 if (DFSF.Opts.dfsan_event_callbacks) {
2671 Value *Addr =
SI.getPointerOperand();
2673 IRB.
CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr});
2678void DFSanVisitor::visitCASOrRMW(Align InstAlignment, Instruction &
I) {
2681 Value *Val =
I.getOperand(1);
2682 const auto &
DL =
I.getDataLayout();
2690 Value *Addr =
I.getOperand(0);
2691 const Align ShadowAlign = DFSF.getShadowAlign(InstAlignment);
2692 DFSF.storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign,
I.getIterator());
2693 DFSF.setShadow(&
I, DFSF.DFS.getZeroShadow(&
I));
2694 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2697void DFSanVisitor::visitAtomicRMWInst(AtomicRMWInst &
I) {
2698 visitCASOrRMW(
I.getAlign(),
I);
2704void DFSanVisitor::visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2705 visitCASOrRMW(
I.getAlign(),
I);
2711void DFSanVisitor::visitUnaryOperator(UnaryOperator &UO) {
2712 visitInstOperands(UO);
2715void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) {
2716 visitInstOperands(BO);
2719void DFSanVisitor::visitBitCastInst(BitCastInst &BCI) {
2726 visitInstOperands(BCI);
2729void DFSanVisitor::visitCastInst(CastInst &CI) { visitInstOperands(CI); }
2731void DFSanVisitor::visitCmpInst(CmpInst &CI) {
2732 visitInstOperands(CI);
2733 if (DFSF.Opts.dfsan_event_callbacks) {
2735 Value *CombinedShadow = DFSF.getShadow(&CI);
2737 IRB.
CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
2743void DFSanVisitor::visitLandingPadInst(LandingPadInst &LPI) {
2755 DFSF.setShadow(&LPI, DFSF.DFS.getZeroShadow(&LPI));
2756 DFSF.setOrigin(&LPI, DFSF.DFS.ZeroOrigin);
2759void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
2760 if (DFSF.Opts.dfsan_combine_offset_labels_on_gep ||
2761 DFSF.isLookupTableConstant(
2763 visitInstOperands(GEPI);
2770 DFSF.setShadow(&GEPI, DFSF.getShadow(BasePointer));
2771 if (DFSF.DFS.shouldTrackOrigins())
2772 DFSF.setOrigin(&GEPI, DFSF.getOrigin(BasePointer));
2775void DFSanVisitor::visitExtractElementInst(ExtractElementInst &
I) {
2776 visitInstOperands(
I);
2779void DFSanVisitor::visitInsertElementInst(InsertElementInst &
I) {
2780 visitInstOperands(
I);
2783void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &
I) {
2784 visitInstOperands(
I);
2787void DFSanVisitor::visitExtractValueInst(ExtractValueInst &
I) {
2789 Value *Agg =
I.getAggregateOperand();
2790 Value *AggShadow = DFSF.getShadow(Agg);
2792 DFSF.setShadow(&
I, ResShadow);
2793 visitInstOperandOrigins(
I);
2796void DFSanVisitor::visitInsertValueInst(InsertValueInst &
I) {
2798 Value *AggShadow = DFSF.getShadow(
I.getAggregateOperand());
2799 Value *InsShadow = DFSF.getShadow(
I.getInsertedValueOperand());
2801 DFSF.setShadow(&
I, Res);
2802 visitInstOperandOrigins(
I);
2805void DFSanVisitor::visitAllocaInst(AllocaInst &
I) {
2806 bool AllLoadsStores =
true;
2807 for (User *U :
I.users()) {
2812 if (
SI->getPointerOperand() == &
I)
2816 AllLoadsStores =
false;
2819 if (AllLoadsStores) {
2821 DFSF.AllocaShadowMap[&
I] = IRB.
CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
2822 if (DFSF.DFS.shouldTrackOrigins()) {
2823 DFSF.AllocaOriginMap[&
I] =
2827 DFSF.setShadow(&
I, DFSF.DFS.ZeroPrimitiveShadow);
2828 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2831void DFSanVisitor::visitSelectInst(SelectInst &
I) {
2832 Value *CondShadow = DFSF.getShadow(
I.getCondition());
2833 Value *TrueShadow = DFSF.getShadow(
I.getTrueValue());
2834 Value *FalseShadow = DFSF.getShadow(
I.getFalseValue());
2835 Value *ShadowSel =
nullptr;
2836 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2837 std::vector<Value *> Shadows;
2838 std::vector<Value *> Origins;
2840 ShouldTrackOrigins ? DFSF.getOrigin(
I.getTrueValue()) :
nullptr;
2841 Value *FalseOrigin =
2842 ShouldTrackOrigins ? DFSF.getOrigin(
I.getFalseValue()) :
nullptr;
2844 DFSF.addConditionalCallbacksIfEnabled(
I,
I.getCondition());
2847 ShadowSel = DFSF.combineShadowsThenConvert(
I.getType(), TrueShadow,
2848 FalseShadow,
I.getIterator());
2849 if (ShouldTrackOrigins) {
2850 Shadows.push_back(TrueShadow);
2851 Shadows.push_back(FalseShadow);
2852 Origins.push_back(TrueOrigin);
2853 Origins.push_back(FalseOrigin);
2856 if (TrueShadow == FalseShadow) {
2857 ShadowSel = TrueShadow;
2858 if (ShouldTrackOrigins) {
2859 Shadows.push_back(TrueShadow);
2860 Origins.push_back(TrueOrigin);
2864 "",
I.getIterator());
2865 if (ShouldTrackOrigins) {
2866 Shadows.push_back(ShadowSel);
2868 FalseOrigin,
"",
I.getIterator()));
2872 DFSF.setShadow(&
I, DFSF.Opts.dfsan_track_select_control_flow
2873 ? DFSF.combineShadowsThenConvert(
I.getType(),
2874 CondShadow, ShadowSel,
2877 if (ShouldTrackOrigins) {
2878 if (DFSF.Opts.dfsan_track_select_control_flow) {
2879 Shadows.push_back(CondShadow);
2880 Origins.push_back(DFSF.getOrigin(
I.getCondition()));
2882 DFSF.setOrigin(&
I, DFSF.combineOrigins(Shadows, Origins,
I.getIterator()));
2886void DFSanVisitor::visitMemSetInst(MemSetInst &
I) {
2888 Value *ValShadow = DFSF.getShadow(
I.getValue());
2889 Value *ValOrigin = DFSF.DFS.shouldTrackOrigins()
2890 ? DFSF.getOrigin(
I.getValue())
2891 : DFSF.DFS.ZeroOrigin;
2893 {ValShadow, ValOrigin, I.getDest(),
2894 IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2897void DFSanVisitor::visitMemTransferInst(MemTransferInst &
I) {
2902 if (DFSF.DFS.shouldTrackOrigins()) {
2904 DFSF.DFS.DFSanMemOriginTransferFn,
2905 {I.getArgOperand(0), I.getArgOperand(1),
2906 IRB.CreateIntCast(I.getArgOperand(2), DFSF.DFS.IntptrTy, false)});
2909 Value *DestShadow = DFSF.DFS.getShadowAddress(
I.getDest(),
I.getIterator());
2910 Value *SrcShadow = DFSF.DFS.getShadowAddress(
I.getSource(),
I.getIterator());
2912 IRB.
CreateMul(
I.getLength(), ConstantInt::get(
I.getLength()->getType(),
2913 DFSF.DFS.ShadowWidthBytes));
2915 IRB.
CreateCall(
I.getFunctionType(),
I.getCalledOperand(),
2916 {DestShadow, SrcShadow, LenShadow, I.getVolatileCst()}));
2917 MTI->setDestAlignment(DFSF.getShadowAlign(
I.getDestAlign().valueOrOne()));
2918 MTI->setSourceAlignment(DFSF.getShadowAlign(
I.getSourceAlign().valueOrOne()));
2919 if (DFSF.Opts.dfsan_event_callbacks) {
2921 DFSF.DFS.DFSanMemTransferCallbackFn,
2922 {DestShadow, IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2926void DFSanVisitor::visitCondBrInst(CondBrInst &BR) {
2927 DFSF.addConditionalCallbacksIfEnabled(BR,
BR.getCondition());
2930void DFSanVisitor::visitSwitchInst(SwitchInst &SW) {
2931 DFSF.addConditionalCallbacksIfEnabled(SW, SW.
getCondition());
2937 RetVal =
I->getOperand(0);
2940 return I->isMustTailCall();
2945void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
2954 unsigned Size = getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
2960 if (DFSF.DFS.shouldTrackOrigins()) {
2967void DFSanVisitor::addShadowArguments(
Function &
F, CallBase &CB,
2968 std::vector<Value *> &Args,
2970 FunctionType *FT =
F.getFunctionType();
2975 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
2977 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()));
2980 if (FT->isVarArg()) {
2981 auto *LabelVATy = ArrayType::get(DFSF.DFS.PrimitiveShadowTy,
2982 CB.
arg_size() - FT->getNumParams());
2983 auto *LabelVAAlloca =
2984 new AllocaInst(LabelVATy, getDataLayout().getAllocaAddrSpace(),
2987 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
2990 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()),
2998 if (!FT->getReturnType()->isVoidTy()) {
2999 if (!DFSF.LabelReturnAlloca) {
3000 DFSF.LabelReturnAlloca =
new AllocaInst(
3001 DFSF.DFS.PrimitiveShadowTy, getDataLayout().getAllocaAddrSpace(),
3004 Args.push_back(DFSF.LabelReturnAlloca);
3008void DFSanVisitor::addOriginArguments(
Function &
F, CallBase &CB,
3009 std::vector<Value *> &Args,
3011 FunctionType *FT =
F.getFunctionType();
3016 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
3017 Args.push_back(DFSF.getOrigin(*
I));
3020 if (FT->isVarArg()) {
3022 ArrayType::get(DFSF.DFS.OriginTy, CB.
arg_size() - FT->getNumParams());
3023 auto *OriginVAAlloca =
3024 new AllocaInst(OriginVATy, getDataLayout().getAllocaAddrSpace(),
3027 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
3036 if (!FT->getReturnType()->isVoidTy()) {
3037 if (!DFSF.OriginReturnAlloca) {
3038 DFSF.OriginReturnAlloca =
new AllocaInst(
3039 DFSF.DFS.OriginTy, getDataLayout().getAllocaAddrSpace(),
3042 Args.push_back(DFSF.OriginReturnAlloca);
3046bool DFSanVisitor::visitWrappedCallBase(
Function &
F, CallBase &CB) {
3048 switch (DFSF.DFS.getWrapperKind(&
F)) {
3049 case DataFlowSanitizer::WK_Warning:
3051 IRB.
CreateCall(DFSF.DFS.DFSanUnimplementedFn,
3053 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3054 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3055 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3057 case DataFlowSanitizer::WK_Discard:
3059 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3060 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3061 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3063 case DataFlowSanitizer::WK_Functional:
3065 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3066 visitInstOperands(CB);
3068 case DataFlowSanitizer::WK_Custom:
3076 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3077 FunctionType *FT =
F.getFunctionType();
3078 TransformedFunction CustomFnTy =
3079 DFSF.DFS.getCustomFunctionType(FT, DFSF.TLI);
3080 std::string CustomFName = ShouldTrackOrigins ?
"__dfso_" :
"__dfsw_";
3081 CustomFName +=
F.getName();
3083 CustomFName, CustomFnTy.TransformedType);
3090 AttributeList CustomAL = CustomFun->getAttributes();
3091 CustomFun->copyAttributesFrom(&
F);
3092 CustomFun->setAttributes(AttributeList::get(
3094 {CustomFun->getAttributes(), CustomAL, CustomFnTy.NewParamAttrs}));
3097 if (!FT->getReturnType()->isVoidTy()) {
3098 CustomFun->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
3102 std::vector<Value *>
Args;
3106 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N) {
3111 addShadowArguments(
F, CB, Args, IRB);
3114 if (ShouldTrackOrigins)
3115 addOriginArguments(
F, CB, Args, IRB);
3120 CallInst *CustomCI = IRB.
CreateCall(CustomFunCallee, Args);
3126 {transformFunctionAttributes(CustomFnTy, CI->getContext(),
3127 CI->getAttributes()),
3128 F.getAttributes(), CustomFnTy.NewParamAttrs}));
3131 if (!FT->getReturnType()->isVoidTy()) {
3132 LoadInst *LabelLoad =
3133 IRB.
CreateLoad(DFSF.DFS.PrimitiveShadowTy, DFSF.LabelReturnAlloca);
3134 DFSF.setShadow(CustomCI,
3135 DFSF.expandFromPrimitiveShadow(
3136 FT->getReturnType(), LabelLoad, CB.
getIterator()));
3137 if (ShouldTrackOrigins) {
3138 LoadInst *OriginLoad =
3139 IRB.
CreateLoad(DFSF.DFS.OriginTy, DFSF.OriginReturnAlloca);
3140 DFSF.setOrigin(CustomCI, OriginLoad);
3152 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3153 uint32_t OrderingTable[NumOrderings] = {};
3155 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3156 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3157 OrderingTable[(int)AtomicOrderingCABI::consume] =
3158 (
int)AtomicOrderingCABI::acquire;
3159 OrderingTable[(int)AtomicOrderingCABI::release] =
3160 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
3161 (int)AtomicOrderingCABI::acq_rel;
3162 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3163 (
int)AtomicOrderingCABI::seq_cst;
3168void DFSanVisitor::visitLibAtomicLoad(CallBase &CB) {
3179 Value *NewOrdering =
3184 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3190 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3191 {DstPtr, SrcPtr, NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3195 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3196 uint32_t OrderingTable[NumOrderings] = {};
3198 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3199 OrderingTable[(
int)AtomicOrderingCABI::release] =
3200 (int)AtomicOrderingCABI::release;
3201 OrderingTable[(int)AtomicOrderingCABI::consume] =
3202 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3203 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
3204 (
int)AtomicOrderingCABI::acq_rel;
3205 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3206 (
int)AtomicOrderingCABI::seq_cst;
3211void DFSanVisitor::visitLibAtomicStore(CallBase &CB) {
3219 Value *NewOrdering =
3227 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3228 {DstPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3231void DFSanVisitor::visitLibAtomicExchange(CallBase &CB) {
3247 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3248 {DstPtr, TargetPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3252 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3253 {TargetPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3256void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
3270 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3272 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3276 CallInst *CI = NextIRB.CreateCall(
3277 DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
3278 {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false), TargetPtr,
3279 ExpectedPtr, DesiredPtr,
3280 NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3284void DFSanVisitor::visitCallBase(CallBase &CB) {
3287 visitInstOperands(CB);
3297 if (LF != NotLibFunc) {
3302 case LibFunc_atomic_load:
3304 llvm::errs() <<
"DFSAN -- cannot instrument invoke of libatomic load. "
3308 visitLibAtomicLoad(CB);
3310 case LibFunc_atomic_store:
3311 visitLibAtomicStore(CB);
3319 if (
F &&
F->hasName() && !
F->isVarArg()) {
3320 if (
F->getName() ==
"__atomic_exchange") {
3321 visitLibAtomicExchange(CB);
3324 if (
F->getName() ==
"__atomic_compare_exchange") {
3325 visitLibAtomicCompareExchange(CB);
3331 if (UnwrappedFnIt != DFSF.DFS.UnwrappedFnMap.end())
3332 if (visitWrappedCallBase(*UnwrappedFnIt->second, CB))
3337 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3339 const DataLayout &
DL = getDataLayout();
3342 unsigned ArgOffset = 0;
3343 for (
unsigned I = 0,
N = FT->getNumParams();
I !=
N; ++
I) {
3344 if (ShouldTrackOrigins) {
3347 if (
I < DFSF.DFS.NumOfElementsInArgOrgTLS &&
3348 !DFSF.DFS.isZeroShadow(ArgShadow))
3350 DFSF.getArgOriginTLS(
I, IRB));
3354 DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(
I)));
3360 DFSF.getArgTLS(FT->getParamType(
I), ArgOffset, IRB),
3368 if (
II->getNormalDest()->getSinglePredecessor()) {
3369 Next = &
II->getNormalDest()->front();
3386 unsigned Size =
DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
3389 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3391 LoadInst *LI = NextIRB.CreateAlignedLoad(
3392 DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.
getType(), NextIRB),
3394 DFSF.SkipInsts.
insert(LI);
3395 DFSF.setShadow(&CB, LI);
3396 DFSF.NonZeroChecks.push_back(LI);
3399 if (ShouldTrackOrigins) {
3400 LoadInst *LI = NextIRB.CreateLoad(DFSF.DFS.OriginTy,
3401 DFSF.getRetvalOriginTLS(),
"_dfsret_o");
3402 DFSF.SkipInsts.
insert(LI);
3403 DFSF.setOrigin(&CB, LI);
3406 DFSF.addReachesFunctionCallbacksIfEnabled(NextIRB, CB, &CB);
3410void DFSanVisitor::visitPHINode(PHINode &PN) {
3411 Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
3417 for (BasicBlock *BB : PN.
blocks())
3420 DFSF.setShadow(&PN, ShadowPN);
3422 PHINode *OriginPN =
nullptr;
3423 if (DFSF.DFS.shouldTrackOrigins()) {
3427 for (BasicBlock *BB : PN.
blocks())
3429 DFSF.setOrigin(&PN, OriginPN);
3432 DFSF.PHIFixups.push_back({&PN, ShadowPN, OriginPN});
3446 if (!DataFlowSanitizer(Opts, 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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 const Align MinOriginAlignment
static Value * expandFromPrimitiveShadowRecursive(Value *Shadow, SmallVector< unsigned, 4 > &Indices, Type *SubShadowTy, Value *PrimitiveShadow, IRBuilder<> &IRB)
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 StringRef getGlobalTypeString(const GlobalValue &G)
static const unsigned ArgTLSSize
static const unsigned RetvalTLSSize
static bool isAMustTailRetVal(Value *RetVal)
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),...
bool empty() const
Return true if the mask contains no attributes.
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.
void maybeAddParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
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
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.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
iterator find(const_arg_type_t< KeyT > Val)
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.
static Attribute::AttrKind getExtAttrForI8Param(bool Signed=true)
LibFunc getLibFunc(StringRef funcName) 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() 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.
@ BR
Control flow instructions. These all have token chains.
@ BasicBlock
Various leaf nodes.
@ CE
Windows NT (Windows on ARM)
@ 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.
const InstrumentationOptions & getInstrumentationOptions(const LLVMContext &C)
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.
@ Load
The value being inserted comes from a load (InsertElement only).
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
LLVM_ABI bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr, bool FoldInstsToUnreachable=true)
Remove all blocks that can not be reached from the function's entry.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
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.
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 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.