LLVM  8.0.1
Macros | Functions | Variables
MemorySanitizer.cpp File Reference

This file is a part of MemorySanitizer, a detector of uninitialized reads. More...

#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/CallingConv.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueMap.h"
#include "llvm/Pass.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/Local.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <tuple>

Go to the source code of this file.

Macros

#define DEBUG_TYPE   "msan"
 

Functions

 INITIALIZE_PASS_BEGIN (MemorySanitizerLegacyPass, "msan", "MemorySanitizer: detects uninitialized reads.", false, false) INITIALIZE_PASS_END(MemorySanitizerLegacyPass
 
static GlobalVariablecreatePrivateNonConstGlobalForString (Module &M, StringRef Str)
 Create a non-const global initialized with the given string. More...
 
static ConstantgetOrInsertGlobal (Module &M, StringRef Name, Type *Ty)
 
static VarArgHelper * CreateVarArgHelper (Function &Func, MemorySanitizer &Msan, MemorySanitizerVisitor &Visitor)
 
static unsigned TypeSizeToSizeIndex (unsigned TypeSize)
 

Variables

static const unsigned kOriginSize = 4
 
static const unsigned kMinOriginAlignment = 4
 
static const unsigned kShadowTLSAlignment = 8
 
static const unsigned kParamTLSSize = 800
 
static const unsigned kRetvalTLSSize = 800
 
static const size_t kNumberOfAccessSizes = 4
 
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. More...
 
static cl::opt< boolClKeepGoing ("msan-keep-going", cl::desc("keep going after reporting a UMR"), cl::Hidden, cl::init(false))
 
static cl::opt< boolClPoisonStack ("msan-poison-stack", cl::desc("poison uninitialized stack variables"), cl::Hidden, cl::init(true))
 
static cl::opt< boolClPoisonStackWithCall ("msan-poison-stack-with-call", cl::desc("poison uninitialized stack variables with a call"), cl::Hidden, cl::init(false))
 
static cl::opt< int > ClPoisonStackPattern ("msan-poison-stack-pattern", cl::desc("poison uninitialized stack variables with the given pattern"), cl::Hidden, cl::init(0xff))
 
static cl::opt< boolClPoisonUndef ("msan-poison-undef", cl::desc("poison undef temps"), cl::Hidden, cl::init(true))
 
static cl::opt< boolClHandleICmp ("msan-handle-icmp", cl::desc("propagate shadow through ICmpEQ and ICmpNE"), cl::Hidden, cl::init(true))
 
static cl::opt< boolClHandleICmpExact ("msan-handle-icmp-exact", cl::desc("exact handling of relational integer ICmp"), cl::Hidden, cl::init(false))
 
static cl::opt< boolClHandleAsmConservative ("msan-handle-asm-conservative", cl::desc("conservative handling of inline assembly"), cl::Hidden, cl::init(true))
 
static cl::opt< boolClCheckAccessAddress ("msan-check-access-address", cl::desc("report accesses through a pointer which has poisoned shadow"), cl::Hidden, cl::init(true))
 
static cl::opt< boolClDumpStrictInstructions ("msan-dump-strict-instructions", cl::desc("print out instructions with default strict semantics"), cl::Hidden, cl::init(false))
 
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))
 
static cl::opt< boolClEnableKmsan ("msan-kernel", cl::desc("Enable KernelMemorySanitizer instrumentation"), cl::Hidden, cl::init(false))
 
static cl::opt< boolClCheckConstantShadow ("msan-check-constant-shadow", cl::desc("Insert checks for constant shadow values"), cl::Hidden, cl::init(false))
 
static cl::opt< boolClWithComdat ("msan-with-comdat", cl::desc("Place MSan constructors in comdat sections"), cl::Hidden, cl::init(false))
 
static cl::opt< unsigned long long > ClAndMask ("msan-and-mask", cl::desc("Define custom MSan AndMask"), cl::Hidden, cl::init(0))
 
static cl::opt< unsigned long long > ClXorMask ("msan-xor-mask", cl::desc("Define custom MSan XorMask"), cl::Hidden, cl::init(0))
 
static cl::opt< unsigned long long > ClShadowBase ("msan-shadow-base", cl::desc("Define custom MSan ShadowBase"), cl::Hidden, cl::init(0))
 
static cl::opt< unsigned long long > ClOriginBase ("msan-origin-base", cl::desc("Define custom MSan OriginBase"), cl::Hidden, cl::init(0))
 
static const char *const kMsanModuleCtorName = "msan.module_ctor"
 
static const char *const kMsanInitName = "__msan_init"
 
static const MemoryMapParams Linux_I386_MemoryMapParams
 
static const MemoryMapParams Linux_X86_64_MemoryMapParams
 
static const MemoryMapParams Linux_MIPS64_MemoryMapParams
 
static const MemoryMapParams Linux_PowerPC64_MemoryMapParams
 
static const MemoryMapParams Linux_AArch64_MemoryMapParams
 
static const MemoryMapParams FreeBSD_I386_MemoryMapParams
 
static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams
 
static const MemoryMapParams NetBSD_X86_64_MemoryMapParams
 
static const PlatformMemoryMapParams Linux_X86_MemoryMapParams
 
static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
 
static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams
 
static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
 
static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
 
static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams
 
 msan
 
MemorySanitizer __pad0__
 
MemorySanitizer false
 

Detailed Description

This file is a part of MemorySanitizer, a detector of uninitialized reads.

The algorithm of the tool is similar to Memcheck (http://goo.gl/QKbem). We associate a few shadow bits with every byte of the application memory, poison the shadow of the malloc-ed or alloca-ed memory, load the shadow bits on every memory read, propagate the shadow bits through some of the arithmetic instruction (including MOV), store the shadow bits on every memory write, report a bug on some other instructions (e.g. JMP) if the associated shadow is poisoned.

But there are differences too. The first and the major one: compiler instrumentation instead of binary instrumentation. This gives us much better register allocation, possible compiler optimizations and a fast start-up. But this brings the major issue as well: msan needs to see all program events, including system calls and reads/writes in system libraries, so we either need to compile everything with msan or use a binary translation component (e.g. DynamoRIO) to instrument pre-built libraries. Another difference from Memcheck is that we use 8 shadow bits per byte of application memory and use a direct shadow mapping. This greatly simplifies the instrumentation code and avoids races on shadow updates (Memcheck is single-threaded so races are not a concern there. Memcheck uses 2 shadow bits per byte with a slow path storage that uses 8 bits per byte).

The default value of shadow is 0, which means "clean" (not poisoned).

Every module initializer should call __msan_init to ensure that the shadow memory is ready. On error, __msan_warning is called. Since parameters and return values may be passed via registers, we have a specialized thread-local shadow for return values (__msan_retval_tls) and parameters (__msan_param_tls).

                      Origin tracking.

MemorySanitizer can track origins (allocation points) of all uninitialized values. This behavior is controlled with a flag (msan-track-origins) and is disabled by default.

Origins are 4-byte values created and interpreted by the runtime library. They are stored in a second shadow mapping, one 4-byte value for 4 bytes of application memory. Propagation of origins is basically a bunch of "select" instructions that pick the origin of a dirty argument, if an instruction has one.

Every 4 aligned, consecutive bytes of application memory have one origin value associated with them. If these bytes contain uninitialized data coming from 2 different allocations, the last store wins. Because of this, MemorySanitizer reports can show unrelated origins, but this is unlikely in practice.

Origins are meaningless for fully initialized values, so MemorySanitizer avoids storing origin to memory when a fully initialized value is stored. This way it avoids needless overwritting origin of the 4-byte region on a short (i.e. 1 byte) clean store, and it is also good for performance.

                       Atomic handling.

Ideally, every atomic store of application value should update the corresponding shadow location in an atomic way. Unfortunately, atomic store of two disjoint locations can not be done without severe slowdown.

Therefore, we implement an approximation that may err on the safe side. In this implementation, every atomically accessed location in the program may only change from (partially) uninitialized to fully initialized, but not the other way around. We load the shadow after the application load, and we store the shadow before the app store. Also, we always store clean shadow (if the application store is atomic). This way, if the store-load pair constitutes a happens-before arc, shadow store and load are correctly ordered such that the load will get either the value that was stored, or some later value (which is always clean).

This does not work very well with Compare-And-Swap (CAS) and Read-Modify-Write (RMW) operations. To follow the above logic, CAS and RMW must store the new shadow before the app operation, and load the shadow after the app operation. Computers don't work this way. Current implementation ignores the load aspect of CAS/RMW, always returning a clean value. It implements the store part as a simple atomic store by storing a clean shadow.

                 Instrumenting inline assembly.

For inline assembly code LLVM has little idea about which memory locations become initialized depending on the arguments. It can be possible to figure out which arguments are meant to point to inputs and outputs, but the actual semantics can be only visible at runtime. In the Linux kernel it's also possible that the arguments only indicate the offset for a base taken from a segment register, so it's dangerous to treat any asm() arguments as pointers. We take a conservative approach generating calls to __msan_instrument_asm_store(ptr, size) , which defer the memory unpoisoning to the runtime library. The latter can perform more complex address checks to figure out whether it's safe to touch the shadow memory. Like with atomic operations, we call __msan_instrument_asm_store() before the assembly call, so that changes to the shadow memory will be seen by other threads together with main memory initialization.

             KernelMemorySanitizer (KMSAN) implementation.

The major differences between KMSAN and MSan instrumentation are:

Also, KMSAN currently ignores uninitialized memory passed into inline asm calls, making sure we're on the safe side wrt. possible false positives.

KernelMemorySanitizer only supports X86_64 at the moment.

Definition in file MemorySanitizer.cpp.

Macro Definition Documentation

◆ DEBUG_TYPE

#define DEBUG_TYPE   "msan"

Definition at line 202 of file MemorySanitizer.cpp.

Function Documentation

◆ createPrivateNonConstGlobalForString()

static GlobalVariable* createPrivateNonConstGlobalForString ( Module M,
StringRef  Str 
)
static

Create a non-const global initialized with the given string.

Creates a writable global for Str so that we can pass it to the run-time lib. Runtime uses first 4 bytes of the string to store the frame ID, so the string needs to be mutable.

Definition at line 654 of file MemorySanitizer.cpp.

References C, llvm::StructType::get(), llvm::ArrayType::get(), llvm::PointerType::get(), llvm::Module::getContext(), llvm::IRBuilderBase::getInt32Ty(), llvm::IRBuilderBase::getInt64Ty(), llvm::IRBuilderBase::getInt8PtrTy(), llvm::IRBuilderBase::getInt8Ty(), llvm::Module::getOrInsertFunction(), llvm::ConstantDataArray::getString(), llvm::Value::getType(), llvm::IRBuilderBase::getVoidTy(), llvm::GlobalValue::PrivateLinkage, llvm::size(), and llvm::to_string().

◆ CreateVarArgHelper()

static VarArgHelper * CreateVarArgHelper ( Function Func,
MemorySanitizer &  Msan,
MemorySanitizerVisitor &  Visitor 
)
static

◆ getOrInsertGlobal()

static Constant* getOrInsertGlobal ( Module M,
StringRef  Name,
Type Ty 
)
static

Definition at line 723 of file MemorySanitizer.cpp.

References llvm::Triple::aarch64, llvm::Triple::aarch64_be, llvm::appendToGlobalCtors(), C, ClAndMask, ClOriginBase, ClShadowBase, ClWithComdat, ClXorMask, llvm::MDBuilder::createBranchWeights(), CreateVarArgHelper(), llvm::GlobalValue::ExternalLinkage, llvm::Triple::FreeBSD, FreeBSD_X86_MemoryMapParams, llvm::InlineAsm::get(), llvm::FunctionType::get(), llvm::ArrayType::get(), llvm::PointerType::get(), llvm::Module::getContext(), llvm::Module::getDataLayout(), llvm::IRBuilderBase::getInt32(), llvm::IRBuilderBase::getInt32Ty(), llvm::IRBuilderBase::getInt64Ty(), llvm::IRBuilderBase::getInt8PtrTy(), llvm::IRBuilderBase::getInt8Ty(), llvm::IRBuilderBase::getIntNTy(), llvm::IRBuilderBase::getIntPtrTy(), llvm::getOrCreateSanitizerCtorAndInitFunctions(), llvm::Module::getOrInsertComdat(), llvm::Module::getOrInsertFunction(), llvm::Module::getOrInsertGlobal(), llvm::Module::getTargetTriple(), llvm::IRBuilderBase::getVoidTy(), I, llvm::GlobalValue::InitialExecTLSModel, isStore(), llvm::itostr(), kMsanInitName, kMsanModuleCtorName, kNumberOfAccessSizes, llvm::Triple::Linux, Linux_ARM_MemoryMapParams, Linux_MIPS_MemoryMapParams, Linux_PowerPC_MemoryMapParams, Linux_X86_MemoryMapParams, llvm::Triple::mips64, llvm::Triple::mips64el, llvm::Triple::NetBSD, NetBSD_X86_MemoryMapParams, llvm::Triple::ppc64, llvm::Triple::ppc64le, llvm::report_fatal_error(), llvm::GlobalObject::setComdat(), llvm::size(), llvm::GlobalValue::WeakODRLinkage, llvm::Triple::x86, and llvm::Triple::x86_64.

◆ INITIALIZE_PASS_BEGIN()

INITIALIZE_PASS_BEGIN ( MemorySanitizerLegacyPass  ,
"msan"  ,
"MemorySanitizer: detects uninitialized reads."  ,
false  ,
false   
)

◆ TypeSizeToSizeIndex()

static unsigned TypeSizeToSizeIndex ( unsigned  TypeSize)
static

Definition at line 995 of file MemorySanitizer.cpp.

References llvm::Acquire, llvm::AcquireRelease, llvm::MCID::Add, llvm::AttrBuilder::addAttribute(), llvm::PHINode::addIncoming(), llvm::AMDGPU::HSAMD::Kernel::Arg::Key::Align, llvm::alignTo(), llvm::CallSiteBase< FunTy, BBTy, ValTy, UserTy, UseTy, InstrTy, CallTy, InvokeTy, IterTy >::arg_begin(), llvm::Function::args(), assert(), B, llvm::Intrinsic::bswap, C, ClCheckAccessAddress, ClCheckConstantShadow, ClHandleAsmConservative, ClHandleICmp, ClHandleICmpExact, ClInstrumentationWithCallThreshold, ClPoisonStack, ClPoisonUndef, llvm::ValueMap< KeyT, ValueT, Config >::count(), llvm::APInt::countTrailingZeros(), llvm::IRBuilder< T, Inserter >::CreateAdd(), llvm::IRBuilder< T, Inserter >::CreateAlignedLoad(), llvm::IRBuilder< T, Inserter >::CreateAlignedStore(), llvm::IRBuilder< T, Inserter >::CreateAnd(), llvm::IRBuilder< T, Inserter >::CreateBinOp(), llvm::IRBuilder< T, Inserter >::CreateBitCast(), llvm::IRBuilder< T, Inserter >::CreateCall(), llvm::IRBuilder< T, Inserter >::CreateConstGEP1_32(), llvm::IRBuilder< T, Inserter >::CreateExtractElement(), llvm::IRBuilder< T, Inserter >::CreateExtractValue(), llvm::IRBuilder< T, Inserter >::CreateGEP(), llvm::IRBuilder< T, Inserter >::CreateICmp(), llvm::IRBuilder< T, Inserter >::CreateICmpEQ(), llvm::IRBuilder< T, Inserter >::CreateICmpNE(), llvm::IRBuilder< T, Inserter >::CreateICmpSLT(), llvm::IRBuilder< T, Inserter >::CreateInsertElement(), llvm::IRBuilder< T, Inserter >::CreateIntCast(), llvm::IRBuilder< T, Inserter >::CreateIntToPtr(), llvm::IRBuilder< T, Inserter >::CreateLoad(), llvm::IRBuilder< T, Inserter >::CreateLShr(), llvm::IRBuilderBase::CreateMaskedLoad(), llvm::IRBuilderBase::CreateMaskedStore(), llvm::IRBuilder< T, Inserter >::CreateMul(), llvm::IRBuilder< T, Inserter >::CreateNeg(), llvm::IRBuilder< T, Inserter >::CreateNot(), llvm::IRBuilder< T, Inserter >::CreateOr(), llvm::IRBuilder< T, Inserter >::CreatePointerCast(), llvm::IRBuilder< T, Inserter >::CreatePtrToInt(), llvm::IRBuilder< T, Inserter >::CreateSelect(), llvm::IRBuilder< T, Inserter >::CreateSExt(), llvm::IRBuilder< T, Inserter >::CreateShl(), llvm::IRBuilder< T, Inserter >::CreateStore(), llvm::IRBuilder< T, Inserter >::CreateTrunc(), CreateVarArgHelper(), llvm::IRBuilder< T, Inserter >::CreateXor(), llvm::IRBuilder< T, Inserter >::CreateZExt(), llvm::dbgs(), llvm::depth_first(), llvm::CallBase::doesNotAccessMemory(), llvm::dyn_cast(), llvm::Instruction::eraseFromParent(), F(), first, llvm::AttributeList::FunctionIndex, GEP, llvm::IntegerType::get(), llvm::ConstantInt::get(), llvm::StructType::get(), llvm::ArrayType::get(), llvm::VectorType::get(), llvm::ConstantArray::get(), llvm::ConstantStruct::get(), llvm::PointerType::get(), llvm::ConstantVector::get(), llvm::DataLayout::getABITypeAlignment(), llvm::Constant::getAggregateElement(), llvm::LoadInst::getAlignment(), llvm::Constant::getAllOnesValue(), llvm::CallBase::getArgOperand(), llvm::APInt::getBitWidth(), llvm::CallBase::getCalledFunction(), llvm::CallBase::getCalledValue(), llvm::Module::getDataLayout(), llvm::Intrinsic::getDeclaration(), llvm::Function::getEntryBlock(), llvm::BasicBlock::getFirstNonPHI(), llvm::IRBuilderBase::GetInsertPoint(), llvm::CallSiteBase< FunTy, BBTy, ValTy, UserTy, UseTy, InstrTy, CallTy, InvokeTy, IterTy >::getInstruction(), llvm::IRBuilderBase::getInt32(), llvm::IRBuilderBase::getInt32Ty(), llvm::IRBuilderBase::getInt64Ty(), llvm::IRBuilderBase::getInt8PtrTy(), llvm::IRBuilderBase::getInt8Ty(), llvm::IRBuilderBase::getIntNTy(), llvm::Type::getIntNTy(), llvm::IntrinsicInst::getIntrinsicID(), llvm::Instruction::getMetadata(), llvm::Instruction::getModule(), llvm::Value::getName(), llvm::ilist_node_with_parent< NodeTy, ParentTy, Options >::getNextNode(), llvm::Constant::getNullValue(), llvm::CallBase::getNumArgOperands(), llvm::BinaryOperator::getOpcode(), llvm::User::getOperand(), llvm::LoadInst::getOrdering(), llvm::AtomicRMWInst::getOrdering(), llvm::GlobalValue::getParent(), llvm::Type::getPointerElementType(), llvm::LoadInst::getPointerOperand(), llvm::StoreInst::getPointerOperand(), llvm::Type::getPointerTo(), llvm::CmpInst::getPredicate(), llvm::Type::getPrimitiveSizeInBits(), llvm::Type::getScalarSizeInBits(), llvm::Type::getScalarType(), llvm::Type::getSequentialElementType(), llvm::AtomicCmpXchgInst::getSuccessOrdering(), llvm::CmpInst::getSwappedPredicate(), llvm::Value::getType(), llvm::DataLayout::getTypeAllocSize(), llvm::DataLayout::getTypeSizeInBits(), llvm::DataLayout::getTypeStoreSize(), llvm::Type::getVectorElementType(), llvm::Type::getVectorNumElements(), llvm::Type::getX86_MMXTy(), llvm::Function::hasFnAttribute(), I, llvm::CmpInst::ICMP_SGE, llvm::CmpInst::ICMP_SGT, llvm::CmpInst::ICMP_SLE, llvm::CmpInst::ICMP_SLT, llvm::Intrinsic::is_constant, llvm::Type::isAggregateType(), llvm::Constant::isAllOnesValue(), llvm::Instruction::isAtomic(), llvm::CallSiteBase< FunTy, BBTy, ValTy, UserTy, UseTy, InstrTy, CallTy, InvokeTy, IterTy >::isCall(), llvm::ICmpInst::isEquality(), llvm::Type::isFPOrFPVectorTy(), llvm::CallInst::isInlineAsm(), llvm::Type::isIntegerTy(), llvm::Type::isIntOrIntVectorTy(), llvm::CallSiteBase< FunTy, BBTy, ValTy, UserTy, UseTy, InstrTy, CallTy, InvokeTy, IterTy >::isInvoke(), llvm::Constant::isNullValue(), llvm::Type::isPointerTy(), llvm::Type::isPtrOrPtrVectorTy(), llvm::ICmpInst::isRelational(), llvm::CmpInst::isSigned(), llvm::Type::isSized(), llvm::CmpInst::isUnsigned(), llvm::Type::isVectorTy(), llvm::Type::isVoidTy(), llvm::Type::isX86_MMXTy(), llvm::Constant::isZeroValue(), IT, kMinOriginAlignment, kNumberOfAccessSizes, kOriginSize, kParamTLSSize, LLVM_DEBUG, LLVM_FALLTHROUGH, llvm_unreachable, llvm::Log2_32_Ceil(), llvm::makeArrayRef(), llvm::BitmaskEnumDetail::Mask(), llvm::Intrinsic::masked_load, llvm::Intrinsic::masked_store, llvm::max(), llvm::maybeMarkSanitizerLibraryCallNoBuiltin(), llvm::Monotonic, N, llvm::NotAtomic, llvm::RISCVFenceField::O, llvm::SystemZISD::OC, llvm::CallBase::onlyReadsMemory(), op, llvm::User::op_begin(), llvm::User::op_end(), llvm::SmallVectorTemplateBase< T >::push_back(), llvm::Attribute::ReadNone, llvm::Attribute::ReadOnly, llvm::Release, llvm::Function::removeAttributes(), llvm::removeUnreachableBlocks(), runOnFunction(), llvm::Attribute::SanitizeMemory, llvm::PPCISD::SC, llvm::SequentiallyConsistent, llvm::IRBuilderBase::SetInsertPoint(), llvm::Value::setName(), llvm::LoadInst::setOrdering(), llvm::AtomicRMWInst::setOrdering(), llvm::AtomicCmpXchgInst::setSuccessOrdering(), SI, Signed, Size, llvm::SmallVectorBase::size(), llvm::SplitBlock(), llvm::SplitBlockAndInsertIfThen(), llvm::ARM_MB::ST, T, llvm::Unordered, llvm::NVPTX::PTXLdStInstCode::V2, llvm::Intrinsic::x86_avx2_packssdw, llvm::Intrinsic::x86_avx2_packsswb, llvm::Intrinsic::x86_avx2_packusdw, llvm::Intrinsic::x86_avx2_packuswb, llvm::Intrinsic::x86_avx2_pmadd_ub_sw, llvm::Intrinsic::x86_avx2_pmadd_wd, llvm::Intrinsic::x86_avx2_psad_bw, llvm::Intrinsic::x86_avx2_psll_d, llvm::Intrinsic::x86_avx2_psll_q, llvm::Intrinsic::x86_avx2_psll_w, llvm::Intrinsic::x86_avx2_pslli_d, llvm::Intrinsic::x86_avx2_pslli_q, llvm::Intrinsic::x86_avx2_pslli_w, llvm::Intrinsic::x86_avx2_psllv_d, llvm::Intrinsic::x86_avx2_psllv_d_256, llvm::Intrinsic::x86_avx2_psllv_q, llvm::Intrinsic::x86_avx2_psllv_q_256, llvm::Intrinsic::x86_avx2_psra_d, llvm::Intrinsic::x86_avx2_psra_w, llvm::Intrinsic::x86_avx2_psrai_d, llvm::Intrinsic::x86_avx2_psrai_w, llvm::Intrinsic::x86_avx2_psrav_d, llvm::Intrinsic::x86_avx2_psrav_d_256, llvm::Intrinsic::x86_avx2_psrl_d, llvm::Intrinsic::x86_avx2_psrl_q, llvm::Intrinsic::x86_avx2_psrl_w, llvm::Intrinsic::x86_avx2_psrli_d, llvm::Intrinsic::x86_avx2_psrli_q, llvm::Intrinsic::x86_avx2_psrli_w, llvm::Intrinsic::x86_avx2_psrlv_d, llvm::Intrinsic::x86_avx2_psrlv_d_256, llvm::Intrinsic::x86_avx2_psrlv_q, llvm::Intrinsic::x86_avx2_psrlv_q_256, llvm::Intrinsic::x86_avx512_cvttsd2usi, llvm::Intrinsic::x86_avx512_cvttsd2usi64, llvm::Intrinsic::x86_avx512_cvttss2usi, llvm::Intrinsic::x86_avx512_cvttss2usi64, llvm::Intrinsic::x86_avx512_cvtusi2ss, llvm::Intrinsic::x86_avx512_cvtusi642sd, llvm::Intrinsic::x86_avx512_cvtusi642ss, llvm::Intrinsic::x86_avx512_psll_d_512, llvm::Intrinsic::x86_avx512_psll_q_512, llvm::Intrinsic::x86_avx512_psll_w_512, llvm::Intrinsic::x86_avx512_pslli_d_512, llvm::Intrinsic::x86_avx512_pslli_q_512, llvm::Intrinsic::x86_avx512_pslli_w_512, llvm::Intrinsic::x86_avx512_psllv_d_512, llvm::Intrinsic::x86_avx512_psllv_q_512, llvm::Intrinsic::x86_avx512_psra_d_512, llvm::Intrinsic::x86_avx512_psra_q_128, llvm::Intrinsic::x86_avx512_psra_q_256, llvm::Intrinsic::x86_avx512_psra_q_512, llvm::Intrinsic::x86_avx512_psra_w_512, llvm::Intrinsic::x86_avx512_psrai_d_512, llvm::Intrinsic::x86_avx512_psrai_q_128, llvm::Intrinsic::x86_avx512_psrai_q_256, llvm::Intrinsic::x86_avx512_psrai_q_512, llvm::Intrinsic::x86_avx512_psrai_w_512, llvm::Intrinsic::x86_avx512_psrav_d_512, llvm::Intrinsic::x86_avx512_psrav_q_128, llvm::Intrinsic::x86_avx512_psrav_q_256, llvm::Intrinsic::x86_avx512_psrav_q_512, llvm::Intrinsic::x86_avx512_psrl_d_512, llvm::Intrinsic::x86_avx512_psrl_q_512, llvm::Intrinsic::x86_avx512_psrl_w_512, llvm::Intrinsic::x86_avx512_psrli_d_512, llvm::Intrinsic::x86_avx512_psrli_q_512, llvm::Intrinsic::x86_avx512_psrli_w_512, llvm::Intrinsic::x86_avx512_psrlv_d_512, llvm::Intrinsic::x86_avx512_psrlv_q_512, llvm::Intrinsic::x86_avx512_vcvtsd2usi32, llvm::Intrinsic::x86_avx512_vcvtsd2usi64, llvm::Intrinsic::x86_avx512_vcvtss2usi32, llvm::Intrinsic::x86_avx512_vcvtss2usi64, llvm::Intrinsic::x86_mmx_packssdw, llvm::Intrinsic::x86_mmx_packsswb, llvm::Intrinsic::x86_mmx_packuswb, llvm::Intrinsic::x86_mmx_pmadd_wd, llvm::Intrinsic::x86_mmx_psad_bw, llvm::Intrinsic::x86_mmx_psll_d, llvm::Intrinsic::x86_mmx_psll_q, llvm::Intrinsic::x86_mmx_psll_w, llvm::Intrinsic::x86_mmx_pslli_d, llvm::Intrinsic::x86_mmx_pslli_q, llvm::Intrinsic::x86_mmx_pslli_w, llvm::Intrinsic::x86_mmx_psra_d, llvm::Intrinsic::x86_mmx_psra_w, llvm::Intrinsic::x86_mmx_psrai_d, llvm::Intrinsic::x86_mmx_psrai_w, llvm::Intrinsic::x86_mmx_psrl_d, llvm::Intrinsic::x86_mmx_psrl_q, llvm::Intrinsic::x86_mmx_psrl_w, llvm::Intrinsic::x86_mmx_psrli_d, llvm::Intrinsic::x86_mmx_psrli_q, llvm::Intrinsic::x86_mmx_psrli_w, llvm::Intrinsic::x86_sse2_cmp_pd, llvm::Intrinsic::x86_sse2_cmp_sd, llvm::Intrinsic::x86_sse2_comieq_sd, llvm::Intrinsic::x86_sse2_comige_sd, llvm::Intrinsic::x86_sse2_comigt_sd, llvm::Intrinsic::x86_sse2_comile_sd, llvm::Intrinsic::x86_sse2_comilt_sd, llvm::Intrinsic::x86_sse2_comineq_sd, llvm::Intrinsic::x86_sse2_cvtsd2si, llvm::Intrinsic::x86_sse2_cvtsd2si64, llvm::Intrinsic::x86_sse2_cvtsd2ss, llvm::Intrinsic::x86_sse2_cvttsd2si, llvm::Intrinsic::x86_sse2_cvttsd2si64, llvm::Intrinsic::x86_sse2_packssdw_128, llvm::Intrinsic::x86_sse2_packsswb_128, llvm::Intrinsic::x86_sse2_packuswb_128, llvm::Intrinsic::x86_sse2_pmadd_wd, llvm::Intrinsic::x86_sse2_psad_bw, llvm::Intrinsic::x86_sse2_psll_d, llvm::Intrinsic::x86_sse2_psll_q, llvm::Intrinsic::x86_sse2_psll_w, llvm::Intrinsic::x86_sse2_pslli_d, llvm::Intrinsic::x86_sse2_pslli_q, llvm::Intrinsic::x86_sse2_pslli_w, llvm::Intrinsic::x86_sse2_psra_d, llvm::Intrinsic::x86_sse2_psra_w, llvm::Intrinsic::x86_sse2_psrai_d, llvm::Intrinsic::x86_sse2_psrai_w, llvm::Intrinsic::x86_sse2_psrl_d, llvm::Intrinsic::x86_sse2_psrl_q, llvm::Intrinsic::x86_sse2_psrl_w, llvm::Intrinsic::x86_sse2_psrli_d, llvm::Intrinsic::x86_sse2_psrli_q, llvm::Intrinsic::x86_sse2_psrli_w, llvm::Intrinsic::x86_sse2_ucomieq_sd, llvm::Intrinsic::x86_sse2_ucomige_sd, llvm::Intrinsic::x86_sse2_ucomigt_sd, llvm::Intrinsic::x86_sse2_ucomile_sd, llvm::Intrinsic::x86_sse2_ucomilt_sd, llvm::Intrinsic::x86_sse2_ucomineq_sd, llvm::Intrinsic::x86_sse41_packusdw, llvm::Intrinsic::x86_sse_cmp_ps, llvm::Intrinsic::x86_sse_cmp_ss, llvm::Intrinsic::x86_sse_comieq_ss, llvm::Intrinsic::x86_sse_comige_ss, llvm::Intrinsic::x86_sse_comigt_ss, llvm::Intrinsic::x86_sse_comile_ss, llvm::Intrinsic::x86_sse_comilt_ss, llvm::Intrinsic::x86_sse_comineq_ss, llvm::Intrinsic::x86_sse_cvtps2pi, llvm::Intrinsic::x86_sse_cvtss2si, llvm::Intrinsic::x86_sse_cvtss2si64, llvm::Intrinsic::x86_sse_cvttps2pi, llvm::Intrinsic::x86_sse_cvttss2si, llvm::Intrinsic::x86_sse_cvttss2si64, llvm::Intrinsic::x86_sse_ldmxcsr, llvm::Intrinsic::x86_sse_stmxcsr, llvm::Intrinsic::x86_sse_ucomieq_ss, llvm::Intrinsic::x86_sse_ucomige_ss, llvm::Intrinsic::x86_sse_ucomigt_ss, llvm::Intrinsic::x86_sse_ucomile_ss, llvm::Intrinsic::x86_sse_ucomilt_ss, llvm::Intrinsic::x86_sse_ucomineq_ss, llvm::Intrinsic::x86_ssse3_pmadd_ub_sw, and llvm::Intrinsic::x86_ssse3_pmadd_ub_sw_128.

Variable Documentation

◆ __pad0__

MemorySanitizer __pad0__

Definition at line 639 of file MemorySanitizer.cpp.

◆ ClAndMask

cl::opt<unsigned long long> ClAndMask("msan-and-mask", cl::desc("Define custom MSan AndMask"), cl::Hidden, cl::init(0))
static

Referenced by getOrInsertGlobal().

◆ ClCheckAccessAddress

cl::opt<bool> ClCheckAccessAddress("msan-check-access-address", cl::desc("report accesses through a pointer which has poisoned shadow"), cl::Hidden, cl::init(true))
static

Referenced by TypeSizeToSizeIndex().

◆ ClCheckConstantShadow

cl::opt<bool> ClCheckConstantShadow("msan-check-constant-shadow", cl::desc("Insert checks for constant shadow values"), cl::Hidden, cl::init(false))
static

Referenced by TypeSizeToSizeIndex().

◆ ClDumpStrictInstructions

cl::opt<bool> ClDumpStrictInstructions("msan-dump-strict-instructions", cl::desc("print out instructions with default strict semantics"), cl::Hidden, cl::init(false))
static

◆ ClEnableKmsan

cl::opt<bool> ClEnableKmsan("msan-kernel", cl::desc("Enable KernelMemorySanitizer instrumentation"), cl::Hidden, cl::init(false))
static

◆ ClHandleAsmConservative

cl::opt<bool> ClHandleAsmConservative("msan-handle-asm-conservative", cl::desc("conservative handling of inline assembly"), cl::Hidden, cl::init(true))
static

Referenced by TypeSizeToSizeIndex().

◆ ClHandleICmp

cl::opt<bool> ClHandleICmp("msan-handle-icmp", cl::desc("propagate shadow through ICmpEQ and ICmpNE"), cl::Hidden, cl::init(true))
static

Referenced by TypeSizeToSizeIndex().

◆ ClHandleICmpExact

cl::opt<bool> ClHandleICmpExact("msan-handle-icmp-exact", cl::desc("exact handling of relational integer ICmp"), cl::Hidden, cl::init(false))
static

Referenced by TypeSizeToSizeIndex().

◆ ClInstrumentationWithCallThreshold

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))
static

Referenced by TypeSizeToSizeIndex().

◆ ClKeepGoing

cl::opt<bool> ClKeepGoing("msan-keep-going", cl::desc("keep going after reporting a UMR"), cl::Hidden, cl::init(false))
static

◆ ClOriginBase

cl::opt<unsigned long long> ClOriginBase("msan-origin-base", cl::desc("Define custom MSan OriginBase"), cl::Hidden, cl::init(0))
static

Referenced by getOrInsertGlobal().

◆ ClPoisonStack

cl::opt<bool> ClPoisonStack("msan-poison-stack", cl::desc("poison uninitialized stack variables"), cl::Hidden, cl::init(true))
static

Referenced by TypeSizeToSizeIndex().

◆ ClPoisonStackPattern

cl::opt<int> ClPoisonStackPattern("msan-poison-stack-pattern", cl::desc("poison uninitialized stack variables with the given pattern"), cl::Hidden, cl::init(0xff))
static

◆ ClPoisonStackWithCall

cl::opt<bool> ClPoisonStackWithCall("msan-poison-stack-with-call", cl::desc("poison uninitialized stack variables with a call"), cl::Hidden, cl::init(false))
static

◆ ClPoisonUndef

cl::opt<bool> ClPoisonUndef("msan-poison-undef", cl::desc("poison undef temps"), cl::Hidden, cl::init(true))
static

Referenced by TypeSizeToSizeIndex().

◆ ClShadowBase

cl::opt<unsigned long long> ClShadowBase("msan-shadow-base", cl::desc("Define custom MSan ShadowBase"), cl::Hidden, cl::init(0))
static

Referenced by getOrInsertGlobal().

◆ ClTrackOrigins

cl::opt<int> ClTrackOrigins("msan-track-origins", cl::desc("Track origins (allocation sites) of poisoned memory"), cl::Hidden, cl::init(0))
static

Track origins of uninitialized values.

Adds a section to MemorySanitizer report that points to the allocation (stack or heap) the uninitialized bits came from originally.

◆ ClWithComdat

cl::opt<bool> ClWithComdat("msan-with-comdat", cl::desc("Place MSan constructors in comdat sections"), cl::Hidden, cl::init(false))
static

Referenced by getOrInsertGlobal().

◆ ClXorMask

cl::opt<unsigned long long> ClXorMask("msan-xor-mask", cl::desc("Define custom MSan XorMask"), cl::Hidden, cl::init(0))
static

Referenced by getOrInsertGlobal().

◆ false

MemorySanitizer false

Definition at line 639 of file MemorySanitizer.cpp.

◆ FreeBSD_I386_MemoryMapParams

const MemoryMapParams FreeBSD_I386_MemoryMapParams
static
Initial value:
= {
0x000180000000,
0x000040000000,
0x000020000000,
0x000700000000,
}

Definition at line 395 of file MemorySanitizer.cpp.

◆ FreeBSD_X86_64_MemoryMapParams

const MemoryMapParams FreeBSD_X86_64_MemoryMapParams
static
Initial value:
= {
0xc00000000000,
0x200000000000,
0x100000000000,
0x380000000000,
}

Definition at line 403 of file MemorySanitizer.cpp.

◆ FreeBSD_X86_MemoryMapParams

const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
static
Initial value:
= {
}
static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams
static const MemoryMapParams FreeBSD_I386_MemoryMapParams

Definition at line 438 of file MemorySanitizer.cpp.

Referenced by getOrInsertGlobal().

◆ kMinOriginAlignment

const unsigned kMinOriginAlignment = 4
static

Definition at line 205 of file MemorySanitizer.cpp.

Referenced by TypeSizeToSizeIndex().

◆ kMsanInitName

const char* const kMsanInitName = "__msan_init"
static

Definition at line 325 of file MemorySanitizer.cpp.

Referenced by getOrInsertGlobal().

◆ kMsanModuleCtorName

const char* const kMsanModuleCtorName = "msan.module_ctor"
static

Definition at line 324 of file MemorySanitizer.cpp.

Referenced by getOrInsertGlobal().

◆ kNumberOfAccessSizes

const size_t kNumberOfAccessSizes = 4
static

Definition at line 213 of file MemorySanitizer.cpp.

Referenced by getOrInsertGlobal(), and TypeSizeToSizeIndex().

◆ kOriginSize

const unsigned kOriginSize = 4
static

Definition at line 204 of file MemorySanitizer.cpp.

Referenced by TypeSizeToSizeIndex().

◆ kParamTLSSize

const unsigned kParamTLSSize = 800
static

Definition at line 209 of file MemorySanitizer.cpp.

Referenced by TypeSizeToSizeIndex().

◆ kRetvalTLSSize

const unsigned kRetvalTLSSize = 800
static

Definition at line 210 of file MemorySanitizer.cpp.

◆ kShadowTLSAlignment

const unsigned kShadowTLSAlignment = 8
static

Definition at line 206 of file MemorySanitizer.cpp.

◆ Linux_AArch64_MemoryMapParams

const MemoryMapParams Linux_AArch64_MemoryMapParams
static
Initial value:
= {
0,
0x06000000000,
0,
0x01000000000,
}

Definition at line 387 of file MemorySanitizer.cpp.

◆ Linux_ARM_MemoryMapParams

const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static
Initial value:
= {
nullptr,
}
static const MemoryMapParams Linux_AArch64_MemoryMapParams

Definition at line 433 of file MemorySanitizer.cpp.

Referenced by getOrInsertGlobal().

◆ Linux_I386_MemoryMapParams

const MemoryMapParams Linux_I386_MemoryMapParams
static
Initial value:
= {
0x000080000000,
0,
0,
0x000040000000,
}

Definition at line 348 of file MemorySanitizer.cpp.

◆ Linux_MIPS64_MemoryMapParams

const MemoryMapParams Linux_MIPS64_MemoryMapParams
static
Initial value:
= {
0,
0x008000000000,
0,
0x002000000000,
}

Definition at line 371 of file MemorySanitizer.cpp.

◆ Linux_MIPS_MemoryMapParams

const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
static
Initial value:
= {
nullptr,
}
static const MemoryMapParams Linux_MIPS64_MemoryMapParams

Definition at line 423 of file MemorySanitizer.cpp.

Referenced by getOrInsertGlobal().

◆ Linux_PowerPC64_MemoryMapParams

const MemoryMapParams Linux_PowerPC64_MemoryMapParams
static
Initial value:
= {
0xE00000000000,
0x100000000000,
0x080000000000,
0x1C0000000000,
}

Definition at line 379 of file MemorySanitizer.cpp.

◆ Linux_PowerPC_MemoryMapParams

const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams
static
Initial value:
= {
nullptr,
}
static const MemoryMapParams Linux_PowerPC64_MemoryMapParams

Definition at line 428 of file MemorySanitizer.cpp.

Referenced by getOrInsertGlobal().

◆ Linux_X86_64_MemoryMapParams

const MemoryMapParams Linux_X86_64_MemoryMapParams
static
Initial value:
= {
0,
0x500000000000,
0,
0x100000000000,
}

Definition at line 356 of file MemorySanitizer.cpp.

◆ Linux_X86_MemoryMapParams

const PlatformMemoryMapParams Linux_X86_MemoryMapParams
static
Initial value:
= {
}
static const MemoryMapParams Linux_I386_MemoryMapParams
static const MemoryMapParams Linux_X86_64_MemoryMapParams

Definition at line 418 of file MemorySanitizer.cpp.

Referenced by getOrInsertGlobal().

◆ msan

msan

Definition at line 639 of file MemorySanitizer.cpp.

◆ NetBSD_X86_64_MemoryMapParams

const MemoryMapParams NetBSD_X86_64_MemoryMapParams
static
Initial value:
= {
0,
0x500000000000,
0,
0x100000000000,
}

Definition at line 411 of file MemorySanitizer.cpp.

◆ NetBSD_X86_MemoryMapParams

const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams
static
Initial value:
= {
nullptr,
}
static const MemoryMapParams NetBSD_X86_64_MemoryMapParams

Definition at line 443 of file MemorySanitizer.cpp.

Referenced by getOrInsertGlobal().