diff options
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp | 73 |
1 files changed, 50 insertions, 23 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp index 194d77c00ab..b3c31f5d53b 100644 --- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -3318,9 +3318,11 @@ struct VarArgAMD64Helper : public VarArgHelper { assert(A->getType()->isPointerTy()); Type *RealTy = A->getType()->getPointerElementType(); uint64_t ArgSize = DL.getTypeAllocSize(RealTy); - Value *ShadowBase = - getShadowPtrForVAArgument(RealTy, IRB, OverflowOffset); + Value *ShadowBase = getShadowPtrForVAArgument( + RealTy, IRB, OverflowOffset, alignTo(ArgSize, 8)); OverflowOffset += alignTo(ArgSize, 8); + if (!ShadowBase) + continue; Value *ShadowPtr, *OriginPtr; std::tie(ShadowPtr, OriginPtr) = MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), kShadowTLSAlignment, @@ -3337,11 +3339,13 @@ struct VarArgAMD64Helper : public VarArgHelper { Value *ShadowBase; switch (AK) { case AK_GeneralPurpose: - ShadowBase = getShadowPtrForVAArgument(A->getType(), IRB, GpOffset); + ShadowBase = + getShadowPtrForVAArgument(A->getType(), IRB, GpOffset, 8); GpOffset += 8; break; case AK_FloatingPoint: - ShadowBase = getShadowPtrForVAArgument(A->getType(), IRB, FpOffset); + ShadowBase = + getShadowPtrForVAArgument(A->getType(), IRB, FpOffset, 16); FpOffset += 16; break; case AK_Memory: @@ -3349,13 +3353,15 @@ struct VarArgAMD64Helper : public VarArgHelper { continue; uint64_t ArgSize = DL.getTypeAllocSize(A->getType()); ShadowBase = - getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset); + getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset, 8); OverflowOffset += alignTo(ArgSize, 8); } // Take fixed arguments into account for GpOffset and FpOffset, // but don't actually store shadows for them. if (IsFixed) continue; + if (!ShadowBase) + continue; IRB.CreateAlignedStore(MSV.getShadow(A), ShadowBase, kShadowTLSAlignment); } @@ -3367,7 +3373,10 @@ struct VarArgAMD64Helper : public VarArgHelper { /// Compute the shadow address for a given va_arg. Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB, - int ArgOffset) { + unsigned ArgOffset, unsigned ArgSize) { + // Make sure we don't overflow __msan_va_arg_tls. + if (ArgOffset + ArgSize > kParamTLSSize) + return nullptr; Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy); Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0), @@ -3483,9 +3492,11 @@ struct VarArgMIPS64Helper : public VarArgHelper { if (ArgSize < 8) VAArgOffset += (8 - ArgSize); } - Base = getShadowPtrForVAArgument(A->getType(), IRB, VAArgOffset); + Base = getShadowPtrForVAArgument(A->getType(), IRB, VAArgOffset, ArgSize); VAArgOffset += ArgSize; VAArgOffset = alignTo(VAArgOffset, 8); + if (!Base) + continue; IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment); } @@ -3497,7 +3508,10 @@ struct VarArgMIPS64Helper : public VarArgHelper { /// Compute the shadow address for a given va_arg. Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB, - int ArgOffset) { + unsigned ArgOffset, unsigned ArgSize) { + // Make sure we don't overflow __msan_va_arg_tls. + if (ArgOffset + ArgSize > kParamTLSSize) + return nullptr; Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy); Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0), @@ -3628,11 +3642,11 @@ struct VarArgAArch64Helper : public VarArgHelper { Value *Base; switch (AK) { case AK_GeneralPurpose: - Base = getShadowPtrForVAArgument(A->getType(), IRB, GrOffset); + Base = getShadowPtrForVAArgument(A->getType(), IRB, GrOffset, 8); GrOffset += 8; break; case AK_FloatingPoint: - Base = getShadowPtrForVAArgument(A->getType(), IRB, VrOffset); + Base = getShadowPtrForVAArgument(A->getType(), IRB, VrOffset, 8); VrOffset += 16; break; case AK_Memory: @@ -3641,7 +3655,8 @@ struct VarArgAArch64Helper : public VarArgHelper { if (IsFixed) continue; uint64_t ArgSize = DL.getTypeAllocSize(A->getType()); - Base = getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset); + Base = getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset, + alignTo(ArgSize, 8)); OverflowOffset += alignTo(ArgSize, 8); break; } @@ -3649,6 +3664,8 @@ struct VarArgAArch64Helper : public VarArgHelper { // bother to actually store a shadow. if (IsFixed) continue; + if (!Base) + continue; IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment); } Constant *OverflowSize = @@ -3658,7 +3675,10 @@ struct VarArgAArch64Helper : public VarArgHelper { /// Compute the shadow address for a given va_arg. Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB, - int ArgOffset) { + unsigned ArgOffset, unsigned ArgSize) { + // Make sure we don't overflow __msan_va_arg_tls. + if (ArgOffset + ArgSize > kParamTLSSize) + return nullptr; Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy); Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0), @@ -3863,14 +3883,17 @@ struct VarArgPowerPC64Helper : public VarArgHelper { ArgAlign = 8; VAArgOffset = alignTo(VAArgOffset, ArgAlign); if (!IsFixed) { - Value *Base = getShadowPtrForVAArgument(RealTy, IRB, - VAArgOffset - VAArgBase); - Value *AShadowPtr, *AOriginPtr; - std::tie(AShadowPtr, AOriginPtr) = MSV.getShadowOriginPtr( - A, IRB, IRB.getInt8Ty(), kShadowTLSAlignment, /*isStore*/ false); - - IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr, - kShadowTLSAlignment, ArgSize); + Value *Base = getShadowPtrForVAArgument( + RealTy, IRB, VAArgOffset - VAArgBase, ArgSize); + if (Base) { + Value *AShadowPtr, *AOriginPtr; + std::tie(AShadowPtr, AOriginPtr) = + MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), + kShadowTLSAlignment, /*isStore*/ false); + + IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr, + kShadowTLSAlignment, ArgSize); + } } VAArgOffset += alignTo(ArgSize, 8); } else { @@ -3898,8 +3921,9 @@ struct VarArgPowerPC64Helper : public VarArgHelper { } if (!IsFixed) { Base = getShadowPtrForVAArgument(A->getType(), IRB, - VAArgOffset - VAArgBase); - IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment); + VAArgOffset - VAArgBase, ArgSize); + if (Base) + IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment); } VAArgOffset += ArgSize; VAArgOffset = alignTo(VAArgOffset, 8); @@ -3917,7 +3941,10 @@ struct VarArgPowerPC64Helper : public VarArgHelper { /// Compute the shadow address for a given va_arg. Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB, - int ArgOffset) { + unsigned ArgOffset, unsigned ArgSize) { + // Make sure we don't overflow __msan_va_arg_tls. + if (ArgOffset + ArgSize > kParamTLSSize) + return nullptr; Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy); Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0), |