Index: Transforms/Instrumentation/MemorySanitizer.cpp =================================================================== --- Transforms/Instrumentation/MemorySanitizer.cpp +++ Transforms/Instrumentation/MemorySanitizer.cpp @@ -118,6 +118,7 @@ using namespace llvm; #define DEBUG_TYPE "msan" +#define SANITIZER_ANDROID 1 static const unsigned kOriginSize = 4; static const unsigned kMinOriginAlignment = 4; @@ -125,7 +126,9 @@ // These constants must be kept in sync with the ones in msan.h. static const unsigned kParamTLSSize = 800; +#if !SANITIZER_ANDROID static const unsigned kRetvalTLSSize = 800; +#endif // !SANITIZER_ANDROID // Accesses sizes are powers of two: 1, 2, 4, 8. static const size_t kNumberOfAccessSizes = 4; @@ -333,6 +336,16 @@ LLVMContext *C; Type *IntptrTy; Type *OriginTy; + +#if SANITIZER_ANDROID + Value *ParamTLSFn; + Value *ParamOriginTLSFn; + Value *RetvalTLSFn; + Value *RetvalOriginTLSFn; + Value *VAArgTLSFn; + Value *VAArgOverflowSizeTLSFn; + Value *OriginTLSFn; +#else /// \brief Thread-local shadow storage for function parameters. GlobalVariable *ParamTLS; /// \brief Thread-local origin storage for function parameters. @@ -350,6 +363,7 @@ /// \brief Thread-local space used to pass origin value to the UMR reporting /// function. GlobalVariable *OriginTLS; +#endif // SANITIZER_ANDROID /// \brief The run-time callback to print a warning. Value *WarningFn; @@ -458,6 +472,22 @@ IntptrTy, nullptr); // Create globals. +#if SANITIZER_ANDROID + RetvalTLSFn = M.getOrInsertFunction( + "get__msan_retval_tls0", Type::getInt64PtrTy(*C), nullptr); + RetvalOriginTLSFn = M.getOrInsertFunction( + "get__msan_retval_origin_tls0", Type::getInt32PtrTy(*C), nullptr); + ParamTLSFn = M.getOrInsertFunction( + "get__msan_param_tls0", Type::getInt64PtrTy(*C), nullptr); + ParamOriginTLSFn = M.getOrInsertFunction( + "get__msan_param_origin_tls0", Type::getInt32PtrTy(*C), nullptr); + VAArgTLSFn = M.getOrInsertFunction( + "get__msan_va_arg_tls0", Type::getInt64PtrTy(*C), nullptr); + VAArgOverflowSizeTLSFn = M.getOrInsertFunction( + "get__msan_va_arg_overflow_size_tls0", Type::getInt64PtrTy(*C), nullptr); + OriginTLSFn = M.getOrInsertFunction( + "get__msan_origin_tls0", Type::getInt32PtrTy(*C), nullptr); +#else RetvalTLS = new GlobalVariable( M, ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8), false, GlobalVariable::ExternalLinkage, nullptr, "__msan_retval_tls", nullptr, @@ -465,7 +495,6 @@ RetvalOriginTLS = new GlobalVariable( M, OriginTy, false, GlobalVariable::ExternalLinkage, nullptr, "__msan_retval_origin_tls", nullptr, GlobalVariable::InitialExecTLSModel); - ParamTLS = new GlobalVariable( M, ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), false, GlobalVariable::ExternalLinkage, nullptr, "__msan_param_tls", nullptr, @@ -474,7 +503,6 @@ M, ArrayType::get(OriginTy, kParamTLSSize / 4), false, GlobalVariable::ExternalLinkage, nullptr, "__msan_param_origin_tls", nullptr, GlobalVariable::InitialExecTLSModel); - VAArgTLS = new GlobalVariable( M, ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), false, GlobalVariable::ExternalLinkage, nullptr, "__msan_va_arg_tls", nullptr, @@ -486,6 +514,7 @@ OriginTLS = new GlobalVariable( M, IRB.getInt32Ty(), false, GlobalVariable::ExternalLinkage, nullptr, "__msan_origin_tls", nullptr, GlobalVariable::InitialExecTLSModel); +#endif // SANITIZER_ANDROID // We insert an empty inline asm after __msan_report* to avoid callback merge. EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), @@ -787,8 +816,13 @@ if (ConstantShadow) { if (ClCheckConstantShadow && !ConstantShadow->isZeroValue()) { if (MS.TrackOrigins) { +#if SANITIZER_ANDROID IRB.CreateStore(Origin ? (Value *)Origin : (Value *)IRB.getInt32(0), + IRB.CreateCall(MS.OriginTLSFn, {})); +#else + IRB.CreateStore(Origin ? (Value *)Origin : (Value *)IRB.getInt32(0), MS.OriginTLS); +#endif // SANITIZER_ANDROID } IRB.CreateCall(MS.WarningFn, {}); IRB.CreateCall(MS.EmptyAsm, {}); @@ -819,8 +853,13 @@ IRB.SetInsertPoint(CheckTerm); if (MS.TrackOrigins) { +#if SANITIZER_ANDROID IRB.CreateStore(Origin ? (Value *)Origin : (Value *)IRB.getInt32(0), + IRB.CreateCall(MS.OriginTLSFn, {})); +#else + IRB.CreateStore(Origin ? (Value *)Origin : (Value *)IRB.getInt32(0), MS.OriginTLS); +#endif } IRB.CreateCall(MS.WarningFn, {}); IRB.CreateCall(MS.EmptyAsm, {}); @@ -992,7 +1031,11 @@ /// Shadow = ParamTLS+ArgOffset. Value *getShadowPtrForArgument(Value *A, IRBuilder<> &IRB, int ArgOffset) { +#if SANITIZER_ANDROID + Value *Base = IRB.CreatePointerCast(IRB.CreateCall(MS.ParamTLSFn, {}), MS.IntptrTy); +#else Value *Base = IRB.CreatePointerCast(MS.ParamTLS, MS.IntptrTy); +#endif // SANITIZER_ANDROID Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); return IRB.CreateIntToPtr(Base, PointerType::get(getShadowTy(A), 0), "_msarg"); @@ -1002,7 +1045,11 @@ Value *getOriginPtrForArgument(Value *A, IRBuilder<> &IRB, int ArgOffset) { if (!MS.TrackOrigins) return nullptr; +#if SANITIZER_ANDROID + Value *Base = IRB.CreatePointerCast(IRB.CreateCall(MS.ParamOriginTLSFn, {}), MS.IntptrTy); +#else Value *Base = IRB.CreatePointerCast(MS.ParamOriginTLS, MS.IntptrTy); +#endif // SANITIZER_ANDROID Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); return IRB.CreateIntToPtr(Base, PointerType::get(MS.OriginTy, 0), "_msarg_o"); @@ -1010,7 +1057,11 @@ /// \brief Compute the shadow address for a retval. Value *getShadowPtrForRetval(Value *A, IRBuilder<> &IRB) { +#if SANITIZER_ANDROID + Value *Base = IRB.CreatePointerCast(IRB.CreateCall(MS.RetvalTLSFn, {}), MS.IntptrTy); +#else Value *Base = IRB.CreatePointerCast(MS.RetvalTLS, MS.IntptrTy); +#endif // SANITIZER_ANDROID return IRB.CreateIntToPtr(Base, PointerType::get(getShadowTy(A), 0), "_msret"); } @@ -1018,7 +1069,11 @@ /// \brief Compute the origin address for a retval. Value *getOriginPtrForRetval(IRBuilder<> &IRB) { // We keep a single origin for the entire retval. Might be too optimistic. +#if SANITIZER_ANDROID + return IRB.CreateCall(MS.RetvalOriginTLSFn, {}); +#else return MS.RetvalOriginTLS; +#endif // SANITIZER_ANDROID } /// \brief Set SV to be the shadow value for V. @@ -2948,13 +3003,21 @@ } Constant *OverflowSize = ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AMD64FpEndOffset); +#if SANITIZER_ANDROID + IRB.CreateStore(OverflowSize, IRB.CreateCall(MS.VAArgOverflowSizeTLSFn, {})); +#else IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS); +#endif // SANITIZER_ANDROID } /// \brief Compute the shadow address for a given va_arg. Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB, int ArgOffset) { +#if SANITIZER_ANDROID + Value *Base = IRB.CreatePointerCast(IRB.CreateCall(MS.VAArgTLSFn, {}), MS.IntptrTy); +#else Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy); +#endif // SANITIZER_ANDROID Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0), "_msarg"); @@ -2994,12 +3057,20 @@ // If there is a va_start in this function, make a backup copy of // va_arg_tls somewhere in the function entry block. IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); +#if SANITIZER_ANDROID + VAArgOverflowSize = IRB.CreateLoad(IRB.CreateCall(MS.VAArgOverflowSizeTLSFn, {})); +#else VAArgOverflowSize = IRB.CreateLoad(MS.VAArgOverflowSizeTLS); +#endif // SANITIZER_ANDROID Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize); VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize); +#if SANITIZER_ANDROID + IRB.CreateMemCpy(VAArgTLSCopy, IRB.CreateCall(MS.VAArgTLSFn, {}), CopySize, 8); +#else IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8); +#endif // SANITIZER_ANDROID } // Instrument va_start. @@ -3075,13 +3146,21 @@ Constant *TotalVAArgSize = ConstantInt::get(IRB.getInt64Ty(), VAArgOffset); // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of // a new class member i.e. it is the total size of all VarArgs. +#if SANITIZER_ANDROID + IRB.CreateStore(TotalVAArgSize, IRB.CreateCall(MS.VAArgOverflowSizeTLSFn, {})); +#else IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS); +#endif // SANITIZER_ANDROID } /// \brief Compute the shadow address for a given va_arg. Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB, int ArgOffset) { +#if SANITIZER_ANDROID + Value *Base = IRB.CreatePointerCast(IRB.CreateCall(MS.VAArgTLSFn, {}), MS.IntptrTy); +#else Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy); +#endif // SANITIZER_ANDROID Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0), "_msarg"); @@ -3110,7 +3189,11 @@ assert(!VAArgSize && !VAArgTLSCopy && "finalizeInstrumentation called twice"); IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); +#if SANITIZER_ANDROID + VAArgSize = IRB.CreateLoad(IRB.CreateCall(MS.VAArgOverflowSizeTLSFn, {})); +#else VAArgSize = IRB.CreateLoad(MS.VAArgOverflowSizeTLS); +#endif // SANITIZER_ANDROID Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize); @@ -3118,7 +3201,11 @@ // If there is a va_start in this function, make a backup copy of // va_arg_tls somewhere in the function entry block. VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize); +#if SANITIZER_ANDROID + IRB.CreateMemCpy(VAArgTLSCopy, IRB.CreateCall(MS.VAArgTLSFn, {}), CopySize, 8); +#else IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8); +#endif // SANITIZER_ANDROID } // Instrument va_start. @@ -3230,13 +3317,21 @@ } Constant *OverflowSize = ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AArch64VAEndOffset); +#if SANITIZER_ANDROID + IRB.CreateStore(OverflowSize, IRB.CreateCall(MS.VAArgOverflowSizeTLSFn, {})); +#else IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS); +#endif // SANITIZER_ANDROID } /// Compute the shadow address for a given va_arg. Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB, int ArgOffset) { +#if SANITIZER_ANDROID + Value *Base = IRB.CreatePointerCast(IRB.CreateCall(MS.VAArgTLSFn, {}), MS.IntptrTy); +#else Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy); +#endif // SANITIZER_ANDROID Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0), "_msarg"); @@ -3291,12 +3386,20 @@ // If there is a va_start in this function, make a backup copy of // va_arg_tls somewhere in the function entry block. IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); +#if SANITIZER_ANDROID + VAArgOverflowSize = IRB.CreateLoad(IRB.CreateCall(MS.VAArgOverflowSizeTLSFn, {})); +#else VAArgOverflowSize = IRB.CreateLoad(MS.VAArgOverflowSizeTLS); +#endif // SANITIZER_ANDROID Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize); VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize); +#if SANITIZER_ANDROID + IRB.CreateMemCpy(VAArgTLSCopy, IRB.CreateCall(MS.VAArgTLSFn, {}), CopySize, 8); +#else IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8); +#endif // SANITIZER_ANDROID } Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize); @@ -3478,13 +3581,21 @@ VAArgOffset - VAArgBase); // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of // a new class member i.e. it is the total size of all VarArgs. +#if SANITIZER_ANDROID + IRB.CreateStore(TotalVAArgSize, IRB.CreateCall(MS.VAArgOverflowSizeTLSFn, {})); +#else IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS); +#endif // SANITIZER_ANDROID } /// \brief Compute the shadow address for a given va_arg. Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB, int ArgOffset) { +#if SANITIZER_ANDROID + Value *Base = IRB.CreatePointerCast(IRB.CreateCall(MS.VAArgTLSFn, {}), MS.IntptrTy); +#else Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy); +#endif // SANITIZER_ANDROID Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0), "_msarg"); @@ -3513,7 +3624,11 @@ assert(!VAArgSize && !VAArgTLSCopy && "finalizeInstrumentation called twice"); IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); +#if SANITIZER_ANDROID + VAArgSize = IRB.CreateLoad(IRB.CreateCall(MS.VAArgOverflowSizeTLSFn, {})); +#else VAArgSize = IRB.CreateLoad(MS.VAArgOverflowSizeTLS); +#endif // SANITIZER_ANDROID Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize); @@ -3521,7 +3636,11 @@ // If there is a va_start in this function, make a backup copy of // va_arg_tls somewhere in the function entry block. VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize); +#if SANITIZER_ANDROID + IRB.CreateMemCpy(VAArgTLSCopy, IRB.CreateCall(MS.VAArgTLSFn, {}), CopySize, 8); +#else IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8); +#endif // SANITIZER_ANDROID } // Instrument va_start.