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));
1644 if (Opts.dfsan_reaches_function_callbacks) {
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);
1673 for (BasicBlock *BB : BBList) {
1683 if (!DFSF.SkipInsts.
count(Inst))
1684 DFSanVisitor(DFSF).visit(Inst);
1695 for (DFSanFunction::PHIFixupElement &
P : DFSF.PHIFixups) {
1696 for (
unsigned Val = 0,
N =
P.Phi->getNumIncomingValues(); Val !=
N;
1698 P.ShadowPhi->setIncomingValue(
1699 Val, DFSF.getShadow(
P.Phi->getIncomingValue(Val)));
1701 P.OriginPhi->setIncomingValue(
1702 Val, DFSF.getOrigin(
P.Phi->getIncomingValue(Val)));
1710 if (Opts.dfsan_debug_nonzero_labels) {
1711 for (
Value *V : DFSF.NonZeroChecks) {
1714 Pos = std::next(
I->getIterator());
1718 Pos = std::next(Pos->getIterator());
1720 Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(V, Pos);
1722 IRB.
CreateICmpNE(PrimitiveShadow, DFSF.DFS.ZeroPrimitiveShadow);
1724 Ne, Pos,
false, ColdCallWeights));
1726 ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn, {});
1731 return Changed || !FnsToInstrument.empty() ||
1732 M.global_size() != InitialGlobalSize ||
M.size() != InitialModuleSize;
1736 return IRB.
CreatePtrAdd(DFS.ArgTLS, ConstantInt::get(DFS.IntptrTy, ArgOffset),
1745Value *DFSanFunction::getRetvalOriginTLS() {
return DFS.RetvalOriginTLS; }
1749 ArgNo,
"_dfsarg_o");
1753 assert(DFS.shouldTrackOrigins());
1755 return DFS.ZeroOrigin;
1756 Value *&Origin = ValOriginMap[
V];
1760 return DFS.ZeroOrigin;
1761 if (
A->getArgNo() < DFS.NumOfElementsInArgOrgTLS) {
1762 Instruction *ArgOriginTLSPos = &*
F->getEntryBlock().begin();
1764 Value *ArgOriginPtr = getArgOriginTLS(
A->getArgNo(), IRB);
1765 Origin = IRB.
CreateLoad(DFS.OriginTy, ArgOriginPtr);
1768 Origin = DFS.ZeroOrigin;
1771 Origin = DFS.ZeroOrigin;
1777void DFSanFunction::setOrigin(Instruction *
I,
Value *Origin) {
1778 if (!DFS.shouldTrackOrigins())
1782 ValOriginMap[
I] = Origin;
1785Value *DFSanFunction::getShadowForTLSArgument(Argument *
A) {
1786 unsigned ArgOffset = 0;
1787 const DataLayout &
DL =
F->getDataLayout();
1788 for (
auto &FArg :
F->args()) {
1789 if (!FArg.getType()->isSized()) {
1795 unsigned Size =
DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
1808 Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
1813 return DFS.getZeroShadow(
A);
1818 return DFS.getZeroShadow(V);
1819 if (IsForceZeroLabels)
1820 return DFS.getZeroShadow(V);
1821 Value *&Shadow = ValShadowMap[
V];
1825 return DFS.getZeroShadow(V);
1826 Shadow = getShadowForTLSArgument(
A);
1827 NonZeroChecks.push_back(Shadow);
1829 Shadow = DFS.getZeroShadow(V);
1835void DFSanFunction::setShadow(Instruction *
I,
Value *Shadow) {
1837 ValShadowMap[
I] = Shadow;
1845 assert(Addr != RetvalTLS &&
"Reinstrumenting?");
1848 uint64_t AndMask = MapParams->AndMask;
1851 IRB.
CreateAnd(OffsetLong, ConstantInt::get(IntptrTy, ~AndMask));
1853 uint64_t XorMask = MapParams->XorMask;
1855 OffsetLong = IRB.
CreateXor(OffsetLong, ConstantInt::get(IntptrTy, XorMask));
1859std::pair<Value *, Value *>
1860DataFlowSanitizer::getShadowOriginAddress(
Value *Addr, Align InstAlignment,
1864 Value *ShadowOffset = getShadowOffset(Addr, IRB);
1865 Value *ShadowLong = ShadowOffset;
1866 uint64_t ShadowBase = MapParams->ShadowBase;
1867 if (ShadowBase != 0) {
1869 IRB.
CreateAdd(ShadowLong, ConstantInt::get(IntptrTy, ShadowBase));
1872 Value *OriginPtr =
nullptr;
1873 if (shouldTrackOrigins()) {
1874 Value *OriginLong = ShadowOffset;
1875 uint64_t OriginBase = MapParams->OriginBase;
1876 if (OriginBase != 0)
1878 IRB.
CreateAdd(OriginLong, ConstantInt::get(IntptrTy, OriginBase));
1884 OriginLong = IRB.
CreateAnd(OriginLong, ConstantInt::get(IntptrTy, ~Mask));
1888 return std::make_pair(ShadowPtr, OriginPtr);
1891Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1893 Value *ShadowOffset) {
1898Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1901 Value *ShadowAddr = getShadowOffset(Addr, IRB);
1902 uint64_t ShadowBase = MapParams->ShadowBase;
1903 if (ShadowBase != 0)
1905 IRB.
CreateAdd(ShadowAddr, ConstantInt::get(IntptrTy, ShadowBase));
1906 return getShadowAddress(Addr, Pos, ShadowAddr);
1911 Value *PrimitiveValue = combineShadows(
V1, V2, Pos);
1912 return expandFromPrimitiveShadow(
T, PrimitiveValue, Pos);
1919 if (DFS.isZeroShadow(
V1))
1920 return collapseToPrimitiveShadow(V2, Pos);
1921 if (DFS.isZeroShadow(V2))
1922 return collapseToPrimitiveShadow(
V1, Pos);
1924 return collapseToPrimitiveShadow(
V1, Pos);
1926 auto V1Elems = ShadowElements.
find(
V1);
1927 auto V2Elems = ShadowElements.
find(V2);
1928 if (V1Elems != ShadowElements.
end() && V2Elems != ShadowElements.
end()) {
1930 return collapseToPrimitiveShadow(
V1, Pos);
1933 return collapseToPrimitiveShadow(V2, Pos);
1935 }
else if (V1Elems != ShadowElements.
end()) {
1936 if (V1Elems->second.count(V2))
1937 return collapseToPrimitiveShadow(
V1, Pos);
1938 }
else if (V2Elems != ShadowElements.
end()) {
1939 if (V2Elems->second.count(
V1))
1940 return collapseToPrimitiveShadow(V2, Pos);
1943 auto Key = std::make_pair(
V1, V2);
1946 CachedShadow &CCS = CachedShadows[
Key];
1947 if (CCS.Block && DT.
dominates(CCS.Block, Pos->getParent()))
1951 Value *PV1 = collapseToPrimitiveShadow(
V1, Pos);
1952 Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
1955 CCS.Block = Pos->getParent();
1956 CCS.Shadow = IRB.
CreateOr(PV1, PV2);
1958 std::set<Value *> UnionElems;
1959 if (V1Elems != ShadowElements.
end()) {
1960 UnionElems = V1Elems->second;
1962 UnionElems.insert(
V1);
1964 if (V2Elems != ShadowElements.
end()) {
1965 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
1967 UnionElems.insert(V2);
1969 ShadowElements[CCS.Shadow] = std::move(UnionElems);
1977Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
1979 return DFS.getZeroShadow(Inst);
1983 Shadow = combineShadows(Shadow, getShadow(Inst->
getOperand(
I)),
1986 return expandFromPrimitiveShadow(Inst->
getType(), Shadow,
1990void DFSanVisitor::visitInstOperands(Instruction &
I) {
1991 Value *CombinedShadow = DFSF.combineOperandShadows(&
I);
1992 DFSF.setShadow(&
I, CombinedShadow);
1993 visitInstOperandOrigins(
I);
1996Value *DFSanFunction::combineOrigins(
const std::vector<Value *> &Shadows,
1997 const std::vector<Value *> &Origins,
1999 ConstantInt *Zero) {
2000 assert(Shadows.size() == Origins.size());
2001 size_t Size = Origins.size();
2003 return DFS.ZeroOrigin;
2004 Value *Origin =
nullptr;
2006 Zero = DFS.ZeroPrimitiveShadow;
2007 for (
size_t I = 0;
I !=
Size; ++
I) {
2008 Value *OpOrigin = Origins[
I];
2010 if (ConstOpOrigin && ConstOpOrigin->
isNullValue())
2016 Value *OpShadow = Shadows[
I];
2017 Value *PrimitiveShadow = collapseToPrimitiveShadow(OpShadow, Pos);
2022 return Origin ? Origin : DFS.ZeroOrigin;
2025Value *DFSanFunction::combineOperandOrigins(Instruction *Inst) {
2027 std::vector<Value *> Shadows(
Size);
2028 std::vector<Value *> Origins(
Size);
2029 for (
unsigned I = 0;
I !=
Size; ++
I) {
2033 return combineOrigins(Shadows, Origins, Inst->
getIterator());
2036void DFSanVisitor::visitInstOperandOrigins(Instruction &
I) {
2037 if (!DFSF.DFS.shouldTrackOrigins())
2039 Value *CombinedOrigin = DFSF.combineOperandOrigins(&
I);
2040 DFSF.setOrigin(&
I, CombinedOrigin);
2043Align DFSanFunction::getShadowAlign(Align InstAlignment) {
2045 Opts.dfsan_preserve_alignment ? InstAlignment :
Align(1);
2049Align DFSanFunction::getOriginAlign(Align InstAlignment) {
2054bool DFSanFunction::isLookupTableConstant(
Value *
P) {
2056 if (GV->isConstant() && GV->
hasName())
2057 return DFS.CombineTaintLookupTableNames.
count(GV->
getName());
2062bool DFSanFunction::useCallbackLoadLabelAndOrigin(
uint64_t Size,
2063 Align InstAlignment) {
2066 if (Opts.dfsan_track_origins == 2)
2087 Value **OriginAddr) {
2090 IRB.
CreateGEP(OriginTy, *OriginAddr, ConstantInt::get(IntptrTy, 1));
2094std::pair<Value *, Value *> DFSanFunction::loadShadowFast(
2097 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2098 const uint64_t ShadowSize =
Size * DFS.ShadowWidthBytes;
2100 assert(
Size >= 4 &&
"Not large enough load size for fast path!");
2103 std::vector<Value *> Shadows;
2104 std::vector<Value *> Origins;
2117 Type *WideShadowTy =
2118 ShadowSize == 4 ? Type::getInt32Ty(*DFS.Ctx) :
Type::getInt64Ty(*DFS.Ctx);
2121 Value *CombinedWideShadow =
2125 const uint64_t BytesPerWideShadow = WideShadowBitWidth / DFS.ShadowWidthBits;
2127 auto AppendWideShadowAndOrigin = [&](
Value *WideShadow,
Value *Origin) {
2128 if (BytesPerWideShadow > 4) {
2129 assert(BytesPerWideShadow == 8);
2136 Value *WideShadowLo =
2137 F->getDataLayout().isLittleEndian()
2140 ConstantInt::get(WideShadowTy, WideShadowBitWidth / 2))
2143 ConstantInt::get(WideShadowTy,
2144 ((1ULL << (WideShadowBitWidth / 2)) - 1)
2145 << (WideShadowBitWidth / 2)));
2146 Shadows.push_back(WideShadow);
2147 Origins.push_back(DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr));
2149 Shadows.push_back(WideShadowLo);
2150 Origins.push_back(Origin);
2152 Shadows.push_back(WideShadow);
2153 Origins.push_back(Origin);
2157 if (ShouldTrackOrigins)
2158 AppendWideShadowAndOrigin(CombinedWideShadow, FirstOrigin);
2165 for (
uint64_t ByteOfs = BytesPerWideShadow; ByteOfs <
Size;
2166 ByteOfs += BytesPerWideShadow) {
2167 ShadowAddr = IRB.
CreateGEP(WideShadowTy, ShadowAddr,
2168 ConstantInt::get(DFS.IntptrTy, 1));
2169 Value *NextWideShadow =
2171 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, NextWideShadow);
2172 if (ShouldTrackOrigins) {
2173 Value *NextOrigin = DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr);
2174 AppendWideShadowAndOrigin(NextWideShadow, NextOrigin);
2177 for (
unsigned Width = WideShadowBitWidth / 2; Width >= DFS.ShadowWidthBits;
2180 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, ShrShadow);
2182 return {IRB.
CreateTrunc(CombinedWideShadow, DFS.PrimitiveShadowTy),
2184 ? combineOrigins(Shadows, Origins, Pos,
2189std::pair<Value *, Value *> DFSanFunction::loadShadowOriginSansLoadTracking(
2191 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2195 const auto SI = AllocaShadowMap.
find(AI);
2196 if (SI != AllocaShadowMap.
end()) {
2199 const auto OI = AllocaOriginMap.
find(AI);
2200 assert(!ShouldTrackOrigins || OI != AllocaOriginMap.
end());
2201 return {ShadowLI, ShouldTrackOrigins
2208 SmallVector<const Value *, 2> Objs;
2210 bool AllConstants =
true;
2211 for (
const Value *Obj : Objs) {
2217 AllConstants =
false;
2221 return {DFS.ZeroPrimitiveShadow,
2222 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2225 return {DFS.ZeroPrimitiveShadow,
2226 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2230 if (ShouldTrackOrigins &&
2231 useCallbackLoadLabelAndOrigin(
Size, InstAlignment)) {
2234 IRB.
CreateCall(DFS.DFSanLoadLabelAndOriginFn,
2235 {Addr, ConstantInt::get(DFS.IntptrTy, Size)});
2238 DFS.PrimitiveShadowTy),
2243 Value *ShadowAddr, *OriginAddr;
2244 std::tie(ShadowAddr, OriginAddr) =
2245 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2247 const Align ShadowAlign = getShadowAlign(InstAlignment);
2248 const Align OriginAlign = getOriginAlign(InstAlignment);
2249 Value *Origin =
nullptr;
2250 if (ShouldTrackOrigins) {
2259 LoadInst *LI =
new LoadInst(DFS.PrimitiveShadowTy, ShadowAddr,
"", Pos);
2261 return {LI, Origin};
2265 Value *ShadowAddr1 = IRB.
CreateGEP(DFS.PrimitiveShadowTy, ShadowAddr,
2266 ConstantInt::get(DFS.IntptrTy, 1));
2271 return {combineShadows(
Load, Load1, Pos), Origin};
2274 bool HasSizeForFastPath = DFS.hasLoadSizeForFastPath(
Size);
2276 if (HasSizeForFastPath)
2277 return loadShadowFast(ShadowAddr, OriginAddr,
Size, ShadowAlign,
2278 OriginAlign, Origin, Pos);
2282 DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
2284 return {FallbackCall, Origin};
2287std::pair<Value *, Value *>
2290 Value *PrimitiveShadow, *Origin;
2291 std::tie(PrimitiveShadow, Origin) =
2292 loadShadowOriginSansLoadTracking(Addr,
Size, InstAlignment, Pos);
2293 if (DFS.shouldTrackOrigins()) {
2294 if (Opts.dfsan_track_origins == 2) {
2297 if (!ConstantShadow || !ConstantShadow->isNullValue())
2298 Origin = updateOriginIfTainted(PrimitiveShadow, Origin, IRB);
2301 return {PrimitiveShadow, Origin};
2322 if (!V->getType()->isPointerTy())
2331 V =
GEP->getPointerOperand();
2334 if (!V->getType()->isPointerTy())
2339 }
while (Visited.
insert(V).second);
2344void DFSanVisitor::visitLoadInst(LoadInst &LI) {
2348 DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
2349 DFSF.setOrigin(&LI, DFSF.DFS.ZeroOrigin);
2364 Pos = std::next(Pos);
2366 std::vector<Value *> Shadows;
2367 std::vector<Value *> Origins;
2368 Value *PrimitiveShadow, *Origin;
2369 std::tie(PrimitiveShadow, Origin) =
2371 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2372 if (ShouldTrackOrigins) {
2373 Shadows.push_back(PrimitiveShadow);
2374 Origins.push_back(Origin);
2376 if (DFSF.Opts.dfsan_combine_pointer_labels_on_load ||
2377 DFSF.isLookupTableConstant(
2380 PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, Pos);
2381 if (ShouldTrackOrigins) {
2382 Shadows.push_back(PtrShadow);
2386 if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
2387 DFSF.NonZeroChecks.push_back(PrimitiveShadow);
2390 DFSF.expandFromPrimitiveShadow(LI.
getType(), PrimitiveShadow, Pos);
2391 DFSF.setShadow(&LI, Shadow);
2393 if (ShouldTrackOrigins) {
2394 DFSF.setOrigin(&LI, DFSF.combineOrigins(Shadows, Origins, Pos));
2397 if (DFSF.Opts.dfsan_event_callbacks) {
2401 IRB.
CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr});
2406 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, LI, &LI);
2409Value *DFSanFunction::updateOriginIfTainted(
Value *Shadow,
Value *Origin,
2411 assert(DFS.shouldTrackOrigins());
2412 return IRB.
CreateCall(DFS.DFSanChainOriginIfTaintedFn, {Shadow, Origin});
2416 if (!DFS.shouldTrackOrigins())
2418 return IRB.
CreateCall(DFS.DFSanChainOriginFn, V);
2422 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2423 const DataLayout &
DL =
F->getDataLayout();
2424 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2425 if (IntptrSize == OriginSize)
2427 assert(IntptrSize == OriginSize * 2);
2433 Value *StoreOriginAddr,
2434 uint64_t StoreOriginSize, Align Alignment) {
2435 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2436 const DataLayout &
DL =
F->getDataLayout();
2437 const Align IntptrAlignment =
DL.getABITypeAlign(DFS.IntptrTy);
2438 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2440 assert(IntptrSize >= OriginSize);
2444 if (Alignment >= IntptrAlignment && IntptrSize > OriginSize) {
2445 Value *IntptrOrigin = originToIntptr(IRB, Origin);
2446 Value *IntptrStoreOriginPtr =
2448 for (
unsigned I = 0;
I < StoreOriginSize / IntptrSize; ++
I) {
2451 : IntptrStoreOriginPtr;
2453 Ofs += IntptrSize / OriginSize;
2454 CurrentAlignment = IntptrAlignment;
2458 for (
unsigned I = Ofs;
I < (StoreOriginSize + OriginSize - 1) / OriginSize;
2468 const Twine &Name) {
2469 Type *VTy =
V->getType();
2474 return IRB.
CreateICmpNE(V, ConstantInt::get(VTy, 0), Name);
2479 Value *StoreOriginAddr, Align InstAlignment) {
2482 const Align OriginAlignment = getOriginAlign(InstAlignment);
2483 Value *CollapsedShadow = collapseToPrimitiveShadow(Shadow, Pos);
2486 if (!ConstantShadow->isNullValue())
2487 paintOrigin(IRB, updateOrigin(Origin, IRB), StoreOriginAddr,
Size,
2492 if (shouldInstrumentWithCall()) {
2494 DFS.DFSanMaybeStoreOriginFn,
2495 {CollapsedShadow, Addr, ConstantInt::get(DFS.IntptrTy, Size), Origin});
2497 Value *
Cmp = convertToBool(CollapsedShadow, IRB,
"_dfscmp");
2498 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
2500 Cmp, &*IRB.
GetInsertPoint(),
false, DFS.OriginStoreWeights, &DTU);
2502 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), StoreOriginAddr,
Size,
2512 IntegerType *ShadowTy =
2514 Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
2515 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
2522 Align InstAlignment,
2523 Value *PrimitiveShadow,
2526 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins() && Origin;
2529 const auto SI = AllocaShadowMap.
find(AI);
2530 if (SI != AllocaShadowMap.
end()) {
2536 if (ShouldTrackOrigins && !DFS.isZeroShadow(PrimitiveShadow)) {
2537 const auto OI = AllocaOriginMap.
find(AI);
2538 assert(OI != AllocaOriginMap.
end() && Origin);
2545 const Align ShadowAlign = getShadowAlign(InstAlignment);
2546 if (DFS.isZeroShadow(PrimitiveShadow)) {
2547 storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign, Pos);
2552 Value *ShadowAddr, *OriginAddr;
2553 std::tie(ShadowAddr, OriginAddr) =
2554 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2556 const unsigned ShadowVecSize = 8;
2557 assert(ShadowVecSize * DFS.ShadowWidthBits <= 128 &&
2558 "Shadow vector is too large!");
2562 if (LeftSize >= ShadowVecSize) {
2566 for (
unsigned I = 0;
I != ShadowVecSize; ++
I) {
2568 ShadowVec, PrimitiveShadow,
2569 ConstantInt::get(Type::getInt32Ty(*DFS.Ctx),
I));
2572 Value *CurShadowVecAddr =
2575 LeftSize -= ShadowVecSize;
2577 }
while (LeftSize >= ShadowVecSize);
2580 while (LeftSize > 0) {
2581 Value *CurShadowAddr =
2588 if (ShouldTrackOrigins) {
2589 storeOrigin(Pos, Addr,
Size, PrimitiveShadow, Origin, OriginAddr,
2611void DFSanVisitor::visitStoreInst(StoreInst &SI) {
2612 auto &
DL =
SI.getDataLayout();
2613 Value *Val =
SI.getValueOperand();
2626 const bool ShouldTrackOrigins =
2627 DFSF.DFS.shouldTrackOrigins() && !
SI.isAtomic();
2628 std::vector<Value *> Shadows;
2629 std::vector<Value *> Origins;
2632 SI.isAtomic() ? DFSF.DFS.getZeroShadow(Val) : DFSF.getShadow(Val);
2634 if (ShouldTrackOrigins) {
2635 Shadows.push_back(Shadow);
2636 Origins.push_back(DFSF.getOrigin(Val));
2639 Value *PrimitiveShadow;
2640 if (DFSF.Opts.dfsan_combine_pointer_labels_on_store) {
2641 Value *PtrShadow = DFSF.getShadow(
SI.getPointerOperand());
2642 if (ShouldTrackOrigins) {
2643 Shadows.push_back(PtrShadow);
2644 Origins.push_back(DFSF.getOrigin(
SI.getPointerOperand()));
2646 PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow,
SI.getIterator());
2648 PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow,
SI.getIterator());
2650 Value *Origin =
nullptr;
2651 if (ShouldTrackOrigins)
2652 Origin = DFSF.combineOrigins(Shadows, Origins,
SI.getIterator());
2653 DFSF.storePrimitiveShadowOrigin(
SI.getPointerOperand(),
Size,
SI.getAlign(),
2654 PrimitiveShadow, Origin,
SI.getIterator());
2655 if (DFSF.Opts.dfsan_event_callbacks) {
2657 Value *Addr =
SI.getPointerOperand();
2659 IRB.
CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr});
2664void DFSanVisitor::visitCASOrRMW(Align InstAlignment, Instruction &
I) {
2667 Value *Val =
I.getOperand(1);
2668 const auto &
DL =
I.getDataLayout();
2676 Value *Addr =
I.getOperand(0);
2677 const Align ShadowAlign = DFSF.getShadowAlign(InstAlignment);
2678 DFSF.storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign,
I.getIterator());
2679 DFSF.setShadow(&
I, DFSF.DFS.getZeroShadow(&
I));
2680 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2683void DFSanVisitor::visitAtomicRMWInst(AtomicRMWInst &
I) {
2684 visitCASOrRMW(
I.getAlign(),
I);
2690void DFSanVisitor::visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2691 visitCASOrRMW(
I.getAlign(),
I);
2697void DFSanVisitor::visitUnaryOperator(UnaryOperator &UO) {
2698 visitInstOperands(UO);
2701void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) {
2702 visitInstOperands(BO);
2705void DFSanVisitor::visitBitCastInst(BitCastInst &BCI) {
2712 visitInstOperands(BCI);
2715void DFSanVisitor::visitCastInst(CastInst &CI) { visitInstOperands(CI); }
2717void DFSanVisitor::visitCmpInst(CmpInst &CI) {
2718 visitInstOperands(CI);
2719 if (DFSF.Opts.dfsan_event_callbacks) {
2721 Value *CombinedShadow = DFSF.getShadow(&CI);
2723 IRB.
CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
2729void DFSanVisitor::visitLandingPadInst(LandingPadInst &LPI) {
2741 DFSF.setShadow(&LPI, DFSF.DFS.getZeroShadow(&LPI));
2742 DFSF.setOrigin(&LPI, DFSF.DFS.ZeroOrigin);
2745void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
2746 if (DFSF.Opts.dfsan_combine_offset_labels_on_gep ||
2747 DFSF.isLookupTableConstant(
2749 visitInstOperands(GEPI);
2756 DFSF.setShadow(&GEPI, DFSF.getShadow(BasePointer));
2757 if (DFSF.DFS.shouldTrackOrigins())
2758 DFSF.setOrigin(&GEPI, DFSF.getOrigin(BasePointer));
2761void DFSanVisitor::visitExtractElementInst(ExtractElementInst &
I) {
2762 visitInstOperands(
I);
2765void DFSanVisitor::visitInsertElementInst(InsertElementInst &
I) {
2766 visitInstOperands(
I);
2769void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &
I) {
2770 visitInstOperands(
I);
2773void DFSanVisitor::visitExtractValueInst(ExtractValueInst &
I) {
2775 Value *Agg =
I.getAggregateOperand();
2776 Value *AggShadow = DFSF.getShadow(Agg);
2778 DFSF.setShadow(&
I, ResShadow);
2779 visitInstOperandOrigins(
I);
2782void DFSanVisitor::visitInsertValueInst(InsertValueInst &
I) {
2784 Value *AggShadow = DFSF.getShadow(
I.getAggregateOperand());
2785 Value *InsShadow = DFSF.getShadow(
I.getInsertedValueOperand());
2787 DFSF.setShadow(&
I, Res);
2788 visitInstOperandOrigins(
I);
2791void DFSanVisitor::visitAllocaInst(AllocaInst &
I) {
2792 bool AllLoadsStores =
true;
2793 for (User *U :
I.users()) {
2798 if (
SI->getPointerOperand() == &
I)
2802 AllLoadsStores =
false;
2805 if (AllLoadsStores) {
2807 DFSF.AllocaShadowMap[&
I] = IRB.
CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
2808 if (DFSF.DFS.shouldTrackOrigins()) {
2809 DFSF.AllocaOriginMap[&
I] =
2813 DFSF.setShadow(&
I, DFSF.DFS.ZeroPrimitiveShadow);
2814 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2817void DFSanVisitor::visitSelectInst(SelectInst &
I) {
2818 Value *CondShadow = DFSF.getShadow(
I.getCondition());
2819 Value *TrueShadow = DFSF.getShadow(
I.getTrueValue());
2820 Value *FalseShadow = DFSF.getShadow(
I.getFalseValue());
2821 Value *ShadowSel =
nullptr;
2822 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2823 std::vector<Value *> Shadows;
2824 std::vector<Value *> Origins;
2826 ShouldTrackOrigins ? DFSF.getOrigin(
I.getTrueValue()) :
nullptr;
2827 Value *FalseOrigin =
2828 ShouldTrackOrigins ? DFSF.getOrigin(
I.getFalseValue()) :
nullptr;
2830 DFSF.addConditionalCallbacksIfEnabled(
I,
I.getCondition());
2833 ShadowSel = DFSF.combineShadowsThenConvert(
I.getType(), TrueShadow,
2834 FalseShadow,
I.getIterator());
2835 if (ShouldTrackOrigins) {
2836 Shadows.push_back(TrueShadow);
2837 Shadows.push_back(FalseShadow);
2838 Origins.push_back(TrueOrigin);
2839 Origins.push_back(FalseOrigin);
2842 if (TrueShadow == FalseShadow) {
2843 ShadowSel = TrueShadow;
2844 if (ShouldTrackOrigins) {
2845 Shadows.push_back(TrueShadow);
2846 Origins.push_back(TrueOrigin);
2850 "",
I.getIterator());
2851 if (ShouldTrackOrigins) {
2852 Shadows.push_back(ShadowSel);
2854 FalseOrigin,
"",
I.getIterator()));
2858 DFSF.setShadow(&
I, DFSF.Opts.dfsan_track_select_control_flow
2859 ? DFSF.combineShadowsThenConvert(
I.getType(),
2860 CondShadow, ShadowSel,
2863 if (ShouldTrackOrigins) {
2864 if (DFSF.Opts.dfsan_track_select_control_flow) {
2865 Shadows.push_back(CondShadow);
2866 Origins.push_back(DFSF.getOrigin(
I.getCondition()));
2868 DFSF.setOrigin(&
I, DFSF.combineOrigins(Shadows, Origins,
I.getIterator()));
2872void DFSanVisitor::visitMemSetInst(MemSetInst &
I) {
2874 Value *ValShadow = DFSF.getShadow(
I.getValue());
2875 Value *ValOrigin = DFSF.DFS.shouldTrackOrigins()
2876 ? DFSF.getOrigin(
I.getValue())
2877 : DFSF.DFS.ZeroOrigin;
2879 {ValShadow, ValOrigin, I.getDest(),
2880 IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2883void DFSanVisitor::visitMemTransferInst(MemTransferInst &
I) {
2888 if (DFSF.DFS.shouldTrackOrigins()) {
2890 DFSF.DFS.DFSanMemOriginTransferFn,
2891 {I.getArgOperand(0), I.getArgOperand(1),
2892 IRB.CreateIntCast(I.getArgOperand(2), DFSF.DFS.IntptrTy, false)});
2895 Value *DestShadow = DFSF.DFS.getShadowAddress(
I.getDest(),
I.getIterator());
2896 Value *SrcShadow = DFSF.DFS.getShadowAddress(
I.getSource(),
I.getIterator());
2898 IRB.
CreateMul(
I.getLength(), ConstantInt::get(
I.getLength()->getType(),
2899 DFSF.DFS.ShadowWidthBytes));
2901 IRB.
CreateCall(
I.getFunctionType(),
I.getCalledOperand(),
2902 {DestShadow, SrcShadow, LenShadow, I.getVolatileCst()}));
2903 MTI->setDestAlignment(DFSF.getShadowAlign(
I.getDestAlign().valueOrOne()));
2904 MTI->setSourceAlignment(DFSF.getShadowAlign(
I.getSourceAlign().valueOrOne()));
2905 if (DFSF.Opts.dfsan_event_callbacks) {
2907 DFSF.DFS.DFSanMemTransferCallbackFn,
2908 {DestShadow, IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2912void DFSanVisitor::visitCondBrInst(CondBrInst &BR) {
2913 DFSF.addConditionalCallbacksIfEnabled(BR,
BR.getCondition());
2916void DFSanVisitor::visitSwitchInst(SwitchInst &SW) {
2917 DFSF.addConditionalCallbacksIfEnabled(SW, SW.
getCondition());
2923 RetVal =
I->getOperand(0);
2926 return I->isMustTailCall();
2931void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
2940 unsigned Size = getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
2946 if (DFSF.DFS.shouldTrackOrigins()) {
2953void DFSanVisitor::addShadowArguments(
Function &
F, CallBase &CB,
2954 std::vector<Value *> &Args,
2956 FunctionType *FT =
F.getFunctionType();
2961 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
2963 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()));
2966 if (FT->isVarArg()) {
2967 auto *LabelVATy = ArrayType::get(DFSF.DFS.PrimitiveShadowTy,
2968 CB.
arg_size() - FT->getNumParams());
2969 auto *LabelVAAlloca =
2970 new AllocaInst(LabelVATy, getDataLayout().getAllocaAddrSpace(),
2973 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
2976 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()),
2984 if (!FT->getReturnType()->isVoidTy()) {
2985 if (!DFSF.LabelReturnAlloca) {
2986 DFSF.LabelReturnAlloca =
new AllocaInst(
2987 DFSF.DFS.PrimitiveShadowTy, getDataLayout().getAllocaAddrSpace(),
2990 Args.push_back(DFSF.LabelReturnAlloca);
2994void DFSanVisitor::addOriginArguments(
Function &
F, CallBase &CB,
2995 std::vector<Value *> &Args,
2997 FunctionType *FT =
F.getFunctionType();
3002 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
3003 Args.push_back(DFSF.getOrigin(*
I));
3006 if (FT->isVarArg()) {
3008 ArrayType::get(DFSF.DFS.OriginTy, CB.
arg_size() - FT->getNumParams());
3009 auto *OriginVAAlloca =
3010 new AllocaInst(OriginVATy, getDataLayout().getAllocaAddrSpace(),
3013 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
3022 if (!FT->getReturnType()->isVoidTy()) {
3023 if (!DFSF.OriginReturnAlloca) {
3024 DFSF.OriginReturnAlloca =
new AllocaInst(
3025 DFSF.DFS.OriginTy, getDataLayout().getAllocaAddrSpace(),
3028 Args.push_back(DFSF.OriginReturnAlloca);
3032bool DFSanVisitor::visitWrappedCallBase(
Function &
F, CallBase &CB) {
3034 switch (DFSF.DFS.getWrapperKind(&
F)) {
3035 case DataFlowSanitizer::WK_Warning:
3037 IRB.
CreateCall(DFSF.DFS.DFSanUnimplementedFn,
3039 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3040 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3041 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3043 case DataFlowSanitizer::WK_Discard:
3045 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3046 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3047 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3049 case DataFlowSanitizer::WK_Functional:
3051 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3052 visitInstOperands(CB);
3054 case DataFlowSanitizer::WK_Custom:
3062 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3063 FunctionType *FT =
F.getFunctionType();
3064 TransformedFunction CustomFnTy =
3065 DFSF.DFS.getCustomFunctionType(FT, DFSF.TLI);
3066 std::string CustomFName = ShouldTrackOrigins ?
"__dfso_" :
"__dfsw_";
3067 CustomFName +=
F.getName();
3069 CustomFName, CustomFnTy.TransformedType);
3076 AttributeList CustomAL = CustomFun->getAttributes();
3077 CustomFun->copyAttributesFrom(&
F);
3078 CustomFun->setAttributes(AttributeList::get(
3080 {CustomFun->getAttributes(), CustomAL, CustomFnTy.NewParamAttrs}));
3083 if (!FT->getReturnType()->isVoidTy()) {
3084 CustomFun->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
3088 std::vector<Value *>
Args;
3092 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N) {
3097 addShadowArguments(
F, CB, Args, IRB);
3100 if (ShouldTrackOrigins)
3101 addOriginArguments(
F, CB, Args, IRB);
3106 CallInst *CustomCI = IRB.
CreateCall(CustomFunCallee, Args);
3112 {transformFunctionAttributes(CustomFnTy, CI->getContext(),
3113 CI->getAttributes()),
3114 F.getAttributes(), CustomFnTy.NewParamAttrs}));
3117 if (!FT->getReturnType()->isVoidTy()) {
3118 LoadInst *LabelLoad =
3119 IRB.
CreateLoad(DFSF.DFS.PrimitiveShadowTy, DFSF.LabelReturnAlloca);
3120 DFSF.setShadow(CustomCI,
3121 DFSF.expandFromPrimitiveShadow(
3122 FT->getReturnType(), LabelLoad, CB.
getIterator()));
3123 if (ShouldTrackOrigins) {
3124 LoadInst *OriginLoad =
3125 IRB.
CreateLoad(DFSF.DFS.OriginTy, DFSF.OriginReturnAlloca);
3126 DFSF.setOrigin(CustomCI, OriginLoad);
3138 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3139 uint32_t OrderingTable[NumOrderings] = {};
3141 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3142 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3143 OrderingTable[(int)AtomicOrderingCABI::consume] =
3144 (
int)AtomicOrderingCABI::acquire;
3145 OrderingTable[(int)AtomicOrderingCABI::release] =
3146 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
3147 (int)AtomicOrderingCABI::acq_rel;
3148 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3149 (
int)AtomicOrderingCABI::seq_cst;
3154void DFSanVisitor::visitLibAtomicLoad(CallBase &CB) {
3165 Value *NewOrdering =
3170 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3176 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3177 {DstPtr, SrcPtr, NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3181 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3182 uint32_t OrderingTable[NumOrderings] = {};
3184 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3185 OrderingTable[(
int)AtomicOrderingCABI::release] =
3186 (int)AtomicOrderingCABI::release;
3187 OrderingTable[(int)AtomicOrderingCABI::consume] =
3188 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3189 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
3190 (
int)AtomicOrderingCABI::acq_rel;
3191 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3192 (
int)AtomicOrderingCABI::seq_cst;
3197void DFSanVisitor::visitLibAtomicStore(CallBase &CB) {
3205 Value *NewOrdering =
3213 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3214 {DstPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3217void DFSanVisitor::visitLibAtomicExchange(CallBase &CB) {
3233 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3234 {DstPtr, TargetPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3238 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3239 {TargetPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3242void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
3256 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3258 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3262 CallInst *CI = NextIRB.CreateCall(
3263 DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
3264 {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false), TargetPtr,
3265 ExpectedPtr, DesiredPtr,
3266 NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3270void DFSanVisitor::visitCallBase(CallBase &CB) {
3273 visitInstOperands(CB);
3283 if (LF != NotLibFunc) {
3288 case LibFunc_atomic_load:
3290 llvm::errs() <<
"DFSAN -- cannot instrument invoke of libatomic load. "
3294 visitLibAtomicLoad(CB);
3296 case LibFunc_atomic_store:
3297 visitLibAtomicStore(CB);
3305 if (
F &&
F->hasName() && !
F->isVarArg()) {
3306 if (
F->getName() ==
"__atomic_exchange") {
3307 visitLibAtomicExchange(CB);
3310 if (
F->getName() ==
"__atomic_compare_exchange") {
3311 visitLibAtomicCompareExchange(CB);
3317 if (UnwrappedFnIt != DFSF.DFS.UnwrappedFnMap.end())
3318 if (visitWrappedCallBase(*UnwrappedFnIt->second, CB))
3323 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3325 const DataLayout &
DL = getDataLayout();
3328 unsigned ArgOffset = 0;
3329 for (
unsigned I = 0,
N = FT->getNumParams();
I !=
N; ++
I) {
3330 if (ShouldTrackOrigins) {
3333 if (
I < DFSF.DFS.NumOfElementsInArgOrgTLS &&
3334 !DFSF.DFS.isZeroShadow(ArgShadow))
3336 DFSF.getArgOriginTLS(
I, IRB));
3340 DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(
I)));
3346 DFSF.getArgTLS(FT->getParamType(
I), ArgOffset, IRB),
3354 if (
II->getNormalDest()->getSinglePredecessor()) {
3355 Next = &
II->getNormalDest()->front();
3372 unsigned Size =
DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
3375 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3377 LoadInst *LI = NextIRB.CreateAlignedLoad(
3378 DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.
getType(), NextIRB),
3380 DFSF.SkipInsts.
insert(LI);
3381 DFSF.setShadow(&CB, LI);
3382 DFSF.NonZeroChecks.push_back(LI);
3385 if (ShouldTrackOrigins) {
3386 LoadInst *LI = NextIRB.CreateLoad(DFSF.DFS.OriginTy,
3387 DFSF.getRetvalOriginTLS(),
"_dfsret_o");
3388 DFSF.SkipInsts.
insert(LI);
3389 DFSF.setOrigin(&CB, LI);
3392 DFSF.addReachesFunctionCallbacksIfEnabled(NextIRB, CB, &CB);
3396void DFSanVisitor::visitPHINode(PHINode &PN) {
3397 Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
3403 for (BasicBlock *BB : PN.
blocks())
3406 DFSF.setShadow(&PN, ShadowPN);
3408 PHINode *OriginPN =
nullptr;
3409 if (DFSF.DFS.shouldTrackOrigins()) {
3413 for (BasicBlock *BB : PN.
blocks())
3415 DFSF.setOrigin(&PN, OriginPN);
3418 DFSF.PHIFixups.push_back({&PN, ShadowPN, OriginPN});
3431 if (!DataFlowSanitizer(InstrumentationOptions::Global, ABIListFiles, FS)
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),...
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.
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.