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 =
792 TLI.getExtAttrForI8Param(
false);
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;
1752Value *DFSanFunction::getRetvalOriginTLS() {
return DFS.RetvalOriginTLS; }
1756 ArgNo,
"_dfsarg_o");
1760 assert(DFS.shouldTrackOrigins());
1762 return DFS.ZeroOrigin;
1763 Value *&Origin = ValOriginMap[
V];
1767 return DFS.ZeroOrigin;
1768 if (
A->getArgNo() < DFS.NumOfElementsInArgOrgTLS) {
1769 Instruction *ArgOriginTLSPos = &*
F->getEntryBlock().begin();
1771 Value *ArgOriginPtr = getArgOriginTLS(
A->getArgNo(), IRB);
1772 Origin = IRB.
CreateLoad(DFS.OriginTy, ArgOriginPtr);
1775 Origin = DFS.ZeroOrigin;
1778 Origin = DFS.ZeroOrigin;
1784void DFSanFunction::setOrigin(Instruction *
I,
Value *Origin) {
1785 if (!DFS.shouldTrackOrigins())
1789 ValOriginMap[
I] = Origin;
1792Value *DFSanFunction::getShadowForTLSArgument(Argument *
A) {
1793 unsigned ArgOffset = 0;
1794 const DataLayout &
DL =
F->getDataLayout();
1795 for (
auto &FArg :
F->args()) {
1796 if (!FArg.getType()->isSized()) {
1802 unsigned Size =
DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
1815 Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
1820 return DFS.getZeroShadow(
A);
1825 return DFS.getZeroShadow(
V);
1826 if (IsForceZeroLabels)
1827 return DFS.getZeroShadow(
V);
1828 Value *&Shadow = ValShadowMap[
V];
1832 return DFS.getZeroShadow(
V);
1833 Shadow = getShadowForTLSArgument(
A);
1834 NonZeroChecks.push_back(Shadow);
1836 Shadow = DFS.getZeroShadow(
V);
1842void DFSanFunction::setShadow(Instruction *
I,
Value *Shadow) {
1844 ValShadowMap[
I] = Shadow;
1852 assert(Addr != RetvalTLS &&
"Reinstrumenting?");
1855 uint64_t AndMask = MapParams->AndMask;
1858 IRB.
CreateAnd(OffsetLong, ConstantInt::get(IntptrTy, ~AndMask));
1860 uint64_t XorMask = MapParams->XorMask;
1862 OffsetLong = IRB.
CreateXor(OffsetLong, ConstantInt::get(IntptrTy, XorMask));
1866std::pair<Value *, Value *>
1867DataFlowSanitizer::getShadowOriginAddress(
Value *Addr, Align InstAlignment,
1871 Value *ShadowOffset = getShadowOffset(Addr, IRB);
1872 Value *ShadowLong = ShadowOffset;
1873 uint64_t ShadowBase = MapParams->ShadowBase;
1874 if (ShadowBase != 0) {
1876 IRB.
CreateAdd(ShadowLong, ConstantInt::get(IntptrTy, ShadowBase));
1879 Value *OriginPtr =
nullptr;
1880 if (shouldTrackOrigins()) {
1881 Value *OriginLong = ShadowOffset;
1882 uint64_t OriginBase = MapParams->OriginBase;
1883 if (OriginBase != 0)
1885 IRB.
CreateAdd(OriginLong, ConstantInt::get(IntptrTy, OriginBase));
1891 OriginLong = IRB.
CreateAnd(OriginLong, ConstantInt::get(IntptrTy, ~Mask));
1895 return std::make_pair(ShadowPtr, OriginPtr);
1898Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1900 Value *ShadowOffset) {
1905Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
1908 Value *ShadowAddr = getShadowOffset(Addr, IRB);
1909 uint64_t ShadowBase = MapParams->ShadowBase;
1910 if (ShadowBase != 0)
1912 IRB.
CreateAdd(ShadowAddr, ConstantInt::get(IntptrTy, ShadowBase));
1913 return getShadowAddress(Addr, Pos, ShadowAddr);
1918 Value *PrimitiveValue = combineShadows(
V1, V2, Pos);
1919 return expandFromPrimitiveShadow(
T, PrimitiveValue, Pos);
1926 if (DFS.isZeroShadow(
V1))
1927 return collapseToPrimitiveShadow(V2, Pos);
1928 if (DFS.isZeroShadow(V2))
1929 return collapseToPrimitiveShadow(
V1, Pos);
1931 return collapseToPrimitiveShadow(
V1, Pos);
1933 auto V1Elems = ShadowElements.
find(
V1);
1934 auto V2Elems = ShadowElements.
find(V2);
1935 if (V1Elems != ShadowElements.
end() && V2Elems != ShadowElements.
end()) {
1937 return collapseToPrimitiveShadow(
V1, Pos);
1940 return collapseToPrimitiveShadow(V2, Pos);
1942 }
else if (V1Elems != ShadowElements.
end()) {
1943 if (V1Elems->second.count(V2))
1944 return collapseToPrimitiveShadow(
V1, Pos);
1945 }
else if (V2Elems != ShadowElements.
end()) {
1946 if (V2Elems->second.count(
V1))
1947 return collapseToPrimitiveShadow(V2, Pos);
1950 auto Key = std::make_pair(
V1, V2);
1953 CachedShadow &CCS = CachedShadows[
Key];
1954 if (CCS.Block && DT.
dominates(CCS.Block, Pos->getParent()))
1958 Value *PV1 = collapseToPrimitiveShadow(
V1, Pos);
1959 Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
1962 CCS.Block = Pos->getParent();
1963 CCS.Shadow = IRB.
CreateOr(PV1, PV2);
1965 std::set<Value *> UnionElems;
1966 if (V1Elems != ShadowElements.
end()) {
1967 UnionElems = V1Elems->second;
1969 UnionElems.insert(
V1);
1971 if (V2Elems != ShadowElements.
end()) {
1972 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
1974 UnionElems.insert(V2);
1976 ShadowElements[CCS.Shadow] = std::move(UnionElems);
1984Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
1986 return DFS.getZeroShadow(Inst);
1990 Shadow = combineShadows(Shadow, getShadow(Inst->
getOperand(
I)),
1993 return expandFromPrimitiveShadow(Inst->
getType(), Shadow,
1997void DFSanVisitor::visitInstOperands(Instruction &
I) {
1998 Value *CombinedShadow = DFSF.combineOperandShadows(&
I);
1999 DFSF.setShadow(&
I, CombinedShadow);
2000 visitInstOperandOrigins(
I);
2003Value *DFSanFunction::combineOrigins(
const std::vector<Value *> &Shadows,
2004 const std::vector<Value *> &Origins,
2006 ConstantInt *
Zero) {
2007 assert(Shadows.size() == Origins.size());
2008 size_t Size = Origins.size();
2010 return DFS.ZeroOrigin;
2011 Value *Origin =
nullptr;
2013 Zero = DFS.ZeroPrimitiveShadow;
2014 for (
size_t I = 0;
I !=
Size; ++
I) {
2015 Value *OpOrigin = Origins[
I];
2017 if (ConstOpOrigin && ConstOpOrigin->
isNullValue())
2023 Value *OpShadow = Shadows[
I];
2024 Value *PrimitiveShadow = collapseToPrimitiveShadow(OpShadow, Pos);
2029 return Origin ? Origin : DFS.ZeroOrigin;
2032Value *DFSanFunction::combineOperandOrigins(Instruction *Inst) {
2034 std::vector<Value *> Shadows(
Size);
2035 std::vector<Value *> Origins(
Size);
2036 for (
unsigned I = 0;
I !=
Size; ++
I) {
2040 return combineOrigins(Shadows, Origins, Inst->
getIterator());
2043void DFSanVisitor::visitInstOperandOrigins(Instruction &
I) {
2044 if (!DFSF.DFS.shouldTrackOrigins())
2046 Value *CombinedOrigin = DFSF.combineOperandOrigins(&
I);
2047 DFSF.setOrigin(&
I, CombinedOrigin);
2050Align DFSanFunction::getShadowAlign(Align InstAlignment) {
2052 Opts.dfsan_preserve_alignment ? InstAlignment :
Align(1);
2056Align DFSanFunction::getOriginAlign(Align InstAlignment) {
2061bool DFSanFunction::isLookupTableConstant(
Value *
P) {
2063 if (GV->isConstant() && GV->
hasName())
2064 return DFS.CombineTaintLookupTableNames.
count(GV->
getName());
2069bool DFSanFunction::useCallbackLoadLabelAndOrigin(
uint64_t Size,
2070 Align InstAlignment) {
2073 if (Opts.dfsan_track_origins == 2)
2094 Value **OriginAddr) {
2097 IRB.
CreateGEP(OriginTy, *OriginAddr, ConstantInt::get(IntptrTy, 1));
2101std::pair<Value *, Value *> DFSanFunction::loadShadowFast(
2104 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2105 const uint64_t ShadowSize =
Size * DFS.ShadowWidthBytes;
2107 assert(
Size >= 4 &&
"Not large enough load size for fast path!");
2110 std::vector<Value *> Shadows;
2111 std::vector<Value *> Origins;
2124 Type *WideShadowTy =
2125 ShadowSize == 4 ? Type::getInt32Ty(*DFS.Ctx) :
Type::getInt64Ty(*DFS.Ctx);
2128 Value *CombinedWideShadow =
2132 const uint64_t BytesPerWideShadow = WideShadowBitWidth / DFS.ShadowWidthBits;
2134 auto AppendWideShadowAndOrigin = [&](
Value *WideShadow,
Value *Origin) {
2135 if (BytesPerWideShadow > 4) {
2136 assert(BytesPerWideShadow == 8);
2143 Value *WideShadowLo =
2144 F->getDataLayout().isLittleEndian()
2147 ConstantInt::get(WideShadowTy, WideShadowBitWidth / 2))
2150 ConstantInt::get(WideShadowTy,
2151 ((1ULL << (WideShadowBitWidth / 2)) - 1)
2152 << (WideShadowBitWidth / 2)));
2153 Shadows.push_back(WideShadow);
2154 Origins.push_back(DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr));
2156 Shadows.push_back(WideShadowLo);
2157 Origins.push_back(Origin);
2159 Shadows.push_back(WideShadow);
2160 Origins.push_back(Origin);
2164 if (ShouldTrackOrigins)
2165 AppendWideShadowAndOrigin(CombinedWideShadow, FirstOrigin);
2172 for (
uint64_t ByteOfs = BytesPerWideShadow; ByteOfs <
Size;
2173 ByteOfs += BytesPerWideShadow) {
2174 ShadowAddr = IRB.
CreateGEP(WideShadowTy, ShadowAddr,
2175 ConstantInt::get(DFS.IntptrTy, 1));
2176 Value *NextWideShadow =
2178 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, NextWideShadow);
2179 if (ShouldTrackOrigins) {
2180 Value *NextOrigin = DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr);
2181 AppendWideShadowAndOrigin(NextWideShadow, NextOrigin);
2184 for (
unsigned Width = WideShadowBitWidth / 2; Width >= DFS.ShadowWidthBits;
2187 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, ShrShadow);
2189 return {IRB.
CreateTrunc(CombinedWideShadow, DFS.PrimitiveShadowTy),
2191 ? combineOrigins(Shadows, Origins, Pos,
2196std::pair<Value *, Value *> DFSanFunction::loadShadowOriginSansLoadTracking(
2198 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2202 const auto SI = AllocaShadowMap.
find(AI);
2203 if (SI != AllocaShadowMap.
end()) {
2206 const auto OI = AllocaOriginMap.
find(AI);
2207 assert(!ShouldTrackOrigins || OI != AllocaOriginMap.
end());
2208 return {ShadowLI, ShouldTrackOrigins
2215 SmallVector<const Value *, 2> Objs;
2217 bool AllConstants =
true;
2218 for (
const Value *Obj : Objs) {
2224 AllConstants =
false;
2228 return {DFS.ZeroPrimitiveShadow,
2229 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2232 return {DFS.ZeroPrimitiveShadow,
2233 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2237 if (ShouldTrackOrigins &&
2238 useCallbackLoadLabelAndOrigin(
Size, InstAlignment)) {
2241 IRB.
CreateCall(DFS.DFSanLoadLabelAndOriginFn,
2242 {Addr, ConstantInt::get(DFS.IntptrTy, Size)});
2245 DFS.PrimitiveShadowTy),
2250 Value *ShadowAddr, *OriginAddr;
2251 std::tie(ShadowAddr, OriginAddr) =
2252 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2254 const Align ShadowAlign = getShadowAlign(InstAlignment);
2255 const Align OriginAlign = getOriginAlign(InstAlignment);
2256 Value *Origin =
nullptr;
2257 if (ShouldTrackOrigins) {
2266 LoadInst *LI =
new LoadInst(DFS.PrimitiveShadowTy, ShadowAddr,
"", Pos);
2268 return {LI, Origin};
2272 Value *ShadowAddr1 = IRB.
CreateGEP(DFS.PrimitiveShadowTy, ShadowAddr,
2273 ConstantInt::get(DFS.IntptrTy, 1));
2278 return {combineShadows(
Load, Load1, Pos), Origin};
2281 bool HasSizeForFastPath = DFS.hasLoadSizeForFastPath(
Size);
2283 if (HasSizeForFastPath)
2284 return loadShadowFast(ShadowAddr, OriginAddr,
Size, ShadowAlign,
2285 OriginAlign, Origin, Pos);
2289 DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
2291 return {FallbackCall, Origin};
2294std::pair<Value *, Value *>
2297 Value *PrimitiveShadow, *Origin;
2298 std::tie(PrimitiveShadow, Origin) =
2299 loadShadowOriginSansLoadTracking(Addr,
Size, InstAlignment, Pos);
2300 if (DFS.shouldTrackOrigins()) {
2301 if (Opts.dfsan_track_origins == 2) {
2304 if (!ConstantShadow || !ConstantShadow->isNullValue())
2305 Origin = updateOriginIfTainted(PrimitiveShadow, Origin, IRB);
2308 return {PrimitiveShadow, Origin};
2329 if (!
V->getType()->isPointerTy())
2338 V =
GEP->getPointerOperand();
2341 if (!
V->getType()->isPointerTy())
2346 }
while (Visited.
insert(
V).second);
2351void DFSanVisitor::visitLoadInst(LoadInst &LI) {
2355 DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
2356 DFSF.setOrigin(&LI, DFSF.DFS.ZeroOrigin);
2371 Pos = std::next(Pos);
2373 std::vector<Value *> Shadows;
2374 std::vector<Value *> Origins;
2375 Value *PrimitiveShadow, *Origin;
2376 std::tie(PrimitiveShadow, Origin) =
2378 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2379 if (ShouldTrackOrigins) {
2380 Shadows.push_back(PrimitiveShadow);
2381 Origins.push_back(Origin);
2383 if (DFSF.Opts.dfsan_combine_pointer_labels_on_load ||
2384 DFSF.isLookupTableConstant(
2387 PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, Pos);
2388 if (ShouldTrackOrigins) {
2389 Shadows.push_back(PtrShadow);
2393 if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
2394 DFSF.NonZeroChecks.push_back(PrimitiveShadow);
2397 DFSF.expandFromPrimitiveShadow(LI.
getType(), PrimitiveShadow, Pos);
2398 DFSF.setShadow(&LI, Shadow);
2400 if (ShouldTrackOrigins) {
2401 DFSF.setOrigin(&LI, DFSF.combineOrigins(Shadows, Origins, Pos));
2404 if (DFSF.Opts.dfsan_event_callbacks) {
2408 IRB.
CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr});
2413 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, LI, &LI);
2416Value *DFSanFunction::updateOriginIfTainted(
Value *Shadow,
Value *Origin,
2418 assert(DFS.shouldTrackOrigins());
2419 return IRB.
CreateCall(DFS.DFSanChainOriginIfTaintedFn, {Shadow, Origin});
2423 if (!DFS.shouldTrackOrigins())
2429 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2430 const DataLayout &
DL =
F->getDataLayout();
2431 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2432 if (IntptrSize == OriginSize)
2434 assert(IntptrSize == OriginSize * 2);
2440 Value *StoreOriginAddr,
2441 uint64_t StoreOriginSize, Align Alignment) {
2442 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2443 const DataLayout &
DL =
F->getDataLayout();
2444 const Align IntptrAlignment =
DL.getABITypeAlign(DFS.IntptrTy);
2445 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2447 assert(IntptrSize >= OriginSize);
2451 if (Alignment >= IntptrAlignment && IntptrSize > OriginSize) {
2452 Value *IntptrOrigin = originToIntptr(IRB, Origin);
2453 Value *IntptrStoreOriginPtr =
2455 for (
unsigned I = 0;
I < StoreOriginSize / IntptrSize; ++
I) {
2458 : IntptrStoreOriginPtr;
2460 Ofs += IntptrSize / OriginSize;
2461 CurrentAlignment = IntptrAlignment;
2465 for (
unsigned I = Ofs;
I < (StoreOriginSize + OriginSize - 1) / OriginSize;
2475 const Twine &Name) {
2476 Type *VTy =
V->getType();
2486 Value *StoreOriginAddr, Align InstAlignment) {
2489 const Align OriginAlignment = getOriginAlign(InstAlignment);
2490 Value *CollapsedShadow = collapseToPrimitiveShadow(Shadow, Pos);
2493 if (!ConstantShadow->isNullValue())
2494 paintOrigin(IRB, updateOrigin(Origin, IRB), StoreOriginAddr,
Size,
2499 if (shouldInstrumentWithCall()) {
2501 DFS.DFSanMaybeStoreOriginFn,
2502 {CollapsedShadow, Addr, ConstantInt::get(DFS.IntptrTy, Size), Origin});
2504 Value *
Cmp = convertToBool(CollapsedShadow, IRB,
"_dfscmp");
2505 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
2507 Cmp, &*IRB.
GetInsertPoint(),
false, DFS.OriginStoreWeights, &DTU);
2509 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), StoreOriginAddr,
Size,
2519 IntegerType *ShadowTy =
2521 Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
2522 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
2529 Align InstAlignment,
2530 Value *PrimitiveShadow,
2533 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins() && Origin;
2536 const auto SI = AllocaShadowMap.
find(AI);
2537 if (SI != AllocaShadowMap.
end()) {
2543 if (ShouldTrackOrigins && !DFS.isZeroShadow(PrimitiveShadow)) {
2544 const auto OI = AllocaOriginMap.
find(AI);
2545 assert(OI != AllocaOriginMap.
end() && Origin);
2552 const Align ShadowAlign = getShadowAlign(InstAlignment);
2553 if (DFS.isZeroShadow(PrimitiveShadow)) {
2554 storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign, Pos);
2559 Value *ShadowAddr, *OriginAddr;
2560 std::tie(ShadowAddr, OriginAddr) =
2561 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2563 const unsigned ShadowVecSize = 8;
2564 assert(ShadowVecSize * DFS.ShadowWidthBits <= 128 &&
2565 "Shadow vector is too large!");
2569 if (LeftSize >= ShadowVecSize) {
2573 for (
unsigned I = 0;
I != ShadowVecSize; ++
I) {
2575 ShadowVec, PrimitiveShadow,
2576 ConstantInt::get(Type::getInt32Ty(*DFS.Ctx),
I));
2579 Value *CurShadowVecAddr =
2582 LeftSize -= ShadowVecSize;
2584 }
while (LeftSize >= ShadowVecSize);
2587 while (LeftSize > 0) {
2588 Value *CurShadowAddr =
2595 if (ShouldTrackOrigins) {
2596 storeOrigin(Pos, Addr,
Size, PrimitiveShadow, Origin, OriginAddr,
2618void DFSanVisitor::visitStoreInst(StoreInst &SI) {
2619 auto &
DL =
SI.getDataLayout();
2620 Value *Val =
SI.getValueOperand();
2633 const bool ShouldTrackOrigins =
2634 DFSF.DFS.shouldTrackOrigins() && !
SI.isAtomic();
2635 std::vector<Value *> Shadows;
2636 std::vector<Value *> Origins;
2639 SI.isAtomic() ? DFSF.DFS.getZeroShadow(Val) : DFSF.getShadow(Val);
2641 if (ShouldTrackOrigins) {
2642 Shadows.push_back(Shadow);
2643 Origins.push_back(DFSF.getOrigin(Val));
2646 Value *PrimitiveShadow;
2647 if (DFSF.Opts.dfsan_combine_pointer_labels_on_store) {
2648 Value *PtrShadow = DFSF.getShadow(
SI.getPointerOperand());
2649 if (ShouldTrackOrigins) {
2650 Shadows.push_back(PtrShadow);
2651 Origins.push_back(DFSF.getOrigin(
SI.getPointerOperand()));
2653 PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow,
SI.getIterator());
2655 PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow,
SI.getIterator());
2657 Value *Origin =
nullptr;
2658 if (ShouldTrackOrigins)
2659 Origin = DFSF.combineOrigins(Shadows, Origins,
SI.getIterator());
2660 DFSF.storePrimitiveShadowOrigin(
SI.getPointerOperand(),
Size,
SI.getAlign(),
2661 PrimitiveShadow, Origin,
SI.getIterator());
2662 if (DFSF.Opts.dfsan_event_callbacks) {
2664 Value *Addr =
SI.getPointerOperand();
2666 IRB.
CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr});
2671void DFSanVisitor::visitCASOrRMW(Align InstAlignment, Instruction &
I) {
2674 Value *Val =
I.getOperand(1);
2675 const auto &
DL =
I.getDataLayout();
2683 Value *Addr =
I.getOperand(0);
2684 const Align ShadowAlign = DFSF.getShadowAlign(InstAlignment);
2685 DFSF.storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign,
I.getIterator());
2686 DFSF.setShadow(&
I, DFSF.DFS.getZeroShadow(&
I));
2687 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2690void DFSanVisitor::visitAtomicRMWInst(AtomicRMWInst &
I) {
2691 visitCASOrRMW(
I.getAlign(),
I);
2697void DFSanVisitor::visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2698 visitCASOrRMW(
I.getAlign(),
I);
2704void DFSanVisitor::visitUnaryOperator(UnaryOperator &UO) {
2705 visitInstOperands(UO);
2708void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) {
2709 visitInstOperands(BO);
2712void DFSanVisitor::visitBitCastInst(BitCastInst &BCI) {
2719 visitInstOperands(BCI);
2722void DFSanVisitor::visitCastInst(CastInst &CI) { visitInstOperands(CI); }
2724void DFSanVisitor::visitCmpInst(CmpInst &CI) {
2725 visitInstOperands(CI);
2726 if (DFSF.Opts.dfsan_event_callbacks) {
2728 Value *CombinedShadow = DFSF.getShadow(&CI);
2730 IRB.
CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
2736void DFSanVisitor::visitLandingPadInst(LandingPadInst &LPI) {
2748 DFSF.setShadow(&LPI, DFSF.DFS.getZeroShadow(&LPI));
2749 DFSF.setOrigin(&LPI, DFSF.DFS.ZeroOrigin);
2752void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
2753 if (DFSF.Opts.dfsan_combine_offset_labels_on_gep ||
2754 DFSF.isLookupTableConstant(
2756 visitInstOperands(GEPI);
2763 DFSF.setShadow(&GEPI, DFSF.getShadow(BasePointer));
2764 if (DFSF.DFS.shouldTrackOrigins())
2765 DFSF.setOrigin(&GEPI, DFSF.getOrigin(BasePointer));
2768void DFSanVisitor::visitExtractElementInst(ExtractElementInst &
I) {
2769 visitInstOperands(
I);
2772void DFSanVisitor::visitInsertElementInst(InsertElementInst &
I) {
2773 visitInstOperands(
I);
2776void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &
I) {
2777 visitInstOperands(
I);
2780void DFSanVisitor::visitExtractValueInst(ExtractValueInst &
I) {
2782 Value *Agg =
I.getAggregateOperand();
2783 Value *AggShadow = DFSF.getShadow(Agg);
2785 DFSF.setShadow(&
I, ResShadow);
2786 visitInstOperandOrigins(
I);
2789void DFSanVisitor::visitInsertValueInst(InsertValueInst &
I) {
2791 Value *AggShadow = DFSF.getShadow(
I.getAggregateOperand());
2792 Value *InsShadow = DFSF.getShadow(
I.getInsertedValueOperand());
2794 DFSF.setShadow(&
I, Res);
2795 visitInstOperandOrigins(
I);
2798void DFSanVisitor::visitAllocaInst(AllocaInst &
I) {
2799 bool AllLoadsStores =
true;
2800 for (User *U :
I.users()) {
2805 if (
SI->getPointerOperand() == &
I)
2809 AllLoadsStores =
false;
2812 if (AllLoadsStores) {
2814 DFSF.AllocaShadowMap[&
I] = IRB.
CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
2815 if (DFSF.DFS.shouldTrackOrigins()) {
2816 DFSF.AllocaOriginMap[&
I] =
2820 DFSF.setShadow(&
I, DFSF.DFS.ZeroPrimitiveShadow);
2821 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2824void DFSanVisitor::visitSelectInst(SelectInst &
I) {
2825 Value *CondShadow = DFSF.getShadow(
I.getCondition());
2826 Value *TrueShadow = DFSF.getShadow(
I.getTrueValue());
2827 Value *FalseShadow = DFSF.getShadow(
I.getFalseValue());
2828 Value *ShadowSel =
nullptr;
2829 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2830 std::vector<Value *> Shadows;
2831 std::vector<Value *> Origins;
2833 ShouldTrackOrigins ? DFSF.getOrigin(
I.getTrueValue()) :
nullptr;
2834 Value *FalseOrigin =
2835 ShouldTrackOrigins ? DFSF.getOrigin(
I.getFalseValue()) :
nullptr;
2837 DFSF.addConditionalCallbacksIfEnabled(
I,
I.getCondition());
2840 ShadowSel = DFSF.combineShadowsThenConvert(
I.getType(), TrueShadow,
2841 FalseShadow,
I.getIterator());
2842 if (ShouldTrackOrigins) {
2843 Shadows.push_back(TrueShadow);
2844 Shadows.push_back(FalseShadow);
2845 Origins.push_back(TrueOrigin);
2846 Origins.push_back(FalseOrigin);
2849 if (TrueShadow == FalseShadow) {
2850 ShadowSel = TrueShadow;
2851 if (ShouldTrackOrigins) {
2852 Shadows.push_back(TrueShadow);
2853 Origins.push_back(TrueOrigin);
2857 "",
I.getIterator());
2858 if (ShouldTrackOrigins) {
2859 Shadows.push_back(ShadowSel);
2861 FalseOrigin,
"",
I.getIterator()));
2865 DFSF.setShadow(&
I, DFSF.Opts.dfsan_track_select_control_flow
2866 ? DFSF.combineShadowsThenConvert(
I.getType(),
2867 CondShadow, ShadowSel,
2870 if (ShouldTrackOrigins) {
2871 if (DFSF.Opts.dfsan_track_select_control_flow) {
2872 Shadows.push_back(CondShadow);
2873 Origins.push_back(DFSF.getOrigin(
I.getCondition()));
2875 DFSF.setOrigin(&
I, DFSF.combineOrigins(Shadows, Origins,
I.getIterator()));
2879void DFSanVisitor::visitMemSetInst(MemSetInst &
I) {
2881 Value *ValShadow = DFSF.getShadow(
I.getValue());
2882 Value *ValOrigin = DFSF.DFS.shouldTrackOrigins()
2883 ? DFSF.getOrigin(
I.getValue())
2884 : DFSF.DFS.ZeroOrigin;
2886 {ValShadow, ValOrigin, I.getDest(),
2887 IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2890void DFSanVisitor::visitMemTransferInst(MemTransferInst &
I) {
2895 if (DFSF.DFS.shouldTrackOrigins()) {
2897 DFSF.DFS.DFSanMemOriginTransferFn,
2898 {I.getArgOperand(0), I.getArgOperand(1),
2899 IRB.CreateIntCast(I.getArgOperand(2), DFSF.DFS.IntptrTy, false)});
2902 Value *DestShadow = DFSF.DFS.getShadowAddress(
I.getDest(),
I.getIterator());
2903 Value *SrcShadow = DFSF.DFS.getShadowAddress(
I.getSource(),
I.getIterator());
2905 IRB.
CreateMul(
I.getLength(), ConstantInt::get(
I.getLength()->getType(),
2906 DFSF.DFS.ShadowWidthBytes));
2908 IRB.
CreateCall(
I.getFunctionType(),
I.getCalledOperand(),
2909 {DestShadow, SrcShadow, LenShadow, I.getVolatileCst()}));
2910 MTI->setDestAlignment(DFSF.getShadowAlign(
I.getDestAlign().valueOrOne()));
2911 MTI->setSourceAlignment(DFSF.getShadowAlign(
I.getSourceAlign().valueOrOne()));
2912 if (DFSF.Opts.dfsan_event_callbacks) {
2914 DFSF.DFS.DFSanMemTransferCallbackFn,
2915 {DestShadow, IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2919void DFSanVisitor::visitCondBrInst(CondBrInst &BR) {
2920 DFSF.addConditionalCallbacksIfEnabled(BR,
BR.getCondition());
2923void DFSanVisitor::visitSwitchInst(SwitchInst &SW) {
2924 DFSF.addConditionalCallbacksIfEnabled(SW, SW.
getCondition());
2930 RetVal =
I->getOperand(0);
2933 return I->isMustTailCall();
2938void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
2947 unsigned Size = getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
2953 if (DFSF.DFS.shouldTrackOrigins()) {
2960void DFSanVisitor::addShadowArguments(
Function &
F, CallBase &CB,
2961 std::vector<Value *> &Args,
2963 FunctionType *FT =
F.getFunctionType();
2968 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
2970 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()));
2973 if (FT->isVarArg()) {
2974 auto *LabelVATy = ArrayType::get(DFSF.DFS.PrimitiveShadowTy,
2975 CB.
arg_size() - FT->getNumParams());
2976 auto *LabelVAAlloca =
2977 new AllocaInst(LabelVATy, getDataLayout().getAllocaAddrSpace(),
2980 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
2983 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()),
2991 if (!FT->getReturnType()->isVoidTy()) {
2992 if (!DFSF.LabelReturnAlloca) {
2993 DFSF.LabelReturnAlloca =
new AllocaInst(
2994 DFSF.DFS.PrimitiveShadowTy, getDataLayout().getAllocaAddrSpace(),
2997 Args.push_back(DFSF.LabelReturnAlloca);
3001void DFSanVisitor::addOriginArguments(
Function &
F, CallBase &CB,
3002 std::vector<Value *> &Args,
3004 FunctionType *FT =
F.getFunctionType();
3009 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
3010 Args.push_back(DFSF.getOrigin(*
I));
3013 if (FT->isVarArg()) {
3015 ArrayType::get(DFSF.DFS.OriginTy, CB.
arg_size() - FT->getNumParams());
3016 auto *OriginVAAlloca =
3017 new AllocaInst(OriginVATy, getDataLayout().getAllocaAddrSpace(),
3020 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
3029 if (!FT->getReturnType()->isVoidTy()) {
3030 if (!DFSF.OriginReturnAlloca) {
3031 DFSF.OriginReturnAlloca =
new AllocaInst(
3032 DFSF.DFS.OriginTy, getDataLayout().getAllocaAddrSpace(),
3035 Args.push_back(DFSF.OriginReturnAlloca);
3039bool DFSanVisitor::visitWrappedCallBase(
Function &
F, CallBase &CB) {
3041 switch (DFSF.DFS.getWrapperKind(&
F)) {
3042 case DataFlowSanitizer::WK_Warning:
3044 IRB.
CreateCall(DFSF.DFS.DFSanUnimplementedFn,
3046 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3047 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3048 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3050 case DataFlowSanitizer::WK_Discard:
3052 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3053 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3054 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3056 case DataFlowSanitizer::WK_Functional:
3058 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3059 visitInstOperands(CB);
3061 case DataFlowSanitizer::WK_Custom:
3069 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3070 FunctionType *FT =
F.getFunctionType();
3071 TransformedFunction CustomFnTy =
3072 DFSF.DFS.getCustomFunctionType(FT, DFSF.TLI);
3073 std::string CustomFName = ShouldTrackOrigins ?
"__dfso_" :
"__dfsw_";
3074 CustomFName +=
F.getName();
3076 CustomFName, CustomFnTy.TransformedType);
3083 AttributeList CustomAL = CustomFun->getAttributes();
3084 CustomFun->copyAttributesFrom(&
F);
3085 CustomFun->setAttributes(AttributeList::get(
3087 {CustomFun->getAttributes(), CustomAL, CustomFnTy.NewParamAttrs}));
3090 if (!FT->getReturnType()->isVoidTy()) {
3091 CustomFun->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
3095 std::vector<Value *>
Args;
3099 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N) {
3104 addShadowArguments(
F, CB, Args, IRB);
3107 if (ShouldTrackOrigins)
3108 addOriginArguments(
F, CB, Args, IRB);
3113 CallInst *CustomCI = IRB.
CreateCall(CustomFunCallee, Args);
3119 {transformFunctionAttributes(CustomFnTy, CI->getContext(),
3120 CI->getAttributes()),
3121 F.getAttributes(), CustomFnTy.NewParamAttrs}));
3124 if (!FT->getReturnType()->isVoidTy()) {
3125 LoadInst *LabelLoad =
3126 IRB.
CreateLoad(DFSF.DFS.PrimitiveShadowTy, DFSF.LabelReturnAlloca);
3127 DFSF.setShadow(CustomCI,
3128 DFSF.expandFromPrimitiveShadow(
3129 FT->getReturnType(), LabelLoad, CB.
getIterator()));
3130 if (ShouldTrackOrigins) {
3131 LoadInst *OriginLoad =
3132 IRB.
CreateLoad(DFSF.DFS.OriginTy, DFSF.OriginReturnAlloca);
3133 DFSF.setOrigin(CustomCI, OriginLoad);
3145 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3146 uint32_t OrderingTable[NumOrderings] = {};
3148 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3149 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3150 OrderingTable[(int)AtomicOrderingCABI::consume] =
3151 (
int)AtomicOrderingCABI::acquire;
3152 OrderingTable[(int)AtomicOrderingCABI::release] =
3153 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
3154 (int)AtomicOrderingCABI::acq_rel;
3155 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3156 (
int)AtomicOrderingCABI::seq_cst;
3161void DFSanVisitor::visitLibAtomicLoad(CallBase &CB) {
3172 Value *NewOrdering =
3177 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3183 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3184 {DstPtr, SrcPtr, NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3188 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3189 uint32_t OrderingTable[NumOrderings] = {};
3191 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3192 OrderingTable[(
int)AtomicOrderingCABI::release] =
3193 (int)AtomicOrderingCABI::release;
3194 OrderingTable[(int)AtomicOrderingCABI::consume] =
3195 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3196 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
3197 (
int)AtomicOrderingCABI::acq_rel;
3198 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3199 (
int)AtomicOrderingCABI::seq_cst;
3204void DFSanVisitor::visitLibAtomicStore(CallBase &CB) {
3212 Value *NewOrdering =
3220 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3221 {DstPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3224void DFSanVisitor::visitLibAtomicExchange(CallBase &CB) {
3240 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3241 {DstPtr, TargetPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3245 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3246 {TargetPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3249void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
3263 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3265 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3269 CallInst *CI = NextIRB.CreateCall(
3270 DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
3271 {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false), TargetPtr,
3272 ExpectedPtr, DesiredPtr,
3273 NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3277void DFSanVisitor::visitCallBase(CallBase &CB) {
3280 visitInstOperands(CB);
3290 if (LF != NotLibFunc) {
3295 case LibFunc_atomic_load:
3297 llvm::errs() <<
"DFSAN -- cannot instrument invoke of libatomic load. "
3301 visitLibAtomicLoad(CB);
3303 case LibFunc_atomic_store:
3304 visitLibAtomicStore(CB);
3312 if (
F &&
F->hasName() && !
F->isVarArg()) {
3313 if (
F->getName() ==
"__atomic_exchange") {
3314 visitLibAtomicExchange(CB);
3317 if (
F->getName() ==
"__atomic_compare_exchange") {
3318 visitLibAtomicCompareExchange(CB);
3324 if (UnwrappedFnIt != DFSF.DFS.UnwrappedFnMap.end())
3325 if (visitWrappedCallBase(*UnwrappedFnIt->second, CB))
3330 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3332 const DataLayout &
DL = getDataLayout();
3335 unsigned ArgOffset = 0;
3336 for (
unsigned I = 0,
N = FT->getNumParams();
I !=
N; ++
I) {
3337 if (ShouldTrackOrigins) {
3340 if (
I < DFSF.DFS.NumOfElementsInArgOrgTLS &&
3341 !DFSF.DFS.isZeroShadow(ArgShadow))
3343 DFSF.getArgOriginTLS(
I, IRB));
3347 DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(
I)));
3353 DFSF.getArgTLS(FT->getParamType(
I), ArgOffset, IRB),
3361 if (
II->getNormalDest()->getSinglePredecessor()) {
3362 Next = &
II->getNormalDest()->front();
3379 unsigned Size =
DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
3382 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3384 LoadInst *LI = NextIRB.CreateAlignedLoad(
3385 DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.
getType(), NextIRB),
3387 DFSF.SkipInsts.
insert(LI);
3388 DFSF.setShadow(&CB, LI);
3389 DFSF.NonZeroChecks.push_back(LI);
3392 if (ShouldTrackOrigins) {
3393 LoadInst *LI = NextIRB.CreateLoad(DFSF.DFS.OriginTy,
3394 DFSF.getRetvalOriginTLS(),
"_dfsret_o");
3395 DFSF.SkipInsts.
insert(LI);
3396 DFSF.setOrigin(&CB, LI);
3399 DFSF.addReachesFunctionCallbacksIfEnabled(NextIRB, CB, &CB);
3403void DFSanVisitor::visitPHINode(PHINode &PN) {
3404 Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
3410 for (BasicBlock *BB : PN.
blocks())
3413 DFSF.setShadow(&PN, ShadowPN);
3415 PHINode *OriginPN =
nullptr;
3416 if (DFSF.DFS.shouldTrackOrigins()) {
3420 for (BasicBlock *BB : PN.
blocks())
3422 DFSF.setOrigin(&PN, OriginPN);
3425 DFSF.PHIFixups.push_back({&PN, ShadowPN, OriginPN});
3439 if (!DataFlowSanitizer(Opts, ABIListFiles, FS).
runImpl(M, GetTLI))
const TargetLowering & TLI
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 * CreatePtrAddWithUnsignedOffset(Value *Ptr, uint64_t Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Create a ptradd with an unsigned constant offset.
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)
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.