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();
1594 if (
I->getOpcode() == Instruction::ICmp) {
1600 F.replaceUsesWithIf(NewF, IsNotCmpUse);
1602 UnwrappedFnMap[NewF] = &
F;
1605 if (!
F.isDeclaration()) {
1615 size_t N = FI - FnsToInstrument.begin(),
1616 Count = FE - FnsToInstrument.begin();
1617 FnsToInstrument.push_back(&
F);
1618 FI = FnsToInstrument.begin() +
N;
1619 FE = FnsToInstrument.begin() +
Count;
1623 }
else if (FT->isVarArg()) {
1624 UnwrappedFnMap[&
F] = &
F;
1630 if (!
F ||
F->isDeclaration())
1635 DFSanFunction DFSF(*
this,
F, FnsWithNativeABI.
count(
F),
1636 FnsWithForceZeroLabel.
count(
F), GetTLI(*
F));
1641 if (Opts.dfsan_reaches_function_callbacks && !UnwrappedFnMap.
count(
F)) {
1643 Instruction *FirstOrigInst = &
F->getEntryBlock().front();
1646 for (
auto &FArg :
F->args()) {
1648 Value *FArgShadow = DFSF.getShadow(&FArg);
1649 if (isZeroShadow(FArgShadow))
1652 Next = FArgShadowInst->getNextNode();
1654 if (shouldTrackOrigins()) {
1655 if (Instruction *Origin =
1659 if (
Next->comesBefore(OriginNext)) {
1665 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, *
Next, &FArg);
1670 for (Instruction &
I :
F->getEntryBlock()) {
1671 if (&
I == FirstOrigInst)
1681 for (BasicBlock *BB : BBList) {
1691 if (!DFSF.SkipInsts.
count(Inst))
1692 DFSanVisitor(DFSF).visit(Inst);
1703 for (DFSanFunction::PHIFixupElement &
P : DFSF.PHIFixups) {
1704 for (
unsigned Val = 0,
N =
P.Phi->getNumIncomingValues(); Val !=
N;
1706 P.ShadowPhi->setIncomingValue(
1707 Val, DFSF.getShadow(
P.Phi->getIncomingValue(Val)));
1709 P.OriginPhi->setIncomingValue(
1710 Val, DFSF.getOrigin(
P.Phi->getIncomingValue(Val)));
1718 if (Opts.dfsan_debug_nonzero_labels) {
1719 for (
Value *V : DFSF.NonZeroChecks) {
1722 Pos = std::next(
I->getIterator());
1726 Pos = std::next(Pos->getIterator());
1728 Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(V, Pos);
1730 IRB.
CreateICmpNE(PrimitiveShadow, DFSF.DFS.ZeroPrimitiveShadow);
1732 Ne, Pos,
false, ColdCallWeights));
1734 ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn, {});
1740 M.global_size() != InitialGlobalSize ||
M.size() != InitialModuleSize;
1744 return IRB.
CreatePtrAdd(DFS.ArgTLS, ConstantInt::get(DFS.IntptrTy, ArgOffset),
1753Value *DFSanFunction::getRetvalOriginTLS() {
return DFS.RetvalOriginTLS; }
1757 ArgNo,
"_dfsarg_o");
1761 assert(DFS.shouldTrackOrigins());
1763 return DFS.ZeroOrigin;
1764 Value *&Origin = ValOriginMap[
V];
1768 return DFS.ZeroOrigin;
1769 if (
A->getArgNo() < DFS.NumOfElementsInArgOrgTLS) {
1770 Instruction *ArgOriginTLSPos = &*
F->getEntryBlock().begin();
1772 Value *ArgOriginPtr = getArgOriginTLS(
A->getArgNo(), IRB);
1773 Origin = IRB.
CreateLoad(DFS.OriginTy, ArgOriginPtr);
1776 Origin = DFS.ZeroOrigin;
1779 Origin = DFS.ZeroOrigin;
1785void DFSanFunction::setOrigin(Instruction *
I,
Value *Origin) {
1786 if (!DFS.shouldTrackOrigins())
1790 ValOriginMap[
I] = Origin;
1793Value *DFSanFunction::getShadowForTLSArgument(Argument *
A) {
1794 unsigned ArgOffset = 0;
1795 const DataLayout &
DL =
F->getDataLayout();
1796 for (
auto &FArg :
F->args()) {
1797 if (!FArg.getType()->isSized()) {
1803 unsigned Size =
DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
1816 Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
1821 return DFS.getZeroShadow(
A);
1826 return DFS.getZeroShadow(V);
1827 if (IsForceZeroLabels)
1828 return DFS.getZeroShadow(V);
1829 Value *&Shadow = ValShadowMap[
V];
1833 return DFS.getZeroShadow(V);
1834 Shadow = getShadowForTLSArgument(
A);
1835 NonZeroChecks.push_back(Shadow);
1837 Shadow = DFS.getZeroShadow(V);
1843void DFSanFunction::setShadow(Instruction *
I,
Value *Shadow) {
1845 ValShadowMap[
I] = Shadow;
1853 assert(Addr != RetvalTLS &&
"Reinstrumenting?");
1856 uint64_t AndMask = MapParams->AndMask;
1859 IRB.
CreateAnd(OffsetLong, ConstantInt::get(IntptrTy, ~AndMask));
1861 uint64_t XorMask = MapParams->XorMask;
1863 OffsetLong = IRB.
CreateXor(OffsetLong, ConstantInt::get(IntptrTy, XorMask));
1867std::pair<Value *, Value *>
1868DataFlowSanitizer::getShadowOriginAddress(
Value *Addr, Align InstAlignment,
1872 Value *ShadowOffset = getShadowOffset(Addr, IRB);
1873 Value *ShadowLong = ShadowOffset;
1874 uint64_t ShadowBase = MapParams->ShadowBase;
1875 if (ShadowBase != 0) {
1877 IRB.
CreateAdd(ShadowLong, ConstantInt::get(IntptrTy, ShadowBase));
1880 Value *OriginPtr =
nullptr;
1881 if (shouldTrackOrigins()) {
1882 Value *OriginLong = ShadowOffset;
1883 uint64_t OriginBase = MapParams->OriginBase;
1884 if (OriginBase != 0)
1886 IRB.
CreateAdd(OriginLong, ConstantInt::get(IntptrTy, OriginBase));
1892 OriginLong = IRB.
CreateAnd(OriginLong, ConstantInt::get(IntptrTy, ~Mask));
1896 return std::make_pair(ShadowPtr, OriginPtr);
1899Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1901 Value *ShadowOffset) {
1906Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1909 Value *ShadowAddr = getShadowOffset(Addr, IRB);
1910 uint64_t ShadowBase = MapParams->ShadowBase;
1911 if (ShadowBase != 0)
1913 IRB.
CreateAdd(ShadowAddr, ConstantInt::get(IntptrTy, ShadowBase));
1914 return getShadowAddress(Addr, Pos, ShadowAddr);
1919 Value *PrimitiveValue = combineShadows(
V1, V2, Pos);
1920 return expandFromPrimitiveShadow(
T, PrimitiveValue, Pos);
1927 if (DFS.isZeroShadow(
V1))
1928 return collapseToPrimitiveShadow(V2, Pos);
1929 if (DFS.isZeroShadow(V2))
1930 return collapseToPrimitiveShadow(
V1, Pos);
1932 return collapseToPrimitiveShadow(
V1, Pos);
1934 auto V1Elems = ShadowElements.
find(
V1);
1935 auto V2Elems = ShadowElements.
find(V2);
1936 if (V1Elems != ShadowElements.
end() && V2Elems != ShadowElements.
end()) {
1938 return collapseToPrimitiveShadow(
V1, Pos);
1941 return collapseToPrimitiveShadow(V2, Pos);
1943 }
else if (V1Elems != ShadowElements.
end()) {
1944 if (V1Elems->second.count(V2))
1945 return collapseToPrimitiveShadow(
V1, Pos);
1946 }
else if (V2Elems != ShadowElements.
end()) {
1947 if (V2Elems->second.count(
V1))
1948 return collapseToPrimitiveShadow(V2, Pos);
1951 auto Key = std::make_pair(
V1, V2);
1954 CachedShadow &CCS = CachedShadows[
Key];
1955 if (CCS.Block && DT.
dominates(CCS.Block, Pos->getParent()))
1959 Value *PV1 = collapseToPrimitiveShadow(
V1, Pos);
1960 Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
1963 CCS.Block = Pos->getParent();
1964 CCS.Shadow = IRB.
CreateOr(PV1, PV2);
1966 std::set<Value *> UnionElems;
1967 if (V1Elems != ShadowElements.
end()) {
1968 UnionElems = V1Elems->second;
1970 UnionElems.insert(
V1);
1972 if (V2Elems != ShadowElements.
end()) {
1973 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
1975 UnionElems.insert(V2);
1977 ShadowElements[CCS.Shadow] = std::move(UnionElems);
1985Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
1987 return DFS.getZeroShadow(Inst);
1991 Shadow = combineShadows(Shadow, getShadow(Inst->
getOperand(
I)),
1994 return expandFromPrimitiveShadow(Inst->
getType(), Shadow,
1998void DFSanVisitor::visitInstOperands(Instruction &
I) {
1999 Value *CombinedShadow = DFSF.combineOperandShadows(&
I);
2000 DFSF.setShadow(&
I, CombinedShadow);
2001 visitInstOperandOrigins(
I);
2004Value *DFSanFunction::combineOrigins(
const std::vector<Value *> &Shadows,
2005 const std::vector<Value *> &Origins,
2007 ConstantInt *Zero) {
2008 assert(Shadows.size() == Origins.size());
2009 size_t Size = Origins.size();
2011 return DFS.ZeroOrigin;
2012 Value *Origin =
nullptr;
2014 Zero = DFS.ZeroPrimitiveShadow;
2015 for (
size_t I = 0;
I !=
Size; ++
I) {
2016 Value *OpOrigin = Origins[
I];
2018 if (ConstOpOrigin && ConstOpOrigin->
isNullValue())
2024 Value *OpShadow = Shadows[
I];
2025 Value *PrimitiveShadow = collapseToPrimitiveShadow(OpShadow, Pos);
2030 return Origin ? Origin : DFS.ZeroOrigin;
2033Value *DFSanFunction::combineOperandOrigins(Instruction *Inst) {
2035 std::vector<Value *> Shadows(
Size);
2036 std::vector<Value *> Origins(
Size);
2037 for (
unsigned I = 0;
I !=
Size; ++
I) {
2041 return combineOrigins(Shadows, Origins, Inst->
getIterator());
2044void DFSanVisitor::visitInstOperandOrigins(Instruction &
I) {
2045 if (!DFSF.DFS.shouldTrackOrigins())
2047 Value *CombinedOrigin = DFSF.combineOperandOrigins(&
I);
2048 DFSF.setOrigin(&
I, CombinedOrigin);
2051Align DFSanFunction::getShadowAlign(Align InstAlignment) {
2053 Opts.dfsan_preserve_alignment ? InstAlignment :
Align(1);
2057Align DFSanFunction::getOriginAlign(Align InstAlignment) {
2062bool DFSanFunction::isLookupTableConstant(
Value *
P) {
2064 if (GV->isConstant() && GV->
hasName())
2065 return DFS.CombineTaintLookupTableNames.
count(GV->
getName());
2070bool DFSanFunction::useCallbackLoadLabelAndOrigin(
uint64_t Size,
2071 Align InstAlignment) {
2074 if (Opts.dfsan_track_origins == 2)
2095 Value **OriginAddr) {
2098 IRB.
CreateGEP(OriginTy, *OriginAddr, ConstantInt::get(IntptrTy, 1));
2102std::pair<Value *, Value *> DFSanFunction::loadShadowFast(
2105 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2106 const uint64_t ShadowSize =
Size * DFS.ShadowWidthBytes;
2108 assert(
Size >= 4 &&
"Not large enough load size for fast path!");
2111 std::vector<Value *> Shadows;
2112 std::vector<Value *> Origins;
2125 Type *WideShadowTy =
2126 ShadowSize == 4 ? Type::getInt32Ty(*DFS.Ctx) :
Type::getInt64Ty(*DFS.Ctx);
2129 Value *CombinedWideShadow =
2133 const uint64_t BytesPerWideShadow = WideShadowBitWidth / DFS.ShadowWidthBits;
2135 auto AppendWideShadowAndOrigin = [&](
Value *WideShadow,
Value *Origin) {
2136 if (BytesPerWideShadow > 4) {
2137 assert(BytesPerWideShadow == 8);
2144 Value *WideShadowLo =
2145 F->getDataLayout().isLittleEndian()
2148 ConstantInt::get(WideShadowTy, WideShadowBitWidth / 2))
2151 ConstantInt::get(WideShadowTy,
2152 ((1ULL << (WideShadowBitWidth / 2)) - 1)
2153 << (WideShadowBitWidth / 2)));
2154 Shadows.push_back(WideShadow);
2155 Origins.push_back(DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr));
2157 Shadows.push_back(WideShadowLo);
2158 Origins.push_back(Origin);
2160 Shadows.push_back(WideShadow);
2161 Origins.push_back(Origin);
2165 if (ShouldTrackOrigins)
2166 AppendWideShadowAndOrigin(CombinedWideShadow, FirstOrigin);
2173 for (
uint64_t ByteOfs = BytesPerWideShadow; ByteOfs <
Size;
2174 ByteOfs += BytesPerWideShadow) {
2175 ShadowAddr = IRB.
CreateGEP(WideShadowTy, ShadowAddr,
2176 ConstantInt::get(DFS.IntptrTy, 1));
2177 Value *NextWideShadow =
2179 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, NextWideShadow);
2180 if (ShouldTrackOrigins) {
2181 Value *NextOrigin = DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr);
2182 AppendWideShadowAndOrigin(NextWideShadow, NextOrigin);
2185 for (
unsigned Width = WideShadowBitWidth / 2; Width >= DFS.ShadowWidthBits;
2188 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, ShrShadow);
2190 return {IRB.
CreateTrunc(CombinedWideShadow, DFS.PrimitiveShadowTy),
2192 ? combineOrigins(Shadows, Origins, Pos,
2197std::pair<Value *, Value *> DFSanFunction::loadShadowOriginSansLoadTracking(
2199 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2203 const auto SI = AllocaShadowMap.
find(AI);
2204 if (SI != AllocaShadowMap.
end()) {
2207 const auto OI = AllocaOriginMap.
find(AI);
2208 assert(!ShouldTrackOrigins || OI != AllocaOriginMap.
end());
2209 return {ShadowLI, ShouldTrackOrigins
2216 SmallVector<const Value *, 2> Objs;
2218 bool AllConstants =
true;
2219 for (
const Value *Obj : Objs) {
2225 AllConstants =
false;
2229 return {DFS.ZeroPrimitiveShadow,
2230 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2233 return {DFS.ZeroPrimitiveShadow,
2234 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2238 if (ShouldTrackOrigins &&
2239 useCallbackLoadLabelAndOrigin(
Size, InstAlignment)) {
2242 IRB.
CreateCall(DFS.DFSanLoadLabelAndOriginFn,
2243 {Addr, ConstantInt::get(DFS.IntptrTy, Size)});
2246 DFS.PrimitiveShadowTy),
2251 Value *ShadowAddr, *OriginAddr;
2252 std::tie(ShadowAddr, OriginAddr) =
2253 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2255 const Align ShadowAlign = getShadowAlign(InstAlignment);
2256 const Align OriginAlign = getOriginAlign(InstAlignment);
2257 Value *Origin =
nullptr;
2258 if (ShouldTrackOrigins) {
2267 LoadInst *LI =
new LoadInst(DFS.PrimitiveShadowTy, ShadowAddr,
"", Pos);
2269 return {LI, Origin};
2273 Value *ShadowAddr1 = IRB.
CreateGEP(DFS.PrimitiveShadowTy, ShadowAddr,
2274 ConstantInt::get(DFS.IntptrTy, 1));
2279 return {combineShadows(
Load, Load1, Pos), Origin};
2282 bool HasSizeForFastPath = DFS.hasLoadSizeForFastPath(
Size);
2284 if (HasSizeForFastPath)
2285 return loadShadowFast(ShadowAddr, OriginAddr,
Size, ShadowAlign,
2286 OriginAlign, Origin, Pos);
2290 DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
2292 return {FallbackCall, Origin};
2295std::pair<Value *, Value *>
2298 Value *PrimitiveShadow, *Origin;
2299 std::tie(PrimitiveShadow, Origin) =
2300 loadShadowOriginSansLoadTracking(Addr,
Size, InstAlignment, Pos);
2301 if (DFS.shouldTrackOrigins()) {
2302 if (Opts.dfsan_track_origins == 2) {
2305 if (!ConstantShadow || !ConstantShadow->isNullValue())
2306 Origin = updateOriginIfTainted(PrimitiveShadow, Origin, IRB);
2309 return {PrimitiveShadow, Origin};
2330 if (!V->getType()->isPointerTy())
2339 V =
GEP->getPointerOperand();
2342 if (!V->getType()->isPointerTy())
2347 }
while (Visited.
insert(V).second);
2352void DFSanVisitor::visitLoadInst(LoadInst &LI) {
2356 DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
2357 DFSF.setOrigin(&LI, DFSF.DFS.ZeroOrigin);
2372 Pos = std::next(Pos);
2374 std::vector<Value *> Shadows;
2375 std::vector<Value *> Origins;
2376 Value *PrimitiveShadow, *Origin;
2377 std::tie(PrimitiveShadow, Origin) =
2379 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2380 if (ShouldTrackOrigins) {
2381 Shadows.push_back(PrimitiveShadow);
2382 Origins.push_back(Origin);
2384 if (DFSF.Opts.dfsan_combine_pointer_labels_on_load ||
2385 DFSF.isLookupTableConstant(
2388 PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, Pos);
2389 if (ShouldTrackOrigins) {
2390 Shadows.push_back(PtrShadow);
2394 if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
2395 DFSF.NonZeroChecks.push_back(PrimitiveShadow);
2398 DFSF.expandFromPrimitiveShadow(LI.
getType(), PrimitiveShadow, Pos);
2399 DFSF.setShadow(&LI, Shadow);
2401 if (ShouldTrackOrigins) {
2402 DFSF.setOrigin(&LI, DFSF.combineOrigins(Shadows, Origins, Pos));
2405 if (DFSF.Opts.dfsan_event_callbacks) {
2409 IRB.
CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr});
2414 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, LI, &LI);
2417Value *DFSanFunction::updateOriginIfTainted(
Value *Shadow,
Value *Origin,
2419 assert(DFS.shouldTrackOrigins());
2420 return IRB.
CreateCall(DFS.DFSanChainOriginIfTaintedFn, {Shadow, Origin});
2424 if (!DFS.shouldTrackOrigins())
2426 return IRB.
CreateCall(DFS.DFSanChainOriginFn, V);
2430 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2431 const DataLayout &
DL =
F->getDataLayout();
2432 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2433 if (IntptrSize == OriginSize)
2435 assert(IntptrSize == OriginSize * 2);
2441 Value *StoreOriginAddr,
2442 uint64_t StoreOriginSize, Align Alignment) {
2443 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2444 const DataLayout &
DL =
F->getDataLayout();
2445 const Align IntptrAlignment =
DL.getABITypeAlign(DFS.IntptrTy);
2446 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2448 assert(IntptrSize >= OriginSize);
2452 if (Alignment >= IntptrAlignment && IntptrSize > OriginSize) {
2453 Value *IntptrOrigin = originToIntptr(IRB, Origin);
2454 Value *IntptrStoreOriginPtr =
2456 for (
unsigned I = 0;
I < StoreOriginSize / IntptrSize; ++
I) {
2459 : IntptrStoreOriginPtr;
2461 Ofs += IntptrSize / OriginSize;
2462 CurrentAlignment = IntptrAlignment;
2466 for (
unsigned I = Ofs;
I < (StoreOriginSize + OriginSize - 1) / OriginSize;
2476 const Twine &Name) {
2477 Type *VTy =
V->getType();
2482 return IRB.
CreateICmpNE(V, ConstantInt::get(VTy, 0), Name);
2487 Value *StoreOriginAddr, Align InstAlignment) {
2490 const Align OriginAlignment = getOriginAlign(InstAlignment);
2491 Value *CollapsedShadow = collapseToPrimitiveShadow(Shadow, Pos);
2494 if (!ConstantShadow->isNullValue())
2495 paintOrigin(IRB, updateOrigin(Origin, IRB), StoreOriginAddr,
Size,
2500 if (shouldInstrumentWithCall()) {
2502 DFS.DFSanMaybeStoreOriginFn,
2503 {CollapsedShadow, Addr, ConstantInt::get(DFS.IntptrTy, Size), Origin});
2505 Value *
Cmp = convertToBool(CollapsedShadow, IRB,
"_dfscmp");
2506 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
2508 Cmp, &*IRB.
GetInsertPoint(),
false, DFS.OriginStoreWeights, &DTU);
2510 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), StoreOriginAddr,
Size,
2520 IntegerType *ShadowTy =
2522 Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
2523 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
2530 Align InstAlignment,
2531 Value *PrimitiveShadow,
2534 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins() && Origin;
2537 const auto SI = AllocaShadowMap.
find(AI);
2538 if (SI != AllocaShadowMap.
end()) {
2544 if (ShouldTrackOrigins && !DFS.isZeroShadow(PrimitiveShadow)) {
2545 const auto OI = AllocaOriginMap.
find(AI);
2546 assert(OI != AllocaOriginMap.
end() && Origin);
2553 const Align ShadowAlign = getShadowAlign(InstAlignment);
2554 if (DFS.isZeroShadow(PrimitiveShadow)) {
2555 storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign, Pos);
2560 Value *ShadowAddr, *OriginAddr;
2561 std::tie(ShadowAddr, OriginAddr) =
2562 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2564 const unsigned ShadowVecSize = 8;
2565 assert(ShadowVecSize * DFS.ShadowWidthBits <= 128 &&
2566 "Shadow vector is too large!");
2570 if (LeftSize >= ShadowVecSize) {
2574 for (
unsigned I = 0;
I != ShadowVecSize; ++
I) {
2576 ShadowVec, PrimitiveShadow,
2577 ConstantInt::get(Type::getInt32Ty(*DFS.Ctx),
I));
2580 Value *CurShadowVecAddr =
2583 LeftSize -= ShadowVecSize;
2585 }
while (LeftSize >= ShadowVecSize);
2588 while (LeftSize > 0) {
2589 Value *CurShadowAddr =
2596 if (ShouldTrackOrigins) {
2597 storeOrigin(Pos, Addr,
Size, PrimitiveShadow, Origin, OriginAddr,
2619void DFSanVisitor::visitStoreInst(StoreInst &SI) {
2620 auto &
DL =
SI.getDataLayout();
2621 Value *Val =
SI.getValueOperand();
2634 const bool ShouldTrackOrigins =
2635 DFSF.DFS.shouldTrackOrigins() && !
SI.isAtomic();
2636 std::vector<Value *> Shadows;
2637 std::vector<Value *> Origins;
2640 SI.isAtomic() ? DFSF.DFS.getZeroShadow(Val) : DFSF.getShadow(Val);
2642 if (ShouldTrackOrigins) {
2643 Shadows.push_back(Shadow);
2644 Origins.push_back(DFSF.getOrigin(Val));
2647 Value *PrimitiveShadow;
2648 if (DFSF.Opts.dfsan_combine_pointer_labels_on_store) {
2649 Value *PtrShadow = DFSF.getShadow(
SI.getPointerOperand());
2650 if (ShouldTrackOrigins) {
2651 Shadows.push_back(PtrShadow);
2652 Origins.push_back(DFSF.getOrigin(
SI.getPointerOperand()));
2654 PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow,
SI.getIterator());
2656 PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow,
SI.getIterator());
2658 Value *Origin =
nullptr;
2659 if (ShouldTrackOrigins)
2660 Origin = DFSF.combineOrigins(Shadows, Origins,
SI.getIterator());
2661 DFSF.storePrimitiveShadowOrigin(
SI.getPointerOperand(),
Size,
SI.getAlign(),
2662 PrimitiveShadow, Origin,
SI.getIterator());
2663 if (DFSF.Opts.dfsan_event_callbacks) {
2665 Value *Addr =
SI.getPointerOperand();
2667 IRB.
CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr});
2672void DFSanVisitor::visitCASOrRMW(Align InstAlignment, Instruction &
I) {
2675 Value *Val =
I.getOperand(1);
2676 const auto &
DL =
I.getDataLayout();
2684 Value *Addr =
I.getOperand(0);
2685 const Align ShadowAlign = DFSF.getShadowAlign(InstAlignment);
2686 DFSF.storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign,
I.getIterator());
2687 DFSF.setShadow(&
I, DFSF.DFS.getZeroShadow(&
I));
2688 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2691void DFSanVisitor::visitAtomicRMWInst(AtomicRMWInst &
I) {
2692 visitCASOrRMW(
I.getAlign(),
I);
2698void DFSanVisitor::visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2699 visitCASOrRMW(
I.getAlign(),
I);
2705void DFSanVisitor::visitUnaryOperator(UnaryOperator &UO) {
2706 visitInstOperands(UO);
2709void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) {
2710 visitInstOperands(BO);
2713void DFSanVisitor::visitBitCastInst(BitCastInst &BCI) {
2720 visitInstOperands(BCI);
2723void DFSanVisitor::visitCastInst(CastInst &CI) { visitInstOperands(CI); }
2725void DFSanVisitor::visitCmpInst(CmpInst &CI) {
2726 visitInstOperands(CI);
2727 if (DFSF.Opts.dfsan_event_callbacks) {
2729 Value *CombinedShadow = DFSF.getShadow(&CI);
2731 IRB.
CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
2737void DFSanVisitor::visitLandingPadInst(LandingPadInst &LPI) {
2749 DFSF.setShadow(&LPI, DFSF.DFS.getZeroShadow(&LPI));
2750 DFSF.setOrigin(&LPI, DFSF.DFS.ZeroOrigin);
2753void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
2754 if (DFSF.Opts.dfsan_combine_offset_labels_on_gep ||
2755 DFSF.isLookupTableConstant(
2757 visitInstOperands(GEPI);
2764 DFSF.setShadow(&GEPI, DFSF.getShadow(BasePointer));
2765 if (DFSF.DFS.shouldTrackOrigins())
2766 DFSF.setOrigin(&GEPI, DFSF.getOrigin(BasePointer));
2769void DFSanVisitor::visitExtractElementInst(ExtractElementInst &
I) {
2770 visitInstOperands(
I);
2773void DFSanVisitor::visitInsertElementInst(InsertElementInst &
I) {
2774 visitInstOperands(
I);
2777void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &
I) {
2778 visitInstOperands(
I);
2781void DFSanVisitor::visitExtractValueInst(ExtractValueInst &
I) {
2783 Value *Agg =
I.getAggregateOperand();
2784 Value *AggShadow = DFSF.getShadow(Agg);
2786 DFSF.setShadow(&
I, ResShadow);
2787 visitInstOperandOrigins(
I);
2790void DFSanVisitor::visitInsertValueInst(InsertValueInst &
I) {
2792 Value *AggShadow = DFSF.getShadow(
I.getAggregateOperand());
2793 Value *InsShadow = DFSF.getShadow(
I.getInsertedValueOperand());
2795 DFSF.setShadow(&
I, Res);
2796 visitInstOperandOrigins(
I);
2799void DFSanVisitor::visitAllocaInst(AllocaInst &
I) {
2800 bool AllLoadsStores =
true;
2801 for (User *U :
I.users()) {
2806 if (
SI->getPointerOperand() == &
I)
2810 AllLoadsStores =
false;
2813 if (AllLoadsStores) {
2815 DFSF.AllocaShadowMap[&
I] = IRB.
CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
2816 if (DFSF.DFS.shouldTrackOrigins()) {
2817 DFSF.AllocaOriginMap[&
I] =
2821 DFSF.setShadow(&
I, DFSF.DFS.ZeroPrimitiveShadow);
2822 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2825void DFSanVisitor::visitSelectInst(SelectInst &
I) {
2826 Value *CondShadow = DFSF.getShadow(
I.getCondition());
2827 Value *TrueShadow = DFSF.getShadow(
I.getTrueValue());
2828 Value *FalseShadow = DFSF.getShadow(
I.getFalseValue());
2829 Value *ShadowSel =
nullptr;
2830 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2831 std::vector<Value *> Shadows;
2832 std::vector<Value *> Origins;
2834 ShouldTrackOrigins ? DFSF.getOrigin(
I.getTrueValue()) :
nullptr;
2835 Value *FalseOrigin =
2836 ShouldTrackOrigins ? DFSF.getOrigin(
I.getFalseValue()) :
nullptr;
2838 DFSF.addConditionalCallbacksIfEnabled(
I,
I.getCondition());
2841 ShadowSel = DFSF.combineShadowsThenConvert(
I.getType(), TrueShadow,
2842 FalseShadow,
I.getIterator());
2843 if (ShouldTrackOrigins) {
2844 Shadows.push_back(TrueShadow);
2845 Shadows.push_back(FalseShadow);
2846 Origins.push_back(TrueOrigin);
2847 Origins.push_back(FalseOrigin);
2850 if (TrueShadow == FalseShadow) {
2851 ShadowSel = TrueShadow;
2852 if (ShouldTrackOrigins) {
2853 Shadows.push_back(TrueShadow);
2854 Origins.push_back(TrueOrigin);
2858 "",
I.getIterator());
2859 if (ShouldTrackOrigins) {
2860 Shadows.push_back(ShadowSel);
2862 FalseOrigin,
"",
I.getIterator()));
2866 DFSF.setShadow(&
I, DFSF.Opts.dfsan_track_select_control_flow
2867 ? DFSF.combineShadowsThenConvert(
I.getType(),
2868 CondShadow, ShadowSel,
2871 if (ShouldTrackOrigins) {
2872 if (DFSF.Opts.dfsan_track_select_control_flow) {
2873 Shadows.push_back(CondShadow);
2874 Origins.push_back(DFSF.getOrigin(
I.getCondition()));
2876 DFSF.setOrigin(&
I, DFSF.combineOrigins(Shadows, Origins,
I.getIterator()));
2880void DFSanVisitor::visitMemSetInst(MemSetInst &
I) {
2882 Value *ValShadow = DFSF.getShadow(
I.getValue());
2883 Value *ValOrigin = DFSF.DFS.shouldTrackOrigins()
2884 ? DFSF.getOrigin(
I.getValue())
2885 : DFSF.DFS.ZeroOrigin;
2887 {ValShadow, ValOrigin, I.getDest(),
2888 IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2891void DFSanVisitor::visitMemTransferInst(MemTransferInst &
I) {
2896 if (DFSF.DFS.shouldTrackOrigins()) {
2898 DFSF.DFS.DFSanMemOriginTransferFn,
2899 {I.getArgOperand(0), I.getArgOperand(1),
2900 IRB.CreateIntCast(I.getArgOperand(2), DFSF.DFS.IntptrTy, false)});
2903 Value *DestShadow = DFSF.DFS.getShadowAddress(
I.getDest(),
I.getIterator());
2904 Value *SrcShadow = DFSF.DFS.getShadowAddress(
I.getSource(),
I.getIterator());
2906 IRB.
CreateMul(
I.getLength(), ConstantInt::get(
I.getLength()->getType(),
2907 DFSF.DFS.ShadowWidthBytes));
2909 IRB.
CreateCall(
I.getFunctionType(),
I.getCalledOperand(),
2910 {DestShadow, SrcShadow, LenShadow, I.getVolatileCst()}));
2911 MTI->setDestAlignment(DFSF.getShadowAlign(
I.getDestAlign().valueOrOne()));
2912 MTI->setSourceAlignment(DFSF.getShadowAlign(
I.getSourceAlign().valueOrOne()));
2913 if (DFSF.Opts.dfsan_event_callbacks) {
2915 DFSF.DFS.DFSanMemTransferCallbackFn,
2916 {DestShadow, IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2920void DFSanVisitor::visitCondBrInst(CondBrInst &BR) {
2921 DFSF.addConditionalCallbacksIfEnabled(BR,
BR.getCondition());
2924void DFSanVisitor::visitSwitchInst(SwitchInst &SW) {
2925 DFSF.addConditionalCallbacksIfEnabled(SW, SW.
getCondition());
2931 RetVal =
I->getOperand(0);
2934 return I->isMustTailCall();
2939void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
2948 unsigned Size = getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
2954 if (DFSF.DFS.shouldTrackOrigins()) {
2961void DFSanVisitor::addShadowArguments(
Function &
F, CallBase &CB,
2962 std::vector<Value *> &Args,
2964 FunctionType *FT =
F.getFunctionType();
2969 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
2971 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()));
2974 if (FT->isVarArg()) {
2975 auto *LabelVATy = ArrayType::get(DFSF.DFS.PrimitiveShadowTy,
2976 CB.
arg_size() - FT->getNumParams());
2977 auto *LabelVAAlloca =
2978 new AllocaInst(LabelVATy, getDataLayout().getAllocaAddrSpace(),
2981 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
2984 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()),
2992 if (!FT->getReturnType()->isVoidTy()) {
2993 if (!DFSF.LabelReturnAlloca) {
2994 DFSF.LabelReturnAlloca =
new AllocaInst(
2995 DFSF.DFS.PrimitiveShadowTy, getDataLayout().getAllocaAddrSpace(),
2998 Args.push_back(DFSF.LabelReturnAlloca);
3002void DFSanVisitor::addOriginArguments(
Function &
F, CallBase &CB,
3003 std::vector<Value *> &Args,
3005 FunctionType *FT =
F.getFunctionType();
3010 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
3011 Args.push_back(DFSF.getOrigin(*
I));
3014 if (FT->isVarArg()) {
3016 ArrayType::get(DFSF.DFS.OriginTy, CB.
arg_size() - FT->getNumParams());
3017 auto *OriginVAAlloca =
3018 new AllocaInst(OriginVATy, getDataLayout().getAllocaAddrSpace(),
3021 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
3030 if (!FT->getReturnType()->isVoidTy()) {
3031 if (!DFSF.OriginReturnAlloca) {
3032 DFSF.OriginReturnAlloca =
new AllocaInst(
3033 DFSF.DFS.OriginTy, getDataLayout().getAllocaAddrSpace(),
3036 Args.push_back(DFSF.OriginReturnAlloca);
3040bool DFSanVisitor::visitWrappedCallBase(
Function &
F, CallBase &CB) {
3042 switch (DFSF.DFS.getWrapperKind(&
F)) {
3043 case DataFlowSanitizer::WK_Warning:
3045 IRB.
CreateCall(DFSF.DFS.DFSanUnimplementedFn,
3047 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3048 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3049 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3051 case DataFlowSanitizer::WK_Discard:
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_Functional:
3059 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3060 visitInstOperands(CB);
3062 case DataFlowSanitizer::WK_Custom:
3070 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3071 FunctionType *FT =
F.getFunctionType();
3072 TransformedFunction CustomFnTy =
3073 DFSF.DFS.getCustomFunctionType(FT, DFSF.TLI);
3074 std::string CustomFName = ShouldTrackOrigins ?
"__dfso_" :
"__dfsw_";
3075 CustomFName +=
F.getName();
3077 CustomFName, CustomFnTy.TransformedType);
3084 AttributeList CustomAL = CustomFun->getAttributes();
3085 CustomFun->copyAttributesFrom(&
F);
3086 CustomFun->setAttributes(AttributeList::get(
3088 {CustomFun->getAttributes(), CustomAL, CustomFnTy.NewParamAttrs}));
3091 if (!FT->getReturnType()->isVoidTy()) {
3092 CustomFun->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
3096 std::vector<Value *>
Args;
3100 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N) {
3105 addShadowArguments(
F, CB, Args, IRB);
3108 if (ShouldTrackOrigins)
3109 addOriginArguments(
F, CB, Args, IRB);
3114 CallInst *CustomCI = IRB.
CreateCall(CustomFunCallee, Args);
3120 {transformFunctionAttributes(CustomFnTy, CI->getContext(),
3121 CI->getAttributes()),
3122 F.getAttributes(), CustomFnTy.NewParamAttrs}));
3125 if (!FT->getReturnType()->isVoidTy()) {
3126 LoadInst *LabelLoad =
3127 IRB.
CreateLoad(DFSF.DFS.PrimitiveShadowTy, DFSF.LabelReturnAlloca);
3128 DFSF.setShadow(CustomCI,
3129 DFSF.expandFromPrimitiveShadow(
3130 FT->getReturnType(), LabelLoad, CB.
getIterator()));
3131 if (ShouldTrackOrigins) {
3132 LoadInst *OriginLoad =
3133 IRB.
CreateLoad(DFSF.DFS.OriginTy, DFSF.OriginReturnAlloca);
3134 DFSF.setOrigin(CustomCI, OriginLoad);
3146 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3147 uint32_t OrderingTable[NumOrderings] = {};
3149 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3150 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3151 OrderingTable[(int)AtomicOrderingCABI::consume] =
3152 (
int)AtomicOrderingCABI::acquire;
3153 OrderingTable[(int)AtomicOrderingCABI::release] =
3154 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
3155 (int)AtomicOrderingCABI::acq_rel;
3156 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3157 (
int)AtomicOrderingCABI::seq_cst;
3162void DFSanVisitor::visitLibAtomicLoad(CallBase &CB) {
3173 Value *NewOrdering =
3178 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3184 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3185 {DstPtr, SrcPtr, NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3189 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3190 uint32_t OrderingTable[NumOrderings] = {};
3192 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3193 OrderingTable[(
int)AtomicOrderingCABI::release] =
3194 (int)AtomicOrderingCABI::release;
3195 OrderingTable[(int)AtomicOrderingCABI::consume] =
3196 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3197 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
3198 (
int)AtomicOrderingCABI::acq_rel;
3199 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3200 (
int)AtomicOrderingCABI::seq_cst;
3205void DFSanVisitor::visitLibAtomicStore(CallBase &CB) {
3213 Value *NewOrdering =
3221 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3222 {DstPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3225void DFSanVisitor::visitLibAtomicExchange(CallBase &CB) {
3241 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3242 {DstPtr, TargetPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3246 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3247 {TargetPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3250void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
3264 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3266 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3270 CallInst *CI = NextIRB.CreateCall(
3271 DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
3272 {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false), TargetPtr,
3273 ExpectedPtr, DesiredPtr,
3274 NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3278void DFSanVisitor::visitCallBase(CallBase &CB) {
3281 visitInstOperands(CB);
3291 if (LF != NotLibFunc) {
3296 case LibFunc_atomic_load:
3298 llvm::errs() <<
"DFSAN -- cannot instrument invoke of libatomic load. "
3302 visitLibAtomicLoad(CB);
3304 case LibFunc_atomic_store:
3305 visitLibAtomicStore(CB);
3313 if (
F &&
F->hasName() && !
F->isVarArg()) {
3314 if (
F->getName() ==
"__atomic_exchange") {
3315 visitLibAtomicExchange(CB);
3318 if (
F->getName() ==
"__atomic_compare_exchange") {
3319 visitLibAtomicCompareExchange(CB);
3325 if (UnwrappedFnIt != DFSF.DFS.UnwrappedFnMap.end())
3326 if (visitWrappedCallBase(*UnwrappedFnIt->second, CB))
3331 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3333 const DataLayout &
DL = getDataLayout();
3336 unsigned ArgOffset = 0;
3337 for (
unsigned I = 0,
N = FT->getNumParams();
I !=
N; ++
I) {
3338 if (ShouldTrackOrigins) {
3341 if (
I < DFSF.DFS.NumOfElementsInArgOrgTLS &&
3342 !DFSF.DFS.isZeroShadow(ArgShadow))
3344 DFSF.getArgOriginTLS(
I, IRB));
3348 DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(
I)));
3354 DFSF.getArgTLS(FT->getParamType(
I), ArgOffset, IRB),
3362 if (
II->getNormalDest()->getSinglePredecessor()) {
3363 Next = &
II->getNormalDest()->front();
3380 unsigned Size =
DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
3383 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3385 LoadInst *LI = NextIRB.CreateAlignedLoad(
3386 DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.
getType(), NextIRB),
3388 DFSF.SkipInsts.
insert(LI);
3389 DFSF.setShadow(&CB, LI);
3390 DFSF.NonZeroChecks.push_back(LI);
3393 if (ShouldTrackOrigins) {
3394 LoadInst *LI = NextIRB.CreateLoad(DFSF.DFS.OriginTy,
3395 DFSF.getRetvalOriginTLS(),
"_dfsret_o");
3396 DFSF.SkipInsts.
insert(LI);
3397 DFSF.setOrigin(&CB, LI);
3400 DFSF.addReachesFunctionCallbacksIfEnabled(NextIRB, CB, &CB);
3404void DFSanVisitor::visitPHINode(PHINode &PN) {
3405 Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
3411 for (BasicBlock *BB : PN.
blocks())
3414 DFSF.setShadow(&PN, ShadowPN);
3416 PHINode *OriginPN =
nullptr;
3417 if (DFSF.DFS.shouldTrackOrigins()) {
3421 for (BasicBlock *BB : PN.
blocks())
3423 DFSF.setOrigin(&PN, OriginPN);
3426 DFSF.PHIFixups.push_back({&PN, ShadowPN, OriginPN});
3440 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
SmallVector< MachineOperand, 4 > 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.
@ 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.