139 "dfsan-preserve-alignment",
161 cl::desc(
"File listing native ABI functions and how the pass treats them"),
167 "dfsan-combine-pointer-labels-on-load",
168 cl::desc(
"Combine the label of the pointer with the label of the data when "
169 "loading from memory."),
175 "dfsan-combine-pointer-labels-on-store",
176 cl::desc(
"Combine the label of the pointer with the label of the data when "
177 "storing in memory."),
182 "dfsan-combine-offset-labels-on-gep",
184 "Combine the label of the offset with the label of the pointer when "
185 "doing pointer arithmetic."),
189 "dfsan-combine-taint-lookup-table",
191 "When dfsan-combine-offset-labels-on-gep and/or "
192 "dfsan-combine-pointer-labels-on-load are false, this flag can "
193 "be used to re-enable combining offset and/or pointer taint when "
194 "loading specific constant global variables (i.e. lookup tables)."),
198 "dfsan-debug-nonzero-labels",
199 cl::desc(
"Insert calls to __dfsan_nonzero_label on observing a parameter, "
200 "load or return with a nonzero label"),
214 "dfsan-event-callbacks",
215 cl::desc(
"Insert calls to __dfsan_*_callback functions on data events."),
222 "dfsan-conditional-callbacks",
230 "dfsan-reaches-function-callbacks",
231 cl::desc(
"Insert calls to callback functions on data reaching a function."),
236 "dfsan-track-select-control-flow",
237 cl::desc(
"Propagate labels from condition values of select instructions "
243 "dfsan-instrument-with-call-threshold",
244 cl::desc(
"If the function being instrumented requires more than "
245 "this number of origin stores, use callbacks instead of "
246 "inline checks (-1 means never use callbacks)."),
255 cl::desc(
"Track origins of labels"),
259 "dfsan-ignore-personality-routine",
260 cl::desc(
"If a personality routine is marked uninstrumented from the ABI "
261 "list, do not create a wrapper for it."),
265 "dfsan-add-global-name-suffix",
271 Type *GType =
G.getValueType();
274 if (!SGType->isLiteral())
275 return SGType->getName();
277 return "<unknown type>";
286struct MemoryMapParams {
332 std::unique_ptr<SpecialCaseList> SCL;
335 DFSanABIList() =
default;
337 void set(std::unique_ptr<SpecialCaseList>
List) { SCL = std::move(
List); }
341 bool isIn(
const Function &
F, StringRef Category)
const {
342 return isIn(*
F.getParent(), Category) ||
343 SCL->inSection(
"dataflow",
"fun",
F.getName(), Category);
350 bool isIn(
const GlobalAlias &GA, StringRef Category)
const {
355 return SCL->inSection(
"dataflow",
"fun", GA.
getName(), Category);
357 return SCL->inSection(
"dataflow",
"global", GA.
getName(), Category) ||
363 bool isIn(
const Module &M, StringRef Category)
const {
364 return SCL->inSection(
"dataflow",
"src",
M.getModuleIdentifier(), Category);
371struct TransformedFunction {
372 TransformedFunction(FunctionType *OriginalType, FunctionType *TransformedType,
373 const std::vector<unsigned> &ArgumentIndexMapping,
374 AttributeList &NewParamAttrs)
375 : OriginalType(OriginalType), TransformedType(TransformedType),
376 ArgumentIndexMapping(ArgumentIndexMapping),
377 NewParamAttrs(NewParamAttrs) {}
380 TransformedFunction(
const TransformedFunction &) =
delete;
381 TransformedFunction &operator=(
const TransformedFunction &) =
delete;
384 TransformedFunction(TransformedFunction &&) =
default;
385 TransformedFunction &operator=(TransformedFunction &&) =
default;
388 FunctionType *OriginalType;
391 FunctionType *TransformedType;
398 std::vector<unsigned> ArgumentIndexMapping;
402 AttributeList NewParamAttrs;
409transformFunctionAttributes(
const TransformedFunction &TransformedFunction,
413 std::vector<llvm::AttributeSet> ArgumentAttributes(
414 TransformedFunction.TransformedType->getNumParams());
419 for (
unsigned I = 0, IE = TransformedFunction.ArgumentIndexMapping.size();
421 unsigned TransformedIndex = TransformedFunction.ArgumentIndexMapping[
I];
422 ArgumentAttributes[TransformedIndex] = CallSiteAttrs.getParamAttrs(
I);
426 for (
unsigned I = TransformedFunction.OriginalType->getNumParams(),
427 IE = CallSiteAttrs.getNumAttrSets();
429 ArgumentAttributes.push_back(CallSiteAttrs.getParamAttrs(
I));
432 return AttributeList::get(Ctx, CallSiteAttrs.getFnAttrs(),
433 CallSiteAttrs.getRetAttrs(),
437class DataFlowSanitizer {
438 friend struct DFSanFunction;
439 friend class DFSanVisitor;
441 enum { ShadowWidthBits = 8, ShadowWidthBytes = ShadowWidthBits / 8 };
443 enum { OriginWidthBits = 32, OriginWidthBytes = OriginWidthBits / 8 };
471 IntegerType *OriginTy;
473 ConstantInt *ZeroOrigin;
475 IntegerType *PrimitiveShadowTy;
477 IntegerType *IntptrTy;
478 ConstantInt *ZeroPrimitiveShadow;
484 FunctionType *DFSanUnionLoadFnTy;
485 FunctionType *DFSanLoadLabelAndOriginFnTy;
486 FunctionType *DFSanUnimplementedFnTy;
487 FunctionType *DFSanWrapperExternWeakNullFnTy;
488 FunctionType *DFSanSetLabelFnTy;
489 FunctionType *DFSanNonzeroLabelFnTy;
490 FunctionType *DFSanVarargWrapperFnTy;
491 FunctionType *DFSanConditionalCallbackFnTy;
492 FunctionType *DFSanConditionalCallbackOriginFnTy;
493 FunctionType *DFSanReachesFunctionCallbackFnTy;
494 FunctionType *DFSanReachesFunctionCallbackOriginFnTy;
495 FunctionType *DFSanCmpCallbackFnTy;
496 FunctionType *DFSanLoadStoreCallbackFnTy;
497 FunctionType *DFSanMemTransferCallbackFnTy;
498 FunctionType *DFSanChainOriginFnTy;
499 FunctionType *DFSanChainOriginIfTaintedFnTy;
500 FunctionType *DFSanMemOriginTransferFnTy;
501 FunctionType *DFSanMemShadowOriginTransferFnTy;
502 FunctionType *DFSanMemShadowOriginConditionalExchangeFnTy;
503 FunctionType *DFSanMaybeStoreOriginFnTy;
504 FunctionCallee DFSanUnionLoadFn;
505 FunctionCallee DFSanLoadLabelAndOriginFn;
506 FunctionCallee DFSanUnimplementedFn;
507 FunctionCallee DFSanWrapperExternWeakNullFn;
508 FunctionCallee DFSanSetLabelFn;
509 FunctionCallee DFSanNonzeroLabelFn;
510 FunctionCallee DFSanVarargWrapperFn;
511 FunctionCallee DFSanLoadCallbackFn;
512 FunctionCallee DFSanStoreCallbackFn;
513 FunctionCallee DFSanMemTransferCallbackFn;
514 FunctionCallee DFSanConditionalCallbackFn;
515 FunctionCallee DFSanConditionalCallbackOriginFn;
516 FunctionCallee DFSanReachesFunctionCallbackFn;
517 FunctionCallee DFSanReachesFunctionCallbackOriginFn;
518 FunctionCallee DFSanCmpCallbackFn;
519 FunctionCallee DFSanChainOriginFn;
520 FunctionCallee DFSanChainOriginIfTaintedFn;
521 FunctionCallee DFSanMemOriginTransferFn;
522 FunctionCallee DFSanMemShadowOriginTransferFn;
523 FunctionCallee DFSanMemShadowOriginConditionalExchangeFn;
524 FunctionCallee DFSanMaybeStoreOriginFn;
525 SmallPtrSet<Value *, 16> DFSanRuntimeFunctions;
526 MDNode *ColdCallWeights;
527 MDNode *OriginStoreWeights;
528 DFSanABIList ABIList;
529 DenseMap<Value *, Function *> UnwrappedFnMap;
530 AttributeMask ReadOnlyNoneAttrs;
531 StringSet<> CombineTaintLookupTableNames;
535 const MemoryMapParams *MapParams;
540 Value *ShadowOffset);
541 std::pair<Value *, Value *> getShadowOriginAddress(
Value *Addr,
545 bool isInstrumented(
const GlobalAlias *GA);
546 bool isForceZeroLabels(
const Function *
F);
547 TransformedFunction getCustomFunctionType(FunctionType *
T,
548 TargetLibraryInfo &TLI);
550 void addGlobalNameSuffix(GlobalValue *GV);
554 FunctionType *NewFT);
555 void initializeCallbackFunctions(
Module &M);
556 void initializeRuntimeFunctions(
Module &M);
557 bool initializeModule(
Module &M);
569 bool shouldTrackOrigins();
581 bool isZeroShadow(
Value *V);
595 DataFlowSanitizer(
const std::vector<std::string> &ABIListFiles,
596 IntrusiveRefCntPtr<vfs::FileSystem> FS);
599 llvm::function_ref<TargetLibraryInfo &(
Function &)> GetTLI);
602struct DFSanFunction {
603 DataFlowSanitizer &DFS;
607 bool IsForceZeroLabels;
608 TargetLibraryInfo &TLI;
609 AllocaInst *LabelReturnAlloca =
nullptr;
610 AllocaInst *OriginReturnAlloca =
nullptr;
611 DenseMap<Value *, Value *> ValShadowMap;
612 DenseMap<Value *, Value *> ValOriginMap;
613 DenseMap<AllocaInst *, AllocaInst *> AllocaShadowMap;
614 DenseMap<AllocaInst *, AllocaInst *> AllocaOriginMap;
616 struct PHIFixupElement {
621 std::vector<PHIFixupElement> PHIFixups;
623 DenseSet<Instruction *> SkipInsts;
624 std::vector<Value *> NonZeroChecks;
626 struct CachedShadow {
631 DenseMap<std::pair<Value *, Value *>, CachedShadow> CachedShadows;
636 DenseMap<Value *, Value *> CachedCollapsedShadows;
637 DenseMap<Value *, std::set<Value *>> ShadowElements;
639 DFSanFunction(DataFlowSanitizer &DFS,
Function *F,
bool IsNativeABI,
640 bool IsForceZeroLabels, TargetLibraryInfo &TLI)
641 : DFS(DFS), F(F), IsNativeABI(IsNativeABI),
642 IsForceZeroLabels(IsForceZeroLabels), TLI(TLI) {
660 Value *getRetvalOriginTLS();
663 void setOrigin(Instruction *
I,
Value *Origin);
665 Value *combineOperandOrigins(Instruction *Inst);
672 Value *combineOrigins(
const std::vector<Value *> &Shadows,
673 const std::vector<Value *> &Origins,
677 void setShadow(Instruction *
I,
Value *Shadow);
685 Value *combineOperandShadows(Instruction *Inst);
699 Align InstAlignment,
Value *PrimitiveShadow,
721 Align getShadowAlign(Align InstAlignment);
725 void addConditionalCallbacksIfEnabled(Instruction &
I,
Value *Condition);
729 void addReachesFunctionCallbacksIfEnabled(
IRBuilder<> &IRB, Instruction &
I,
732 bool isLookupTableConstant(
Value *
P);
737 template <
class AggregateType>
738 Value *collapseAggregateShadow(AggregateType *AT,
Value *Shadow,
744 Value *getShadowForTLSArgument(Argument *
A);
747 std::pair<Value *, Value *>
749 Align ShadowAlign, Align OriginAlign,
Value *FirstOrigin,
752 Align getOriginAlign(Align InstAlignment);
763 bool useCallbackLoadLabelAndOrigin(
uint64_t Size, Align InstAlignment);
779 uint64_t StoreOriginSize, Align Alignment);
788 Align InstAlignment);
793 bool shouldInstrumentWithCall();
799 std::pair<Value *, Value *>
803 int NumOriginStores = 0;
806class DFSanVisitor :
public InstVisitor<DFSanVisitor> {
810 DFSanVisitor(DFSanFunction &DFSF) : DFSF(DFSF) {}
812 const DataLayout &getDataLayout()
const {
813 return DFSF.F->getDataLayout();
817 void visitInstOperands(Instruction &
I);
819 void visitUnaryOperator(UnaryOperator &UO);
820 void visitBinaryOperator(BinaryOperator &BO);
821 void visitBitCastInst(BitCastInst &BCI);
822 void visitCastInst(CastInst &CI);
823 void visitCmpInst(CmpInst &CI);
824 void visitLandingPadInst(LandingPadInst &LPI);
825 void visitGetElementPtrInst(GetElementPtrInst &GEPI);
826 void visitLoadInst(LoadInst &LI);
827 void visitStoreInst(StoreInst &SI);
828 void visitAtomicRMWInst(AtomicRMWInst &
I);
829 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I);
830 void visitReturnInst(ReturnInst &RI);
831 void visitLibAtomicLoad(CallBase &CB);
832 void visitLibAtomicStore(CallBase &CB);
833 void visitLibAtomicExchange(CallBase &CB);
834 void visitLibAtomicCompareExchange(CallBase &CB);
835 void visitCallBase(CallBase &CB);
836 void visitPHINode(PHINode &PN);
837 void visitExtractElementInst(ExtractElementInst &
I);
838 void visitInsertElementInst(InsertElementInst &
I);
839 void visitShuffleVectorInst(ShuffleVectorInst &
I);
840 void visitExtractValueInst(ExtractValueInst &
I);
841 void visitInsertValueInst(InsertValueInst &
I);
842 void visitAllocaInst(AllocaInst &
I);
843 void visitSelectInst(SelectInst &
I);
844 void visitMemSetInst(MemSetInst &
I);
845 void visitMemTransferInst(MemTransferInst &
I);
846 void visitCondBrInst(CondBrInst &BR);
847 void visitSwitchInst(SwitchInst &SW);
850 void visitCASOrRMW(Align InstAlignment, Instruction &
I);
853 bool visitWrappedCallBase(
Function &
F, CallBase &CB);
856 void visitInstOperandOrigins(Instruction &
I);
858 void addShadowArguments(
Function &
F, CallBase &CB, std::vector<Value *> &Args,
861 void addOriginArguments(
Function &
F, CallBase &CB, std::vector<Value *> &Args,
868bool LibAtomicFunction(
const Function &
F) {
874 if (!
F.hasName() ||
F.isVarArg())
876 switch (
F.arg_size()) {
878 return F.getName() ==
"__atomic_load" ||
F.getName() ==
"__atomic_store";
880 return F.getName() ==
"__atomic_exchange";
882 return F.getName() ==
"__atomic_compare_exchange";
890DataFlowSanitizer::DataFlowSanitizer(
891 const std::vector<std::string> &ABIListFiles,
893 std::vector<std::string> AllABIListFiles(std::move(ABIListFiles));
901DataFlowSanitizer::getCustomFunctionType(FunctionType *
T,
902 TargetLibraryInfo &TLI) {
904 AttributeList NewParamAttrs;
905 Attribute::AttrKind ShadowParamExtAttr =
907 Attribute::AttrKind OriginParamExtAttr =
908 TLI.getExtAttrForI32Param(
false);
914 std::vector<unsigned> ArgumentIndexMapping;
915 for (
unsigned I = 0,
E =
T->getNumParams();
I !=
E; ++
I) {
916 Type *ParamType =
T->getParamType(
I);
917 ArgumentIndexMapping.push_back(ArgTypes.
size());
920 for (
unsigned I = 0,
E =
T->getNumParams();
I !=
E; ++
I) {
921 NewParamAttrs = NewParamAttrs.maybeAddParamAttribute(*Ctx, ArgTypes.
size(),
926 ArgTypes.
push_back(PrimitiveShadowPtrTy);
927 Type *RetType =
T->getReturnType();
929 ArgTypes.
push_back(PrimitiveShadowPtrTy);
931 if (shouldTrackOrigins()) {
932 for (
unsigned I = 0,
E =
T->getNumParams();
I !=
E; ++
I) {
933 NewParamAttrs = NewParamAttrs.maybeAddParamAttribute(
934 *Ctx, ArgTypes.
size(), OriginParamExtAttr);
943 return TransformedFunction(
944 T, FunctionType::get(
T->getReturnType(), ArgTypes,
T->isVarArg()),
945 ArgumentIndexMapping, NewParamAttrs);
948bool DataFlowSanitizer::isZeroShadow(
Value *V) {
959bool DataFlowSanitizer::hasLoadSizeForFastPath(
uint64_t Size) {
961 return ShadowSize % 8 == 0 || ShadowSize == 4;
964bool DataFlowSanitizer::shouldTrackOrigins() {
966 return ShouldTrackOrigins;
969Constant *DataFlowSanitizer::getZeroShadow(
Type *OrigTy) {
971 return ZeroPrimitiveShadow;
972 Type *ShadowTy = getShadowTy(OrigTy);
977 return getZeroShadow(
V->getType());
987 for (
unsigned Idx = 0; Idx < AT->getNumElements(); Idx++) {
990 Shadow, Indices, AT->getElementType(), PrimitiveShadow, IRB);
997 for (
unsigned Idx = 0; Idx < ST->getNumElements(); Idx++) {
1000 Shadow, Indices, ST->getElementType(Idx), PrimitiveShadow, IRB);
1008bool DFSanFunction::shouldInstrumentWithCall() {
1013Value *DFSanFunction::expandFromPrimitiveShadow(
Type *
T,
Value *PrimitiveShadow,
1015 Type *ShadowTy = DFS.getShadowTy(
T);
1018 return PrimitiveShadow;
1020 if (DFS.isZeroShadow(PrimitiveShadow))
1021 return DFS.getZeroShadow(ShadowTy);
1024 SmallVector<unsigned, 4> Indices;
1027 PrimitiveShadow, IRB);
1030 CachedCollapsedShadows[Shadow] = PrimitiveShadow;
1034template <
class AggregateType>
1035Value *DFSanFunction::collapseAggregateShadow(AggregateType *AT,
Value *Shadow,
1037 if (!AT->getNumElements())
1038 return DFS.ZeroPrimitiveShadow;
1041 Value *Aggregator = collapseToPrimitiveShadow(FirstItem, IRB);
1043 for (
unsigned Idx = 1; Idx < AT->getNumElements(); Idx++) {
1045 Value *ShadowInner = collapseToPrimitiveShadow(ShadowItem, IRB);
1046 Aggregator = IRB.
CreateOr(Aggregator, ShadowInner);
1051Value *DFSanFunction::collapseToPrimitiveShadow(
Value *Shadow,
1057 return collapseAggregateShadow<>(AT, Shadow, IRB);
1059 return collapseAggregateShadow<>(ST, Shadow, IRB);
1063Value *DFSanFunction::collapseToPrimitiveShadow(
Value *Shadow,
1070 Value *&CS = CachedCollapsedShadows[Shadow];
1075 Value *PrimitiveShadow = collapseToPrimitiveShadow(Shadow, IRB);
1077 CS = PrimitiveShadow;
1078 return PrimitiveShadow;
1081void DFSanFunction::addConditionalCallbacksIfEnabled(Instruction &
I,
1087 Value *CondShadow = getShadow(Condition);
1089 if (DFS.shouldTrackOrigins()) {
1090 Value *CondOrigin = getOrigin(Condition);
1091 CI = IRB.
CreateCall(DFS.DFSanConditionalCallbackOriginFn,
1092 {CondShadow, CondOrigin});
1095 CI = IRB.
CreateCall(DFS.DFSanConditionalCallbackFn, {CondShadow});
1100void DFSanFunction::addReachesFunctionCallbacksIfEnabled(
IRBuilder<> &IRB,
1106 const DebugLoc &dbgloc =
I.getDebugLoc();
1107 Value *DataShadow = collapseToPrimitiveShadow(getShadow(
Data), IRB);
1108 ConstantInt *CILine;
1111 if (dbgloc.
get() ==
nullptr) {
1112 CILine = llvm::ConstantInt::get(
I.getContext(), llvm::APInt(32, 0));
1114 I.getFunction()->getParent()->getSourceFileName());
1116 CILine = llvm::ConstantInt::get(
I.getContext(),
1117 llvm::APInt(32, dbgloc.
getLine()));
1125 std::vector<Value *>
args;
1127 Attribute::AttrKind I32ParamExtAttr =
1128 TLI.getExtAttrForI32Param(
false);
1129 if (DFS.shouldTrackOrigins()) {
1131 args = { DataShadow, DataOrigin, FilePathPtr, CILine, FunctionNamePtr };
1132 CB = IRB.
CreateCall(DFS.DFSanReachesFunctionCallbackOriginFn,
args);
1136 args = { DataShadow, FilePathPtr, CILine, FunctionNamePtr };
1144Type *DataFlowSanitizer::getShadowTy(
Type *OrigTy) {
1146 return PrimitiveShadowTy;
1148 return PrimitiveShadowTy;
1150 return PrimitiveShadowTy;
1152 return ArrayType::get(getShadowTy(AT->getElementType()),
1153 AT->getNumElements());
1156 for (
unsigned I = 0,
N =
ST->getNumElements();
I <
N; ++
I)
1157 Elements.push_back(getShadowTy(
ST->getElementType(
I)));
1160 return PrimitiveShadowTy;
1163Type *DataFlowSanitizer::getShadowTy(
Value *V) {
1164 return getShadowTy(
V->getType());
1167bool DataFlowSanitizer::initializeModule(
Module &M) {
1168 Triple TargetTriple(
M.getTargetTriple());
1169 const DataLayout &
DL =
M.getDataLayout();
1173 switch (TargetTriple.getArch()) {
1191 Ctx = &
M.getContext();
1192 Int8Ptr = PointerType::getUnqual(*Ctx);
1194 OriginPtrTy = PointerType::getUnqual(*Ctx);
1196 PrimitiveShadowPtrTy = PointerType::getUnqual(*Ctx);
1197 IntptrTy =
DL.getIntPtrType(*Ctx);
1201 Type *DFSanUnionLoadArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
1202 DFSanUnionLoadFnTy = FunctionType::get(PrimitiveShadowTy, DFSanUnionLoadArgs,
1204 Type *DFSanLoadLabelAndOriginArgs[2] = {Int8Ptr, IntptrTy};
1205 DFSanLoadLabelAndOriginFnTy =
1208 DFSanUnimplementedFnTy = FunctionType::get(
1209 Type::getVoidTy(*Ctx), PointerType::getUnqual(*Ctx),
false);
1210 Type *DFSanWrapperExternWeakNullArgs[2] = {Int8Ptr, Int8Ptr};
1211 DFSanWrapperExternWeakNullFnTy =
1212 FunctionType::get(Type::getVoidTy(*Ctx), DFSanWrapperExternWeakNullArgs,
1214 Type *DFSanSetLabelArgs[4] = {PrimitiveShadowTy, OriginTy,
1215 PointerType::getUnqual(*Ctx), IntptrTy};
1216 DFSanSetLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx),
1217 DFSanSetLabelArgs,
false);
1218 DFSanNonzeroLabelFnTy = FunctionType::get(Type::getVoidTy(*Ctx), {},
1220 DFSanVarargWrapperFnTy = FunctionType::get(
1221 Type::getVoidTy(*Ctx), PointerType::getUnqual(*Ctx),
false);
1222 DFSanConditionalCallbackFnTy =
1223 FunctionType::get(Type::getVoidTy(*Ctx), PrimitiveShadowTy,
1225 Type *DFSanConditionalCallbackOriginArgs[2] = {PrimitiveShadowTy, OriginTy};
1226 DFSanConditionalCallbackOriginFnTy = FunctionType::get(
1227 Type::getVoidTy(*Ctx), DFSanConditionalCallbackOriginArgs,
1229 Type *DFSanReachesFunctionCallbackArgs[4] = {PrimitiveShadowTy, Int8Ptr,
1231 DFSanReachesFunctionCallbackFnTy =
1232 FunctionType::get(Type::getVoidTy(*Ctx), DFSanReachesFunctionCallbackArgs,
1234 Type *DFSanReachesFunctionCallbackOriginArgs[5] = {
1235 PrimitiveShadowTy, OriginTy, Int8Ptr, OriginTy, Int8Ptr};
1236 DFSanReachesFunctionCallbackOriginFnTy = FunctionType::get(
1237 Type::getVoidTy(*Ctx), DFSanReachesFunctionCallbackOriginArgs,
1239 DFSanCmpCallbackFnTy =
1240 FunctionType::get(Type::getVoidTy(*Ctx), PrimitiveShadowTy,
1242 DFSanChainOriginFnTy =
1243 FunctionType::get(OriginTy, OriginTy,
false);
1244 Type *DFSanChainOriginIfTaintedArgs[2] = {PrimitiveShadowTy, OriginTy};
1245 DFSanChainOriginIfTaintedFnTy = FunctionType::get(
1246 OriginTy, DFSanChainOriginIfTaintedArgs,
false);
1248 Int8Ptr, IntptrTy, OriginTy};
1249 DFSanMaybeStoreOriginFnTy = FunctionType::get(
1250 Type::getVoidTy(*Ctx), DFSanMaybeStoreOriginArgs,
false);
1251 Type *DFSanMemOriginTransferArgs[3] = {Int8Ptr, Int8Ptr, IntptrTy};
1252 DFSanMemOriginTransferFnTy = FunctionType::get(
1253 Type::getVoidTy(*Ctx), DFSanMemOriginTransferArgs,
false);
1254 Type *DFSanMemShadowOriginTransferArgs[3] = {Int8Ptr, Int8Ptr, IntptrTy};
1255 DFSanMemShadowOriginTransferFnTy =
1256 FunctionType::get(Type::getVoidTy(*Ctx), DFSanMemShadowOriginTransferArgs,
1258 Type *DFSanMemShadowOriginConditionalExchangeArgs[5] = {
1260 DFSanMemShadowOriginConditionalExchangeFnTy = FunctionType::get(
1261 Type::getVoidTy(*Ctx), DFSanMemShadowOriginConditionalExchangeArgs,
1263 Type *DFSanLoadStoreCallbackArgs[2] = {PrimitiveShadowTy, Int8Ptr};
1264 DFSanLoadStoreCallbackFnTy =
1265 FunctionType::get(Type::getVoidTy(*Ctx), DFSanLoadStoreCallbackArgs,
1267 Type *DFSanMemTransferCallbackArgs[2] = {PrimitiveShadowPtrTy, IntptrTy};
1268 DFSanMemTransferCallbackFnTy =
1269 FunctionType::get(Type::getVoidTy(*Ctx), DFSanMemTransferCallbackArgs,
1272 ColdCallWeights = MDBuilder(*Ctx).createUnlikelyBranchWeights();
1273 OriginStoreWeights = MDBuilder(*Ctx).createUnlikelyBranchWeights();
1277bool DataFlowSanitizer::isInstrumented(
const Function *
F) {
1278 return !ABIList.isIn(*
F,
"uninstrumented");
1281bool DataFlowSanitizer::isInstrumented(
const GlobalAlias *GA) {
1282 return !ABIList.isIn(*GA,
"uninstrumented");
1285bool DataFlowSanitizer::isForceZeroLabels(
const Function *
F) {
1286 return ABIList.isIn(*
F,
"force_zero_labels");
1289DataFlowSanitizer::WrapperKind DataFlowSanitizer::getWrapperKind(
Function *
F) {
1290 if (ABIList.isIn(*
F,
"functional"))
1291 return WK_Functional;
1292 if (ABIList.isIn(*
F,
"discard"))
1294 if (ABIList.isIn(*
F,
"custom"))
1300void DataFlowSanitizer::addGlobalNameSuffix(GlobalValue *GV) {
1304 std::string GVName = std::string(GV->
getName()), Suffix =
".dfsan";
1312 for (Module::GlobalAsmFragment &Frag :
1314 std::string SearchStr =
".symver " + GVName +
",";
1315 size_t Pos = Frag.Asm.find(SearchStr);
1316 if (Pos != std::string::npos) {
1317 Frag.Asm.replace(Pos, SearchStr.size(),
1318 ".symver " + GVName + Suffix +
",");
1319 Pos = Frag.Asm.find(
'@');
1321 if (Pos == std::string::npos)
1324 Frag.Asm.replace(Pos, 1, Suffix +
"@");
1329void DataFlowSanitizer::buildExternWeakCheckIfNeeded(
IRBuilder<> &IRB,
1339 std::vector<Value *>
Args;
1342 IRB.
CreateCall(DFSanWrapperExternWeakNullFn, Args);
1347DataFlowSanitizer::buildWrapperFunction(
Function *
F, StringRef NewFName,
1349 FunctionType *NewFT) {
1350 FunctionType *FT =
F->getFunctionType();
1352 NewFName,
F->getParent());
1355 NewFT->getReturnType(), NewF->
getAttributes().getRetAttrs()));
1358 if (
F->isVarArg()) {
1361 IRBuilder<>(BB).CreateGlobalString(
F->getName()),
"", BB);
1362 new UnreachableInst(*Ctx, BB);
1364 auto ArgIt = pointer_iterator<Argument *>(NewF->
arg_begin());
1365 std::vector<Value *>
Args(ArgIt, ArgIt + FT->getNumParams());
1368 if (FT->getReturnType()->isVoidTy())
1378void DataFlowSanitizer::initializeRuntimeFunctions(
Module &M) {
1379 LLVMContext &
C =
M.getContext();
1380 Attribute::AttrKind I8ParamExtAttr =
1382 Attribute::AttrKind I32ParamExtAttr =
1383 TargetLibraryInfo::getExtAttrForI32Param(
M.getTargetTriple(),
1387 AL =
AL.addFnAttribute(
C, Attribute::NoUnwind);
1388 AL =
AL.addFnAttribute(
1390 AL =
AL.addRetAttribute(
C, Attribute::ZExt);
1392 Mod->getOrInsertFunction(
"__dfsan_union_load", DFSanUnionLoadFnTy, AL);
1396 AL =
AL.addFnAttribute(
C, Attribute::NoUnwind);
1397 AL =
AL.addFnAttribute(
1399 AL =
AL.addRetAttribute(
C, Attribute::ZExt);
1400 DFSanLoadLabelAndOriginFn =
Mod->getOrInsertFunction(
1401 "__dfsan_load_label_and_origin", DFSanLoadLabelAndOriginFnTy, AL);
1403 DFSanUnimplementedFn =
1404 Mod->getOrInsertFunction(
"__dfsan_unimplemented", DFSanUnimplementedFnTy);
1405 DFSanWrapperExternWeakNullFn =
Mod->getOrInsertFunction(
1406 "__dfsan_wrapper_extern_weak_null", DFSanWrapperExternWeakNullFnTy);
1409 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1410 AL =
AL.maybeAddParamAttribute(
M.getContext(), 1, I32ParamExtAttr);
1412 Mod->getOrInsertFunction(
"__dfsan_set_label", DFSanSetLabelFnTy, AL);
1414 DFSanNonzeroLabelFn =
1415 Mod->getOrInsertFunction(
"__dfsan_nonzero_label", DFSanNonzeroLabelFnTy);
1416 DFSanVarargWrapperFn =
Mod->getOrInsertFunction(
"__dfsan_vararg_wrapper",
1417 DFSanVarargWrapperFnTy);
1420 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I32ParamExtAttr);
1421 AL =
AL.addRetAttribute(
M.getContext(), Attribute::ZExt);
1422 DFSanChainOriginFn =
Mod->getOrInsertFunction(
"__dfsan_chain_origin",
1423 DFSanChainOriginFnTy, AL);
1427 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1428 AL =
AL.maybeAddParamAttribute(
M.getContext(), 1, I32ParamExtAttr);
1429 AL =
AL.addRetAttribute(
M.getContext(), Attribute::ZExt);
1430 DFSanChainOriginIfTaintedFn =
Mod->getOrInsertFunction(
1431 "__dfsan_chain_origin_if_tainted", DFSanChainOriginIfTaintedFnTy, AL);
1433 DFSanMemOriginTransferFn =
Mod->getOrInsertFunction(
1434 "__dfsan_mem_origin_transfer", DFSanMemOriginTransferFnTy);
1436 DFSanMemShadowOriginTransferFn =
Mod->getOrInsertFunction(
1437 "__dfsan_mem_shadow_origin_transfer", DFSanMemShadowOriginTransferFnTy);
1441 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1442 DFSanMemShadowOriginConditionalExchangeFn =
Mod->getOrInsertFunction(
1443 "__dfsan_mem_shadow_origin_conditional_exchange",
1444 DFSanMemShadowOriginConditionalExchangeFnTy, AL);
1449 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1450 AL =
AL.maybeAddParamAttribute(
M.getContext(), 3, I32ParamExtAttr);
1451 DFSanMaybeStoreOriginFn =
Mod->getOrInsertFunction(
1452 "__dfsan_maybe_store_origin", DFSanMaybeStoreOriginFnTy, AL);
1455 DFSanRuntimeFunctions.
insert(
1457 DFSanRuntimeFunctions.
insert(
1459 DFSanRuntimeFunctions.
insert(
1461 DFSanRuntimeFunctions.
insert(
1463 DFSanRuntimeFunctions.
insert(
1465 DFSanRuntimeFunctions.
insert(
1467 DFSanRuntimeFunctions.
insert(
1469 DFSanRuntimeFunctions.
insert(
1471 DFSanRuntimeFunctions.
insert(
1473 DFSanRuntimeFunctions.
insert(
1475 DFSanRuntimeFunctions.
insert(
1477 DFSanRuntimeFunctions.
insert(
1479 DFSanRuntimeFunctions.
insert(
1481 DFSanRuntimeFunctions.
insert(
1483 DFSanRuntimeFunctions.
insert(
1485 DFSanRuntimeFunctions.
insert(
1487 DFSanRuntimeFunctions.
insert(
1489 DFSanRuntimeFunctions.
insert(
1491 DFSanRuntimeFunctions.
insert(
1493 DFSanRuntimeFunctions.
insert(
1494 DFSanMemShadowOriginConditionalExchangeFn.
getCallee()
1496 DFSanRuntimeFunctions.
insert(
1501void DataFlowSanitizer::initializeCallbackFunctions(
Module &M) {
1502 Attribute::AttrKind I8ParamExtAttr =
1504 Attribute::AttrKind I32ParamExtAttr =
1505 TargetLibraryInfo::getExtAttrForI32Param(
M.getTargetTriple(),
1509 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1510 DFSanLoadCallbackFn =
Mod->getOrInsertFunction(
1511 "__dfsan_load_callback", DFSanLoadStoreCallbackFnTy, AL);
1515 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1516 DFSanStoreCallbackFn =
Mod->getOrInsertFunction(
1517 "__dfsan_store_callback", DFSanLoadStoreCallbackFnTy, AL);
1519 DFSanMemTransferCallbackFn =
Mod->getOrInsertFunction(
1520 "__dfsan_mem_transfer_callback", DFSanMemTransferCallbackFnTy);
1523 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1524 DFSanCmpCallbackFn =
Mod->getOrInsertFunction(
"__dfsan_cmp_callback",
1525 DFSanCmpCallbackFnTy, AL);
1529 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1530 DFSanConditionalCallbackFn =
Mod->getOrInsertFunction(
1531 "__dfsan_conditional_callback", DFSanConditionalCallbackFnTy, AL);
1535 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1536 AL =
AL.maybeAddParamAttribute(
M.getContext(), 1, I32ParamExtAttr);
1537 DFSanConditionalCallbackOriginFn =
1538 Mod->getOrInsertFunction(
"__dfsan_conditional_callback_origin",
1539 DFSanConditionalCallbackOriginFnTy, AL);
1543 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1544 AL =
AL.maybeAddParamAttribute(
M.getContext(), 2, I32ParamExtAttr);
1545 DFSanReachesFunctionCallbackFn =
1546 Mod->getOrInsertFunction(
"__dfsan_reaches_function_callback",
1547 DFSanReachesFunctionCallbackFnTy, AL);
1551 AL =
AL.maybeAddParamAttribute(
M.getContext(), 0, I8ParamExtAttr);
1552 AL =
AL.maybeAddParamAttribute(
M.getContext(), 1, I32ParamExtAttr);
1553 AL =
AL.maybeAddParamAttribute(
M.getContext(), 3, I32ParamExtAttr);
1554 DFSanReachesFunctionCallbackOriginFn =
1555 Mod->getOrInsertFunction(
"__dfsan_reaches_function_callback_origin",
1556 DFSanReachesFunctionCallbackOriginFnTy, AL);
1560bool DataFlowSanitizer::runImpl(
1561 Module &M, llvm::function_ref<TargetLibraryInfo &(
Function &)> GetTLI) {
1562 initializeModule(M);
1564 if (ABIList.isIn(M,
"skip"))
1567 const unsigned InitialGlobalSize =
M.global_size();
1568 const unsigned InitialModuleSize =
M.size();
1572 auto GetOrInsertGlobal = [
this, &
Changed](StringRef
Name,
1573 Type *Ty) -> Constant * {
1574 GlobalVariable *
G =
Mod->getOrInsertGlobal(Name, Ty);
1575 Changed |=
G->getThreadLocalMode() != GlobalVariable::InitialExecTLSModel;
1576 G->setThreadLocalMode(GlobalVariable::InitialExecTLSModel);
1582 GetOrInsertGlobal(
"__dfsan_arg_tls",
1583 ArrayType::get(Type::getInt64Ty(*Ctx),
ArgTLSSize / 8));
1584 RetvalTLS = GetOrInsertGlobal(
1585 "__dfsan_retval_tls",
1587 ArgOriginTLSTy = ArrayType::get(OriginTy, NumOfElementsInArgOrgTLS);
1588 ArgOriginTLS = GetOrInsertGlobal(
"__dfsan_arg_origin_tls", ArgOriginTLSTy);
1589 RetvalOriginTLS = GetOrInsertGlobal(
"__dfsan_retval_origin_tls", OriginTy);
1591 (void)
Mod->getOrInsertGlobal(
"__dfsan_track_origins", OriginTy, [&] {
1593 return new GlobalVariable(
1594 M, OriginTy, true, GlobalValue::WeakODRLinkage,
1595 ConstantInt::getSigned(OriginTy,
1596 shouldTrackOrigins() ? ClTrackOrigins : 0),
1597 "__dfsan_track_origins");
1600 initializeCallbackFunctions(M);
1601 initializeRuntimeFunctions(M);
1603 std::vector<Function *> FnsToInstrument;
1604 SmallPtrSet<Function *, 2> FnsWithNativeABI;
1605 SmallPtrSet<Function *, 2> FnsWithForceZeroLabel;
1606 SmallPtrSet<Constant *, 1> PersonalityFns;
1608 if (!
F.isIntrinsic() && !DFSanRuntimeFunctions.
contains(&
F) &&
1609 !LibAtomicFunction(
F) &&
1610 !
F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) {
1611 FnsToInstrument.push_back(&
F);
1612 if (
F.hasPersonalityFn())
1613 PersonalityFns.
insert(
F.getPersonalityFn()->stripPointerCasts());
1617 for (
auto *
C : PersonalityFns) {
1620 if (!isInstrumented(
F))
1634 bool GAInst = isInstrumented(&GA), FInst = isInstrumented(
F);
1635 if (GAInst && FInst) {
1636 addGlobalNameSuffix(&GA);
1637 }
else if (GAInst != FInst) {
1642 buildWrapperFunction(
F,
"", GA.
getLinkage(),
F->getFunctionType());
1646 FnsToInstrument.push_back(NewF);
1655 for (std::vector<Function *>::iterator FI = FnsToInstrument.begin(),
1656 FE = FnsToInstrument.end();
1659 FunctionType *FT =
F.getFunctionType();
1661 bool IsZeroArgsVoidRet = (FT->getNumParams() == 0 && !FT->isVarArg() &&
1662 FT->getReturnType()->isVoidTy());
1664 if (isInstrumented(&
F)) {
1665 if (isForceZeroLabels(&
F))
1666 FnsWithForceZeroLabel.
insert(&
F);
1671 addGlobalNameSuffix(&
F);
1672 }
else if (!IsZeroArgsVoidRet || getWrapperKind(&
F) == WK_Custom) {
1680 F.hasLocalLinkage() ?
F.getLinkage()
1683 Function *NewF = buildWrapperFunction(
1685 (shouldTrackOrigins() ? std::string(
"dfso$") : std::string(
"dfsw$")) +
1686 std::string(
F.getName()),
1687 WrapperLinkage, FT);
1707 auto IsNotCmpUse = [](
Use &
U) ->
bool {
1708 User *Usr =
U.getUser();
1711 if (
CE->getOpcode() == Instruction::ICmp) {
1716 if (
I->getOpcode() == Instruction::ICmp) {
1722 F.replaceUsesWithIf(NewF, IsNotCmpUse);
1724 UnwrappedFnMap[NewF] = &
F;
1727 if (!
F.isDeclaration()) {
1737 size_t N = FI - FnsToInstrument.begin(),
1738 Count = FE - FnsToInstrument.begin();
1739 FnsToInstrument.push_back(&
F);
1740 FI = FnsToInstrument.begin() +
N;
1741 FE = FnsToInstrument.begin() +
Count;
1745 }
else if (FT->isVarArg()) {
1746 UnwrappedFnMap[&
F] = &
F;
1752 if (!
F ||
F->isDeclaration())
1757 DFSanFunction DFSF(*
this,
F, FnsWithNativeABI.
count(
F),
1758 FnsWithForceZeroLabel.
count(
F), GetTLI(*
F));
1762 for (
auto &FArg :
F->args()) {
1764 Value *FArgShadow = DFSF.getShadow(&FArg);
1765 if (isZeroShadow(FArgShadow))
1768 Next = FArgShadowInst->getNextNode();
1770 if (shouldTrackOrigins()) {
1771 if (Instruction *Origin =
1775 if (
Next->comesBefore(OriginNext)) {
1781 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, *
Next, &FArg);
1789 for (BasicBlock *BB : BBList) {
1799 if (!DFSF.SkipInsts.
count(Inst))
1800 DFSanVisitor(DFSF).visit(Inst);
1811 for (DFSanFunction::PHIFixupElement &
P : DFSF.PHIFixups) {
1812 for (
unsigned Val = 0,
N =
P.Phi->getNumIncomingValues(); Val !=
N;
1814 P.ShadowPhi->setIncomingValue(
1815 Val, DFSF.getShadow(
P.Phi->getIncomingValue(Val)));
1817 P.OriginPhi->setIncomingValue(
1818 Val, DFSF.getOrigin(
P.Phi->getIncomingValue(Val)));
1827 for (
Value *V : DFSF.NonZeroChecks) {
1830 Pos = std::next(
I->getIterator());
1834 Pos = std::next(Pos->getIterator());
1836 Value *PrimitiveShadow = DFSF.collapseToPrimitiveShadow(V, Pos);
1838 IRB.
CreateICmpNE(PrimitiveShadow, DFSF.DFS.ZeroPrimitiveShadow);
1840 Ne, Pos,
false, ColdCallWeights));
1842 ThenIRB.CreateCall(DFSF.DFS.DFSanNonzeroLabelFn, {});
1847 return Changed || !FnsToInstrument.empty() ||
1848 M.global_size() != InitialGlobalSize ||
M.size() != InitialModuleSize;
1852 return IRB.
CreatePtrAdd(DFS.ArgTLS, ConstantInt::get(DFS.IntptrTy, ArgOffset),
1861Value *DFSanFunction::getRetvalOriginTLS() {
return DFS.RetvalOriginTLS; }
1865 ArgNo,
"_dfsarg_o");
1869 assert(DFS.shouldTrackOrigins());
1871 return DFS.ZeroOrigin;
1872 Value *&Origin = ValOriginMap[
V];
1876 return DFS.ZeroOrigin;
1877 if (
A->getArgNo() < DFS.NumOfElementsInArgOrgTLS) {
1878 Instruction *ArgOriginTLSPos = &*
F->getEntryBlock().begin();
1880 Value *ArgOriginPtr = getArgOriginTLS(
A->getArgNo(), IRB);
1881 Origin = IRB.
CreateLoad(DFS.OriginTy, ArgOriginPtr);
1884 Origin = DFS.ZeroOrigin;
1887 Origin = DFS.ZeroOrigin;
1893void DFSanFunction::setOrigin(Instruction *
I,
Value *Origin) {
1894 if (!DFS.shouldTrackOrigins())
1898 ValOriginMap[
I] = Origin;
1901Value *DFSanFunction::getShadowForTLSArgument(Argument *
A) {
1902 unsigned ArgOffset = 0;
1903 const DataLayout &
DL =
F->getDataLayout();
1904 for (
auto &FArg :
F->args()) {
1905 if (!FArg.getType()->isSized()) {
1911 unsigned Size =
DL.getTypeAllocSize(DFS.getShadowTy(&FArg));
1924 Value *ArgShadowPtr = getArgTLS(FArg.getType(), ArgOffset, IRB);
1929 return DFS.getZeroShadow(
A);
1934 return DFS.getZeroShadow(V);
1935 if (IsForceZeroLabels)
1936 return DFS.getZeroShadow(V);
1937 Value *&Shadow = ValShadowMap[
V];
1941 return DFS.getZeroShadow(V);
1942 Shadow = getShadowForTLSArgument(
A);
1943 NonZeroChecks.push_back(Shadow);
1945 Shadow = DFS.getZeroShadow(V);
1951void DFSanFunction::setShadow(Instruction *
I,
Value *Shadow) {
1953 ValShadowMap[
I] = Shadow;
1961 assert(Addr != RetvalTLS &&
"Reinstrumenting?");
1964 uint64_t AndMask = MapParams->AndMask;
1967 IRB.
CreateAnd(OffsetLong, ConstantInt::get(IntptrTy, ~AndMask));
1969 uint64_t XorMask = MapParams->XorMask;
1971 OffsetLong = IRB.
CreateXor(OffsetLong, ConstantInt::get(IntptrTy, XorMask));
1975std::pair<Value *, Value *>
1976DataFlowSanitizer::getShadowOriginAddress(
Value *Addr, Align InstAlignment,
1980 Value *ShadowOffset = getShadowOffset(Addr, IRB);
1981 Value *ShadowLong = ShadowOffset;
1982 uint64_t ShadowBase = MapParams->ShadowBase;
1983 if (ShadowBase != 0) {
1985 IRB.
CreateAdd(ShadowLong, ConstantInt::get(IntptrTy, ShadowBase));
1988 Value *OriginPtr =
nullptr;
1989 if (shouldTrackOrigins()) {
1990 Value *OriginLong = ShadowOffset;
1991 uint64_t OriginBase = MapParams->OriginBase;
1992 if (OriginBase != 0)
1994 IRB.
CreateAdd(OriginLong, ConstantInt::get(IntptrTy, OriginBase));
2000 OriginLong = IRB.
CreateAnd(OriginLong, ConstantInt::get(IntptrTy, ~Mask));
2004 return std::make_pair(ShadowPtr, OriginPtr);
2007Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
2009 Value *ShadowOffset) {
2014Value *DataFlowSanitizer::getShadowAddress(
Value *Addr,
2017 Value *ShadowAddr = getShadowOffset(Addr, IRB);
2018 uint64_t ShadowBase = MapParams->ShadowBase;
2019 if (ShadowBase != 0)
2021 IRB.
CreateAdd(ShadowAddr, ConstantInt::get(IntptrTy, ShadowBase));
2022 return getShadowAddress(Addr, Pos, ShadowAddr);
2027 Value *PrimitiveValue = combineShadows(
V1, V2, Pos);
2028 return expandFromPrimitiveShadow(
T, PrimitiveValue, Pos);
2035 if (DFS.isZeroShadow(
V1))
2036 return collapseToPrimitiveShadow(V2, Pos);
2037 if (DFS.isZeroShadow(V2))
2038 return collapseToPrimitiveShadow(
V1, Pos);
2040 return collapseToPrimitiveShadow(
V1, Pos);
2042 auto V1Elems = ShadowElements.
find(
V1);
2043 auto V2Elems = ShadowElements.
find(V2);
2044 if (V1Elems != ShadowElements.
end() && V2Elems != ShadowElements.
end()) {
2046 return collapseToPrimitiveShadow(
V1, Pos);
2049 return collapseToPrimitiveShadow(V2, Pos);
2051 }
else if (V1Elems != ShadowElements.
end()) {
2052 if (V1Elems->second.count(V2))
2053 return collapseToPrimitiveShadow(
V1, Pos);
2054 }
else if (V2Elems != ShadowElements.
end()) {
2055 if (V2Elems->second.count(
V1))
2056 return collapseToPrimitiveShadow(V2, Pos);
2059 auto Key = std::make_pair(
V1, V2);
2062 CachedShadow &CCS = CachedShadows[
Key];
2063 if (CCS.Block && DT.
dominates(CCS.Block, Pos->getParent()))
2067 Value *PV1 = collapseToPrimitiveShadow(
V1, Pos);
2068 Value *PV2 = collapseToPrimitiveShadow(V2, Pos);
2071 CCS.Block = Pos->getParent();
2072 CCS.Shadow = IRB.
CreateOr(PV1, PV2);
2074 std::set<Value *> UnionElems;
2075 if (V1Elems != ShadowElements.
end()) {
2076 UnionElems = V1Elems->second;
2078 UnionElems.insert(
V1);
2080 if (V2Elems != ShadowElements.
end()) {
2081 UnionElems.insert(V2Elems->second.begin(), V2Elems->second.end());
2083 UnionElems.insert(V2);
2085 ShadowElements[CCS.Shadow] = std::move(UnionElems);
2093Value *DFSanFunction::combineOperandShadows(Instruction *Inst) {
2095 return DFS.getZeroShadow(Inst);
2099 Shadow = combineShadows(Shadow, getShadow(Inst->
getOperand(
I)),
2102 return expandFromPrimitiveShadow(Inst->
getType(), Shadow,
2106void DFSanVisitor::visitInstOperands(Instruction &
I) {
2107 Value *CombinedShadow = DFSF.combineOperandShadows(&
I);
2108 DFSF.setShadow(&
I, CombinedShadow);
2109 visitInstOperandOrigins(
I);
2112Value *DFSanFunction::combineOrigins(
const std::vector<Value *> &Shadows,
2113 const std::vector<Value *> &Origins,
2115 ConstantInt *Zero) {
2116 assert(Shadows.size() == Origins.size());
2117 size_t Size = Origins.size();
2119 return DFS.ZeroOrigin;
2120 Value *Origin =
nullptr;
2122 Zero = DFS.ZeroPrimitiveShadow;
2123 for (
size_t I = 0;
I !=
Size; ++
I) {
2124 Value *OpOrigin = Origins[
I];
2126 if (ConstOpOrigin && ConstOpOrigin->
isNullValue())
2132 Value *OpShadow = Shadows[
I];
2133 Value *PrimitiveShadow = collapseToPrimitiveShadow(OpShadow, Pos);
2138 return Origin ? Origin : DFS.ZeroOrigin;
2141Value *DFSanFunction::combineOperandOrigins(Instruction *Inst) {
2143 std::vector<Value *> Shadows(
Size);
2144 std::vector<Value *> Origins(
Size);
2145 for (
unsigned I = 0;
I !=
Size; ++
I) {
2149 return combineOrigins(Shadows, Origins, Inst->
getIterator());
2152void DFSanVisitor::visitInstOperandOrigins(Instruction &
I) {
2153 if (!DFSF.DFS.shouldTrackOrigins())
2155 Value *CombinedOrigin = DFSF.combineOperandOrigins(&
I);
2156 DFSF.setOrigin(&
I, CombinedOrigin);
2159Align DFSanFunction::getShadowAlign(Align InstAlignment) {
2164Align DFSanFunction::getOriginAlign(Align InstAlignment) {
2169bool DFSanFunction::isLookupTableConstant(
Value *
P) {
2171 if (GV->isConstant() && GV->
hasName())
2172 return DFS.CombineTaintLookupTableNames.
count(GV->
getName());
2177bool DFSanFunction::useCallbackLoadLabelAndOrigin(
uint64_t Size,
2178 Align InstAlignment) {
2202 Value **OriginAddr) {
2205 IRB.
CreateGEP(OriginTy, *OriginAddr, ConstantInt::get(IntptrTy, 1));
2209std::pair<Value *, Value *> DFSanFunction::loadShadowFast(
2212 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2213 const uint64_t ShadowSize =
Size * DFS.ShadowWidthBytes;
2215 assert(
Size >= 4 &&
"Not large enough load size for fast path!");
2218 std::vector<Value *> Shadows;
2219 std::vector<Value *> Origins;
2232 Type *WideShadowTy =
2233 ShadowSize == 4 ? Type::getInt32Ty(*DFS.Ctx) :
Type::getInt64Ty(*DFS.Ctx);
2236 Value *CombinedWideShadow =
2240 const uint64_t BytesPerWideShadow = WideShadowBitWidth / DFS.ShadowWidthBits;
2242 auto AppendWideShadowAndOrigin = [&](
Value *WideShadow,
Value *Origin) {
2243 if (BytesPerWideShadow > 4) {
2244 assert(BytesPerWideShadow == 8);
2251 Value *WideShadowLo =
2252 F->getParent()->getDataLayout().isLittleEndian()
2255 ConstantInt::get(WideShadowTy, WideShadowBitWidth / 2))
2258 ConstantInt::get(WideShadowTy,
2259 ((1ULL << (WideShadowBitWidth / 2)) - 1)
2260 << (WideShadowBitWidth / 2)));
2261 Shadows.push_back(WideShadow);
2262 Origins.push_back(DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr));
2264 Shadows.push_back(WideShadowLo);
2265 Origins.push_back(Origin);
2267 Shadows.push_back(WideShadow);
2268 Origins.push_back(Origin);
2272 if (ShouldTrackOrigins)
2273 AppendWideShadowAndOrigin(CombinedWideShadow, FirstOrigin);
2280 for (
uint64_t ByteOfs = BytesPerWideShadow; ByteOfs <
Size;
2281 ByteOfs += BytesPerWideShadow) {
2282 ShadowAddr = IRB.
CreateGEP(WideShadowTy, ShadowAddr,
2283 ConstantInt::get(DFS.IntptrTy, 1));
2284 Value *NextWideShadow =
2286 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, NextWideShadow);
2287 if (ShouldTrackOrigins) {
2288 Value *NextOrigin = DFS.loadNextOrigin(Pos, OriginAlign, &OriginAddr);
2289 AppendWideShadowAndOrigin(NextWideShadow, NextOrigin);
2292 for (
unsigned Width = WideShadowBitWidth / 2; Width >= DFS.ShadowWidthBits;
2295 CombinedWideShadow = IRB.
CreateOr(CombinedWideShadow, ShrShadow);
2297 return {IRB.
CreateTrunc(CombinedWideShadow, DFS.PrimitiveShadowTy),
2299 ? combineOrigins(Shadows, Origins, Pos,
2304std::pair<Value *, Value *> DFSanFunction::loadShadowOriginSansLoadTracking(
2306 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins();
2310 const auto SI = AllocaShadowMap.
find(AI);
2311 if (SI != AllocaShadowMap.
end()) {
2314 const auto OI = AllocaOriginMap.
find(AI);
2315 assert(!ShouldTrackOrigins || OI != AllocaOriginMap.
end());
2316 return {ShadowLI, ShouldTrackOrigins
2323 SmallVector<const Value *, 2> Objs;
2325 bool AllConstants =
true;
2326 for (
const Value *Obj : Objs) {
2332 AllConstants =
false;
2336 return {DFS.ZeroPrimitiveShadow,
2337 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2340 return {DFS.ZeroPrimitiveShadow,
2341 ShouldTrackOrigins ? DFS.ZeroOrigin :
nullptr};
2345 if (ShouldTrackOrigins &&
2346 useCallbackLoadLabelAndOrigin(
Size, InstAlignment)) {
2349 IRB.
CreateCall(DFS.DFSanLoadLabelAndOriginFn,
2350 {Addr, ConstantInt::get(DFS.IntptrTy, Size)});
2353 DFS.PrimitiveShadowTy),
2358 Value *ShadowAddr, *OriginAddr;
2359 std::tie(ShadowAddr, OriginAddr) =
2360 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2362 const Align ShadowAlign = getShadowAlign(InstAlignment);
2363 const Align OriginAlign = getOriginAlign(InstAlignment);
2364 Value *Origin =
nullptr;
2365 if (ShouldTrackOrigins) {
2374 LoadInst *LI =
new LoadInst(DFS.PrimitiveShadowTy, ShadowAddr,
"", Pos);
2376 return {LI, Origin};
2380 Value *ShadowAddr1 = IRB.
CreateGEP(DFS.PrimitiveShadowTy, ShadowAddr,
2381 ConstantInt::get(DFS.IntptrTy, 1));
2386 return {combineShadows(
Load, Load1, Pos), Origin};
2389 bool HasSizeForFastPath = DFS.hasLoadSizeForFastPath(
Size);
2391 if (HasSizeForFastPath)
2392 return loadShadowFast(ShadowAddr, OriginAddr,
Size, ShadowAlign,
2393 OriginAlign, Origin, Pos);
2397 DFS.DFSanUnionLoadFn, {ShadowAddr, ConstantInt::get(DFS.IntptrTy, Size)});
2399 return {FallbackCall, Origin};
2402std::pair<Value *, Value *>
2405 Value *PrimitiveShadow, *Origin;
2406 std::tie(PrimitiveShadow, Origin) =
2407 loadShadowOriginSansLoadTracking(Addr,
Size, InstAlignment, Pos);
2408 if (DFS.shouldTrackOrigins()) {
2412 if (!ConstantShadow || !ConstantShadow->isNullValue())
2413 Origin = updateOriginIfTainted(PrimitiveShadow, Origin, IRB);
2416 return {PrimitiveShadow, Origin};
2437 if (!V->getType()->isPointerTy())
2446 V =
GEP->getPointerOperand();
2449 if (!V->getType()->isPointerTy())
2454 }
while (Visited.
insert(V).second);
2459void DFSanVisitor::visitLoadInst(LoadInst &LI) {
2463 DFSF.setShadow(&LI, DFSF.DFS.getZeroShadow(&LI));
2464 DFSF.setOrigin(&LI, DFSF.DFS.ZeroOrigin);
2479 Pos = std::next(Pos);
2481 std::vector<Value *> Shadows;
2482 std::vector<Value *> Origins;
2483 Value *PrimitiveShadow, *Origin;
2484 std::tie(PrimitiveShadow, Origin) =
2486 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2487 if (ShouldTrackOrigins) {
2488 Shadows.push_back(PrimitiveShadow);
2489 Origins.push_back(Origin);
2492 DFSF.isLookupTableConstant(
2495 PrimitiveShadow = DFSF.combineShadows(PrimitiveShadow, PtrShadow, Pos);
2496 if (ShouldTrackOrigins) {
2497 Shadows.push_back(PtrShadow);
2501 if (!DFSF.DFS.isZeroShadow(PrimitiveShadow))
2502 DFSF.NonZeroChecks.push_back(PrimitiveShadow);
2505 DFSF.expandFromPrimitiveShadow(LI.
getType(), PrimitiveShadow, Pos);
2506 DFSF.setShadow(&LI, Shadow);
2508 if (ShouldTrackOrigins) {
2509 DFSF.setOrigin(&LI, DFSF.combineOrigins(Shadows, Origins, Pos));
2516 IRB.
CreateCall(DFSF.DFS.DFSanLoadCallbackFn, {PrimitiveShadow, Addr});
2521 DFSF.addReachesFunctionCallbacksIfEnabled(IRB, LI, &LI);
2524Value *DFSanFunction::updateOriginIfTainted(
Value *Shadow,
Value *Origin,
2526 assert(DFS.shouldTrackOrigins());
2527 return IRB.
CreateCall(DFS.DFSanChainOriginIfTaintedFn, {Shadow, Origin});
2531 if (!DFS.shouldTrackOrigins())
2533 return IRB.
CreateCall(DFS.DFSanChainOriginFn, V);
2537 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2538 const DataLayout &
DL =
F->getDataLayout();
2539 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2540 if (IntptrSize == OriginSize)
2542 assert(IntptrSize == OriginSize * 2);
2548 Value *StoreOriginAddr,
2549 uint64_t StoreOriginSize, Align Alignment) {
2550 const unsigned OriginSize = DataFlowSanitizer::OriginWidthBytes;
2551 const DataLayout &
DL =
F->getDataLayout();
2552 const Align IntptrAlignment =
DL.getABITypeAlign(DFS.IntptrTy);
2553 unsigned IntptrSize =
DL.getTypeStoreSize(DFS.IntptrTy);
2555 assert(IntptrSize >= OriginSize);
2559 if (Alignment >= IntptrAlignment && IntptrSize > OriginSize) {
2560 Value *IntptrOrigin = originToIntptr(IRB, Origin);
2561 Value *IntptrStoreOriginPtr =
2563 for (
unsigned I = 0;
I < StoreOriginSize / IntptrSize; ++
I) {
2566 : IntptrStoreOriginPtr;
2568 Ofs += IntptrSize / OriginSize;
2569 CurrentAlignment = IntptrAlignment;
2573 for (
unsigned I = Ofs;
I < (StoreOriginSize + OriginSize - 1) / OriginSize;
2583 const Twine &Name) {
2584 Type *VTy =
V->getType();
2589 return IRB.
CreateICmpNE(V, ConstantInt::get(VTy, 0), Name);
2594 Value *StoreOriginAddr, Align InstAlignment) {
2597 const Align OriginAlignment = getOriginAlign(InstAlignment);
2598 Value *CollapsedShadow = collapseToPrimitiveShadow(Shadow, Pos);
2601 if (!ConstantShadow->isNullValue())
2602 paintOrigin(IRB, updateOrigin(Origin, IRB), StoreOriginAddr,
Size,
2607 if (shouldInstrumentWithCall()) {
2609 DFS.DFSanMaybeStoreOriginFn,
2610 {CollapsedShadow, Addr, ConstantInt::get(DFS.IntptrTy, Size), Origin});
2612 Value *
Cmp = convertToBool(CollapsedShadow, IRB,
"_dfscmp");
2613 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
2615 Cmp, &*IRB.
GetInsertPoint(),
false, DFS.OriginStoreWeights, &DTU);
2617 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), StoreOriginAddr,
Size,
2627 IntegerType *ShadowTy =
2629 Value *ExtZeroShadow = ConstantInt::get(ShadowTy, 0);
2630 Value *ShadowAddr = DFS.getShadowAddress(Addr, Pos);
2637 Align InstAlignment,
2638 Value *PrimitiveShadow,
2641 const bool ShouldTrackOrigins = DFS.shouldTrackOrigins() && Origin;
2644 const auto SI = AllocaShadowMap.
find(AI);
2645 if (SI != AllocaShadowMap.
end()) {
2651 if (ShouldTrackOrigins && !DFS.isZeroShadow(PrimitiveShadow)) {
2652 const auto OI = AllocaOriginMap.
find(AI);
2653 assert(OI != AllocaOriginMap.
end() && Origin);
2660 const Align ShadowAlign = getShadowAlign(InstAlignment);
2661 if (DFS.isZeroShadow(PrimitiveShadow)) {
2662 storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign, Pos);
2667 Value *ShadowAddr, *OriginAddr;
2668 std::tie(ShadowAddr, OriginAddr) =
2669 DFS.getShadowOriginAddress(Addr, InstAlignment, Pos);
2671 const unsigned ShadowVecSize = 8;
2672 assert(ShadowVecSize * DFS.ShadowWidthBits <= 128 &&
2673 "Shadow vector is too large!");
2677 if (LeftSize >= ShadowVecSize) {
2681 for (
unsigned I = 0;
I != ShadowVecSize; ++
I) {
2683 ShadowVec, PrimitiveShadow,
2684 ConstantInt::get(Type::getInt32Ty(*DFS.Ctx),
I));
2687 Value *CurShadowVecAddr =
2690 LeftSize -= ShadowVecSize;
2692 }
while (LeftSize >= ShadowVecSize);
2695 while (LeftSize > 0) {
2696 Value *CurShadowAddr =
2703 if (ShouldTrackOrigins) {
2704 storeOrigin(Pos, Addr,
Size, PrimitiveShadow, Origin, OriginAddr,
2726void DFSanVisitor::visitStoreInst(StoreInst &SI) {
2727 auto &
DL =
SI.getDataLayout();
2728 Value *Val =
SI.getValueOperand();
2741 const bool ShouldTrackOrigins =
2742 DFSF.DFS.shouldTrackOrigins() && !
SI.isAtomic();
2743 std::vector<Value *> Shadows;
2744 std::vector<Value *> Origins;
2747 SI.isAtomic() ? DFSF.DFS.getZeroShadow(Val) : DFSF.getShadow(Val);
2749 if (ShouldTrackOrigins) {
2750 Shadows.push_back(Shadow);
2751 Origins.push_back(DFSF.getOrigin(Val));
2754 Value *PrimitiveShadow;
2756 Value *PtrShadow = DFSF.getShadow(
SI.getPointerOperand());
2757 if (ShouldTrackOrigins) {
2758 Shadows.push_back(PtrShadow);
2759 Origins.push_back(DFSF.getOrigin(
SI.getPointerOperand()));
2761 PrimitiveShadow = DFSF.combineShadows(Shadow, PtrShadow,
SI.getIterator());
2763 PrimitiveShadow = DFSF.collapseToPrimitiveShadow(Shadow,
SI.getIterator());
2765 Value *Origin =
nullptr;
2766 if (ShouldTrackOrigins)
2767 Origin = DFSF.combineOrigins(Shadows, Origins,
SI.getIterator());
2768 DFSF.storePrimitiveShadowOrigin(
SI.getPointerOperand(),
Size,
SI.getAlign(),
2769 PrimitiveShadow, Origin,
SI.getIterator());
2772 Value *Addr =
SI.getPointerOperand();
2774 IRB.
CreateCall(DFSF.DFS.DFSanStoreCallbackFn, {PrimitiveShadow, Addr});
2779void DFSanVisitor::visitCASOrRMW(Align InstAlignment, Instruction &
I) {
2782 Value *Val =
I.getOperand(1);
2783 const auto &
DL =
I.getDataLayout();
2791 Value *Addr =
I.getOperand(0);
2792 const Align ShadowAlign = DFSF.getShadowAlign(InstAlignment);
2793 DFSF.storeZeroPrimitiveShadow(Addr,
Size, ShadowAlign,
I.getIterator());
2794 DFSF.setShadow(&
I, DFSF.DFS.getZeroShadow(&
I));
2795 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2798void DFSanVisitor::visitAtomicRMWInst(AtomicRMWInst &
I) {
2799 visitCASOrRMW(
I.getAlign(),
I);
2805void DFSanVisitor::visitAtomicCmpXchgInst(AtomicCmpXchgInst &
I) {
2806 visitCASOrRMW(
I.getAlign(),
I);
2812void DFSanVisitor::visitUnaryOperator(UnaryOperator &UO) {
2813 visitInstOperands(UO);
2816void DFSanVisitor::visitBinaryOperator(BinaryOperator &BO) {
2817 visitInstOperands(BO);
2820void DFSanVisitor::visitBitCastInst(BitCastInst &BCI) {
2827 visitInstOperands(BCI);
2830void DFSanVisitor::visitCastInst(CastInst &CI) { visitInstOperands(CI); }
2832void DFSanVisitor::visitCmpInst(CmpInst &CI) {
2833 visitInstOperands(CI);
2836 Value *CombinedShadow = DFSF.getShadow(&CI);
2838 IRB.
CreateCall(DFSF.DFS.DFSanCmpCallbackFn, CombinedShadow);
2844void DFSanVisitor::visitLandingPadInst(LandingPadInst &LPI) {
2856 DFSF.setShadow(&LPI, DFSF.DFS.getZeroShadow(&LPI));
2857 DFSF.setOrigin(&LPI, DFSF.DFS.ZeroOrigin);
2860void DFSanVisitor::visitGetElementPtrInst(GetElementPtrInst &GEPI) {
2862 DFSF.isLookupTableConstant(
2864 visitInstOperands(GEPI);
2871 DFSF.setShadow(&GEPI, DFSF.getShadow(BasePointer));
2872 if (DFSF.DFS.shouldTrackOrigins())
2873 DFSF.setOrigin(&GEPI, DFSF.getOrigin(BasePointer));
2876void DFSanVisitor::visitExtractElementInst(ExtractElementInst &
I) {
2877 visitInstOperands(
I);
2880void DFSanVisitor::visitInsertElementInst(InsertElementInst &
I) {
2881 visitInstOperands(
I);
2884void DFSanVisitor::visitShuffleVectorInst(ShuffleVectorInst &
I) {
2885 visitInstOperands(
I);
2888void DFSanVisitor::visitExtractValueInst(ExtractValueInst &
I) {
2890 Value *Agg =
I.getAggregateOperand();
2891 Value *AggShadow = DFSF.getShadow(Agg);
2893 DFSF.setShadow(&
I, ResShadow);
2894 visitInstOperandOrigins(
I);
2897void DFSanVisitor::visitInsertValueInst(InsertValueInst &
I) {
2899 Value *AggShadow = DFSF.getShadow(
I.getAggregateOperand());
2900 Value *InsShadow = DFSF.getShadow(
I.getInsertedValueOperand());
2902 DFSF.setShadow(&
I, Res);
2903 visitInstOperandOrigins(
I);
2906void DFSanVisitor::visitAllocaInst(AllocaInst &
I) {
2907 bool AllLoadsStores =
true;
2908 for (User *U :
I.users()) {
2913 if (
SI->getPointerOperand() == &
I)
2917 AllLoadsStores =
false;
2920 if (AllLoadsStores) {
2922 DFSF.AllocaShadowMap[&
I] = IRB.
CreateAlloca(DFSF.DFS.PrimitiveShadowTy);
2923 if (DFSF.DFS.shouldTrackOrigins()) {
2924 DFSF.AllocaOriginMap[&
I] =
2928 DFSF.setShadow(&
I, DFSF.DFS.ZeroPrimitiveShadow);
2929 DFSF.setOrigin(&
I, DFSF.DFS.ZeroOrigin);
2932void DFSanVisitor::visitSelectInst(SelectInst &
I) {
2933 Value *CondShadow = DFSF.getShadow(
I.getCondition());
2934 Value *TrueShadow = DFSF.getShadow(
I.getTrueValue());
2935 Value *FalseShadow = DFSF.getShadow(
I.getFalseValue());
2936 Value *ShadowSel =
nullptr;
2937 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
2938 std::vector<Value *> Shadows;
2939 std::vector<Value *> Origins;
2941 ShouldTrackOrigins ? DFSF.getOrigin(
I.getTrueValue()) :
nullptr;
2942 Value *FalseOrigin =
2943 ShouldTrackOrigins ? DFSF.getOrigin(
I.getFalseValue()) :
nullptr;
2945 DFSF.addConditionalCallbacksIfEnabled(
I,
I.getCondition());
2948 ShadowSel = DFSF.combineShadowsThenConvert(
I.getType(), TrueShadow,
2949 FalseShadow,
I.getIterator());
2950 if (ShouldTrackOrigins) {
2951 Shadows.push_back(TrueShadow);
2952 Shadows.push_back(FalseShadow);
2953 Origins.push_back(TrueOrigin);
2954 Origins.push_back(FalseOrigin);
2957 if (TrueShadow == FalseShadow) {
2958 ShadowSel = TrueShadow;
2959 if (ShouldTrackOrigins) {
2960 Shadows.push_back(TrueShadow);
2961 Origins.push_back(TrueOrigin);
2965 "",
I.getIterator());
2966 if (ShouldTrackOrigins) {
2967 Shadows.push_back(ShadowSel);
2969 FalseOrigin,
"",
I.getIterator()));
2974 I.getType(), CondShadow,
2975 ShadowSel,
I.getIterator())
2977 if (ShouldTrackOrigins) {
2979 Shadows.push_back(CondShadow);
2980 Origins.push_back(DFSF.getOrigin(
I.getCondition()));
2982 DFSF.setOrigin(&
I, DFSF.combineOrigins(Shadows, Origins,
I.getIterator()));
2986void DFSanVisitor::visitMemSetInst(MemSetInst &
I) {
2988 Value *ValShadow = DFSF.getShadow(
I.getValue());
2989 Value *ValOrigin = DFSF.DFS.shouldTrackOrigins()
2990 ? DFSF.getOrigin(
I.getValue())
2991 : DFSF.DFS.ZeroOrigin;
2993 {ValShadow, ValOrigin, I.getDest(),
2994 IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
2997void DFSanVisitor::visitMemTransferInst(MemTransferInst &
I) {
3002 if (DFSF.DFS.shouldTrackOrigins()) {
3004 DFSF.DFS.DFSanMemOriginTransferFn,
3005 {I.getArgOperand(0), I.getArgOperand(1),
3006 IRB.CreateIntCast(I.getArgOperand(2), DFSF.DFS.IntptrTy, false)});
3009 Value *DestShadow = DFSF.DFS.getShadowAddress(
I.getDest(),
I.getIterator());
3010 Value *SrcShadow = DFSF.DFS.getShadowAddress(
I.getSource(),
I.getIterator());
3012 IRB.
CreateMul(
I.getLength(), ConstantInt::get(
I.getLength()->getType(),
3013 DFSF.DFS.ShadowWidthBytes));
3015 IRB.
CreateCall(
I.getFunctionType(),
I.getCalledOperand(),
3016 {DestShadow, SrcShadow, LenShadow, I.getVolatileCst()}));
3017 MTI->setDestAlignment(DFSF.getShadowAlign(
I.getDestAlign().valueOrOne()));
3018 MTI->setSourceAlignment(DFSF.getShadowAlign(
I.getSourceAlign().valueOrOne()));
3021 DFSF.DFS.DFSanMemTransferCallbackFn,
3022 {DestShadow, IRB.CreateZExtOrTrunc(I.getLength(), DFSF.DFS.IntptrTy)});
3026void DFSanVisitor::visitCondBrInst(CondBrInst &BR) {
3027 DFSF.addConditionalCallbacksIfEnabled(BR,
BR.getCondition());
3030void DFSanVisitor::visitSwitchInst(SwitchInst &SW) {
3031 DFSF.addConditionalCallbacksIfEnabled(SW, SW.
getCondition());
3037 RetVal =
I->getOperand(0);
3040 return I->isMustTailCall();
3045void DFSanVisitor::visitReturnInst(ReturnInst &RI) {
3054 unsigned Size = getDataLayout().getTypeAllocSize(DFSF.DFS.getShadowTy(RT));
3060 if (DFSF.DFS.shouldTrackOrigins()) {
3067void DFSanVisitor::addShadowArguments(
Function &
F, CallBase &CB,
3068 std::vector<Value *> &Args,
3070 FunctionType *FT =
F.getFunctionType();
3075 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
3077 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()));
3080 if (FT->isVarArg()) {
3081 auto *LabelVATy = ArrayType::get(DFSF.DFS.PrimitiveShadowTy,
3082 CB.
arg_size() - FT->getNumParams());
3083 auto *LabelVAAlloca =
3084 new AllocaInst(LabelVATy, getDataLayout().getAllocaAddrSpace(),
3087 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
3090 DFSF.collapseToPrimitiveShadow(DFSF.getShadow(*
I), CB.
getIterator()),
3098 if (!FT->getReturnType()->isVoidTy()) {
3099 if (!DFSF.LabelReturnAlloca) {
3100 DFSF.LabelReturnAlloca =
new AllocaInst(
3101 DFSF.DFS.PrimitiveShadowTy, getDataLayout().getAllocaAddrSpace(),
3104 Args.push_back(DFSF.LabelReturnAlloca);
3108void DFSanVisitor::addOriginArguments(
Function &
F, CallBase &CB,
3109 std::vector<Value *> &Args,
3111 FunctionType *FT =
F.getFunctionType();
3116 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N)
3117 Args.push_back(DFSF.getOrigin(*
I));
3120 if (FT->isVarArg()) {
3122 ArrayType::get(DFSF.DFS.OriginTy, CB.
arg_size() - FT->getNumParams());
3123 auto *OriginVAAlloca =
3124 new AllocaInst(OriginVATy, getDataLayout().getAllocaAddrSpace(),
3127 for (
unsigned N = 0;
I != CB.
arg_end(); ++
I, ++
N) {
3136 if (!FT->getReturnType()->isVoidTy()) {
3137 if (!DFSF.OriginReturnAlloca) {
3138 DFSF.OriginReturnAlloca =
new AllocaInst(
3139 DFSF.DFS.OriginTy, getDataLayout().getAllocaAddrSpace(),
3142 Args.push_back(DFSF.OriginReturnAlloca);
3146bool DFSanVisitor::visitWrappedCallBase(
Function &
F, CallBase &CB) {
3148 switch (DFSF.DFS.getWrapperKind(&
F)) {
3149 case DataFlowSanitizer::WK_Warning:
3151 IRB.
CreateCall(DFSF.DFS.DFSanUnimplementedFn,
3153 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3154 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3155 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3157 case DataFlowSanitizer::WK_Discard:
3159 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3160 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3161 DFSF.setOrigin(&CB, DFSF.DFS.ZeroOrigin);
3163 case DataFlowSanitizer::WK_Functional:
3165 DFSF.DFS.buildExternWeakCheckIfNeeded(IRB, &
F);
3166 visitInstOperands(CB);
3168 case DataFlowSanitizer::WK_Custom:
3176 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3177 FunctionType *FT =
F.getFunctionType();
3178 TransformedFunction CustomFnTy =
3179 DFSF.DFS.getCustomFunctionType(FT, DFSF.TLI);
3180 std::string CustomFName = ShouldTrackOrigins ?
"__dfso_" :
"__dfsw_";
3181 CustomFName +=
F.getName();
3183 CustomFName, CustomFnTy.TransformedType);
3190 AttributeList CustomAL = CustomFun->getAttributes();
3191 CustomFun->copyAttributesFrom(&
F);
3192 CustomFun->setAttributes(AttributeList::get(
3194 {CustomFun->getAttributes(), CustomAL, CustomFnTy.NewParamAttrs}));
3197 if (!FT->getReturnType()->isVoidTy()) {
3198 CustomFun->removeFnAttrs(DFSF.DFS.ReadOnlyNoneAttrs);
3202 std::vector<Value *>
Args;
3206 for (
unsigned N = FT->getNumParams();
N != 0; ++
I, --
N) {
3211 addShadowArguments(
F, CB, Args, IRB);
3214 if (ShouldTrackOrigins)
3215 addOriginArguments(
F, CB, Args, IRB);
3220 CallInst *CustomCI = IRB.
CreateCall(CustomFunCallee, Args);
3226 {transformFunctionAttributes(CustomFnTy, CI->getContext(),
3227 CI->getAttributes()),
3228 F.getAttributes(), CustomFnTy.NewParamAttrs}));
3231 if (!FT->getReturnType()->isVoidTy()) {
3232 LoadInst *LabelLoad =
3233 IRB.
CreateLoad(DFSF.DFS.PrimitiveShadowTy, DFSF.LabelReturnAlloca);
3234 DFSF.setShadow(CustomCI,
3235 DFSF.expandFromPrimitiveShadow(
3236 FT->getReturnType(), LabelLoad, CB.
getIterator()));
3237 if (ShouldTrackOrigins) {
3238 LoadInst *OriginLoad =
3239 IRB.
CreateLoad(DFSF.DFS.OriginTy, DFSF.OriginReturnAlloca);
3240 DFSF.setOrigin(CustomCI, OriginLoad);
3252 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3253 uint32_t OrderingTable[NumOrderings] = {};
3255 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3256 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3257 OrderingTable[(int)AtomicOrderingCABI::consume] =
3258 (
int)AtomicOrderingCABI::acquire;
3259 OrderingTable[(int)AtomicOrderingCABI::release] =
3260 OrderingTable[(
int)AtomicOrderingCABI::acq_rel] =
3261 (int)AtomicOrderingCABI::acq_rel;
3262 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3263 (
int)AtomicOrderingCABI::seq_cst;
3268void DFSanVisitor::visitLibAtomicLoad(CallBase &CB) {
3279 Value *NewOrdering =
3284 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3290 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3291 {DstPtr, SrcPtr, NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3295 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
3296 uint32_t OrderingTable[NumOrderings] = {};
3298 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
3299 OrderingTable[(
int)AtomicOrderingCABI::release] =
3300 (int)AtomicOrderingCABI::release;
3301 OrderingTable[(int)AtomicOrderingCABI::consume] =
3302 OrderingTable[(
int)AtomicOrderingCABI::acquire] =
3303 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
3304 (
int)AtomicOrderingCABI::acq_rel;
3305 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
3306 (
int)AtomicOrderingCABI::seq_cst;
3311void DFSanVisitor::visitLibAtomicStore(CallBase &CB) {
3319 Value *NewOrdering =
3327 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3328 {DstPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3331void DFSanVisitor::visitLibAtomicExchange(CallBase &CB) {
3347 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3348 {DstPtr, TargetPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3352 DFSF.DFS.DFSanMemShadowOriginTransferFn,
3353 {TargetPtr, SrcPtr, IRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3356void DFSanVisitor::visitLibAtomicCompareExchange(CallBase &CB) {
3370 NextIRB.SetCurrentDebugLocation(CB.
getDebugLoc());
3372 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3376 CallInst *CI = NextIRB.CreateCall(
3377 DFSF.DFS.DFSanMemShadowOriginConditionalExchangeFn,
3378 {NextIRB.CreateIntCast(&CB, NextIRB.getInt8Ty(), false), TargetPtr,
3379 ExpectedPtr, DesiredPtr,
3380 NextIRB.CreateIntCast(Size, DFSF.DFS.IntptrTy, false)});
3384void DFSanVisitor::visitCallBase(CallBase &CB) {
3387 visitInstOperands(CB);
3397 if (LF != NotLibFunc) {
3402 case LibFunc_atomic_load:
3404 llvm::errs() <<
"DFSAN -- cannot instrument invoke of libatomic load. "
3408 visitLibAtomicLoad(CB);
3410 case LibFunc_atomic_store:
3411 visitLibAtomicStore(CB);
3419 if (
F &&
F->hasName() && !
F->isVarArg()) {
3420 if (
F->getName() ==
"__atomic_exchange") {
3421 visitLibAtomicExchange(CB);
3424 if (
F->getName() ==
"__atomic_compare_exchange") {
3425 visitLibAtomicCompareExchange(CB);
3431 if (UnwrappedFnIt != DFSF.DFS.UnwrappedFnMap.end())
3432 if (visitWrappedCallBase(*UnwrappedFnIt->second, CB))
3437 const bool ShouldTrackOrigins = DFSF.DFS.shouldTrackOrigins();
3439 const DataLayout &
DL = getDataLayout();
3442 unsigned ArgOffset = 0;
3443 for (
unsigned I = 0,
N = FT->getNumParams();
I !=
N; ++
I) {
3444 if (ShouldTrackOrigins) {
3447 if (
I < DFSF.DFS.NumOfElementsInArgOrgTLS &&
3448 !DFSF.DFS.isZeroShadow(ArgShadow))
3450 DFSF.getArgOriginTLS(
I, IRB));
3454 DL.getTypeAllocSize(DFSF.DFS.getShadowTy(FT->getParamType(
I)));
3460 DFSF.getArgTLS(FT->getParamType(
I), ArgOffset, IRB),
3468 if (
II->getNormalDest()->getSinglePredecessor()) {
3469 Next = &
II->getNormalDest()->front();
3486 unsigned Size =
DL.getTypeAllocSize(DFSF.DFS.getShadowTy(&CB));
3489 DFSF.setShadow(&CB, DFSF.DFS.getZeroShadow(&CB));
3491 LoadInst *LI = NextIRB.CreateAlignedLoad(
3492 DFSF.DFS.getShadowTy(&CB), DFSF.getRetvalTLS(CB.
getType(), NextIRB),
3494 DFSF.SkipInsts.
insert(LI);
3495 DFSF.setShadow(&CB, LI);
3496 DFSF.NonZeroChecks.push_back(LI);
3499 if (ShouldTrackOrigins) {
3500 LoadInst *LI = NextIRB.CreateLoad(DFSF.DFS.OriginTy,
3501 DFSF.getRetvalOriginTLS(),
"_dfsret_o");
3502 DFSF.SkipInsts.
insert(LI);
3503 DFSF.setOrigin(&CB, LI);
3506 DFSF.addReachesFunctionCallbacksIfEnabled(NextIRB, CB, &CB);
3510void DFSanVisitor::visitPHINode(PHINode &PN) {
3511 Type *ShadowTy = DFSF.DFS.getShadowTy(&PN);
3517 for (BasicBlock *BB : PN.
blocks())
3520 DFSF.setShadow(&PN, ShadowPN);
3522 PHINode *OriginPN =
nullptr;
3523 if (DFSF.DFS.shouldTrackOrigins()) {
3527 for (BasicBlock *BB : PN.
blocks())
3529 DFSF.setOrigin(&PN, OriginPN);
3532 DFSF.PHIFixups.push_back({&PN, ShadowPN, OriginPN});
3545 if (!DataFlowSanitizer(ABIListFiles, FS).
runImpl(M, GetTLI))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isConstant(const MachineInstr &MI)
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< 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 cl::opt< bool > ClAddGlobalNameSuffix("dfsan-add-global-name-suffix", cl::desc("Whether to add .dfsan suffix to global names"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClTrackSelectControlFlow("dfsan-track-select-control-flow", cl::desc("Propagate labels from condition values of select instructions " "to results."), cl::Hidden, cl::init(true))
static cl::list< std::string > ClCombineTaintLookupTables("dfsan-combine-taint-lookup-table", cl::desc("When dfsan-combine-offset-labels-on-gep and/or " "dfsan-combine-pointer-labels-on-load are false, this flag can " "be used to re-enable combining offset and/or pointer taint when " "loading specific constant global variables (i.e. lookup tables)."), cl::Hidden)
static const Align MinOriginAlignment
static cl::opt< int > ClTrackOrigins("dfsan-track-origins", cl::desc("Track origins of labels"), cl::Hidden, cl::init(0))
static cl::list< std::string > ClABIListFiles("dfsan-abilist", cl::desc("File listing native ABI functions and how the pass treats them"), cl::Hidden)
static cl::opt< bool > ClReachesFunctionCallbacks("dfsan-reaches-function-callbacks", cl::desc("Insert calls to callback functions on data reaching a function."), cl::Hidden, cl::init(false))
static Value * expandFromPrimitiveShadowRecursive(Value *Shadow, SmallVector< unsigned, 4 > &Indices, Type *SubShadowTy, Value *PrimitiveShadow, IRBuilder<> &IRB)
static cl::opt< int > ClInstrumentWithCallThreshold("dfsan-instrument-with-call-threshold", cl::desc("If the function being instrumented requires more than " "this number of origin stores, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(3500))
static cl::opt< bool > ClPreserveAlignment("dfsan-preserve-alignment", cl::desc("respect alignment requirements provided by input IR"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClDebugNonzeroLabels("dfsan-debug-nonzero-labels", cl::desc("Insert calls to __dfsan_nonzero_label on observing a parameter, " "load or return with a nonzero label"), cl::Hidden)
static cl::opt< bool > ClCombineOffsetLabelsOnGEP("dfsan-combine-offset-labels-on-gep", cl::desc("Combine the label of the offset with the label of the pointer when " "doing pointer arithmetic."), cl::Hidden, cl::init(true))
static cl::opt< bool > ClIgnorePersonalityRoutine("dfsan-ignore-personality-routine", cl::desc("If a personality routine is marked uninstrumented from the ABI " "list, do not create a wrapper for it."), cl::Hidden, cl::init(false))
static const Align ShadowTLSAlignment
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
const MemoryMapParams Linux_S390X_MemoryMapParams
static AtomicOrdering addAcquireOrdering(AtomicOrdering AO)
Value * StripPointerGEPsAndCasts(Value *V)
const MemoryMapParams Linux_AArch64_MemoryMapParams
static cl::opt< bool > ClConditionalCallbacks("dfsan-conditional-callbacks", cl::desc("Insert calls to callback functions on conditionals."), cl::Hidden, cl::init(false))
static cl::opt< bool > ClCombinePointerLabelsOnLoad("dfsan-combine-pointer-labels-on-load", cl::desc("Combine the label of the pointer with the label of the data when " "loading from memory."), cl::Hidden, cl::init(true))
static StringRef getGlobalTypeString(const GlobalValue &G)
static cl::opt< bool > ClCombinePointerLabelsOnStore("dfsan-combine-pointer-labels-on-store", cl::desc("Combine the label of the pointer with the label of the data when " "storing in memory."), cl::Hidden, cl::init(false))
static const unsigned ArgTLSSize
static const unsigned RetvalTLSSize
static bool isAMustTailRetVal(Value *RetVal)
static cl::opt< bool > ClEventCallbacks("dfsan-event-callbacks", cl::desc("Insert calls to __dfsan_*_callback functions on data events."), cl::Hidden, cl::init(false))
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
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)
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< UseNode * > Use
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
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.