119 using namespace llvm;
121 #define DEBUG_TYPE "msan"
139 cl::desc(
"Track origins (allocation sites) of poisoned memory"),
142 cl::desc(
"keep going after reporting a UMR"),
145 cl::desc(
"poison uninitialized stack variables"),
148 cl::desc(
"poison uninitialized stack variables with a call"),
151 cl::desc(
"poison uninitialized stack variables with the given patter"),
158 cl::desc(
"propagate shadow through ICmpEQ and ICmpNE"),
162 cl::desc(
"exact handling of relational integer ICmp"),
172 cl::desc(
"report accesses through a pointer which has poisoned shadow"),
176 cl::desc(
"print out instructions with default strict semantics"),
180 "msan-instrumentation-with-call-threshold",
182 "If the function being instrumented requires more than "
183 "this number of checks and origin stores, use callbacks instead of "
184 "inline checks (-1 means never use callbacks)."),
191 cl::desc(
"Insert checks for constant shadow values"),
203 struct MemoryMapParams {
210 struct PlatformMemoryMapParams {
211 const MemoryMapParams *bits32;
212 const MemoryMapParams *bits64;
216 static const MemoryMapParams Linux_I386_MemoryMapParams = {
224 static const MemoryMapParams Linux_X86_64_MemoryMapParams = {
232 static const MemoryMapParams Linux_MIPS64_MemoryMapParams = {
240 static const MemoryMapParams Linux_PowerPC64_MemoryMapParams = {
248 static const MemoryMapParams FreeBSD_I386_MemoryMapParams = {
256 static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams = {
263 static const PlatformMemoryMapParams Linux_X86_MemoryMapParams = {
264 &Linux_I386_MemoryMapParams,
265 &Linux_X86_64_MemoryMapParams,
268 static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams = {
270 &Linux_MIPS64_MemoryMapParams,
273 static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams = {
275 &Linux_PowerPC64_MemoryMapParams,
278 static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams = {
279 &FreeBSD_I386_MemoryMapParams,
280 &FreeBSD_X86_64_MemoryMapParams,
290 MemorySanitizer(
int TrackOrigins = 0)
293 WarningFn(
nullptr) {}
294 const char *getPassName()
const override {
return "MemorySanitizer"; }
295 bool runOnFunction(
Function &
F)
override;
296 bool doInitialization(
Module &M)
override;
300 void initializeCallbacks(
Module &M);
334 Value *MsanSetAllocaOrigin4Fn;
336 Value *MsanPoisonStackFn;
339 Value *MsanChainOriginFn;
341 Value *MemmoveFn, *MemcpyFn, *MemsetFn;
344 const MemoryMapParams *MapParams;
348 MDNode *OriginStoreWeights;
353 friend struct MemorySanitizerVisitor;
354 friend struct VarArgAMD64Helper;
355 friend struct VarArgMIPS64Helper;
361 "MemorySanitizer: detects uninitialized reads.",
365 return new MemorySanitizer(TrackOrigins);
382 void MemorySanitizer::initializeCallbacks(
Module &M) {
392 :
"__msan_warning_noreturn";
397 unsigned AccessSize = 1 << AccessSizeIndex;
398 std::string FunctionName =
"__msan_maybe_warning_" +
itostr(AccessSize);
400 FunctionName, IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8),
401 IRB.getInt32Ty(),
nullptr);
403 FunctionName =
"__msan_maybe_store_origin_" +
itostr(AccessSize);
405 FunctionName, IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8),
406 IRB.getInt8PtrTy(), IRB.getInt32Ty(),
nullptr);
410 "__msan_set_alloca_origin4", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy,
411 IRB.getInt8PtrTy(), IntptrTy,
nullptr);
414 IRB.getInt8PtrTy(), IntptrTy,
nullptr);
416 "__msan_chain_origin", IRB.getInt32Ty(), IRB.getInt32Ty(),
nullptr);
418 "__msan_memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
419 IRB.getInt8PtrTy(), IntptrTy,
nullptr);
421 "__msan_memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
424 "__msan_memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(),
451 "__msan_va_arg_overflow_size_tls",
nullptr,
466 bool MemorySanitizer::doInitialization(
Module &M) {
470 switch (TargetTriple.getOS()) {
472 switch (TargetTriple.getArch()) {
474 MapParams = FreeBSD_X86_MemoryMapParams.bits64;
477 MapParams = FreeBSD_X86_MemoryMapParams.bits32;
484 switch (TargetTriple.getArch()) {
486 MapParams = Linux_X86_MemoryMapParams.bits64;
489 MapParams = Linux_X86_MemoryMapParams.bits32;
493 MapParams = Linux_MIPS_MemoryMapParams.bits64;
497 MapParams = Linux_PowerPC_MemoryMapParams.bits64;
509 IntptrTy = IRB.getIntPtrTy(DL);
510 OriginTy = IRB.getInt32Ty();
515 std::tie(MsanCtorFunction, std::ignore) =
524 IRB.getInt32(TrackOrigins),
"__msan_track_origins");
543 struct VarArgHelper {
557 virtual void finalizeInstrumentation() = 0;
559 virtual ~VarArgHelper() {}
562 struct MemorySanitizerVisitor;
565 CreateVarArgHelper(
Function &
Func, MemorySanitizer &Msan,
566 MemorySanitizerVisitor &Visitor);
569 if (TypeSize <= 8)
return 0;
579 struct MemorySanitizerVisitor :
public InstVisitor<MemorySanitizerVisitor> {
584 std::unique_ptr<VarArgHelper> VAHelper;
589 bool PropagateShadow;
592 bool CheckReturnValue;
594 struct ShadowOriginAndInsertPoint {
599 : Shadow(S), Origin(O), OrigIns(I) { }
604 MemorySanitizerVisitor(
Function &
F, MemorySanitizer &MS)
605 : F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)) {
607 InsertChecks = SanitizeFunction;
608 PropagateShadow = SanitizeFunction;
613 CheckReturnValue = SanitizeFunction && (F.
getName() ==
"main");
615 DEBUG(
if (!InsertChecks)
616 dbgs() <<
"MemorySanitizer is not inserting checks into '"
621 if (MS.TrackOrigins <= 1)
return V;
622 return IRB.
CreateCall(MS.MsanChainOriginFn, V);
636 unsigned Size,
unsigned Alignment) {
644 unsigned CurrentAlignment = Alignment;
645 if (Alignment >= IntptrAlignment && IntptrSize >
kOriginSize) {
646 Value *IntptrOrigin = originToIntptr(IRB, Origin);
647 Value *IntptrOriginPtr =
649 for (
unsigned i = 0; i < Size / IntptrSize; ++i) {
654 CurrentAlignment = IntptrAlignment;
667 unsigned Alignment,
bool AsCall) {
671 if (isa<StructType>(Shadow->
getType())) {
672 paintOrigin(IRB, updateOrigin(Origin, IRB),
673 getOriginPtr(Addr, IRB, Alignment), StoreSize,
676 Value *ConvertedShadow = convertToShadowTyNoVec(Shadow, IRB);
677 Constant *ConstantShadow = dyn_cast_or_null<Constant>(ConvertedShadow);
678 if (ConstantShadow) {
680 paintOrigin(IRB, updateOrigin(Origin, IRB),
681 getOriginPtr(Addr, IRB, Alignment), StoreSize,
686 unsigned TypeSizeInBits =
689 if (AsCall && SizeIndex < kNumberOfAccessSizes) {
690 Value *Fn = MS.MaybeStoreOriginFn[SizeIndex];
692 ConvertedShadow, IRB.
getIntNTy(8 * (1 << SizeIndex)));
698 ConvertedShadow, getCleanShadow(ConvertedShadow),
"_mscmp");
702 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew),
703 getOriginPtr(Addr, IRBNew, Alignment), StoreSize,
709 void materializeStores(
bool InstrumentWithCalls) {
710 for (
auto Inst : StoreList) {
716 Value *Shadow = SI.
isAtomic() ? getCleanShadow(Val) : getShadow(Val);
717 Value *ShadowPtr = getShadowPtr(Addr, Shadow->
getType(), IRB);
721 DEBUG(
dbgs() <<
" STORE: " << *NewSI <<
"\n");
728 if (MS.TrackOrigins && !SI.
isAtomic())
729 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), SI.
getAlignment(),
730 InstrumentWithCalls);
737 DEBUG(
dbgs() <<
" SHAD0 : " << *Shadow <<
"\n");
738 Value *ConvertedShadow = convertToShadowTyNoVec(Shadow, IRB);
739 DEBUG(
dbgs() <<
" SHAD1 : " << *ConvertedShadow <<
"\n");
741 Constant *ConstantShadow = dyn_cast_or_null<Constant>(ConvertedShadow);
742 if (ConstantShadow) {
744 if (MS.TrackOrigins) {
761 if (AsCall && SizeIndex < kNumberOfAccessSizes) {
762 Value *Fn = MS.MaybeWarningFn[SizeIndex];
763 Value *ConvertedShadow2 =
765 IRB.
CreateCall(Fn, {ConvertedShadow2, MS.TrackOrigins && Origin
770 getCleanShadow(ConvertedShadow),
"_mscmp");
776 if (MS.TrackOrigins) {
782 DEBUG(
dbgs() <<
" CHECK: " << *Cmp <<
"\n");
786 void materializeChecks(
bool InstrumentWithCalls) {
787 for (
const auto &ShadowData : InstrumentationList) {
789 Value *Shadow = ShadowData.Shadow;
790 Value *Origin = ShadowData.Origin;
791 materializeOneCheck(OrigIns, Shadow, Origin, InstrumentWithCalls);
797 bool runOnFunction() {
814 for (
PHINode *PN : ShadowPHINodes) {
815 PHINode *PNS = cast<PHINode>(getShadow(PN));
816 PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) :
nullptr;
817 size_t NumValues = PN->getNumIncomingValues();
818 for (
size_t v = 0; v < NumValues; v++) {
819 PNS->
addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
820 if (PNO) PNO->addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
824 VAHelper->finalizeInstrumentation();
827 InstrumentationList.size() + StoreList.size() >
832 materializeStores(InstrumentWithCalls);
835 materializeChecks(InstrumentWithCalls);
842 return getShadowTy(V->
getType());
855 if (
VectorType *VT = dyn_cast<VectorType>(OrigTy)) {
857 return VectorType::get(IntegerType::get(*MS.C, EltSize),
858 VT->getNumElements());
860 if (
ArrayType *AT = dyn_cast<ArrayType>(OrigTy)) {
861 return ArrayType::get(getShadowTy(AT->getElementType()),
862 AT->getNumElements());
866 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
867 Elements.
push_back(getShadowTy(
ST->getElementType(i)));
868 StructType *Res = StructType::get(*MS.C, Elements,
ST->isPacked());
869 DEBUG(
dbgs() <<
"getShadowTy: " << *
ST <<
" ===> " << *Res <<
"\n");
873 return IntegerType::get(*MS.C, TypeSize);
878 if (
VectorType *vt = dyn_cast<VectorType>(ty))
879 return IntegerType::get(*MS.C, vt->getBitWidth());
886 Type *NoVecTy = getShadowTyNoVec(Ty);
887 if (Ty == NoVecTy)
return V;
896 uint64_t AndMask = MS.MapParams->AndMask;
897 assert(AndMask != 0 &&
"AndMask shall be specified");
900 ConstantInt::get(MS.IntptrTy, ~AndMask));
902 uint64_t XorMask = MS.MapParams->XorMask;
905 ConstantInt::get(MS.IntptrTy, XorMask));
915 Value *ShadowLong = getShadowPtrOffset(Addr, IRB);
916 uint64_t ShadowBase = MS.MapParams->ShadowBase;
920 ConstantInt::get(MS.IntptrTy, ShadowBase));
921 return IRB.
CreateIntToPtr(ShadowLong, PointerType::get(ShadowTy, 0));
929 Value *OriginLong = getShadowPtrOffset(Addr, IRB);
930 uint64_t OriginBase = MS.MapParams->OriginBase;
934 ConstantInt::get(MS.IntptrTy, OriginBase));
938 ConstantInt::get(MS.IntptrTy, ~Mask));
950 Base = IRB.
CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
951 return IRB.
CreateIntToPtr(Base, PointerType::get(getShadowTy(A), 0),
958 if (!MS.TrackOrigins)
return nullptr;
960 Base = IRB.
CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
968 return IRB.
CreateIntToPtr(Base, PointerType::get(getShadowTy(A), 0),
975 return MS.RetvalOriginTLS;
980 assert(!ShadowMap.count(V) &&
"Values may only have one shadow");
981 ShadowMap[V] = PropagateShadow ? SV : getCleanShadow(V);
986 if (!MS.TrackOrigins)
return;
987 assert(!OriginMap.count(V) &&
"Values may only have one origin");
988 DEBUG(
dbgs() <<
"ORIGIN: " << *V <<
" ==> " << *Origin <<
"\n");
989 OriginMap[V] = Origin;
997 Type *ShadowTy = getShadowTy(V);
1000 return Constant::getNullValue(ShadowTy);
1006 if (isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy))
1007 return Constant::getAllOnesValue(ShadowTy);
1008 if (
ArrayType *AT = dyn_cast<ArrayType>(ShadowTy)) {
1010 getPoisonedShadow(AT->getElementType()));
1011 return ConstantArray::get(AT, Vals);
1015 for (
unsigned i = 0, n =
ST->getNumElements(); i < n; i++)
1016 Vals.
push_back(getPoisonedShadow(
ST->getElementType(i)));
1017 return ConstantStruct::get(
ST, Vals);
1024 Type *ShadowTy = getShadowTy(V);
1027 return getPoisonedShadow(ShadowTy);
1031 Value *getCleanOrigin() {
1032 return Constant::getNullValue(MS.OriginTy);
1040 if (!PropagateShadow)
return getCleanShadow(V);
1043 Value *Shadow = ShadowMap[V];
1045 DEBUG(
dbgs() <<
"No shadow: " << *V <<
"\n" << *(
I->getParent()));
1047 assert(Shadow &&
"No shadow for a value");
1051 if (
UndefValue *U = dyn_cast<UndefValue>(V)) {
1052 Value *AllOnes = PoisonUndef ? getPoisonedShadow(V) : getCleanShadow(V);
1053 DEBUG(
dbgs() <<
"Undef: " << *U <<
" ==> " << *AllOnes <<
"\n");
1057 if (
Argument *A = dyn_cast<Argument>(V)) {
1059 Value **ShadowPtr = &ShadowMap[V];
1064 unsigned ArgOffset = 0;
1066 for (
auto &FArg : F->
args()) {
1067 if (!FArg.getType()->isSized()) {
1077 Value *Base = getShadowPtrForArgument(&FArg, EntryIRB, ArgOffset);
1078 if (FArg.hasByValAttr()) {
1082 unsigned ArgAlign = FArg.getParamAlignment();
1083 if (ArgAlign == 0) {
1089 EntryIRB.CreateMemSet(
1090 getShadowPtr(V, EntryIRB.getInt8Ty(), EntryIRB),
1091 Constant::getNullValue(EntryIRB.getInt8Ty()), Size, ArgAlign);
1094 Value *Cpy = EntryIRB.CreateMemCpy(
1095 getShadowPtr(V, EntryIRB.getInt8Ty(), EntryIRB), Base, Size,
1097 DEBUG(
dbgs() <<
" ByValCpy: " << *Cpy <<
"\n");
1100 *ShadowPtr = getCleanShadow(V);
1104 *ShadowPtr = getCleanShadow(V);
1110 DEBUG(
dbgs() <<
" ARG: " << FArg <<
" ==> " <<
1111 **ShadowPtr <<
"\n");
1112 if (MS.TrackOrigins && !Overflow) {
1114 getOriginPtrForArgument(&FArg, EntryIRB, ArgOffset);
1115 setOrigin(A, EntryIRB.CreateLoad(OriginPtr));
1117 setOrigin(A, getCleanOrigin());
1122 assert(*ShadowPtr &&
"Could not find shadow for an argument");
1126 return getCleanShadow(V);
1136 if (!MS.TrackOrigins)
return nullptr;
1137 if (!PropagateShadow)
return getCleanOrigin();
1138 if (isa<Constant>(V))
return getCleanOrigin();
1139 assert((isa<Instruction>(V) || isa<Argument>(V)) &&
1140 "Unexpected value type in getOrigin()");
1141 Value *Origin = OriginMap[V];
1142 assert(Origin &&
"Missing origin");
1157 if (!InsertChecks)
return;
1160 assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy)) &&
1161 "Can only insert checks for integer and vector shadow types");
1163 InstrumentationList.push_back(
1164 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
1173 Value *Shadow, *Origin;
1175 Shadow = getShadow(Val);
1176 if (!Shadow)
return;
1177 Origin = getOrigin(Val);
1179 Shadow = dyn_cast_or_null<Instruction>(getShadow(Val));
1180 if (!Shadow)
return;
1181 Origin = dyn_cast_or_null<Instruction>(getOrigin(Val));
1183 insertShadowCheck(Shadow, Origin, OrigIns);
1229 Type *ShadowTy = getShadowTy(&I);
1231 if (PropagateShadow && !I.
getMetadata(
"nosanitize")) {
1232 Value *ShadowPtr = getShadowPtr(Addr, ShadowTy, IRB);
1236 setShadow(&I, getCleanShadow(&I));
1245 if (MS.TrackOrigins) {
1246 if (PropagateShadow) {
1252 setOrigin(&I, getCleanOrigin());
1262 StoreList.push_back(&I);
1266 assert(isa<AtomicRMWInst>(I) || isa<AtomicCmpXchgInst>(I));
1270 Value *ShadowPtr = getShadowPtr(Addr, I.
getType(), IRB);
1273 insertShadowCheck(Addr, &I);
1278 if (isa<AtomicCmpXchgInst>(I))
1283 setShadow(&I, getCleanShadow(&I));
1284 setOrigin(&I, getCleanOrigin());
1303 setOrigin(&I, getOrigin(&I, 0));
1311 setOriginForNaryOp(I);
1319 setOriginForNaryOp(I);
1326 setOrigin(&I, getOrigin(&I, 0));
1332 setOrigin(&I, getOrigin(&I, 0));
1338 setOrigin(&I, getOrigin(&I, 0));
1343 setShadow(&I, IRB.
CreateBitCast(getShadow(&I, 0), getShadowTy(&I)));
1344 setOrigin(&I, getOrigin(&I, 0));
1349 setShadow(&I, IRB.
CreateIntCast(getShadow(&I, 0), getShadowTy(&I),
false,
1350 "_msprop_ptrtoint"));
1351 setOrigin(&I, getOrigin(&I, 0));
1356 setShadow(&I, IRB.
CreateIntCast(getShadow(&I, 0), getShadowTy(&I),
false,
1357 "_msprop_inttoptr"));
1358 setOrigin(&I, getOrigin(&I, 0));
1361 void visitFPToSIInst(
CastInst& I) { handleShadowOr(I); }
1362 void visitFPToUIInst(
CastInst& I) { handleShadowOr(I); }
1363 void visitSIToFPInst(
CastInst& I) { handleShadowOr(I); }
1364 void visitUIToFPInst(
CastInst& I) { handleShadowOr(I); }
1365 void visitFPExtInst(
CastInst& I) { handleShadowOr(I); }
1366 void visitFPTruncInst(
CastInst& I) { handleShadowOr(I); }
1380 Value *S1 = getShadow(&I, 0);
1381 Value *S2 = getShadow(&I, 1);
1392 setOriginForNaryOp(I);
1402 Value *S1 = getShadow(&I, 0);
1403 Value *S2 = getShadow(&I, 1);
1414 setOriginForNaryOp(I);
1432 template <
bool CombineShadow>
1437 MemorySanitizerVisitor *MSV;
1440 Combiner(MemorySanitizerVisitor *MSV,
IRBuilder<> &IRB) :
1441 Shadow(nullptr), Origin(nullptr), IRB(IRB), MSV(MSV) {}
1444 Combiner &Add(
Value *OpShadow,
Value *OpOrigin) {
1445 if (CombineShadow) {
1450 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->
getType());
1451 Shadow = IRB.
CreateOr(Shadow, OpShadow,
"_msprop");
1455 if (MSV->MS.TrackOrigins) {
1462 if (!ConstOrigin || !ConstOrigin->
isNullValue()) {
1463 Value *FlatShadow = MSV->convertToShadowTyNoVec(OpShadow, IRB);
1465 IRB.
CreateICmpNE(FlatShadow, MSV->getCleanShadow(FlatShadow));
1474 Combiner &Add(
Value *V) {
1475 Value *OpShadow = MSV->getShadow(V);
1476 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) :
nullptr;
1477 return Add(OpShadow, OpOrigin);
1483 if (CombineShadow) {
1485 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(I));
1486 MSV->setShadow(I, Shadow);
1488 if (MSV->MS.TrackOrigins) {
1490 MSV->setOrigin(I, Origin);
1495 typedef Combiner<true> ShadowAndOriginCombiner;
1496 typedef Combiner<false> OriginCombiner;
1500 if (!MS.TrackOrigins)
return;
1502 OriginCombiner
OC(
this, IRB);
1503 for (Instruction::op_iterator OI = I.
op_begin(); OI != I.
op_end(); ++OI)
1508 size_t VectorOrPrimitiveTypeSizeInBits(
Type *Ty) {
1510 "Vector of pointers is not a valid shadow type");
1526 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
1527 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
1537 Type *ShadowTy = getShadowTy(V);
1549 ShadowAndOriginCombiner
SC(
this, IRB);
1550 for (Instruction::op_iterator OI = I.
op_begin(); OI != I.
op_end(); ++OI)
1572 for (
unsigned Idx = 0; Idx < NumElements; ++Idx) {
1577 Elements.
push_back(ConstantInt::get(EltTy, V2));
1579 ShadowMul = ConstantVector::get(Elements);
1584 ShadowMul = ConstantInt::get(Elt->
getType(),
V2);
1589 IRB.
CreateMul(getShadow(OtherArg), ShadowMul,
"msprop_mul_cst"));
1590 setOrigin(&I, getOrigin(OtherArg));
1596 if (constOp0 && !constOp1)
1597 handleMulByConstant(I, constOp0, I.
getOperand(1));
1598 else if (constOp1 && !constOp0)
1599 handleMulByConstant(I, constOp1, I.
getOperand(0));
1615 setShadow(&I, getShadow(&I, 0));
1616 setOrigin(&I, getOrigin(&I, 0));
1630 void handleEqualityComparison(
ICmpInst &I) {
1634 Value *Sa = getShadow(A);
1635 Value *Sb = getShadow(B);
1654 Value *MinusOne = Constant::getAllOnesValue(Sc->
getType());
1661 setOriginForNaryOp(I);
1703 void handleRelationalComparisonExact(
ICmpInst &I) {
1707 Value *Sa = getShadow(A);
1708 Value *Sb = getShadow(B);
1721 getLowestPossibleValue(IRB, A, Sa, IsSigned),
1722 getHighestPossibleValue(IRB, B, Sb, IsSigned));
1724 getHighestPossibleValue(IRB, A, Sa, IsSigned),
1725 getLowestPossibleValue(IRB, B, Sb, IsSigned));
1728 setOriginForNaryOp(I);
1736 void handleSignedRelationalComparison(
ICmpInst &I) {
1744 }
else if (constOp1 && constOp1->isNullValue() &&
1751 IRB.
CreateICmpSLT(getShadow(op), getCleanShadow(op),
"_msprop_icmpslt");
1752 setShadow(&I, Shadow);
1753 setOrigin(&I, getOrigin(op));
1765 handleEqualityComparison(I);
1771 handleRelationalComparisonExact(I);
1775 handleSignedRelationalComparison(I);
1781 handleRelationalComparisonExact(I);
1796 Value *S1 = getShadow(&I, 0);
1797 Value *S2 = getShadow(&I, 1);
1802 setShadow(&I, IRB.
CreateOr(Shift, S2Conv));
1803 setOriginForNaryOp(I);
1856 VAHelper->visitVAStartInst(I);
1860 VAHelper->visitVACopyInst(I);
1863 enum IntrinsicKind {
1864 IK_DoesNotAccessMemory,
1870 const int DoesNotAccessMemory = IK_DoesNotAccessMemory;
1871 const int OnlyReadsArgumentPointees = IK_OnlyReadsMemory;
1872 const int OnlyReadsMemory = IK_OnlyReadsMemory;
1873 const int OnlyAccessesArgumentPointees = IK_WritesMemory;
1874 const int UnknownModRefBehavior = IK_WritesMemory;
1875 #define GET_INTRINSIC_MODREF_BEHAVIOR
1876 #define ModRefBehavior IntrinsicKind
1877 #include "llvm/IR/Intrinsics.gen"
1878 #undef ModRefBehavior
1879 #undef GET_INTRINSIC_MODREF_BEHAVIOR
1889 Value *Shadow = getShadow(&I, 1);
1890 Value *ShadowPtr = getShadowPtr(Addr, Shadow->
getType(), IRB);
1897 insertShadowCheck(Addr, &I);
1901 if (MS.TrackOrigins)
1902 IRB.
CreateStore(getOrigin(&I, 1), getOriginPtr(Addr, IRB, 1));
1914 Type *ShadowTy = getShadowTy(&I);
1915 if (PropagateShadow) {
1916 Value *ShadowPtr = getShadowPtr(Addr, ShadowTy, IRB);
1921 setShadow(&I, getCleanShadow(&I));
1925 insertShadowCheck(Addr, &I);
1927 if (MS.TrackOrigins) {
1928 if (PropagateShadow)
1929 setOrigin(&I, IRB.
CreateLoad(getOriginPtr(Addr, IRB, 1)));
1931 setOrigin(&I, getCleanOrigin());
1951 for (
unsigned i = 0; i < NumArgOperands; ++i) {
1958 ShadowAndOriginCombiner
SC(
this, IRB);
1959 for (
unsigned i = 0; i < NumArgOperands; ++i)
1978 if (NumArgOperands == 0)
1982 IntrinsicKind IK = getIntrinsicKind(iid);
1983 bool OnlyReadsMemory = IK == IK_OnlyReadsMemory;
1984 bool WritesMemory = IK == IK_WritesMemory;
1985 assert(!(OnlyReadsMemory && WritesMemory));
1987 if (NumArgOperands == 2 &&
1993 return handleVectorStoreIntrinsic(I);
1996 if (NumArgOperands == 1 &&
2001 return handleVectorLoadIntrinsic(I);
2004 if (!OnlyReadsMemory && !WritesMemory)
2005 if (maybeHandleSimpleNomemIntrinsic(I))
2018 setShadow(&I, IRB.
CreateCall(BswapFunc, getShadow(Op)));
2019 setOrigin(&I, getOrigin(Op));
2037 void handleVectorConvertIntrinsic(
IntrinsicInst &I,
int NumUsedElements) {
2039 Value *CopyOp, *ConvertOp;
2043 assert(isa<ConstantInt>(I.
getArgOperand(2)) &&
"Invalid rounding mode");
2063 Value *ConvertShadow = getShadow(ConvertOp);
2064 Value *AggShadow =
nullptr;
2067 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), 0));
2068 for (
int i = 1; i < NumUsedElements; ++i) {
2070 ConvertShadow, ConstantInt::get(IRB.
getInt32Ty(), i));
2071 AggShadow = IRB.
CreateOr(AggShadow, MoreShadow);
2074 AggShadow = ConvertShadow;
2077 insertShadowCheck(AggShadow, getOrigin(ConvertOp), &I);
2084 Value *ResultShadow = getShadow(CopyOp);
2086 for (
int i = 0; i < NumUsedElements; ++i) {
2088 ResultShadow, ConstantInt::getNullValue(EltTy),
2091 setShadow(&I, ResultShadow);
2092 setOrigin(&I, getOrigin(CopyOp));
2094 setShadow(&I, getCleanShadow(&I));
2095 setOrigin(&I, getCleanOrigin());
2103 S = CreateShadowCast(IRB, S, IRB.
getInt64Ty(),
true);
2106 return CreateShadowCast(IRB, S2, T,
true);
2123 void handleVectorShiftIntrinsic(
IntrinsicInst &I,
bool Variable) {
2128 Value *S1 = getShadow(&I, 0);
2129 Value *S2 = getShadow(&I, 1);
2130 Value *S2Conv = Variable ? VariableShadowExtend(IRB, S2)
2131 : Lower64ShadowExtend(IRB, S2, getShadowTy(&I));
2137 setShadow(&I, IRB.
CreateOr(Shift, S2Conv));
2138 setOriginForNaryOp(I);
2142 Type *getMMXVectorTy(
unsigned EltSizeInBits) {
2143 const unsigned X86_MMXSizeInBits = 64;
2144 return VectorType::get(IntegerType::get(*MS.C, EltSizeInBits),
2145 X86_MMXSizeInBits / EltSizeInBits);
2152 case llvm::Intrinsic::x86_sse2_packsswb_128:
2153 case llvm::Intrinsic::x86_sse2_packuswb_128:
2154 return llvm::Intrinsic::x86_sse2_packsswb_128;
2156 case llvm::Intrinsic::x86_sse2_packssdw_128:
2157 case llvm::Intrinsic::x86_sse41_packusdw:
2158 return llvm::Intrinsic::x86_sse2_packssdw_128;
2160 case llvm::Intrinsic::x86_avx2_packsswb:
2161 case llvm::Intrinsic::x86_avx2_packuswb:
2162 return llvm::Intrinsic::x86_avx2_packsswb;
2164 case llvm::Intrinsic::x86_avx2_packssdw:
2165 case llvm::Intrinsic::x86_avx2_packusdw:
2166 return llvm::Intrinsic::x86_avx2_packssdw;
2168 case llvm::Intrinsic::x86_mmx_packsswb:
2169 case llvm::Intrinsic::x86_mmx_packuswb:
2170 return llvm::Intrinsic::x86_mmx_packsswb;
2172 case llvm::Intrinsic::x86_mmx_packssdw:
2173 return llvm::Intrinsic::x86_mmx_packssdw;
2186 void handleVectorPackIntrinsic(
IntrinsicInst &I,
unsigned EltSizeInBits = 0) {
2190 Value *S1 = getShadow(&I, 0);
2191 Value *S2 = getShadow(&I, 1);
2197 Type *T = isX86_MMX ? getMMXVectorTy(EltSizeInBits) : S1->
getType();
2207 Type *X86_MMXTy = Type::getX86_MMXTy(*MS.C);
2216 IRB.
CreateCall(ShadowFn, {S1_ext, S2_ext},
"_msprop_vector_pack");
2219 setOriginForNaryOp(I);
2224 const unsigned SignificantBitsPerResultElement = 16;
2226 Type *ResTy = isX86_MMX ? IntegerType::get(*MS.C, 64) : I.
getType();
2227 unsigned ZeroBitsPerResultElement =
2231 Value *S = IRB.
CreateOr(getShadow(&I, 0), getShadow(&I, 1));
2235 S = IRB.
CreateLShr(S, ZeroBitsPerResultElement);
2238 setOriginForNaryOp(I);
2243 unsigned EltSizeInBits = 0) {
2245 Type *ResTy = isX86_MMX ? getMMXVectorTy(EltSizeInBits * 2) : I.
getType();
2247 Value *S = IRB.
CreateOr(getShadow(&I, 0), getShadow(&I, 1));
2253 setOriginForNaryOp(I);
2258 case llvm::Intrinsic::bswap:
2261 case llvm::Intrinsic::x86_avx512_cvtsd2usi64:
2262 case llvm::Intrinsic::x86_avx512_cvtsd2usi:
2263 case llvm::Intrinsic::x86_avx512_cvtss2usi64:
2264 case llvm::Intrinsic::x86_avx512_cvtss2usi:
2265 case llvm::Intrinsic::x86_avx512_cvttss2usi64:
2266 case llvm::Intrinsic::x86_avx512_cvttss2usi:
2267 case llvm::Intrinsic::x86_avx512_cvttsd2usi64:
2268 case llvm::Intrinsic::x86_avx512_cvttsd2usi:
2269 case llvm::Intrinsic::x86_avx512_cvtusi2sd:
2270 case llvm::Intrinsic::x86_avx512_cvtusi2ss:
2271 case llvm::Intrinsic::x86_avx512_cvtusi642sd:
2272 case llvm::Intrinsic::x86_avx512_cvtusi642ss:
2273 case llvm::Intrinsic::x86_sse2_cvtsd2si64:
2274 case llvm::Intrinsic::x86_sse2_cvtsd2si:
2275 case llvm::Intrinsic::x86_sse2_cvtsd2ss:
2276 case llvm::Intrinsic::x86_sse2_cvtsi2sd:
2277 case llvm::Intrinsic::x86_sse2_cvtsi642sd:
2278 case llvm::Intrinsic::x86_sse2_cvtss2sd:
2279 case llvm::Intrinsic::x86_sse2_cvttsd2si64:
2280 case llvm::Intrinsic::x86_sse2_cvttsd2si:
2281 case llvm::Intrinsic::x86_sse_cvtsi2ss:
2282 case llvm::Intrinsic::x86_sse_cvtsi642ss:
2283 case llvm::Intrinsic::x86_sse_cvtss2si64:
2284 case llvm::Intrinsic::x86_sse_cvtss2si:
2285 case llvm::Intrinsic::x86_sse_cvttss2si64:
2286 case llvm::Intrinsic::x86_sse_cvttss2si:
2287 handleVectorConvertIntrinsic(I, 1);
2289 case llvm::Intrinsic::x86_sse2_cvtdq2pd:
2290 case llvm::Intrinsic::x86_sse2_cvtps2pd:
2291 case llvm::Intrinsic::x86_sse_cvtps2pi:
2292 case llvm::Intrinsic::x86_sse_cvttps2pi:
2293 handleVectorConvertIntrinsic(I, 2);
2295 case llvm::Intrinsic::x86_avx2_psll_w:
2296 case llvm::Intrinsic::x86_avx2_psll_d:
2297 case llvm::Intrinsic::x86_avx2_psll_q:
2298 case llvm::Intrinsic::x86_avx2_pslli_w:
2299 case llvm::Intrinsic::x86_avx2_pslli_d:
2300 case llvm::Intrinsic::x86_avx2_pslli_q:
2301 case llvm::Intrinsic::x86_avx2_psrl_w:
2302 case llvm::Intrinsic::x86_avx2_psrl_d:
2303 case llvm::Intrinsic::x86_avx2_psrl_q:
2304 case llvm::Intrinsic::x86_avx2_psra_w:
2305 case llvm::Intrinsic::x86_avx2_psra_d:
2306 case llvm::Intrinsic::x86_avx2_psrli_w:
2307 case llvm::Intrinsic::x86_avx2_psrli_d:
2308 case llvm::Intrinsic::x86_avx2_psrli_q:
2309 case llvm::Intrinsic::x86_avx2_psrai_w:
2310 case llvm::Intrinsic::x86_avx2_psrai_d:
2311 case llvm::Intrinsic::x86_sse2_psll_w:
2312 case llvm::Intrinsic::x86_sse2_psll_d:
2313 case llvm::Intrinsic::x86_sse2_psll_q:
2314 case llvm::Intrinsic::x86_sse2_pslli_w:
2315 case llvm::Intrinsic::x86_sse2_pslli_d:
2316 case llvm::Intrinsic::x86_sse2_pslli_q:
2317 case llvm::Intrinsic::x86_sse2_psrl_w:
2318 case llvm::Intrinsic::x86_sse2_psrl_d:
2319 case llvm::Intrinsic::x86_sse2_psrl_q:
2320 case llvm::Intrinsic::x86_sse2_psra_w:
2321 case llvm::Intrinsic::x86_sse2_psra_d:
2322 case llvm::Intrinsic::x86_sse2_psrli_w:
2323 case llvm::Intrinsic::x86_sse2_psrli_d:
2324 case llvm::Intrinsic::x86_sse2_psrli_q:
2325 case llvm::Intrinsic::x86_sse2_psrai_w:
2326 case llvm::Intrinsic::x86_sse2_psrai_d:
2327 case llvm::Intrinsic::x86_mmx_psll_w:
2328 case llvm::Intrinsic::x86_mmx_psll_d:
2329 case llvm::Intrinsic::x86_mmx_psll_q:
2330 case llvm::Intrinsic::x86_mmx_pslli_w:
2331 case llvm::Intrinsic::x86_mmx_pslli_d:
2332 case llvm::Intrinsic::x86_mmx_pslli_q:
2333 case llvm::Intrinsic::x86_mmx_psrl_w:
2334 case llvm::Intrinsic::x86_mmx_psrl_d:
2335 case llvm::Intrinsic::x86_mmx_psrl_q:
2336 case llvm::Intrinsic::x86_mmx_psra_w:
2337 case llvm::Intrinsic::x86_mmx_psra_d:
2338 case llvm::Intrinsic::x86_mmx_psrli_w:
2339 case llvm::Intrinsic::x86_mmx_psrli_d:
2340 case llvm::Intrinsic::x86_mmx_psrli_q:
2341 case llvm::Intrinsic::x86_mmx_psrai_w:
2342 case llvm::Intrinsic::x86_mmx_psrai_d:
2343 handleVectorShiftIntrinsic(I,
false);
2345 case llvm::Intrinsic::x86_avx2_psllv_d:
2346 case llvm::Intrinsic::x86_avx2_psllv_d_256:
2347 case llvm::Intrinsic::x86_avx2_psllv_q:
2348 case llvm::Intrinsic::x86_avx2_psllv_q_256:
2349 case llvm::Intrinsic::x86_avx2_psrlv_d:
2350 case llvm::Intrinsic::x86_avx2_psrlv_d_256:
2351 case llvm::Intrinsic::x86_avx2_psrlv_q:
2352 case llvm::Intrinsic::x86_avx2_psrlv_q_256:
2353 case llvm::Intrinsic::x86_avx2_psrav_d:
2354 case llvm::Intrinsic::x86_avx2_psrav_d_256:
2355 handleVectorShiftIntrinsic(I,
true);
2358 case llvm::Intrinsic::x86_sse2_packsswb_128:
2359 case llvm::Intrinsic::x86_sse2_packssdw_128:
2360 case llvm::Intrinsic::x86_sse2_packuswb_128:
2361 case llvm::Intrinsic::x86_sse41_packusdw:
2362 case llvm::Intrinsic::x86_avx2_packsswb:
2363 case llvm::Intrinsic::x86_avx2_packssdw:
2364 case llvm::Intrinsic::x86_avx2_packuswb:
2365 case llvm::Intrinsic::x86_avx2_packusdw:
2366 handleVectorPackIntrinsic(I);
2369 case llvm::Intrinsic::x86_mmx_packsswb:
2370 case llvm::Intrinsic::x86_mmx_packuswb:
2371 handleVectorPackIntrinsic(I, 16);
2374 case llvm::Intrinsic::x86_mmx_packssdw:
2375 handleVectorPackIntrinsic(I, 32);
2378 case llvm::Intrinsic::x86_mmx_psad_bw:
2379 case llvm::Intrinsic::x86_sse2_psad_bw:
2380 case llvm::Intrinsic::x86_avx2_psad_bw:
2381 handleVectorSadIntrinsic(I);
2384 case llvm::Intrinsic::x86_sse2_pmadd_wd:
2385 case llvm::Intrinsic::x86_avx2_pmadd_wd:
2386 case llvm::Intrinsic::x86_ssse3_pmadd_ub_sw_128:
2387 case llvm::Intrinsic::x86_avx2_pmadd_ub_sw:
2388 handleVectorPmaddIntrinsic(I);
2391 case llvm::Intrinsic::x86_ssse3_pmadd_ub_sw:
2392 handleVectorPmaddIntrinsic(I, 8);
2395 case llvm::Intrinsic::x86_mmx_pmadd_wd:
2396 handleVectorPmaddIntrinsic(I, 16);
2400 if (!handleUnknownIntrinsic(I))
2401 visitInstruction(I);
2408 assert((CS.
isCall() || CS.
isInvoke()) &&
"Unknown type of CallSite");
2416 visitInstruction(I);
2420 assert(!isa<IntrinsicInst>(&I) &&
"intrinsics are handled elsewhere");
2431 Func->removeAttributes(AttributeSet::FunctionIndex,
2432 AttributeSet::get(
Func->getContext(),
2433 AttributeSet::FunctionIndex,
2439 unsigned ArgOffset = 0;
2440 DEBUG(
dbgs() <<
" CallSite: " << I <<
"\n");
2442 ArgIt != End; ++ArgIt) {
2446 DEBUG(
dbgs() <<
"Arg " << i <<
" is not sized: " << I <<
"\n");
2454 Value *ArgShadow = getShadow(A);
2455 Value *ArgShadowBase = getShadowPtrForArgument(A, IRB, ArgOffset);
2456 DEBUG(
dbgs() <<
" Arg#" << i <<
": " << *A <<
2457 " Shadow: " << *ArgShadow <<
"\n");
2458 bool ArgIsInitialized =
false;
2462 "ByVal argument is not a pointer!");
2464 if (ArgOffset + Size > kParamTLSSize)
break;
2468 getShadowPtr(A, Type::getInt8Ty(*MS.C), IRB),
2472 if (ArgOffset + Size > kParamTLSSize)
break;
2476 if (Cst && Cst->
isNullValue()) ArgIsInitialized =
true;
2478 if (MS.TrackOrigins && !ArgIsInitialized)
2480 getOriginPtrForArgument(A, IRB, ArgOffset));
2482 assert(Size != 0 && Store !=
nullptr);
2483 DEBUG(
dbgs() <<
" Param:" << *Store <<
"\n");
2486 DEBUG(
dbgs() <<
" done with call args\n");
2491 VAHelper->visitCallSite(CS, IRB);
2498 Value *Base = getShadowPtrForRetval(&I, IRBBefore);
2504 BasicBlock *NormalDest = cast<InvokeInst>(&
I)->getNormalDest();
2509 setShadow(&I, getCleanShadow(&I));
2510 setOrigin(&I, getCleanOrigin());
2515 "Could not find insertion point for retval shadow load");
2518 Value *RetvalShadow =
2519 IRBAfter.CreateAlignedLoad(getShadowPtrForRetval(&I, IRBAfter),
2521 setShadow(&I, RetvalShadow);
2522 if (MS.TrackOrigins)
2523 setOrigin(&I, IRBAfter.CreateLoad(getOriginPtrForRetval(IRBAfter)));
2529 if (!RetVal)
return;
2530 Value *ShadowPtr = getShadowPtrForRetval(RetVal, IRB);
2531 if (CheckReturnValue) {
2532 insertShadowCheck(RetVal, &I);
2533 Value *Shadow = getCleanShadow(RetVal);
2536 Value *Shadow = getShadow(RetVal);
2539 if (MS.TrackOrigins)
2540 IRB.
CreateStore(getOrigin(RetVal), getOriginPtrForRetval(IRB));
2544 void visitPHINode(
PHINode &I) {
2546 if (!PropagateShadow) {
2547 setShadow(&I, getCleanShadow(&I));
2548 setOrigin(&I, getCleanOrigin());
2552 ShadowPHINodes.push_back(&I);
2555 if (MS.TrackOrigins)
2561 setShadow(&I, getCleanShadow(&I));
2562 setOrigin(&I, getCleanOrigin());
2569 ConstantInt::get(MS.IntptrTy, Size)});
2571 Value *ShadowBase = getShadowPtr(&I, Type::getInt8PtrTy(*MS.C), IRB);
2576 if (PoisonStack && MS.TrackOrigins) {
2587 StackDescription.str());
2591 ConstantInt::get(MS.IntptrTy, Size),
2603 Value *Sb = getShadow(B);
2604 Value *Sc = getShadow(C);
2605 Value *Sd = getShadow(D);
2614 Sa1 = getPoisonedShadow(getShadowTy(I.
getType()));
2622 C = CreateAppToShadowCast(IRB, C);
2623 D = CreateAppToShadowCast(IRB, D);
2630 if (MS.TrackOrigins) {
2636 ConstantInt::getNullValue(FlatTy));
2638 ConstantInt::getNullValue(FlatTy));
2652 setShadow(&I, getCleanShadow(&I));
2653 setOrigin(&I, getCleanOrigin());
2663 DEBUG(
dbgs() <<
"ExtractValue: " << I <<
"\n");
2664 Value *AggShadow = getShadow(Agg);
2665 DEBUG(
dbgs() <<
" AggShadow: " << *AggShadow <<
"\n");
2667 DEBUG(
dbgs() <<
" ResShadow: " << *ResShadow <<
"\n");
2668 setShadow(&I, ResShadow);
2669 setOriginForNaryOp(I);
2674 DEBUG(
dbgs() <<
"InsertValue: " << I <<
"\n");
2677 DEBUG(
dbgs() <<
" AggShadow: " << *AggShadow <<
"\n");
2678 DEBUG(
dbgs() <<
" InsShadow: " << *InsShadow <<
"\n");
2680 DEBUG(
dbgs() <<
" Res: " << *Res <<
"\n");
2682 setOriginForNaryOp(I);
2686 if (
CallInst *CI = dyn_cast<CallInst>(&I)) {
2687 errs() <<
"ZZZ call " << CI->getCalledFunction()->getName() <<
"\n";
2691 errs() <<
"QQQ " << I <<
"\n";
2695 DEBUG(
dbgs() <<
"Resume: " << I <<
"\n");
2703 DEBUG(
dbgs() <<
"DEFAULT: " << I <<
"\n");
2706 setShadow(&I, getCleanShadow(&I));
2707 setOrigin(&I, getCleanOrigin());
2712 struct VarArgAMD64Helper :
public VarArgHelper {
2715 static const unsigned AMD64GpEndOffset = 48;
2716 static const unsigned AMD64FpEndOffset = 176;
2719 MemorySanitizer &MS;
2720 MemorySanitizerVisitor &MSV;
2721 Value *VAArgTLSCopy;
2722 Value *VAArgOverflowSize;
2726 VarArgAMD64Helper(
Function &F, MemorySanitizer &MS,
2727 MemorySanitizerVisitor &MSV)
2728 : F(F), MS(MS), MSV(MSV), VAArgTLSCopy(nullptr),
2729 VAArgOverflowSize(nullptr) {}
2731 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
2733 ArgKind classifyArgument(
Value* arg) {
2737 return AK_FloatingPoint;
2739 return AK_GeneralPurpose;
2741 return AK_GeneralPurpose;
2754 unsigned GpOffset = 0;
2755 unsigned FpOffset = AMD64GpEndOffset;
2756 unsigned OverflowOffset = AMD64FpEndOffset;
2759 ArgIt != End; ++ArgIt) {
2762 bool IsByVal = CS.
paramHasAttr(ArgNo + 1, Attribute::ByVal);
2768 Value *Base = getShadowPtrForVAArgument(RealTy, IRB, OverflowOffset);
2773 ArgKind AK = classifyArgument(A);
2774 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
2776 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
2780 case AK_GeneralPurpose:
2781 Base = getShadowPtrForVAArgument(A->
getType(), IRB, GpOffset);
2784 case AK_FloatingPoint:
2785 Base = getShadowPtrForVAArgument(A->
getType(), IRB, FpOffset);
2790 Base = getShadowPtrForVAArgument(A->
getType(), IRB, OverflowOffset);
2797 ConstantInt::get(IRB.
getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
2798 IRB.
CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
2805 Base = IRB.
CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
2806 return IRB.
CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0),
2812 VAStartInstrumentationList.push_back(&I);
2814 Value *ShadowPtr = MSV.getShadowPtr(VAListTag, IRB.
getInt8Ty(), IRB);
2822 void visitVACopyInst(
VACopyInst &I)
override {
2825 Value *ShadowPtr = MSV.getShadowPtr(VAListTag, IRB.
getInt8Ty(), IRB);
2833 void finalizeInstrumentation()
override {
2834 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
2835 "finalizeInstrumentation called twice");
2836 if (!VAStartInstrumentationList.empty()) {
2840 VAArgOverflowSize = IRB.
CreateLoad(MS.VAArgOverflowSizeTLS);
2842 IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset),
2844 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
2845 IRB.
CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8);
2850 for (
size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) {
2851 CallInst *OrigInst = VAStartInstrumentationList[i];
2855 Value *RegSaveAreaPtrPtr =
2858 ConstantInt::get(MS.IntptrTy, 16)),
2859 Type::getInt64PtrTy(*MS.C));
2861 Value *RegSaveAreaShadowPtr =
2862 MSV.getShadowPtr(RegSaveAreaPtr, IRB.
getInt8Ty(), IRB);
2864 AMD64FpEndOffset, 16);
2866 Value *OverflowArgAreaPtrPtr =
2869 ConstantInt::get(MS.IntptrTy, 8)),
2870 Type::getInt64PtrTy(*MS.C));
2872 Value *OverflowArgAreaShadowPtr =
2873 MSV.getShadowPtr(OverflowArgAreaPtr, IRB.
getInt8Ty(), IRB);
2876 IRB.
CreateMemCpy(OverflowArgAreaShadowPtr, SrcPtr, VAArgOverflowSize, 16);
2882 struct VarArgMIPS64Helper :
public VarArgHelper {
2884 MemorySanitizer &MS;
2885 MemorySanitizerVisitor &MSV;
2886 Value *VAArgTLSCopy;
2891 VarArgMIPS64Helper(
Function &F, MemorySanitizer &MS,
2892 MemorySanitizerVisitor &MSV)
2893 : F(F), MS(MS), MSV(MSV), VAArgTLSCopy(nullptr),
2894 VAArgSize(nullptr) {}
2897 unsigned VAArgOffset = 0;
2899 for (CallSite::arg_iterator ArgIt = CS.
arg_begin() + 1, End = CS.
arg_end();
2900 ArgIt != End; ++ArgIt) {
2904 #if defined(__MIPSEB__) || defined(MIPSEB)
2908 VAArgOffset += (8 - ArgSize);
2910 Base = getShadowPtrForVAArgument(A->
getType(), IRB, VAArgOffset);
2911 VAArgOffset += ArgSize;
2919 IRB.
CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
2926 Base = IRB.
CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
2927 return IRB.
CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0),
2933 VAStartInstrumentationList.push_back(&I);
2935 Value *ShadowPtr = MSV.getShadowPtr(VAListTag, IRB.
getInt8Ty(), IRB);
2940 void visitVACopyInst(
VACopyInst &I)
override {
2943 Value *ShadowPtr = MSV.getShadowPtr(VAListTag, IRB.
getInt8Ty(), IRB);
2950 void finalizeInstrumentation()
override {
2951 assert(!VAArgSize && !VAArgTLSCopy &&
2952 "finalizeInstrumentation called twice");
2954 VAArgSize = IRB.
CreateLoad(MS.VAArgOverflowSizeTLS);
2955 Value *CopySize = IRB.
CreateAdd(ConstantInt::get(MS.IntptrTy, 0),
2958 if (!VAStartInstrumentationList.empty()) {
2961 VAArgTLSCopy = IRB.
CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
2962 IRB.
CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8);
2967 for (
size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) {
2968 CallInst *OrigInst = VAStartInstrumentationList[i];
2971 Value *RegSaveAreaPtrPtr =
2973 Type::getInt64PtrTy(*MS.C));
2975 Value *RegSaveAreaShadowPtr =
2976 MSV.getShadowPtr(RegSaveAreaPtr, IRB.
getInt8Ty(), IRB);
2977 IRB.
CreateMemCpy(RegSaveAreaShadowPtr, VAArgTLSCopy, CopySize, 8);
2983 struct VarArgNoOpHelper :
public VarArgHelper {
2984 VarArgNoOpHelper(
Function &F, MemorySanitizer &MS,
2985 MemorySanitizerVisitor &MSV) {}
2991 void visitVACopyInst(
VACopyInst &I)
override {}
2993 void finalizeInstrumentation()
override {}
2996 VarArgHelper *CreateVarArgHelper(
Function &
Func, MemorySanitizer &Msan,
2997 MemorySanitizerVisitor &Visitor) {
3002 return new VarArgAMD64Helper(Func, Msan, Visitor);
3005 return new VarArgMIPS64Helper(Func, Msan, Visitor);
3007 return new VarArgNoOpHelper(Func, Msan, Visitor);
3012 bool MemorySanitizer::runOnFunction(
Function &F) {
3013 if (&F == MsanCtorFunction)
3015 MemorySanitizerVisitor Visitor(F, *
this);
3023 AttributeSet::FunctionIndex, B));
3025 return Visitor.runOnFunction();
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
ReturnInst - Return a value (possibly void), from a function.
Value * getValueOperand()
const Value * getCalledValue() const
getCalledValue - Get a pointer to the function that is invoked by this instruction.
iplist< Instruction >::iterator eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing basic block and deletes it...
void push_back(const T &Elt)
unsigned Log2_32_Ceil(uint32_t Value)
Log2_32_Ceil - This function returns the ceil log base 2 of the specified value, 32 if the value is z...
A parsed version of the target data layout string in and methods for querying it. ...
IntegerType * getType() const
getType - Specialize the getType() method to always return an IntegerType, which reduces the amount o...
AllocaInst * CreateAlloca(Type *Ty, Value *ArraySize=nullptr, const Twine &Name="")
static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
getString - This method constructs a CDS and initializes it with a text string.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
BasicBlock::iterator GetInsertPoint() const
LoadInst * CreateLoad(Value *Ptr, const char *Name)
void addIncoming(Value *V, BasicBlock *BB)
addIncoming - Add an incoming value to the end of the PHI list
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
LLVM Argument representation.
Base class for instruction visitors.
Value * getAggregateOperand()
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Type * getSequentialElementType() const
ArrayRef< unsigned > getIndices() const
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
A Module instance is used to store all the information related to an LLVM module. ...
void setOrdering(AtomicOrdering Ordering)
Set the ordering constraint on this RMW.
AtomicOrdering getSuccessOrdering() const
Returns the ordering constraint on this cmpxchg.
InstrTy * getInstruction() const
Same, but only replaced by something equivalent.
Intrinsic::ID getIntrinsicID() const
getIntrinsicID - Return the intrinsic ID of this intrinsic.
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
AtomicCmpXchgInst - an instruction that atomically checks whether a specified value is in a memory lo...
static cl::opt< int > ClPoisonStackPattern("msan-poison-stack-pattern", cl::desc("poison uninitialized stack variables with the given patter"), cl::Hidden, cl::init(0xff))
static cl::opt< bool > ClPoisonStackWithCall("msan-poison-stack-with-call", cl::desc("poison uninitialized stack variables with a call"), cl::Hidden, cl::init(false))
This class represents zero extension of integer types.
unsigned getNumOperands() const
static const unsigned kRetvalTLSSize
void appendToGlobalCtors(Module &M, Function *F, int Priority)
Append F to the list of global ctors of module M with the given Priority.
CallInst - This class represents a function call, abstracting a target machine's calling convention...
void setOrdering(AtomicOrdering Ordering)
Set the ordering constraint on this load.
TerminatorInst * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr)
SplitBlockAndInsertIfThen - Split the containing block at the specified instruction - everything befo...
static PointerType * get(Type *ElementType, unsigned AddressSpace)
PointerType::get - This constructs a pointer to an object of the specified type in a numbered address...
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
bool isSigned() const
Determine if this instruction is using a signed comparison.
Like Internal, but omit from symbol table.
ShuffleVectorInst - This instruction constructs a fixed permutation of two input vectors.
Externally visible function.
A raw_ostream that writes to an SmallVector or SmallString.
bool isPtrOrPtrVectorTy() const
isPtrOrPtrVectorTy - Return true if this is a pointer type or a vector of pointer types...
MemSetInst - This class wraps the llvm.memset intrinsic.
static bool isEquality(Predicate P)
isEquality - Return true if this predicate is either EQ or NE.
This class represents a sign extension of integer types.
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memset to the specified pointer and the specified value.
LoadInst - an instruction for reading from memory.
FunctionType * getType(LLVMContext &Context, ID id, ArrayRef< Type * > Tys=None)
Return the function type for an intrinsic.
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
AtomicRMWInst - an instruction that atomically reads a memory location, combines it with another valu...
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
static cl::opt< bool > ClHandleICmp("msan-handle-icmp", cl::desc("propagate shadow through ICmpEQ and ICmpNE"), cl::Hidden, cl::init(true))
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
Reports a serious error, calling any installed error handler.
Type * getPointerElementType() const
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Value * CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx, const Twine &Name="")
static Constant * getNullValue(Type *Ty)
StringRef getName() const
Return a constant reference to the value's name.
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
static cl::opt< bool > ClDumpStrictInstructions("msan-dump-strict-instructions", cl::desc("print out instructions with default strict semantics"), cl::Hidden, cl::init(false))
SelectInst - This class represents the LLVM 'select' instruction.
Value * getReturnValue() const
Convenience accessor. Returns null if there is no return value.
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::ZeroOrMore, cl::values(clEnumValN(DefaultIT,"arm-default-it","Generate IT block based on arch"), clEnumValN(RestrictedIT,"arm-restrict-it","Disallow deprecated IT based on ARMv8"), clEnumValN(NoRestrictedIT,"arm-no-restrict-it","Allow IT blocks based on ARMv7"), clEnumValEnd))
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
This is the base class for all instructions that perform data casts.
const APInt & getValue() const
Return the constant as an APInt value reference.
NodeTy * getNextNode()
Get the next node, or 0 for the list tail.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
UndefValue - 'undef' values are things that do not have specified contents.
MemMoveInst - This class wraps the llvm.memmove intrinsic.
StructType - Class to represent struct types.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
static cl::opt< bool > ClCheckAccessAddress("msan-check-access-address", cl::desc("report accesses through a pointer which has poisoned shadow"), cl::Hidden, cl::init(true))
unsigned getNumArgOperands() const
getNumArgOperands - Return the number of call arguments.
Instruction * getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
bool isSized(SmallPtrSetImpl< const Type * > *Visited=nullptr) const
isSized - Return true if it makes sense to take the size of this type.
Number of individual test Apply this number of consecutive mutations to each input exit after the first new interesting input is found the minimized corpus is saved into the first input directory Number of jobs to run If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
void setName(const Twine &Name)
Change the name of the value.
Type * getVectorElementType() const
uint16_t getParamAlignment(uint16_t i) const
Extract the alignment for a call or parameter (0=unknown).
This class represents a cast from a pointer to an integer.
FunctionType - Class to represent function types.
void dumpInst(Value *base, char *instName)
AtomicOrdering getOrdering() const
Returns the ordering constraint on this RMW.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
VAStartInst - This represents the llvm.va_start intrinsic.
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
static const char *const kMsanInitName
ValTy * getCalledValue() const
getCalledValue - Return the pointer to function that is being called.
static cl::opt< int > ClTrackOrigins("msan-track-origins", cl::desc("Track origins (allocation sites) of poisoned memory"), cl::Hidden, cl::init(0))
Track origins of uninitialized values.
ArrayType - Class to represent array types.
This instruction compares its operands according to the predicate given to the constructor.
This class represents a no-op cast from one type to another.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
FunctionType::get - This static method is the primary way of constructing a FunctionType.
Value * getInsertedValueOperand()
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
StoreInst - an instruction for storing to memory.
static const unsigned kParamTLSSize
Value * CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name="")
static cl::opt< bool > ClPoisonStack("msan-poison-stack", cl::desc("poison uninitialized stack variables"), cl::Hidden, cl::init(true))
void removeAttributes(unsigned i, AttributeSet attr)
removes the attributes from the list of attributes.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
const char * getOpcodeName() const
This class represents a truncation of integer types.
bool isAtomic() const
isAtomic - Return true if this instruction has an AtomicOrdering of unordered or higher.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
FunctionPass * createMemorySanitizerPass(int TrackOrigins=0)
unsigned getNumIncomingValues() const
getNumIncomingValues - Return the number of incoming edges
static const unsigned kMinOriginAlignment
GetElementPtrInst - an instruction for type-safe pointer arithmetic to access elements of arrays and ...
bool isX86_MMXTy() const
isX86_MMXTy - Return true if this is X86 MMX.
bool isIntOrIntVectorTy() const
isIntOrIntVectorTy - Return true if this is an integer type or a vector of integer types...
initializer< Ty > init(const Ty &Val)
InsertElementInst - This instruction inserts a single (scalar) element into a VectorType value...
LandingPadInst - The landingpad instruction holds all of the information necessary to generate correc...
unsigned getAlignment() const
getAlignment - Return the alignment of the access that is being performed
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeSet AttributeList)
Look up the specified function in the module symbol table.
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
unsigned getArgumentNo(Value::const_user_iterator I) const
Given a value use iterator, returns the argument that corresponds to it.
bool isVectorTy() const
isVectorTy - True if this is an instance of VectorType.
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Type * getContainedType(unsigned i) const
getContainedType - This method is used to implement the type iterator (defined at the end of the file...
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
This is an important base class in LLVM.
const Value * getCondition() const
ResumeInst - Resume the propagation of an exception.
unsigned getAlignment() const
getAlignment - Return the alignment of the memory that is being allocated by the instruction.
bool isZeroValue() const
Return true if the value is negative zero or null value.
This instruction compares its operands according to the predicate given to the constructor.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
FunctionPass class - This class is used to implement most global optimizations.
static const unsigned kShadowTLSAlignment
Value * getOperand(unsigned i) const
Value * getPointerOperand()
Class to represent integer types.
Predicate getPredicate() const
Return the predicate for this instruction.
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Constant * getAggregateElement(unsigned Elt) const
getAggregateElement - For aggregates (struct/array/vector) return the constant that corresponds to th...
This class represents a cast from an integer to a pointer.
bool isPointerTy() const
isPointerTy - True if this is an instance of PointerType.
static std::string itostr(int64_t X)
CallInst * CreateCall(Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="")
bool isFPOrFPVectorTy() const
isFPOrFPVectorTy - Return true if this is a FP type or a vector of FP.
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, unsigned Align, bool isVolatile=false)
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
LoadInst * CreateAlignedLoad(Value *Ptr, unsigned Align, const char *Name)
const Value * getTrueValue() const
Triple - Helper class for working with autoconf configuration names.
bool isRelational() const
isRelational - Return true if the predicate is relational (not EQ or NE).
unsigned countTrailingZeros() const
Count the number of trailing zero bits.
BinaryOps getOpcode() const
unsigned getABITypeAlignment(Type *Ty) const
Returns the minimum ABI-required alignment for the specified type.
AtomicOrdering getOrdering() const
Returns the ordering effect of this store.
This is the shared class of boolean and integer constants.
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
unsigned getVectorNumElements() const
bool paramHasAttr(unsigned i, Attribute::AttrKind A) const
Return true if the call or the callee has the given attribute.
unsigned getScalarSizeInBits() const LLVM_READONLY
getScalarSizeInBits - If this is a vector type, return the getPrimitiveSizeInBits value for the eleme...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
MDNode * getMetadata(unsigned KindID) const
getMetadata - Get the metadata of given kind attached to this Instruction.
static cl::opt< int > ClInstrumentationWithCallThreshold("msan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented requires more than ""this number of checks and origin stores, use callbacks instead of ""inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(3500))
CHAIN = SC CHAIN, Imm128 - System call.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
MemCpyInst - This class wraps the llvm.memcpy intrinsic.
Function * getCalledFunction() const
getCalledFunction - Return the function called, or null if this is an indirect function invocation...
AtomicOrdering getOrdering() const
Returns the ordering effect of this fence.
const BasicBlock & getEntryBlock() const
bool isNullValue() const
isNullValue - Return true if this is the value that would be returned by getNullValue.
static const size_t kNumberOfAccessSizes
static GlobalVariable * createPrivateNonConstGlobalForString(Module &M, StringRef Str)
Create a non-const global initialized with the given string.
static cl::opt< bool > ClKeepGoing("msan-keep-going", cl::desc("keep going after reporting a UMR"), cl::Hidden, cl::init(false))
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
VectorType - Class to represent vector types.
Class for arbitrary precision integers.
bool isIntegerTy() const
isIntegerTy - True if this is an instance of IntegerType.
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="")
BasicBlock * getSinglePredecessor()
Return the predecessor of this block if it has a single predecessor block.
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool isInlineAsm() const
isInlineAsm - Check if this call is an inline asm statement.
uint64_t RoundUpToAlignment(uint64_t Value, uint64_t Align)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
const Type * getScalarType() const LLVM_READONLY
getScalarType - If this is a vector type, return the element type, otherwise return 'this'...
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
void setOrdering(AtomicOrdering Ordering)
Set the ordering constraint on this store.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
static cl::opt< bool > ClHandleICmpExact("msan-handle-icmp-exact", cl::desc("exact handling of relational integer ICmp"), cl::Hidden, cl::init(false))
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isAggregateType() const
isAggregateType - Return true if the type is an aggregate type.
CallInst * CreateMemCpy(Value *Dst, Value *Src, uint64_t Size, unsigned Align, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *TBAAStructTag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memcpy between the specified pointers.
INITIALIZE_PASS(MemorySanitizer,"msan","MemorySanitizer: detects uninitialized reads.", false, false) FunctionPass *llvm
unsigned getAlignment() const
getAlignment - Return the alignment of the access that is being performed
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
static ArrayType * get(Type *ElementType, uint64_t NumElements)
ArrayType::get - This static method is the primary way to construct an ArrayType. ...
std::pair< Function *, Function * > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs)
Creates sanitizer constructor function, and calls sanitizer's init function from it.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT)
InlineAsm::get - Return the specified uniqued inline asm string.
uint64_t getTypeStoreSize(Type *Ty) const
Returns the maximum number of bytes that may be overwritten by storing the specified type...
static cl::opt< bool > ClCheckConstantShadow("msan-check-constant-shadow", cl::desc("Insert checks for constant shadow values"), cl::Hidden, cl::init(false))
static const unsigned kOriginSize
iterator_range< df_iterator< T > > depth_first(const T &G)
bool isUnsigned() const
Determine if this instruction is using an unsigned comparison.
VACopyInst - This represents the llvm.va_copy intrinsic.
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
getPrimitiveSizeInBits - Return the basic size of this type if it is a primitive type.
void setSuccessOrdering(AtomicOrdering Ordering)
Set the ordering constraint on this cmpxchg.
Module * getParent()
Get the module that this global value is contained inside of...
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
LLVM Value Representation.
uint64_t getTypeSizeInBits(Type *Ty) const
Size examples:
static cl::opt< bool > ClPoisonUndef("msan-poison-undef", cl::desc("poison undef temps"), cl::Hidden, cl::init(true))
IterTy arg_begin() const
arg_begin/arg_end - Return iterators corresponding to the actual argument list for a call site...
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
C - The default llvm calling convention, compatible with C.
const Value * getFalseValue() const
StringRef - Represent a constant reference to a string, i.e.
bool removeUnreachableBlocks(Function &F)
Remove all blocks that can not be reached from the function's entry.
iterator getFirstInsertionPt()
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
bool isInvoke() const
isInvoke - true if a InvokeInst is enclosed.
Type * getAllocatedType() const
getAllocatedType - Return the type that is being allocated by the instruction.
bool isCall() const
isCall - true if a CallInst is enclosed.
Value * getPointerOperand()
static const char *const kMsanModuleCtorName
iterator_range< arg_iterator > args()
IntrinsicInst - A useful wrapper class for inspecting calls to intrinsic functions.
LLVMContext & getContext() const
Get the global data context.
bool isVoidTy() const
isVoidTy - Return true if this is 'void'.
AllocaInst - an instruction to allocate memory on the stack.
InsertValueInst - This instruction inserts a struct field of array element value into an aggregate va...