LLVM API Documentation
00001 //===-- MemorySanitizer.cpp - detector of uninitialized reads -------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 /// \file 00010 /// This file is a part of MemorySanitizer, a detector of uninitialized 00011 /// reads. 00012 /// 00013 /// The algorithm of the tool is similar to Memcheck 00014 /// (http://goo.gl/QKbem). We associate a few shadow bits with every 00015 /// byte of the application memory, poison the shadow of the malloc-ed 00016 /// or alloca-ed memory, load the shadow bits on every memory read, 00017 /// propagate the shadow bits through some of the arithmetic 00018 /// instruction (including MOV), store the shadow bits on every memory 00019 /// write, report a bug on some other instructions (e.g. JMP) if the 00020 /// associated shadow is poisoned. 00021 /// 00022 /// But there are differences too. The first and the major one: 00023 /// compiler instrumentation instead of binary instrumentation. This 00024 /// gives us much better register allocation, possible compiler 00025 /// optimizations and a fast start-up. But this brings the major issue 00026 /// as well: msan needs to see all program events, including system 00027 /// calls and reads/writes in system libraries, so we either need to 00028 /// compile *everything* with msan or use a binary translation 00029 /// component (e.g. DynamoRIO) to instrument pre-built libraries. 00030 /// Another difference from Memcheck is that we use 8 shadow bits per 00031 /// byte of application memory and use a direct shadow mapping. This 00032 /// greatly simplifies the instrumentation code and avoids races on 00033 /// shadow updates (Memcheck is single-threaded so races are not a 00034 /// concern there. Memcheck uses 2 shadow bits per byte with a slow 00035 /// path storage that uses 8 bits per byte). 00036 /// 00037 /// The default value of shadow is 0, which means "clean" (not poisoned). 00038 /// 00039 /// Every module initializer should call __msan_init to ensure that the 00040 /// shadow memory is ready. On error, __msan_warning is called. Since 00041 /// parameters and return values may be passed via registers, we have a 00042 /// specialized thread-local shadow for return values 00043 /// (__msan_retval_tls) and parameters (__msan_param_tls). 00044 /// 00045 /// Origin tracking. 00046 /// 00047 /// MemorySanitizer can track origins (allocation points) of all uninitialized 00048 /// values. This behavior is controlled with a flag (msan-track-origins) and is 00049 /// disabled by default. 00050 /// 00051 /// Origins are 4-byte values created and interpreted by the runtime library. 00052 /// They are stored in a second shadow mapping, one 4-byte value for 4 bytes 00053 /// of application memory. Propagation of origins is basically a bunch of 00054 /// "select" instructions that pick the origin of a dirty argument, if an 00055 /// instruction has one. 00056 /// 00057 /// Every 4 aligned, consecutive bytes of application memory have one origin 00058 /// value associated with them. If these bytes contain uninitialized data 00059 /// coming from 2 different allocations, the last store wins. Because of this, 00060 /// MemorySanitizer reports can show unrelated origins, but this is unlikely in 00061 /// practice. 00062 /// 00063 /// Origins are meaningless for fully initialized values, so MemorySanitizer 00064 /// avoids storing origin to memory when a fully initialized value is stored. 00065 /// This way it avoids needless overwritting origin of the 4-byte region on 00066 /// a short (i.e. 1 byte) clean store, and it is also good for performance. 00067 /// 00068 /// Atomic handling. 00069 /// 00070 /// Ideally, every atomic store of application value should update the 00071 /// corresponding shadow location in an atomic way. Unfortunately, atomic store 00072 /// of two disjoint locations can not be done without severe slowdown. 00073 /// 00074 /// Therefore, we implement an approximation that may err on the safe side. 00075 /// In this implementation, every atomically accessed location in the program 00076 /// may only change from (partially) uninitialized to fully initialized, but 00077 /// not the other way around. We load the shadow _after_ the application load, 00078 /// and we store the shadow _before_ the app store. Also, we always store clean 00079 /// shadow (if the application store is atomic). This way, if the store-load 00080 /// pair constitutes a happens-before arc, shadow store and load are correctly 00081 /// ordered such that the load will get either the value that was stored, or 00082 /// some later value (which is always clean). 00083 /// 00084 /// This does not work very well with Compare-And-Swap (CAS) and 00085 /// Read-Modify-Write (RMW) operations. To follow the above logic, CAS and RMW 00086 /// must store the new shadow before the app operation, and load the shadow 00087 /// after the app operation. Computers don't work this way. Current 00088 /// implementation ignores the load aspect of CAS/RMW, always returning a clean 00089 /// value. It implements the store part as a simple atomic store by storing a 00090 /// clean shadow. 00091 00092 //===----------------------------------------------------------------------===// 00093 00094 #include "llvm/Transforms/Instrumentation.h" 00095 #include "llvm/ADT/DepthFirstIterator.h" 00096 #include "llvm/ADT/SmallString.h" 00097 #include "llvm/ADT/SmallVector.h" 00098 #include "llvm/ADT/StringExtras.h" 00099 #include "llvm/ADT/Triple.h" 00100 #include "llvm/IR/DataLayout.h" 00101 #include "llvm/IR/Function.h" 00102 #include "llvm/IR/IRBuilder.h" 00103 #include "llvm/IR/InlineAsm.h" 00104 #include "llvm/IR/InstVisitor.h" 00105 #include "llvm/IR/IntrinsicInst.h" 00106 #include "llvm/IR/LLVMContext.h" 00107 #include "llvm/IR/MDBuilder.h" 00108 #include "llvm/IR/Module.h" 00109 #include "llvm/IR/Type.h" 00110 #include "llvm/IR/ValueMap.h" 00111 #include "llvm/Support/CommandLine.h" 00112 #include "llvm/Support/Compiler.h" 00113 #include "llvm/Support/Debug.h" 00114 #include "llvm/Support/raw_ostream.h" 00115 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 00116 #include "llvm/Transforms/Utils/Local.h" 00117 #include "llvm/Transforms/Utils/ModuleUtils.h" 00118 00119 using namespace llvm; 00120 00121 #define DEBUG_TYPE "msan" 00122 00123 static const uint64_t kShadowMask32 = 1ULL << 31; 00124 static const uint64_t kShadowMask64 = 1ULL << 46; 00125 static const uint64_t kOriginOffset32 = 1ULL << 30; 00126 static const uint64_t kOriginOffset64 = 1ULL << 45; 00127 static const unsigned kMinOriginAlignment = 4; 00128 static const unsigned kShadowTLSAlignment = 8; 00129 00130 // Accesses sizes are powers of two: 1, 2, 4, 8. 00131 static const size_t kNumberOfAccessSizes = 4; 00132 00133 /// \brief Track origins of uninitialized values. 00134 /// 00135 /// Adds a section to MemorySanitizer report that points to the allocation 00136 /// (stack or heap) the uninitialized bits came from originally. 00137 static cl::opt<int> ClTrackOrigins("msan-track-origins", 00138 cl::desc("Track origins (allocation sites) of poisoned memory"), 00139 cl::Hidden, cl::init(0)); 00140 static cl::opt<bool> ClKeepGoing("msan-keep-going", 00141 cl::desc("keep going after reporting a UMR"), 00142 cl::Hidden, cl::init(false)); 00143 static cl::opt<bool> ClPoisonStack("msan-poison-stack", 00144 cl::desc("poison uninitialized stack variables"), 00145 cl::Hidden, cl::init(true)); 00146 static cl::opt<bool> ClPoisonStackWithCall("msan-poison-stack-with-call", 00147 cl::desc("poison uninitialized stack variables with a call"), 00148 cl::Hidden, cl::init(false)); 00149 static cl::opt<int> ClPoisonStackPattern("msan-poison-stack-pattern", 00150 cl::desc("poison uninitialized stack variables with the given patter"), 00151 cl::Hidden, cl::init(0xff)); 00152 static cl::opt<bool> ClPoisonUndef("msan-poison-undef", 00153 cl::desc("poison undef temps"), 00154 cl::Hidden, cl::init(true)); 00155 00156 static cl::opt<bool> ClHandleICmp("msan-handle-icmp", 00157 cl::desc("propagate shadow through ICmpEQ and ICmpNE"), 00158 cl::Hidden, cl::init(true)); 00159 00160 static cl::opt<bool> ClHandleICmpExact("msan-handle-icmp-exact", 00161 cl::desc("exact handling of relational integer ICmp"), 00162 cl::Hidden, cl::init(false)); 00163 00164 // This flag controls whether we check the shadow of the address 00165 // operand of load or store. Such bugs are very rare, since load from 00166 // a garbage address typically results in SEGV, but still happen 00167 // (e.g. only lower bits of address are garbage, or the access happens 00168 // early at program startup where malloc-ed memory is more likely to 00169 // be zeroed. As of 2012-08-28 this flag adds 20% slowdown. 00170 static cl::opt<bool> ClCheckAccessAddress("msan-check-access-address", 00171 cl::desc("report accesses through a pointer which has poisoned shadow"), 00172 cl::Hidden, cl::init(true)); 00173 00174 static cl::opt<bool> ClDumpStrictInstructions("msan-dump-strict-instructions", 00175 cl::desc("print out instructions with default strict semantics"), 00176 cl::Hidden, cl::init(false)); 00177 00178 static cl::opt<int> ClInstrumentationWithCallThreshold( 00179 "msan-instrumentation-with-call-threshold", 00180 cl::desc( 00181 "If the function being instrumented requires more than " 00182 "this number of checks and origin stores, use callbacks instead of " 00183 "inline checks (-1 means never use callbacks)."), 00184 cl::Hidden, cl::init(3500)); 00185 00186 // Experimental. Wraps all indirect calls in the instrumented code with 00187 // a call to the given function. This is needed to assist the dynamic 00188 // helper tool (MSanDR) to regain control on transition between instrumented and 00189 // non-instrumented code. 00190 static cl::opt<std::string> ClWrapIndirectCalls("msan-wrap-indirect-calls", 00191 cl::desc("Wrap indirect calls with a given function"), 00192 cl::Hidden); 00193 00194 static cl::opt<bool> ClWrapIndirectCallsFast("msan-wrap-indirect-calls-fast", 00195 cl::desc("Do not wrap indirect calls with target in the same module"), 00196 cl::Hidden, cl::init(true)); 00197 00198 namespace { 00199 00200 /// \brief An instrumentation pass implementing detection of uninitialized 00201 /// reads. 00202 /// 00203 /// MemorySanitizer: instrument the code in module to find 00204 /// uninitialized reads. 00205 class MemorySanitizer : public FunctionPass { 00206 public: 00207 MemorySanitizer(int TrackOrigins = 0) 00208 : FunctionPass(ID), 00209 TrackOrigins(std::max(TrackOrigins, (int)ClTrackOrigins)), 00210 DL(nullptr), 00211 WarningFn(nullptr), 00212 WrapIndirectCalls(!ClWrapIndirectCalls.empty()) {} 00213 const char *getPassName() const override { return "MemorySanitizer"; } 00214 bool runOnFunction(Function &F) override; 00215 bool doInitialization(Module &M) override; 00216 static char ID; // Pass identification, replacement for typeid. 00217 00218 private: 00219 void initializeCallbacks(Module &M); 00220 00221 /// \brief Track origins (allocation points) of uninitialized values. 00222 int TrackOrigins; 00223 00224 const DataLayout *DL; 00225 LLVMContext *C; 00226 Type *IntptrTy; 00227 Type *OriginTy; 00228 /// \brief Thread-local shadow storage for function parameters. 00229 GlobalVariable *ParamTLS; 00230 /// \brief Thread-local origin storage for function parameters. 00231 GlobalVariable *ParamOriginTLS; 00232 /// \brief Thread-local shadow storage for function return value. 00233 GlobalVariable *RetvalTLS; 00234 /// \brief Thread-local origin storage for function return value. 00235 GlobalVariable *RetvalOriginTLS; 00236 /// \brief Thread-local shadow storage for in-register va_arg function 00237 /// parameters (x86_64-specific). 00238 GlobalVariable *VAArgTLS; 00239 /// \brief Thread-local shadow storage for va_arg overflow area 00240 /// (x86_64-specific). 00241 GlobalVariable *VAArgOverflowSizeTLS; 00242 /// \brief Thread-local space used to pass origin value to the UMR reporting 00243 /// function. 00244 GlobalVariable *OriginTLS; 00245 00246 GlobalVariable *MsandrModuleStart; 00247 GlobalVariable *MsandrModuleEnd; 00248 00249 /// \brief The run-time callback to print a warning. 00250 Value *WarningFn; 00251 // These arrays are indexed by log2(AccessSize). 00252 Value *MaybeWarningFn[kNumberOfAccessSizes]; 00253 Value *MaybeStoreOriginFn[kNumberOfAccessSizes]; 00254 00255 /// \brief Run-time helper that generates a new origin value for a stack 00256 /// allocation. 00257 Value *MsanSetAllocaOrigin4Fn; 00258 /// \brief Run-time helper that poisons stack on function entry. 00259 Value *MsanPoisonStackFn; 00260 /// \brief Run-time helper that records a store (or any event) of an 00261 /// uninitialized value and returns an updated origin id encoding this info. 00262 Value *MsanChainOriginFn; 00263 /// \brief MSan runtime replacements for memmove, memcpy and memset. 00264 Value *MemmoveFn, *MemcpyFn, *MemsetFn; 00265 00266 /// \brief Address mask used in application-to-shadow address calculation. 00267 /// ShadowAddr is computed as ApplicationAddr & ~ShadowMask. 00268 uint64_t ShadowMask; 00269 /// \brief Offset of the origin shadow from the "normal" shadow. 00270 /// OriginAddr is computed as (ShadowAddr + OriginOffset) & ~3ULL 00271 uint64_t OriginOffset; 00272 /// \brief Branch weights for error reporting. 00273 MDNode *ColdCallWeights; 00274 /// \brief Branch weights for origin store. 00275 MDNode *OriginStoreWeights; 00276 /// \brief An empty volatile inline asm that prevents callback merge. 00277 InlineAsm *EmptyAsm; 00278 00279 bool WrapIndirectCalls; 00280 /// \brief Run-time wrapper for indirect calls. 00281 Value *IndirectCallWrapperFn; 00282 // Argument and return type of IndirectCallWrapperFn: void (*f)(void). 00283 Type *AnyFunctionPtrTy; 00284 00285 friend struct MemorySanitizerVisitor; 00286 friend struct VarArgAMD64Helper; 00287 }; 00288 } // namespace 00289 00290 char MemorySanitizer::ID = 0; 00291 INITIALIZE_PASS(MemorySanitizer, "msan", 00292 "MemorySanitizer: detects uninitialized reads.", 00293 false, false) 00294 00295 FunctionPass *llvm::createMemorySanitizerPass(int TrackOrigins) { 00296 return new MemorySanitizer(TrackOrigins); 00297 } 00298 00299 /// \brief Create a non-const global initialized with the given string. 00300 /// 00301 /// Creates a writable global for Str so that we can pass it to the 00302 /// run-time lib. Runtime uses first 4 bytes of the string to store the 00303 /// frame ID, so the string needs to be mutable. 00304 static GlobalVariable *createPrivateNonConstGlobalForString(Module &M, 00305 StringRef Str) { 00306 Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str); 00307 return new GlobalVariable(M, StrConst->getType(), /*isConstant=*/false, 00308 GlobalValue::PrivateLinkage, StrConst, ""); 00309 } 00310 00311 00312 /// \brief Insert extern declaration of runtime-provided functions and globals. 00313 void MemorySanitizer::initializeCallbacks(Module &M) { 00314 // Only do this once. 00315 if (WarningFn) 00316 return; 00317 00318 IRBuilder<> IRB(*C); 00319 // Create the callback. 00320 // FIXME: this function should have "Cold" calling conv, 00321 // which is not yet implemented. 00322 StringRef WarningFnName = ClKeepGoing ? "__msan_warning" 00323 : "__msan_warning_noreturn"; 00324 WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy(), NULL); 00325 00326 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes; 00327 AccessSizeIndex++) { 00328 unsigned AccessSize = 1 << AccessSizeIndex; 00329 std::string FunctionName = "__msan_maybe_warning_" + itostr(AccessSize); 00330 MaybeWarningFn[AccessSizeIndex] = M.getOrInsertFunction( 00331 FunctionName, IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), 00332 IRB.getInt32Ty(), NULL); 00333 00334 FunctionName = "__msan_maybe_store_origin_" + itostr(AccessSize); 00335 MaybeStoreOriginFn[AccessSizeIndex] = M.getOrInsertFunction( 00336 FunctionName, IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), 00337 IRB.getInt8PtrTy(), IRB.getInt32Ty(), NULL); 00338 } 00339 00340 MsanSetAllocaOrigin4Fn = M.getOrInsertFunction( 00341 "__msan_set_alloca_origin4", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy, 00342 IRB.getInt8PtrTy(), IntptrTy, NULL); 00343 MsanPoisonStackFn = M.getOrInsertFunction( 00344 "__msan_poison_stack", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy, NULL); 00345 MsanChainOriginFn = M.getOrInsertFunction( 00346 "__msan_chain_origin", IRB.getInt32Ty(), IRB.getInt32Ty(), NULL); 00347 MemmoveFn = M.getOrInsertFunction( 00348 "__msan_memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), 00349 IRB.getInt8PtrTy(), IntptrTy, NULL); 00350 MemcpyFn = M.getOrInsertFunction( 00351 "__msan_memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), 00352 IntptrTy, NULL); 00353 MemsetFn = M.getOrInsertFunction( 00354 "__msan_memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(), 00355 IntptrTy, NULL); 00356 00357 // Create globals. 00358 RetvalTLS = new GlobalVariable( 00359 M, ArrayType::get(IRB.getInt64Ty(), 8), false, 00360 GlobalVariable::ExternalLinkage, nullptr, "__msan_retval_tls", nullptr, 00361 GlobalVariable::InitialExecTLSModel); 00362 RetvalOriginTLS = new GlobalVariable( 00363 M, OriginTy, false, GlobalVariable::ExternalLinkage, nullptr, 00364 "__msan_retval_origin_tls", nullptr, GlobalVariable::InitialExecTLSModel); 00365 00366 ParamTLS = new GlobalVariable( 00367 M, ArrayType::get(IRB.getInt64Ty(), 1000), false, 00368 GlobalVariable::ExternalLinkage, nullptr, "__msan_param_tls", nullptr, 00369 GlobalVariable::InitialExecTLSModel); 00370 ParamOriginTLS = new GlobalVariable( 00371 M, ArrayType::get(OriginTy, 1000), false, GlobalVariable::ExternalLinkage, 00372 nullptr, "__msan_param_origin_tls", nullptr, 00373 GlobalVariable::InitialExecTLSModel); 00374 00375 VAArgTLS = new GlobalVariable( 00376 M, ArrayType::get(IRB.getInt64Ty(), 1000), false, 00377 GlobalVariable::ExternalLinkage, nullptr, "__msan_va_arg_tls", nullptr, 00378 GlobalVariable::InitialExecTLSModel); 00379 VAArgOverflowSizeTLS = new GlobalVariable( 00380 M, IRB.getInt64Ty(), false, GlobalVariable::ExternalLinkage, nullptr, 00381 "__msan_va_arg_overflow_size_tls", nullptr, 00382 GlobalVariable::InitialExecTLSModel); 00383 OriginTLS = new GlobalVariable( 00384 M, IRB.getInt32Ty(), false, GlobalVariable::ExternalLinkage, nullptr, 00385 "__msan_origin_tls", nullptr, GlobalVariable::InitialExecTLSModel); 00386 00387 // We insert an empty inline asm after __msan_report* to avoid callback merge. 00388 EmptyAsm = InlineAsm::get(FunctionType::get(IRB.getVoidTy(), false), 00389 StringRef(""), StringRef(""), 00390 /*hasSideEffects=*/true); 00391 00392 if (WrapIndirectCalls) { 00393 AnyFunctionPtrTy = 00394 PointerType::getUnqual(FunctionType::get(IRB.getVoidTy(), false)); 00395 IndirectCallWrapperFn = M.getOrInsertFunction( 00396 ClWrapIndirectCalls, AnyFunctionPtrTy, AnyFunctionPtrTy, NULL); 00397 } 00398 00399 if (WrapIndirectCalls && ClWrapIndirectCallsFast) { 00400 MsandrModuleStart = new GlobalVariable( 00401 M, IRB.getInt32Ty(), false, GlobalValue::ExternalLinkage, 00402 nullptr, "__executable_start"); 00403 MsandrModuleStart->setVisibility(GlobalVariable::HiddenVisibility); 00404 MsandrModuleEnd = new GlobalVariable( 00405 M, IRB.getInt32Ty(), false, GlobalValue::ExternalLinkage, 00406 nullptr, "_end"); 00407 MsandrModuleEnd->setVisibility(GlobalVariable::HiddenVisibility); 00408 } 00409 } 00410 00411 /// \brief Module-level initialization. 00412 /// 00413 /// inserts a call to __msan_init to the module's constructor list. 00414 bool MemorySanitizer::doInitialization(Module &M) { 00415 DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>(); 00416 if (!DLP) 00417 report_fatal_error("data layout missing"); 00418 DL = &DLP->getDataLayout(); 00419 00420 C = &(M.getContext()); 00421 unsigned PtrSize = DL->getPointerSizeInBits(/* AddressSpace */0); 00422 switch (PtrSize) { 00423 case 64: 00424 ShadowMask = kShadowMask64; 00425 OriginOffset = kOriginOffset64; 00426 break; 00427 case 32: 00428 ShadowMask = kShadowMask32; 00429 OriginOffset = kOriginOffset32; 00430 break; 00431 default: 00432 report_fatal_error("unsupported pointer size"); 00433 break; 00434 } 00435 00436 IRBuilder<> IRB(*C); 00437 IntptrTy = IRB.getIntPtrTy(DL); 00438 OriginTy = IRB.getInt32Ty(); 00439 00440 ColdCallWeights = MDBuilder(*C).createBranchWeights(1, 1000); 00441 OriginStoreWeights = MDBuilder(*C).createBranchWeights(1, 1000); 00442 00443 // Insert a call to __msan_init/__msan_track_origins into the module's CTORs. 00444 appendToGlobalCtors(M, cast<Function>(M.getOrInsertFunction( 00445 "__msan_init", IRB.getVoidTy(), NULL)), 0); 00446 00447 if (TrackOrigins) 00448 new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage, 00449 IRB.getInt32(TrackOrigins), "__msan_track_origins"); 00450 00451 if (ClKeepGoing) 00452 new GlobalVariable(M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage, 00453 IRB.getInt32(ClKeepGoing), "__msan_keep_going"); 00454 00455 return true; 00456 } 00457 00458 namespace { 00459 00460 /// \brief A helper class that handles instrumentation of VarArg 00461 /// functions on a particular platform. 00462 /// 00463 /// Implementations are expected to insert the instrumentation 00464 /// necessary to propagate argument shadow through VarArg function 00465 /// calls. Visit* methods are called during an InstVisitor pass over 00466 /// the function, and should avoid creating new basic blocks. A new 00467 /// instance of this class is created for each instrumented function. 00468 struct VarArgHelper { 00469 /// \brief Visit a CallSite. 00470 virtual void visitCallSite(CallSite &CS, IRBuilder<> &IRB) = 0; 00471 00472 /// \brief Visit a va_start call. 00473 virtual void visitVAStartInst(VAStartInst &I) = 0; 00474 00475 /// \brief Visit a va_copy call. 00476 virtual void visitVACopyInst(VACopyInst &I) = 0; 00477 00478 /// \brief Finalize function instrumentation. 00479 /// 00480 /// This method is called after visiting all interesting (see above) 00481 /// instructions in a function. 00482 virtual void finalizeInstrumentation() = 0; 00483 00484 virtual ~VarArgHelper() {} 00485 }; 00486 00487 struct MemorySanitizerVisitor; 00488 00489 VarArgHelper* 00490 CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, 00491 MemorySanitizerVisitor &Visitor); 00492 00493 unsigned TypeSizeToSizeIndex(unsigned TypeSize) { 00494 if (TypeSize <= 8) return 0; 00495 return Log2_32_Ceil(TypeSize / 8); 00496 } 00497 00498 /// This class does all the work for a given function. Store and Load 00499 /// instructions store and load corresponding shadow and origin 00500 /// values. Most instructions propagate shadow from arguments to their 00501 /// return values. Certain instructions (most importantly, BranchInst) 00502 /// test their argument shadow and print reports (with a runtime call) if it's 00503 /// non-zero. 00504 struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> { 00505 Function &F; 00506 MemorySanitizer &MS; 00507 SmallVector<PHINode *, 16> ShadowPHINodes, OriginPHINodes; 00508 ValueMap<Value*, Value*> ShadowMap, OriginMap; 00509 std::unique_ptr<VarArgHelper> VAHelper; 00510 00511 // The following flags disable parts of MSan instrumentation based on 00512 // blacklist contents and command-line options. 00513 bool InsertChecks; 00514 bool PropagateShadow; 00515 bool PoisonStack; 00516 bool PoisonUndef; 00517 bool CheckReturnValue; 00518 00519 struct ShadowOriginAndInsertPoint { 00520 Value *Shadow; 00521 Value *Origin; 00522 Instruction *OrigIns; 00523 ShadowOriginAndInsertPoint(Value *S, Value *O, Instruction *I) 00524 : Shadow(S), Origin(O), OrigIns(I) { } 00525 }; 00526 SmallVector<ShadowOriginAndInsertPoint, 16> InstrumentationList; 00527 SmallVector<Instruction*, 16> StoreList; 00528 SmallVector<CallSite, 16> IndirectCallList; 00529 00530 MemorySanitizerVisitor(Function &F, MemorySanitizer &MS) 00531 : F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)) { 00532 bool SanitizeFunction = F.getAttributes().hasAttribute( 00533 AttributeSet::FunctionIndex, Attribute::SanitizeMemory); 00534 InsertChecks = SanitizeFunction; 00535 PropagateShadow = SanitizeFunction; 00536 PoisonStack = SanitizeFunction && ClPoisonStack; 00537 PoisonUndef = SanitizeFunction && ClPoisonUndef; 00538 // FIXME: Consider using SpecialCaseList to specify a list of functions that 00539 // must always return fully initialized values. For now, we hardcode "main". 00540 CheckReturnValue = SanitizeFunction && (F.getName() == "main"); 00541 00542 DEBUG(if (!InsertChecks) 00543 dbgs() << "MemorySanitizer is not inserting checks into '" 00544 << F.getName() << "'\n"); 00545 } 00546 00547 Value *updateOrigin(Value *V, IRBuilder<> &IRB) { 00548 if (MS.TrackOrigins <= 1) return V; 00549 return IRB.CreateCall(MS.MsanChainOriginFn, V); 00550 } 00551 00552 void storeOrigin(IRBuilder<> &IRB, Value *Addr, Value *Shadow, Value *Origin, 00553 unsigned Alignment, bool AsCall) { 00554 if (isa<StructType>(Shadow->getType())) { 00555 IRB.CreateAlignedStore(updateOrigin(Origin, IRB), getOriginPtr(Addr, IRB), 00556 Alignment); 00557 } else { 00558 Value *ConvertedShadow = convertToShadowTyNoVec(Shadow, IRB); 00559 // TODO(eugenis): handle non-zero constant shadow by inserting an 00560 // unconditional check (can not simply fail compilation as this could 00561 // be in the dead code). 00562 if (isa<Constant>(ConvertedShadow)) return; 00563 unsigned TypeSizeInBits = 00564 MS.DL->getTypeSizeInBits(ConvertedShadow->getType()); 00565 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits); 00566 if (AsCall && SizeIndex < kNumberOfAccessSizes) { 00567 Value *Fn = MS.MaybeStoreOriginFn[SizeIndex]; 00568 Value *ConvertedShadow2 = IRB.CreateZExt( 00569 ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex))); 00570 IRB.CreateCall3(Fn, ConvertedShadow2, 00571 IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()), 00572 Origin); 00573 } else { 00574 Value *Cmp = IRB.CreateICmpNE( 00575 ConvertedShadow, getCleanShadow(ConvertedShadow), "_mscmp"); 00576 Instruction *CheckTerm = SplitBlockAndInsertIfThen( 00577 Cmp, IRB.GetInsertPoint(), false, MS.OriginStoreWeights); 00578 IRBuilder<> IRBNew(CheckTerm); 00579 IRBNew.CreateAlignedStore(updateOrigin(Origin, IRBNew), 00580 getOriginPtr(Addr, IRBNew), Alignment); 00581 } 00582 } 00583 } 00584 00585 void materializeStores(bool InstrumentWithCalls) { 00586 for (auto Inst : StoreList) { 00587 StoreInst &SI = *dyn_cast<StoreInst>(Inst); 00588 00589 IRBuilder<> IRB(&SI); 00590 Value *Val = SI.getValueOperand(); 00591 Value *Addr = SI.getPointerOperand(); 00592 Value *Shadow = SI.isAtomic() ? getCleanShadow(Val) : getShadow(Val); 00593 Value *ShadowPtr = getShadowPtr(Addr, Shadow->getType(), IRB); 00594 00595 StoreInst *NewSI = 00596 IRB.CreateAlignedStore(Shadow, ShadowPtr, SI.getAlignment()); 00597 DEBUG(dbgs() << " STORE: " << *NewSI << "\n"); 00598 (void)NewSI; 00599 00600 if (ClCheckAccessAddress) insertShadowCheck(Addr, &SI); 00601 00602 if (SI.isAtomic()) SI.setOrdering(addReleaseOrdering(SI.getOrdering())); 00603 00604 if (MS.TrackOrigins) { 00605 unsigned Alignment = std::max(kMinOriginAlignment, SI.getAlignment()); 00606 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), Alignment, 00607 InstrumentWithCalls); 00608 } 00609 } 00610 } 00611 00612 void materializeOneCheck(Instruction *OrigIns, Value *Shadow, Value *Origin, 00613 bool AsCall) { 00614 IRBuilder<> IRB(OrigIns); 00615 DEBUG(dbgs() << " SHAD0 : " << *Shadow << "\n"); 00616 Value *ConvertedShadow = convertToShadowTyNoVec(Shadow, IRB); 00617 DEBUG(dbgs() << " SHAD1 : " << *ConvertedShadow << "\n"); 00618 // See the comment in materializeStores(). 00619 if (isa<Constant>(ConvertedShadow)) return; 00620 unsigned TypeSizeInBits = 00621 MS.DL->getTypeSizeInBits(ConvertedShadow->getType()); 00622 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits); 00623 if (AsCall && SizeIndex < kNumberOfAccessSizes) { 00624 Value *Fn = MS.MaybeWarningFn[SizeIndex]; 00625 Value *ConvertedShadow2 = 00626 IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex))); 00627 IRB.CreateCall2(Fn, ConvertedShadow2, MS.TrackOrigins && Origin 00628 ? Origin 00629 : (Value *)IRB.getInt32(0)); 00630 } else { 00631 Value *Cmp = IRB.CreateICmpNE(ConvertedShadow, 00632 getCleanShadow(ConvertedShadow), "_mscmp"); 00633 Instruction *CheckTerm = SplitBlockAndInsertIfThen( 00634 Cmp, OrigIns, 00635 /* Unreachable */ !ClKeepGoing, MS.ColdCallWeights); 00636 00637 IRB.SetInsertPoint(CheckTerm); 00638 if (MS.TrackOrigins) { 00639 IRB.CreateStore(Origin ? (Value *)Origin : (Value *)IRB.getInt32(0), 00640 MS.OriginTLS); 00641 } 00642 IRB.CreateCall(MS.WarningFn); 00643 IRB.CreateCall(MS.EmptyAsm); 00644 DEBUG(dbgs() << " CHECK: " << *Cmp << "\n"); 00645 } 00646 } 00647 00648 void materializeChecks(bool InstrumentWithCalls) { 00649 for (const auto &ShadowData : InstrumentationList) { 00650 Instruction *OrigIns = ShadowData.OrigIns; 00651 Value *Shadow = ShadowData.Shadow; 00652 Value *Origin = ShadowData.Origin; 00653 materializeOneCheck(OrigIns, Shadow, Origin, InstrumentWithCalls); 00654 } 00655 DEBUG(dbgs() << "DONE:\n" << F); 00656 } 00657 00658 void materializeIndirectCalls() { 00659 for (auto &CS : IndirectCallList) { 00660 Instruction *I = CS.getInstruction(); 00661 BasicBlock *B = I->getParent(); 00662 IRBuilder<> IRB(I); 00663 Value *Fn0 = CS.getCalledValue(); 00664 Value *Fn = IRB.CreateBitCast(Fn0, MS.AnyFunctionPtrTy); 00665 00666 if (ClWrapIndirectCallsFast) { 00667 // Check that call target is inside this module limits. 00668 Value *Start = 00669 IRB.CreateBitCast(MS.MsandrModuleStart, MS.AnyFunctionPtrTy); 00670 Value *End = IRB.CreateBitCast(MS.MsandrModuleEnd, MS.AnyFunctionPtrTy); 00671 00672 Value *NotInThisModule = IRB.CreateOr(IRB.CreateICmpULT(Fn, Start), 00673 IRB.CreateICmpUGE(Fn, End)); 00674 00675 PHINode *NewFnPhi = 00676 IRB.CreatePHI(Fn0->getType(), 2, "msandr.indirect_target"); 00677 00678 Instruction *CheckTerm = SplitBlockAndInsertIfThen( 00679 NotInThisModule, NewFnPhi, 00680 /* Unreachable */ false, MS.ColdCallWeights); 00681 00682 IRB.SetInsertPoint(CheckTerm); 00683 // Slow path: call wrapper function to possibly transform the call 00684 // target. 00685 Value *NewFn = IRB.CreateBitCast( 00686 IRB.CreateCall(MS.IndirectCallWrapperFn, Fn), Fn0->getType()); 00687 00688 NewFnPhi->addIncoming(Fn0, B); 00689 NewFnPhi->addIncoming(NewFn, dyn_cast<Instruction>(NewFn)->getParent()); 00690 CS.setCalledFunction(NewFnPhi); 00691 } else { 00692 Value *NewFn = IRB.CreateBitCast( 00693 IRB.CreateCall(MS.IndirectCallWrapperFn, Fn), Fn0->getType()); 00694 CS.setCalledFunction(NewFn); 00695 } 00696 } 00697 } 00698 00699 /// \brief Add MemorySanitizer instrumentation to a function. 00700 bool runOnFunction() { 00701 MS.initializeCallbacks(*F.getParent()); 00702 if (!MS.DL) return false; 00703 00704 // In the presence of unreachable blocks, we may see Phi nodes with 00705 // incoming nodes from such blocks. Since InstVisitor skips unreachable 00706 // blocks, such nodes will not have any shadow value associated with them. 00707 // It's easier to remove unreachable blocks than deal with missing shadow. 00708 removeUnreachableBlocks(F); 00709 00710 // Iterate all BBs in depth-first order and create shadow instructions 00711 // for all instructions (where applicable). 00712 // For PHI nodes we create dummy shadow PHIs which will be finalized later. 00713 for (BasicBlock *BB : depth_first(&F.getEntryBlock())) 00714 visit(*BB); 00715 00716 00717 // Finalize PHI nodes. 00718 for (PHINode *PN : ShadowPHINodes) { 00719 PHINode *PNS = cast<PHINode>(getShadow(PN)); 00720 PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : nullptr; 00721 size_t NumValues = PN->getNumIncomingValues(); 00722 for (size_t v = 0; v < NumValues; v++) { 00723 PNS->addIncoming(getShadow(PN, v), PN->getIncomingBlock(v)); 00724 if (PNO) PNO->addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v)); 00725 } 00726 } 00727 00728 VAHelper->finalizeInstrumentation(); 00729 00730 bool InstrumentWithCalls = ClInstrumentationWithCallThreshold >= 0 && 00731 InstrumentationList.size() + StoreList.size() > 00732 (unsigned)ClInstrumentationWithCallThreshold; 00733 00734 // Delayed instrumentation of StoreInst. 00735 // This may add new checks to be inserted later. 00736 materializeStores(InstrumentWithCalls); 00737 00738 // Insert shadow value checks. 00739 materializeChecks(InstrumentWithCalls); 00740 00741 // Wrap indirect calls. 00742 materializeIndirectCalls(); 00743 00744 return true; 00745 } 00746 00747 /// \brief Compute the shadow type that corresponds to a given Value. 00748 Type *getShadowTy(Value *V) { 00749 return getShadowTy(V->getType()); 00750 } 00751 00752 /// \brief Compute the shadow type that corresponds to a given Type. 00753 Type *getShadowTy(Type *OrigTy) { 00754 if (!OrigTy->isSized()) { 00755 return nullptr; 00756 } 00757 // For integer type, shadow is the same as the original type. 00758 // This may return weird-sized types like i1. 00759 if (IntegerType *IT = dyn_cast<IntegerType>(OrigTy)) 00760 return IT; 00761 if (VectorType *VT = dyn_cast<VectorType>(OrigTy)) { 00762 uint32_t EltSize = MS.DL->getTypeSizeInBits(VT->getElementType()); 00763 return VectorType::get(IntegerType::get(*MS.C, EltSize), 00764 VT->getNumElements()); 00765 } 00766 if (ArrayType *AT = dyn_cast<ArrayType>(OrigTy)) { 00767 return ArrayType::get(getShadowTy(AT->getElementType()), 00768 AT->getNumElements()); 00769 } 00770 if (StructType *ST = dyn_cast<StructType>(OrigTy)) { 00771 SmallVector<Type*, 4> Elements; 00772 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++) 00773 Elements.push_back(getShadowTy(ST->getElementType(i))); 00774 StructType *Res = StructType::get(*MS.C, Elements, ST->isPacked()); 00775 DEBUG(dbgs() << "getShadowTy: " << *ST << " ===> " << *Res << "\n"); 00776 return Res; 00777 } 00778 uint32_t TypeSize = MS.DL->getTypeSizeInBits(OrigTy); 00779 return IntegerType::get(*MS.C, TypeSize); 00780 } 00781 00782 /// \brief Flatten a vector type. 00783 Type *getShadowTyNoVec(Type *ty) { 00784 if (VectorType *vt = dyn_cast<VectorType>(ty)) 00785 return IntegerType::get(*MS.C, vt->getBitWidth()); 00786 return ty; 00787 } 00788 00789 /// \brief Convert a shadow value to it's flattened variant. 00790 Value *convertToShadowTyNoVec(Value *V, IRBuilder<> &IRB) { 00791 Type *Ty = V->getType(); 00792 Type *NoVecTy = getShadowTyNoVec(Ty); 00793 if (Ty == NoVecTy) return V; 00794 return IRB.CreateBitCast(V, NoVecTy); 00795 } 00796 00797 /// \brief Compute the shadow address that corresponds to a given application 00798 /// address. 00799 /// 00800 /// Shadow = Addr & ~ShadowMask. 00801 Value *getShadowPtr(Value *Addr, Type *ShadowTy, 00802 IRBuilder<> &IRB) { 00803 Value *ShadowLong = 00804 IRB.CreateAnd(IRB.CreatePointerCast(Addr, MS.IntptrTy), 00805 ConstantInt::get(MS.IntptrTy, ~MS.ShadowMask)); 00806 return IRB.CreateIntToPtr(ShadowLong, PointerType::get(ShadowTy, 0)); 00807 } 00808 00809 /// \brief Compute the origin address that corresponds to a given application 00810 /// address. 00811 /// 00812 /// OriginAddr = (ShadowAddr + OriginOffset) & ~3ULL 00813 Value *getOriginPtr(Value *Addr, IRBuilder<> &IRB) { 00814 Value *ShadowLong = 00815 IRB.CreateAnd(IRB.CreatePointerCast(Addr, MS.IntptrTy), 00816 ConstantInt::get(MS.IntptrTy, ~MS.ShadowMask)); 00817 Value *Add = 00818 IRB.CreateAdd(ShadowLong, 00819 ConstantInt::get(MS.IntptrTy, MS.OriginOffset)); 00820 Value *SecondAnd = 00821 IRB.CreateAnd(Add, ConstantInt::get(MS.IntptrTy, ~3ULL)); 00822 return IRB.CreateIntToPtr(SecondAnd, PointerType::get(IRB.getInt32Ty(), 0)); 00823 } 00824 00825 /// \brief Compute the shadow address for a given function argument. 00826 /// 00827 /// Shadow = ParamTLS+ArgOffset. 00828 Value *getShadowPtrForArgument(Value *A, IRBuilder<> &IRB, 00829 int ArgOffset) { 00830 Value *Base = IRB.CreatePointerCast(MS.ParamTLS, MS.IntptrTy); 00831 Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); 00832 return IRB.CreateIntToPtr(Base, PointerType::get(getShadowTy(A), 0), 00833 "_msarg"); 00834 } 00835 00836 /// \brief Compute the origin address for a given function argument. 00837 Value *getOriginPtrForArgument(Value *A, IRBuilder<> &IRB, 00838 int ArgOffset) { 00839 if (!MS.TrackOrigins) return nullptr; 00840 Value *Base = IRB.CreatePointerCast(MS.ParamOriginTLS, MS.IntptrTy); 00841 Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); 00842 return IRB.CreateIntToPtr(Base, PointerType::get(MS.OriginTy, 0), 00843 "_msarg_o"); 00844 } 00845 00846 /// \brief Compute the shadow address for a retval. 00847 Value *getShadowPtrForRetval(Value *A, IRBuilder<> &IRB) { 00848 Value *Base = IRB.CreatePointerCast(MS.RetvalTLS, MS.IntptrTy); 00849 return IRB.CreateIntToPtr(Base, PointerType::get(getShadowTy(A), 0), 00850 "_msret"); 00851 } 00852 00853 /// \brief Compute the origin address for a retval. 00854 Value *getOriginPtrForRetval(IRBuilder<> &IRB) { 00855 // We keep a single origin for the entire retval. Might be too optimistic. 00856 return MS.RetvalOriginTLS; 00857 } 00858 00859 /// \brief Set SV to be the shadow value for V. 00860 void setShadow(Value *V, Value *SV) { 00861 assert(!ShadowMap.count(V) && "Values may only have one shadow"); 00862 ShadowMap[V] = PropagateShadow ? SV : getCleanShadow(V); 00863 } 00864 00865 /// \brief Set Origin to be the origin value for V. 00866 void setOrigin(Value *V, Value *Origin) { 00867 if (!MS.TrackOrigins) return; 00868 assert(!OriginMap.count(V) && "Values may only have one origin"); 00869 DEBUG(dbgs() << "ORIGIN: " << *V << " ==> " << *Origin << "\n"); 00870 OriginMap[V] = Origin; 00871 } 00872 00873 /// \brief Create a clean shadow value for a given value. 00874 /// 00875 /// Clean shadow (all zeroes) means all bits of the value are defined 00876 /// (initialized). 00877 Constant *getCleanShadow(Value *V) { 00878 Type *ShadowTy = getShadowTy(V); 00879 if (!ShadowTy) 00880 return nullptr; 00881 return Constant::getNullValue(ShadowTy); 00882 } 00883 00884 /// \brief Create a dirty shadow of a given shadow type. 00885 Constant *getPoisonedShadow(Type *ShadowTy) { 00886 assert(ShadowTy); 00887 if (isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy)) 00888 return Constant::getAllOnesValue(ShadowTy); 00889 if (ArrayType *AT = dyn_cast<ArrayType>(ShadowTy)) { 00890 SmallVector<Constant *, 4> Vals(AT->getNumElements(), 00891 getPoisonedShadow(AT->getElementType())); 00892 return ConstantArray::get(AT, Vals); 00893 } 00894 if (StructType *ST = dyn_cast<StructType>(ShadowTy)) { 00895 SmallVector<Constant *, 4> Vals; 00896 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++) 00897 Vals.push_back(getPoisonedShadow(ST->getElementType(i))); 00898 return ConstantStruct::get(ST, Vals); 00899 } 00900 llvm_unreachable("Unexpected shadow type"); 00901 } 00902 00903 /// \brief Create a dirty shadow for a given value. 00904 Constant *getPoisonedShadow(Value *V) { 00905 Type *ShadowTy = getShadowTy(V); 00906 if (!ShadowTy) 00907 return nullptr; 00908 return getPoisonedShadow(ShadowTy); 00909 } 00910 00911 /// \brief Create a clean (zero) origin. 00912 Value *getCleanOrigin() { 00913 return Constant::getNullValue(MS.OriginTy); 00914 } 00915 00916 /// \brief Get the shadow value for a given Value. 00917 /// 00918 /// This function either returns the value set earlier with setShadow, 00919 /// or extracts if from ParamTLS (for function arguments). 00920 Value *getShadow(Value *V) { 00921 if (!PropagateShadow) return getCleanShadow(V); 00922 if (Instruction *I = dyn_cast<Instruction>(V)) { 00923 // For instructions the shadow is already stored in the map. 00924 Value *Shadow = ShadowMap[V]; 00925 if (!Shadow) { 00926 DEBUG(dbgs() << "No shadow: " << *V << "\n" << *(I->getParent())); 00927 (void)I; 00928 assert(Shadow && "No shadow for a value"); 00929 } 00930 return Shadow; 00931 } 00932 if (UndefValue *U = dyn_cast<UndefValue>(V)) { 00933 Value *AllOnes = PoisonUndef ? getPoisonedShadow(V) : getCleanShadow(V); 00934 DEBUG(dbgs() << "Undef: " << *U << " ==> " << *AllOnes << "\n"); 00935 (void)U; 00936 return AllOnes; 00937 } 00938 if (Argument *A = dyn_cast<Argument>(V)) { 00939 // For arguments we compute the shadow on demand and store it in the map. 00940 Value **ShadowPtr = &ShadowMap[V]; 00941 if (*ShadowPtr) 00942 return *ShadowPtr; 00943 Function *F = A->getParent(); 00944 IRBuilder<> EntryIRB(F->getEntryBlock().getFirstNonPHI()); 00945 unsigned ArgOffset = 0; 00946 for (auto &FArg : F->args()) { 00947 if (!FArg.getType()->isSized()) { 00948 DEBUG(dbgs() << "Arg is not sized\n"); 00949 continue; 00950 } 00951 unsigned Size = FArg.hasByValAttr() 00952 ? MS.DL->getTypeAllocSize(FArg.getType()->getPointerElementType()) 00953 : MS.DL->getTypeAllocSize(FArg.getType()); 00954 if (A == &FArg) { 00955 Value *Base = getShadowPtrForArgument(&FArg, EntryIRB, ArgOffset); 00956 if (FArg.hasByValAttr()) { 00957 // ByVal pointer itself has clean shadow. We copy the actual 00958 // argument shadow to the underlying memory. 00959 // Figure out maximal valid memcpy alignment. 00960 unsigned ArgAlign = FArg.getParamAlignment(); 00961 if (ArgAlign == 0) { 00962 Type *EltType = A->getType()->getPointerElementType(); 00963 ArgAlign = MS.DL->getABITypeAlignment(EltType); 00964 } 00965 unsigned CopyAlign = std::min(ArgAlign, kShadowTLSAlignment); 00966 Value *Cpy = EntryIRB.CreateMemCpy( 00967 getShadowPtr(V, EntryIRB.getInt8Ty(), EntryIRB), Base, Size, 00968 CopyAlign); 00969 DEBUG(dbgs() << " ByValCpy: " << *Cpy << "\n"); 00970 (void)Cpy; 00971 *ShadowPtr = getCleanShadow(V); 00972 } else { 00973 *ShadowPtr = EntryIRB.CreateAlignedLoad(Base, kShadowTLSAlignment); 00974 } 00975 DEBUG(dbgs() << " ARG: " << FArg << " ==> " << 00976 **ShadowPtr << "\n"); 00977 if (MS.TrackOrigins) { 00978 Value *OriginPtr = 00979 getOriginPtrForArgument(&FArg, EntryIRB, ArgOffset); 00980 setOrigin(A, EntryIRB.CreateLoad(OriginPtr)); 00981 } 00982 } 00983 ArgOffset += DataLayout::RoundUpAlignment(Size, kShadowTLSAlignment); 00984 } 00985 assert(*ShadowPtr && "Could not find shadow for an argument"); 00986 return *ShadowPtr; 00987 } 00988 // For everything else the shadow is zero. 00989 return getCleanShadow(V); 00990 } 00991 00992 /// \brief Get the shadow for i-th argument of the instruction I. 00993 Value *getShadow(Instruction *I, int i) { 00994 return getShadow(I->getOperand(i)); 00995 } 00996 00997 /// \brief Get the origin for a value. 00998 Value *getOrigin(Value *V) { 00999 if (!MS.TrackOrigins) return nullptr; 01000 if (isa<Instruction>(V) || isa<Argument>(V)) { 01001 Value *Origin = OriginMap[V]; 01002 if (!Origin) { 01003 DEBUG(dbgs() << "NO ORIGIN: " << *V << "\n"); 01004 Origin = getCleanOrigin(); 01005 } 01006 return Origin; 01007 } 01008 return getCleanOrigin(); 01009 } 01010 01011 /// \brief Get the origin for i-th argument of the instruction I. 01012 Value *getOrigin(Instruction *I, int i) { 01013 return getOrigin(I->getOperand(i)); 01014 } 01015 01016 /// \brief Remember the place where a shadow check should be inserted. 01017 /// 01018 /// This location will be later instrumented with a check that will print a 01019 /// UMR warning in runtime if the shadow value is not 0. 01020 void insertShadowCheck(Value *Shadow, Value *Origin, Instruction *OrigIns) { 01021 assert(Shadow); 01022 if (!InsertChecks) return; 01023 #ifndef NDEBUG 01024 Type *ShadowTy = Shadow->getType(); 01025 assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy)) && 01026 "Can only insert checks for integer and vector shadow types"); 01027 #endif 01028 InstrumentationList.push_back( 01029 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns)); 01030 } 01031 01032 /// \brief Remember the place where a shadow check should be inserted. 01033 /// 01034 /// This location will be later instrumented with a check that will print a 01035 /// UMR warning in runtime if the value is not fully defined. 01036 void insertShadowCheck(Value *Val, Instruction *OrigIns) { 01037 assert(Val); 01038 Instruction *Shadow = dyn_cast_or_null<Instruction>(getShadow(Val)); 01039 if (!Shadow) return; 01040 Instruction *Origin = dyn_cast_or_null<Instruction>(getOrigin(Val)); 01041 insertShadowCheck(Shadow, Origin, OrigIns); 01042 } 01043 01044 AtomicOrdering addReleaseOrdering(AtomicOrdering a) { 01045 switch (a) { 01046 case NotAtomic: 01047 return NotAtomic; 01048 case Unordered: 01049 case Monotonic: 01050 case Release: 01051 return Release; 01052 case Acquire: 01053 case AcquireRelease: 01054 return AcquireRelease; 01055 case SequentiallyConsistent: 01056 return SequentiallyConsistent; 01057 } 01058 llvm_unreachable("Unknown ordering"); 01059 } 01060 01061 AtomicOrdering addAcquireOrdering(AtomicOrdering a) { 01062 switch (a) { 01063 case NotAtomic: 01064 return NotAtomic; 01065 case Unordered: 01066 case Monotonic: 01067 case Acquire: 01068 return Acquire; 01069 case Release: 01070 case AcquireRelease: 01071 return AcquireRelease; 01072 case SequentiallyConsistent: 01073 return SequentiallyConsistent; 01074 } 01075 llvm_unreachable("Unknown ordering"); 01076 } 01077 01078 // ------------------- Visitors. 01079 01080 /// \brief Instrument LoadInst 01081 /// 01082 /// Loads the corresponding shadow and (optionally) origin. 01083 /// Optionally, checks that the load address is fully defined. 01084 void visitLoadInst(LoadInst &I) { 01085 assert(I.getType()->isSized() && "Load type must have size"); 01086 IRBuilder<> IRB(I.getNextNode()); 01087 Type *ShadowTy = getShadowTy(&I); 01088 Value *Addr = I.getPointerOperand(); 01089 if (PropagateShadow) { 01090 Value *ShadowPtr = getShadowPtr(Addr, ShadowTy, IRB); 01091 setShadow(&I, 01092 IRB.CreateAlignedLoad(ShadowPtr, I.getAlignment(), "_msld")); 01093 } else { 01094 setShadow(&I, getCleanShadow(&I)); 01095 } 01096 01097 if (ClCheckAccessAddress) 01098 insertShadowCheck(I.getPointerOperand(), &I); 01099 01100 if (I.isAtomic()) 01101 I.setOrdering(addAcquireOrdering(I.getOrdering())); 01102 01103 if (MS.TrackOrigins) { 01104 if (PropagateShadow) { 01105 unsigned Alignment = std::max(kMinOriginAlignment, I.getAlignment()); 01106 setOrigin(&I, 01107 IRB.CreateAlignedLoad(getOriginPtr(Addr, IRB), Alignment)); 01108 } else { 01109 setOrigin(&I, getCleanOrigin()); 01110 } 01111 } 01112 } 01113 01114 /// \brief Instrument StoreInst 01115 /// 01116 /// Stores the corresponding shadow and (optionally) origin. 01117 /// Optionally, checks that the store address is fully defined. 01118 void visitStoreInst(StoreInst &I) { 01119 StoreList.push_back(&I); 01120 } 01121 01122 void handleCASOrRMW(Instruction &I) { 01123 assert(isa<AtomicRMWInst>(I) || isa<AtomicCmpXchgInst>(I)); 01124 01125 IRBuilder<> IRB(&I); 01126 Value *Addr = I.getOperand(0); 01127 Value *ShadowPtr = getShadowPtr(Addr, I.getType(), IRB); 01128 01129 if (ClCheckAccessAddress) 01130 insertShadowCheck(Addr, &I); 01131 01132 // Only test the conditional argument of cmpxchg instruction. 01133 // The other argument can potentially be uninitialized, but we can not 01134 // detect this situation reliably without possible false positives. 01135 if (isa<AtomicCmpXchgInst>(I)) 01136 insertShadowCheck(I.getOperand(1), &I); 01137 01138 IRB.CreateStore(getCleanShadow(&I), ShadowPtr); 01139 01140 setShadow(&I, getCleanShadow(&I)); 01141 } 01142 01143 void visitAtomicRMWInst(AtomicRMWInst &I) { 01144 handleCASOrRMW(I); 01145 I.setOrdering(addReleaseOrdering(I.getOrdering())); 01146 } 01147 01148 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) { 01149 handleCASOrRMW(I); 01150 I.setSuccessOrdering(addReleaseOrdering(I.getSuccessOrdering())); 01151 } 01152 01153 // Vector manipulation. 01154 void visitExtractElementInst(ExtractElementInst &I) { 01155 insertShadowCheck(I.getOperand(1), &I); 01156 IRBuilder<> IRB(&I); 01157 setShadow(&I, IRB.CreateExtractElement(getShadow(&I, 0), I.getOperand(1), 01158 "_msprop")); 01159 setOrigin(&I, getOrigin(&I, 0)); 01160 } 01161 01162 void visitInsertElementInst(InsertElementInst &I) { 01163 insertShadowCheck(I.getOperand(2), &I); 01164 IRBuilder<> IRB(&I); 01165 setShadow(&I, IRB.CreateInsertElement(getShadow(&I, 0), getShadow(&I, 1), 01166 I.getOperand(2), "_msprop")); 01167 setOriginForNaryOp(I); 01168 } 01169 01170 void visitShuffleVectorInst(ShuffleVectorInst &I) { 01171 insertShadowCheck(I.getOperand(2), &I); 01172 IRBuilder<> IRB(&I); 01173 setShadow(&I, IRB.CreateShuffleVector(getShadow(&I, 0), getShadow(&I, 1), 01174 I.getOperand(2), "_msprop")); 01175 setOriginForNaryOp(I); 01176 } 01177 01178 // Casts. 01179 void visitSExtInst(SExtInst &I) { 01180 IRBuilder<> IRB(&I); 01181 setShadow(&I, IRB.CreateSExt(getShadow(&I, 0), I.getType(), "_msprop")); 01182 setOrigin(&I, getOrigin(&I, 0)); 01183 } 01184 01185 void visitZExtInst(ZExtInst &I) { 01186 IRBuilder<> IRB(&I); 01187 setShadow(&I, IRB.CreateZExt(getShadow(&I, 0), I.getType(), "_msprop")); 01188 setOrigin(&I, getOrigin(&I, 0)); 01189 } 01190 01191 void visitTruncInst(TruncInst &I) { 01192 IRBuilder<> IRB(&I); 01193 setShadow(&I, IRB.CreateTrunc(getShadow(&I, 0), I.getType(), "_msprop")); 01194 setOrigin(&I, getOrigin(&I, 0)); 01195 } 01196 01197 void visitBitCastInst(BitCastInst &I) { 01198 IRBuilder<> IRB(&I); 01199 setShadow(&I, IRB.CreateBitCast(getShadow(&I, 0), getShadowTy(&I))); 01200 setOrigin(&I, getOrigin(&I, 0)); 01201 } 01202 01203 void visitPtrToIntInst(PtrToIntInst &I) { 01204 IRBuilder<> IRB(&I); 01205 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false, 01206 "_msprop_ptrtoint")); 01207 setOrigin(&I, getOrigin(&I, 0)); 01208 } 01209 01210 void visitIntToPtrInst(IntToPtrInst &I) { 01211 IRBuilder<> IRB(&I); 01212 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false, 01213 "_msprop_inttoptr")); 01214 setOrigin(&I, getOrigin(&I, 0)); 01215 } 01216 01217 void visitFPToSIInst(CastInst& I) { handleShadowOr(I); } 01218 void visitFPToUIInst(CastInst& I) { handleShadowOr(I); } 01219 void visitSIToFPInst(CastInst& I) { handleShadowOr(I); } 01220 void visitUIToFPInst(CastInst& I) { handleShadowOr(I); } 01221 void visitFPExtInst(CastInst& I) { handleShadowOr(I); } 01222 void visitFPTruncInst(CastInst& I) { handleShadowOr(I); } 01223 01224 /// \brief Propagate shadow for bitwise AND. 01225 /// 01226 /// This code is exact, i.e. if, for example, a bit in the left argument 01227 /// is defined and 0, then neither the value not definedness of the 01228 /// corresponding bit in B don't affect the resulting shadow. 01229 void visitAnd(BinaryOperator &I) { 01230 IRBuilder<> IRB(&I); 01231 // "And" of 0 and a poisoned value results in unpoisoned value. 01232 // 1&1 => 1; 0&1 => 0; p&1 => p; 01233 // 1&0 => 0; 0&0 => 0; p&0 => 0; 01234 // 1&p => p; 0&p => 0; p&p => p; 01235 // S = (S1 & S2) | (V1 & S2) | (S1 & V2) 01236 Value *S1 = getShadow(&I, 0); 01237 Value *S2 = getShadow(&I, 1); 01238 Value *V1 = I.getOperand(0); 01239 Value *V2 = I.getOperand(1); 01240 if (V1->getType() != S1->getType()) { 01241 V1 = IRB.CreateIntCast(V1, S1->getType(), false); 01242 V2 = IRB.CreateIntCast(V2, S2->getType(), false); 01243 } 01244 Value *S1S2 = IRB.CreateAnd(S1, S2); 01245 Value *V1S2 = IRB.CreateAnd(V1, S2); 01246 Value *S1V2 = IRB.CreateAnd(S1, V2); 01247 setShadow(&I, IRB.CreateOr(S1S2, IRB.CreateOr(V1S2, S1V2))); 01248 setOriginForNaryOp(I); 01249 } 01250 01251 void visitOr(BinaryOperator &I) { 01252 IRBuilder<> IRB(&I); 01253 // "Or" of 1 and a poisoned value results in unpoisoned value. 01254 // 1|1 => 1; 0|1 => 1; p|1 => 1; 01255 // 1|0 => 1; 0|0 => 0; p|0 => p; 01256 // 1|p => 1; 0|p => p; p|p => p; 01257 // S = (S1 & S2) | (~V1 & S2) | (S1 & ~V2) 01258 Value *S1 = getShadow(&I, 0); 01259 Value *S2 = getShadow(&I, 1); 01260 Value *V1 = IRB.CreateNot(I.getOperand(0)); 01261 Value *V2 = IRB.CreateNot(I.getOperand(1)); 01262 if (V1->getType() != S1->getType()) { 01263 V1 = IRB.CreateIntCast(V1, S1->getType(), false); 01264 V2 = IRB.CreateIntCast(V2, S2->getType(), false); 01265 } 01266 Value *S1S2 = IRB.CreateAnd(S1, S2); 01267 Value *V1S2 = IRB.CreateAnd(V1, S2); 01268 Value *S1V2 = IRB.CreateAnd(S1, V2); 01269 setShadow(&I, IRB.CreateOr(S1S2, IRB.CreateOr(V1S2, S1V2))); 01270 setOriginForNaryOp(I); 01271 } 01272 01273 /// \brief Default propagation of shadow and/or origin. 01274 /// 01275 /// This class implements the general case of shadow propagation, used in all 01276 /// cases where we don't know and/or don't care about what the operation 01277 /// actually does. It converts all input shadow values to a common type 01278 /// (extending or truncating as necessary), and bitwise OR's them. 01279 /// 01280 /// This is much cheaper than inserting checks (i.e. requiring inputs to be 01281 /// fully initialized), and less prone to false positives. 01282 /// 01283 /// This class also implements the general case of origin propagation. For a 01284 /// Nary operation, result origin is set to the origin of an argument that is 01285 /// not entirely initialized. If there is more than one such arguments, the 01286 /// rightmost of them is picked. It does not matter which one is picked if all 01287 /// arguments are initialized. 01288 template <bool CombineShadow> 01289 class Combiner { 01290 Value *Shadow; 01291 Value *Origin; 01292 IRBuilder<> &IRB; 01293 MemorySanitizerVisitor *MSV; 01294 01295 public: 01296 Combiner(MemorySanitizerVisitor *MSV, IRBuilder<> &IRB) : 01297 Shadow(nullptr), Origin(nullptr), IRB(IRB), MSV(MSV) {} 01298 01299 /// \brief Add a pair of shadow and origin values to the mix. 01300 Combiner &Add(Value *OpShadow, Value *OpOrigin) { 01301 if (CombineShadow) { 01302 assert(OpShadow); 01303 if (!Shadow) 01304 Shadow = OpShadow; 01305 else { 01306 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType()); 01307 Shadow = IRB.CreateOr(Shadow, OpShadow, "_msprop"); 01308 } 01309 } 01310 01311 if (MSV->MS.TrackOrigins) { 01312 assert(OpOrigin); 01313 if (!Origin) { 01314 Origin = OpOrigin; 01315 } else { 01316 Constant *ConstOrigin = dyn_cast<Constant>(OpOrigin); 01317 // No point in adding something that might result in 0 origin value. 01318 if (!ConstOrigin || !ConstOrigin->isNullValue()) { 01319 Value *FlatShadow = MSV->convertToShadowTyNoVec(OpShadow, IRB); 01320 Value *Cond = 01321 IRB.CreateICmpNE(FlatShadow, MSV->getCleanShadow(FlatShadow)); 01322 Origin = IRB.CreateSelect(Cond, OpOrigin, Origin); 01323 } 01324 } 01325 } 01326 return *this; 01327 } 01328 01329 /// \brief Add an application value to the mix. 01330 Combiner &Add(Value *V) { 01331 Value *OpShadow = MSV->getShadow(V); 01332 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) : nullptr; 01333 return Add(OpShadow, OpOrigin); 01334 } 01335 01336 /// \brief Set the current combined values as the given instruction's shadow 01337 /// and origin. 01338 void Done(Instruction *I) { 01339 if (CombineShadow) { 01340 assert(Shadow); 01341 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(I)); 01342 MSV->setShadow(I, Shadow); 01343 } 01344 if (MSV->MS.TrackOrigins) { 01345 assert(Origin); 01346 MSV->setOrigin(I, Origin); 01347 } 01348 } 01349 }; 01350 01351 typedef Combiner<true> ShadowAndOriginCombiner; 01352 typedef Combiner<false> OriginCombiner; 01353 01354 /// \brief Propagate origin for arbitrary operation. 01355 void setOriginForNaryOp(Instruction &I) { 01356 if (!MS.TrackOrigins) return; 01357 IRBuilder<> IRB(&I); 01358 OriginCombiner OC(this, IRB); 01359 for (Instruction::op_iterator OI = I.op_begin(); OI != I.op_end(); ++OI) 01360 OC.Add(OI->get()); 01361 OC.Done(&I); 01362 } 01363 01364 size_t VectorOrPrimitiveTypeSizeInBits(Type *Ty) { 01365 assert(!(Ty->isVectorTy() && Ty->getScalarType()->isPointerTy()) && 01366 "Vector of pointers is not a valid shadow type"); 01367 return Ty->isVectorTy() ? 01368 Ty->getVectorNumElements() * Ty->getScalarSizeInBits() : 01369 Ty->getPrimitiveSizeInBits(); 01370 } 01371 01372 /// \brief Cast between two shadow types, extending or truncating as 01373 /// necessary. 01374 Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy, 01375 bool Signed = false) { 01376 Type *srcTy = V->getType(); 01377 if (dstTy->isIntegerTy() && srcTy->isIntegerTy()) 01378 return IRB.CreateIntCast(V, dstTy, Signed); 01379 if (dstTy->isVectorTy() && srcTy->isVectorTy() && 01380 dstTy->getVectorNumElements() == srcTy->getVectorNumElements()) 01381 return IRB.CreateIntCast(V, dstTy, Signed); 01382 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy); 01383 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy); 01384 Value *V1 = IRB.CreateBitCast(V, Type::getIntNTy(*MS.C, srcSizeInBits)); 01385 Value *V2 = 01386 IRB.CreateIntCast(V1, Type::getIntNTy(*MS.C, dstSizeInBits), Signed); 01387 return IRB.CreateBitCast(V2, dstTy); 01388 // TODO: handle struct types. 01389 } 01390 01391 /// \brief Cast an application value to the type of its own shadow. 01392 Value *CreateAppToShadowCast(IRBuilder<> &IRB, Value *V) { 01393 Type *ShadowTy = getShadowTy(V); 01394 if (V->getType() == ShadowTy) 01395 return V; 01396 if (V->getType()->isPtrOrPtrVectorTy()) 01397 return IRB.CreatePtrToInt(V, ShadowTy); 01398 else 01399 return IRB.CreateBitCast(V, ShadowTy); 01400 } 01401 01402 /// \brief Propagate shadow for arbitrary operation. 01403 void handleShadowOr(Instruction &I) { 01404 IRBuilder<> IRB(&I); 01405 ShadowAndOriginCombiner SC(this, IRB); 01406 for (Instruction::op_iterator OI = I.op_begin(); OI != I.op_end(); ++OI) 01407 SC.Add(OI->get()); 01408 SC.Done(&I); 01409 } 01410 01411 // \brief Handle multiplication by constant. 01412 // 01413 // Handle a special case of multiplication by constant that may have one or 01414 // more zeros in the lower bits. This makes corresponding number of lower bits 01415 // of the result zero as well. We model it by shifting the other operand 01416 // shadow left by the required number of bits. Effectively, we transform 01417 // (X * (A * 2**B)) to ((X << B) * A) and instrument (X << B) as (Sx << B). 01418 // We use multiplication by 2**N instead of shift to cover the case of 01419 // multiplication by 0, which may occur in some elements of a vector operand. 01420 void handleMulByConstant(BinaryOperator &I, Constant *ConstArg, 01421 Value *OtherArg) { 01422 Constant *ShadowMul; 01423 Type *Ty = ConstArg->getType(); 01424 if (Ty->isVectorTy()) { 01425 unsigned NumElements = Ty->getVectorNumElements(); 01426 Type *EltTy = Ty->getSequentialElementType(); 01427 SmallVector<Constant *, 16> Elements; 01428 for (unsigned Idx = 0; Idx < NumElements; ++Idx) { 01429 ConstantInt *Elt = 01430 dyn_cast<ConstantInt>(ConstArg->getAggregateElement(Idx)); 01431 APInt V = Elt->getValue(); 01432 APInt V2 = APInt(V.getBitWidth(), 1) << V.countTrailingZeros(); 01433 Elements.push_back(ConstantInt::get(EltTy, V2)); 01434 } 01435 ShadowMul = ConstantVector::get(Elements); 01436 } else { 01437 ConstantInt *Elt = dyn_cast<ConstantInt>(ConstArg); 01438 APInt V = Elt->getValue(); 01439 APInt V2 = APInt(V.getBitWidth(), 1) << V.countTrailingZeros(); 01440 ShadowMul = ConstantInt::get(Elt->getType(), V2); 01441 } 01442 01443 IRBuilder<> IRB(&I); 01444 setShadow(&I, 01445 IRB.CreateMul(getShadow(OtherArg), ShadowMul, "msprop_mul_cst")); 01446 setOrigin(&I, getOrigin(OtherArg)); 01447 } 01448 01449 void visitMul(BinaryOperator &I) { 01450 Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0)); 01451 Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1)); 01452 if (constOp0 && !constOp1) 01453 handleMulByConstant(I, constOp0, I.getOperand(1)); 01454 else if (constOp1 && !constOp0) 01455 handleMulByConstant(I, constOp1, I.getOperand(0)); 01456 else 01457 handleShadowOr(I); 01458 } 01459 01460 void visitFAdd(BinaryOperator &I) { handleShadowOr(I); } 01461 void visitFSub(BinaryOperator &I) { handleShadowOr(I); } 01462 void visitFMul(BinaryOperator &I) { handleShadowOr(I); } 01463 void visitAdd(BinaryOperator &I) { handleShadowOr(I); } 01464 void visitSub(BinaryOperator &I) { handleShadowOr(I); } 01465 void visitXor(BinaryOperator &I) { handleShadowOr(I); } 01466 01467 void handleDiv(Instruction &I) { 01468 IRBuilder<> IRB(&I); 01469 // Strict on the second argument. 01470 insertShadowCheck(I.getOperand(1), &I); 01471 setShadow(&I, getShadow(&I, 0)); 01472 setOrigin(&I, getOrigin(&I, 0)); 01473 } 01474 01475 void visitUDiv(BinaryOperator &I) { handleDiv(I); } 01476 void visitSDiv(BinaryOperator &I) { handleDiv(I); } 01477 void visitFDiv(BinaryOperator &I) { handleDiv(I); } 01478 void visitURem(BinaryOperator &I) { handleDiv(I); } 01479 void visitSRem(BinaryOperator &I) { handleDiv(I); } 01480 void visitFRem(BinaryOperator &I) { handleDiv(I); } 01481 01482 /// \brief Instrument == and != comparisons. 01483 /// 01484 /// Sometimes the comparison result is known even if some of the bits of the 01485 /// arguments are not. 01486 void handleEqualityComparison(ICmpInst &I) { 01487 IRBuilder<> IRB(&I); 01488 Value *A = I.getOperand(0); 01489 Value *B = I.getOperand(1); 01490 Value *Sa = getShadow(A); 01491 Value *Sb = getShadow(B); 01492 01493 // Get rid of pointers and vectors of pointers. 01494 // For ints (and vectors of ints), types of A and Sa match, 01495 // and this is a no-op. 01496 A = IRB.CreatePointerCast(A, Sa->getType()); 01497 B = IRB.CreatePointerCast(B, Sb->getType()); 01498 01499 // A == B <==> (C = A^B) == 0 01500 // A != B <==> (C = A^B) != 0 01501 // Sc = Sa | Sb 01502 Value *C = IRB.CreateXor(A, B); 01503 Value *Sc = IRB.CreateOr(Sa, Sb); 01504 // Now dealing with i = (C == 0) comparison (or C != 0, does not matter now) 01505 // Result is defined if one of the following is true 01506 // * there is a defined 1 bit in C 01507 // * C is fully defined 01508 // Si = !(C & ~Sc) && Sc 01509 Value *Zero = Constant::getNullValue(Sc->getType()); 01510 Value *MinusOne = Constant::getAllOnesValue(Sc->getType()); 01511 Value *Si = 01512 IRB.CreateAnd(IRB.CreateICmpNE(Sc, Zero), 01513 IRB.CreateICmpEQ( 01514 IRB.CreateAnd(IRB.CreateXor(Sc, MinusOne), C), Zero)); 01515 Si->setName("_msprop_icmp"); 01516 setShadow(&I, Si); 01517 setOriginForNaryOp(I); 01518 } 01519 01520 /// \brief Build the lowest possible value of V, taking into account V's 01521 /// uninitialized bits. 01522 Value *getLowestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa, 01523 bool isSigned) { 01524 if (isSigned) { 01525 // Split shadow into sign bit and other bits. 01526 Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1); 01527 Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits); 01528 // Maximise the undefined shadow bit, minimize other undefined bits. 01529 return 01530 IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaOtherBits)), SaSignBit); 01531 } else { 01532 // Minimize undefined bits. 01533 return IRB.CreateAnd(A, IRB.CreateNot(Sa)); 01534 } 01535 } 01536 01537 /// \brief Build the highest possible value of V, taking into account V's 01538 /// uninitialized bits. 01539 Value *getHighestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa, 01540 bool isSigned) { 01541 if (isSigned) { 01542 // Split shadow into sign bit and other bits. 01543 Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1); 01544 Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits); 01545 // Minimise the undefined shadow bit, maximise other undefined bits. 01546 return 01547 IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaSignBit)), SaOtherBits); 01548 } else { 01549 // Maximize undefined bits. 01550 return IRB.CreateOr(A, Sa); 01551 } 01552 } 01553 01554 /// \brief Instrument relational comparisons. 01555 /// 01556 /// This function does exact shadow propagation for all relational 01557 /// comparisons of integers, pointers and vectors of those. 01558 /// FIXME: output seems suboptimal when one of the operands is a constant 01559 void handleRelationalComparisonExact(ICmpInst &I) { 01560 IRBuilder<> IRB(&I); 01561 Value *A = I.getOperand(0); 01562 Value *B = I.getOperand(1); 01563 Value *Sa = getShadow(A); 01564 Value *Sb = getShadow(B); 01565 01566 // Get rid of pointers and vectors of pointers. 01567 // For ints (and vectors of ints), types of A and Sa match, 01568 // and this is a no-op. 01569 A = IRB.CreatePointerCast(A, Sa->getType()); 01570 B = IRB.CreatePointerCast(B, Sb->getType()); 01571 01572 // Let [a0, a1] be the interval of possible values of A, taking into account 01573 // its undefined bits. Let [b0, b1] be the interval of possible values of B. 01574 // Then (A cmp B) is defined iff (a0 cmp b1) == (a1 cmp b0). 01575 bool IsSigned = I.isSigned(); 01576 Value *S1 = IRB.CreateICmp(I.getPredicate(), 01577 getLowestPossibleValue(IRB, A, Sa, IsSigned), 01578 getHighestPossibleValue(IRB, B, Sb, IsSigned)); 01579 Value *S2 = IRB.CreateICmp(I.getPredicate(), 01580 getHighestPossibleValue(IRB, A, Sa, IsSigned), 01581 getLowestPossibleValue(IRB, B, Sb, IsSigned)); 01582 Value *Si = IRB.CreateXor(S1, S2); 01583 setShadow(&I, Si); 01584 setOriginForNaryOp(I); 01585 } 01586 01587 /// \brief Instrument signed relational comparisons. 01588 /// 01589 /// Handle (x<0) and (x>=0) comparisons (essentially, sign bit tests) by 01590 /// propagating the highest bit of the shadow. Everything else is delegated 01591 /// to handleShadowOr(). 01592 void handleSignedRelationalComparison(ICmpInst &I) { 01593 Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0)); 01594 Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1)); 01595 Value* op = nullptr; 01596 CmpInst::Predicate pre = I.getPredicate(); 01597 if (constOp0 && constOp0->isNullValue() && 01598 (pre == CmpInst::ICMP_SGT || pre == CmpInst::ICMP_SLE)) { 01599 op = I.getOperand(1); 01600 } else if (constOp1 && constOp1->isNullValue() && 01601 (pre == CmpInst::ICMP_SLT || pre == CmpInst::ICMP_SGE)) { 01602 op = I.getOperand(0); 01603 } 01604 if (op) { 01605 IRBuilder<> IRB(&I); 01606 Value* Shadow = 01607 IRB.CreateICmpSLT(getShadow(op), getCleanShadow(op), "_msprop_icmpslt"); 01608 setShadow(&I, Shadow); 01609 setOrigin(&I, getOrigin(op)); 01610 } else { 01611 handleShadowOr(I); 01612 } 01613 } 01614 01615 void visitICmpInst(ICmpInst &I) { 01616 if (!ClHandleICmp) { 01617 handleShadowOr(I); 01618 return; 01619 } 01620 if (I.isEquality()) { 01621 handleEqualityComparison(I); 01622 return; 01623 } 01624 01625 assert(I.isRelational()); 01626 if (ClHandleICmpExact) { 01627 handleRelationalComparisonExact(I); 01628 return; 01629 } 01630 if (I.isSigned()) { 01631 handleSignedRelationalComparison(I); 01632 return; 01633 } 01634 01635 assert(I.isUnsigned()); 01636 if ((isa<Constant>(I.getOperand(0)) || isa<Constant>(I.getOperand(1)))) { 01637 handleRelationalComparisonExact(I); 01638 return; 01639 } 01640 01641 handleShadowOr(I); 01642 } 01643 01644 void visitFCmpInst(FCmpInst &I) { 01645 handleShadowOr(I); 01646 } 01647 01648 void handleShift(BinaryOperator &I) { 01649 IRBuilder<> IRB(&I); 01650 // If any of the S2 bits are poisoned, the whole thing is poisoned. 01651 // Otherwise perform the same shift on S1. 01652 Value *S1 = getShadow(&I, 0); 01653 Value *S2 = getShadow(&I, 1); 01654 Value *S2Conv = IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)), 01655 S2->getType()); 01656 Value *V2 = I.getOperand(1); 01657 Value *Shift = IRB.CreateBinOp(I.getOpcode(), S1, V2); 01658 setShadow(&I, IRB.CreateOr(Shift, S2Conv)); 01659 setOriginForNaryOp(I); 01660 } 01661 01662 void visitShl(BinaryOperator &I) { handleShift(I); } 01663 void visitAShr(BinaryOperator &I) { handleShift(I); } 01664 void visitLShr(BinaryOperator &I) { handleShift(I); } 01665 01666 /// \brief Instrument llvm.memmove 01667 /// 01668 /// At this point we don't know if llvm.memmove will be inlined or not. 01669 /// If we don't instrument it and it gets inlined, 01670 /// our interceptor will not kick in and we will lose the memmove. 01671 /// If we instrument the call here, but it does not get inlined, 01672 /// we will memove the shadow twice: which is bad in case 01673 /// of overlapping regions. So, we simply lower the intrinsic to a call. 01674 /// 01675 /// Similar situation exists for memcpy and memset. 01676 void visitMemMoveInst(MemMoveInst &I) { 01677 IRBuilder<> IRB(&I); 01678 IRB.CreateCall3( 01679 MS.MemmoveFn, 01680 IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()), 01681 IRB.CreatePointerCast(I.getArgOperand(1), IRB.getInt8PtrTy()), 01682 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)); 01683 I.eraseFromParent(); 01684 } 01685 01686 // Similar to memmove: avoid copying shadow twice. 01687 // This is somewhat unfortunate as it may slowdown small constant memcpys. 01688 // FIXME: consider doing manual inline for small constant sizes and proper 01689 // alignment. 01690 void visitMemCpyInst(MemCpyInst &I) { 01691 IRBuilder<> IRB(&I); 01692 IRB.CreateCall3( 01693 MS.MemcpyFn, 01694 IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()), 01695 IRB.CreatePointerCast(I.getArgOperand(1), IRB.getInt8PtrTy()), 01696 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)); 01697 I.eraseFromParent(); 01698 } 01699 01700 // Same as memcpy. 01701 void visitMemSetInst(MemSetInst &I) { 01702 IRBuilder<> IRB(&I); 01703 IRB.CreateCall3( 01704 MS.MemsetFn, 01705 IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()), 01706 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false), 01707 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)); 01708 I.eraseFromParent(); 01709 } 01710 01711 void visitVAStartInst(VAStartInst &I) { 01712 VAHelper->visitVAStartInst(I); 01713 } 01714 01715 void visitVACopyInst(VACopyInst &I) { 01716 VAHelper->visitVACopyInst(I); 01717 } 01718 01719 enum IntrinsicKind { 01720 IK_DoesNotAccessMemory, 01721 IK_OnlyReadsMemory, 01722 IK_WritesMemory 01723 }; 01724 01725 static IntrinsicKind getIntrinsicKind(Intrinsic::ID iid) { 01726 const int DoesNotAccessMemory = IK_DoesNotAccessMemory; 01727 const int OnlyReadsArgumentPointees = IK_OnlyReadsMemory; 01728 const int OnlyReadsMemory = IK_OnlyReadsMemory; 01729 const int OnlyAccessesArgumentPointees = IK_WritesMemory; 01730 const int UnknownModRefBehavior = IK_WritesMemory; 01731 #define GET_INTRINSIC_MODREF_BEHAVIOR 01732 #define ModRefBehavior IntrinsicKind 01733 #include "llvm/IR/Intrinsics.gen" 01734 #undef ModRefBehavior 01735 #undef GET_INTRINSIC_MODREF_BEHAVIOR 01736 } 01737 01738 /// \brief Handle vector store-like intrinsics. 01739 /// 01740 /// Instrument intrinsics that look like a simple SIMD store: writes memory, 01741 /// has 1 pointer argument and 1 vector argument, returns void. 01742 bool handleVectorStoreIntrinsic(IntrinsicInst &I) { 01743 IRBuilder<> IRB(&I); 01744 Value* Addr = I.getArgOperand(0); 01745 Value *Shadow = getShadow(&I, 1); 01746 Value *ShadowPtr = getShadowPtr(Addr, Shadow->getType(), IRB); 01747 01748 // We don't know the pointer alignment (could be unaligned SSE store!). 01749 // Have to assume to worst case. 01750 IRB.CreateAlignedStore(Shadow, ShadowPtr, 1); 01751 01752 if (ClCheckAccessAddress) 01753 insertShadowCheck(Addr, &I); 01754 01755 // FIXME: use ClStoreCleanOrigin 01756 // FIXME: factor out common code from materializeStores 01757 if (MS.TrackOrigins) 01758 IRB.CreateStore(getOrigin(&I, 1), getOriginPtr(Addr, IRB)); 01759 return true; 01760 } 01761 01762 /// \brief Handle vector load-like intrinsics. 01763 /// 01764 /// Instrument intrinsics that look like a simple SIMD load: reads memory, 01765 /// has 1 pointer argument, returns a vector. 01766 bool handleVectorLoadIntrinsic(IntrinsicInst &I) { 01767 IRBuilder<> IRB(&I); 01768 Value *Addr = I.getArgOperand(0); 01769 01770 Type *ShadowTy = getShadowTy(&I); 01771 if (PropagateShadow) { 01772 Value *ShadowPtr = getShadowPtr(Addr, ShadowTy, IRB); 01773 // We don't know the pointer alignment (could be unaligned SSE load!). 01774 // Have to assume to worst case. 01775 setShadow(&I, IRB.CreateAlignedLoad(ShadowPtr, 1, "_msld")); 01776 } else { 01777 setShadow(&I, getCleanShadow(&I)); 01778 } 01779 01780 if (ClCheckAccessAddress) 01781 insertShadowCheck(Addr, &I); 01782 01783 if (MS.TrackOrigins) { 01784 if (PropagateShadow) 01785 setOrigin(&I, IRB.CreateLoad(getOriginPtr(Addr, IRB))); 01786 else 01787 setOrigin(&I, getCleanOrigin()); 01788 } 01789 return true; 01790 } 01791 01792 /// \brief Handle (SIMD arithmetic)-like intrinsics. 01793 /// 01794 /// Instrument intrinsics with any number of arguments of the same type, 01795 /// equal to the return type. The type should be simple (no aggregates or 01796 /// pointers; vectors are fine). 01797 /// Caller guarantees that this intrinsic does not access memory. 01798 bool maybeHandleSimpleNomemIntrinsic(IntrinsicInst &I) { 01799 Type *RetTy = I.getType(); 01800 if (!(RetTy->isIntOrIntVectorTy() || 01801 RetTy->isFPOrFPVectorTy() || 01802 RetTy->isX86_MMXTy())) 01803 return false; 01804 01805 unsigned NumArgOperands = I.getNumArgOperands(); 01806 01807 for (unsigned i = 0; i < NumArgOperands; ++i) { 01808 Type *Ty = I.getArgOperand(i)->getType(); 01809 if (Ty != RetTy) 01810 return false; 01811 } 01812 01813 IRBuilder<> IRB(&I); 01814 ShadowAndOriginCombiner SC(this, IRB); 01815 for (unsigned i = 0; i < NumArgOperands; ++i) 01816 SC.Add(I.getArgOperand(i)); 01817 SC.Done(&I); 01818 01819 return true; 01820 } 01821 01822 /// \brief Heuristically instrument unknown intrinsics. 01823 /// 01824 /// The main purpose of this code is to do something reasonable with all 01825 /// random intrinsics we might encounter, most importantly - SIMD intrinsics. 01826 /// We recognize several classes of intrinsics by their argument types and 01827 /// ModRefBehaviour and apply special intrumentation when we are reasonably 01828 /// sure that we know what the intrinsic does. 01829 /// 01830 /// We special-case intrinsics where this approach fails. See llvm.bswap 01831 /// handling as an example of that. 01832 bool handleUnknownIntrinsic(IntrinsicInst &I) { 01833 unsigned NumArgOperands = I.getNumArgOperands(); 01834 if (NumArgOperands == 0) 01835 return false; 01836 01837 Intrinsic::ID iid = I.getIntrinsicID(); 01838 IntrinsicKind IK = getIntrinsicKind(iid); 01839 bool OnlyReadsMemory = IK == IK_OnlyReadsMemory; 01840 bool WritesMemory = IK == IK_WritesMemory; 01841 assert(!(OnlyReadsMemory && WritesMemory)); 01842 01843 if (NumArgOperands == 2 && 01844 I.getArgOperand(0)->getType()->isPointerTy() && 01845 I.getArgOperand(1)->getType()->isVectorTy() && 01846 I.getType()->isVoidTy() && 01847 WritesMemory) { 01848 // This looks like a vector store. 01849 return handleVectorStoreIntrinsic(I); 01850 } 01851 01852 if (NumArgOperands == 1 && 01853 I.getArgOperand(0)->getType()->isPointerTy() && 01854 I.getType()->isVectorTy() && 01855 OnlyReadsMemory) { 01856 // This looks like a vector load. 01857 return handleVectorLoadIntrinsic(I); 01858 } 01859 01860 if (!OnlyReadsMemory && !WritesMemory) 01861 if (maybeHandleSimpleNomemIntrinsic(I)) 01862 return true; 01863 01864 // FIXME: detect and handle SSE maskstore/maskload 01865 return false; 01866 } 01867 01868 void handleBswap(IntrinsicInst &I) { 01869 IRBuilder<> IRB(&I); 01870 Value *Op = I.getArgOperand(0); 01871 Type *OpType = Op->getType(); 01872 Function *BswapFunc = Intrinsic::getDeclaration( 01873 F.getParent(), Intrinsic::bswap, makeArrayRef(&OpType, 1)); 01874 setShadow(&I, IRB.CreateCall(BswapFunc, getShadow(Op))); 01875 setOrigin(&I, getOrigin(Op)); 01876 } 01877 01878 // \brief Instrument vector convert instrinsic. 01879 // 01880 // This function instruments intrinsics like cvtsi2ss: 01881 // %Out = int_xxx_cvtyyy(%ConvertOp) 01882 // or 01883 // %Out = int_xxx_cvtyyy(%CopyOp, %ConvertOp) 01884 // Intrinsic converts \p NumUsedElements elements of \p ConvertOp to the same 01885 // number \p Out elements, and (if has 2 arguments) copies the rest of the 01886 // elements from \p CopyOp. 01887 // In most cases conversion involves floating-point value which may trigger a 01888 // hardware exception when not fully initialized. For this reason we require 01889 // \p ConvertOp[0:NumUsedElements] to be fully initialized and trap otherwise. 01890 // We copy the shadow of \p CopyOp[NumUsedElements:] to \p 01891 // Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always 01892 // return a fully initialized value. 01893 void handleVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements) { 01894 IRBuilder<> IRB(&I); 01895 Value *CopyOp, *ConvertOp; 01896 01897 switch (I.getNumArgOperands()) { 01898 case 2: 01899 CopyOp = I.getArgOperand(0); 01900 ConvertOp = I.getArgOperand(1); 01901 break; 01902 case 1: 01903 ConvertOp = I.getArgOperand(0); 01904 CopyOp = nullptr; 01905 break; 01906 default: 01907 llvm_unreachable("Cvt intrinsic with unsupported number of arguments."); 01908 } 01909 01910 // The first *NumUsedElements* elements of ConvertOp are converted to the 01911 // same number of output elements. The rest of the output is copied from 01912 // CopyOp, or (if not available) filled with zeroes. 01913 // Combine shadow for elements of ConvertOp that are used in this operation, 01914 // and insert a check. 01915 // FIXME: consider propagating shadow of ConvertOp, at least in the case of 01916 // int->any conversion. 01917 Value *ConvertShadow = getShadow(ConvertOp); 01918 Value *AggShadow = nullptr; 01919 if (ConvertOp->getType()->isVectorTy()) { 01920 AggShadow = IRB.CreateExtractElement( 01921 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), 0)); 01922 for (int i = 1; i < NumUsedElements; ++i) { 01923 Value *MoreShadow = IRB.CreateExtractElement( 01924 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), i)); 01925 AggShadow = IRB.CreateOr(AggShadow, MoreShadow); 01926 } 01927 } else { 01928 AggShadow = ConvertShadow; 01929 } 01930 assert(AggShadow->getType()->isIntegerTy()); 01931 insertShadowCheck(AggShadow, getOrigin(ConvertOp), &I); 01932 01933 // Build result shadow by zero-filling parts of CopyOp shadow that come from 01934 // ConvertOp. 01935 if (CopyOp) { 01936 assert(CopyOp->getType() == I.getType()); 01937 assert(CopyOp->getType()->isVectorTy()); 01938 Value *ResultShadow = getShadow(CopyOp); 01939 Type *EltTy = ResultShadow->getType()->getVectorElementType(); 01940 for (int i = 0; i < NumUsedElements; ++i) { 01941 ResultShadow = IRB.CreateInsertElement( 01942 ResultShadow, ConstantInt::getNullValue(EltTy), 01943 ConstantInt::get(IRB.getInt32Ty(), i)); 01944 } 01945 setShadow(&I, ResultShadow); 01946 setOrigin(&I, getOrigin(CopyOp)); 01947 } else { 01948 setShadow(&I, getCleanShadow(&I)); 01949 } 01950 } 01951 01952 // Given a scalar or vector, extract lower 64 bits (or less), and return all 01953 // zeroes if it is zero, and all ones otherwise. 01954 Value *Lower64ShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) { 01955 if (S->getType()->isVectorTy()) 01956 S = CreateShadowCast(IRB, S, IRB.getInt64Ty(), /* Signed */ true); 01957 assert(S->getType()->getPrimitiveSizeInBits() <= 64); 01958 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S)); 01959 return CreateShadowCast(IRB, S2, T, /* Signed */ true); 01960 } 01961 01962 Value *VariableShadowExtend(IRBuilder<> &IRB, Value *S) { 01963 Type *T = S->getType(); 01964 assert(T->isVectorTy()); 01965 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S)); 01966 return IRB.CreateSExt(S2, T); 01967 } 01968 01969 // \brief Instrument vector shift instrinsic. 01970 // 01971 // This function instruments intrinsics like int_x86_avx2_psll_w. 01972 // Intrinsic shifts %In by %ShiftSize bits. 01973 // %ShiftSize may be a vector. In that case the lower 64 bits determine shift 01974 // size, and the rest is ignored. Behavior is defined even if shift size is 01975 // greater than register (or field) width. 01976 void handleVectorShiftIntrinsic(IntrinsicInst &I, bool Variable) { 01977 assert(I.getNumArgOperands() == 2); 01978 IRBuilder<> IRB(&I); 01979 // If any of the S2 bits are poisoned, the whole thing is poisoned. 01980 // Otherwise perform the same shift on S1. 01981 Value *S1 = getShadow(&I, 0); 01982 Value *S2 = getShadow(&I, 1); 01983 Value *S2Conv = Variable ? VariableShadowExtend(IRB, S2) 01984 : Lower64ShadowExtend(IRB, S2, getShadowTy(&I)); 01985 Value *V1 = I.getOperand(0); 01986 Value *V2 = I.getOperand(1); 01987 Value *Shift = IRB.CreateCall2(I.getCalledValue(), 01988 IRB.CreateBitCast(S1, V1->getType()), V2); 01989 Shift = IRB.CreateBitCast(Shift, getShadowTy(&I)); 01990 setShadow(&I, IRB.CreateOr(Shift, S2Conv)); 01991 setOriginForNaryOp(I); 01992 } 01993 01994 // \brief Get an X86_MMX-sized vector type. 01995 Type *getMMXVectorTy(unsigned EltSizeInBits) { 01996 const unsigned X86_MMXSizeInBits = 64; 01997 return VectorType::get(IntegerType::get(*MS.C, EltSizeInBits), 01998 X86_MMXSizeInBits / EltSizeInBits); 01999 } 02000 02001 // \brief Returns a signed counterpart for an (un)signed-saturate-and-pack 02002 // intrinsic. 02003 Intrinsic::ID getSignedPackIntrinsic(Intrinsic::ID id) { 02004 switch (id) { 02005 case llvm::Intrinsic::x86_sse2_packsswb_128: 02006 case llvm::Intrinsic::x86_sse2_packuswb_128: 02007 return llvm::Intrinsic::x86_sse2_packsswb_128; 02008 02009 case llvm::Intrinsic::x86_sse2_packssdw_128: 02010 case llvm::Intrinsic::x86_sse41_packusdw: 02011 return llvm::Intrinsic::x86_sse2_packssdw_128; 02012 02013 case llvm::Intrinsic::x86_avx2_packsswb: 02014 case llvm::Intrinsic::x86_avx2_packuswb: 02015 return llvm::Intrinsic::x86_avx2_packsswb; 02016 02017 case llvm::Intrinsic::x86_avx2_packssdw: 02018 case llvm::Intrinsic::x86_avx2_packusdw: 02019 return llvm::Intrinsic::x86_avx2_packssdw; 02020 02021 case llvm::Intrinsic::x86_mmx_packsswb: 02022 case llvm::Intrinsic::x86_mmx_packuswb: 02023 return llvm::Intrinsic::x86_mmx_packsswb; 02024 02025 case llvm::Intrinsic::x86_mmx_packssdw: 02026 return llvm::Intrinsic::x86_mmx_packssdw; 02027 default: 02028 llvm_unreachable("unexpected intrinsic id"); 02029 } 02030 } 02031 02032 // \brief Instrument vector pack instrinsic. 02033 // 02034 // This function instruments intrinsics like x86_mmx_packsswb, that 02035 // packs elements of 2 input vectors into half as many bits with saturation. 02036 // Shadow is propagated with the signed variant of the same intrinsic applied 02037 // to sext(Sa != zeroinitializer), sext(Sb != zeroinitializer). 02038 // EltSizeInBits is used only for x86mmx arguments. 02039 void handleVectorPackIntrinsic(IntrinsicInst &I, unsigned EltSizeInBits = 0) { 02040 assert(I.getNumArgOperands() == 2); 02041 bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy(); 02042 IRBuilder<> IRB(&I); 02043 Value *S1 = getShadow(&I, 0); 02044 Value *S2 = getShadow(&I, 1); 02045 assert(isX86_MMX || S1->getType()->isVectorTy()); 02046 02047 // SExt and ICmpNE below must apply to individual elements of input vectors. 02048 // In case of x86mmx arguments, cast them to appropriate vector types and 02049 // back. 02050 Type *T = isX86_MMX ? getMMXVectorTy(EltSizeInBits) : S1->getType(); 02051 if (isX86_MMX) { 02052 S1 = IRB.CreateBitCast(S1, T); 02053 S2 = IRB.CreateBitCast(S2, T); 02054 } 02055 Value *S1_ext = IRB.CreateSExt( 02056 IRB.CreateICmpNE(S1, llvm::Constant::getNullValue(T)), T); 02057 Value *S2_ext = IRB.CreateSExt( 02058 IRB.CreateICmpNE(S2, llvm::Constant::getNullValue(T)), T); 02059 if (isX86_MMX) { 02060 Type *X86_MMXTy = Type::getX86_MMXTy(*MS.C); 02061 S1_ext = IRB.CreateBitCast(S1_ext, X86_MMXTy); 02062 S2_ext = IRB.CreateBitCast(S2_ext, X86_MMXTy); 02063 } 02064 02065 Function *ShadowFn = Intrinsic::getDeclaration( 02066 F.getParent(), getSignedPackIntrinsic(I.getIntrinsicID())); 02067 02068 Value *S = IRB.CreateCall2(ShadowFn, S1_ext, S2_ext, "_msprop_vector_pack"); 02069 if (isX86_MMX) S = IRB.CreateBitCast(S, getShadowTy(&I)); 02070 setShadow(&I, S); 02071 setOriginForNaryOp(I); 02072 } 02073 02074 // \brief Instrument sum-of-absolute-differencies intrinsic. 02075 void handleVectorSadIntrinsic(IntrinsicInst &I) { 02076 const unsigned SignificantBitsPerResultElement = 16; 02077 bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy(); 02078 Type *ResTy = isX86_MMX ? IntegerType::get(*MS.C, 64) : I.getType(); 02079 unsigned ZeroBitsPerResultElement = 02080 ResTy->getScalarSizeInBits() - SignificantBitsPerResultElement; 02081 02082 IRBuilder<> IRB(&I); 02083 Value *S = IRB.CreateOr(getShadow(&I, 0), getShadow(&I, 1)); 02084 S = IRB.CreateBitCast(S, ResTy); 02085 S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)), 02086 ResTy); 02087 S = IRB.CreateLShr(S, ZeroBitsPerResultElement); 02088 S = IRB.CreateBitCast(S, getShadowTy(&I)); 02089 setShadow(&I, S); 02090 setOriginForNaryOp(I); 02091 } 02092 02093 // \brief Instrument multiply-add intrinsic. 02094 void handleVectorPmaddIntrinsic(IntrinsicInst &I, 02095 unsigned EltSizeInBits = 0) { 02096 bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy(); 02097 Type *ResTy = isX86_MMX ? getMMXVectorTy(EltSizeInBits * 2) : I.getType(); 02098 IRBuilder<> IRB(&I); 02099 Value *S = IRB.CreateOr(getShadow(&I, 0), getShadow(&I, 1)); 02100 S = IRB.CreateBitCast(S, ResTy); 02101 S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)), 02102 ResTy); 02103 S = IRB.CreateBitCast(S, getShadowTy(&I)); 02104 setShadow(&I, S); 02105 setOriginForNaryOp(I); 02106 } 02107 02108 void visitIntrinsicInst(IntrinsicInst &I) { 02109 switch (I.getIntrinsicID()) { 02110 case llvm::Intrinsic::bswap: 02111 handleBswap(I); 02112 break; 02113 case llvm::Intrinsic::x86_avx512_cvtsd2usi64: 02114 case llvm::Intrinsic::x86_avx512_cvtsd2usi: 02115 case llvm::Intrinsic::x86_avx512_cvtss2usi64: 02116 case llvm::Intrinsic::x86_avx512_cvtss2usi: 02117 case llvm::Intrinsic::x86_avx512_cvttss2usi64: 02118 case llvm::Intrinsic::x86_avx512_cvttss2usi: 02119 case llvm::Intrinsic::x86_avx512_cvttsd2usi64: 02120 case llvm::Intrinsic::x86_avx512_cvttsd2usi: 02121 case llvm::Intrinsic::x86_avx512_cvtusi2sd: 02122 case llvm::Intrinsic::x86_avx512_cvtusi2ss: 02123 case llvm::Intrinsic::x86_avx512_cvtusi642sd: 02124 case llvm::Intrinsic::x86_avx512_cvtusi642ss: 02125 case llvm::Intrinsic::x86_sse2_cvtsd2si64: 02126 case llvm::Intrinsic::x86_sse2_cvtsd2si: 02127 case llvm::Intrinsic::x86_sse2_cvtsd2ss: 02128 case llvm::Intrinsic::x86_sse2_cvtsi2sd: 02129 case llvm::Intrinsic::x86_sse2_cvtsi642sd: 02130 case llvm::Intrinsic::x86_sse2_cvtss2sd: 02131 case llvm::Intrinsic::x86_sse2_cvttsd2si64: 02132 case llvm::Intrinsic::x86_sse2_cvttsd2si: 02133 case llvm::Intrinsic::x86_sse_cvtsi2ss: 02134 case llvm::Intrinsic::x86_sse_cvtsi642ss: 02135 case llvm::Intrinsic::x86_sse_cvtss2si64: 02136 case llvm::Intrinsic::x86_sse_cvtss2si: 02137 case llvm::Intrinsic::x86_sse_cvttss2si64: 02138 case llvm::Intrinsic::x86_sse_cvttss2si: 02139 handleVectorConvertIntrinsic(I, 1); 02140 break; 02141 case llvm::Intrinsic::x86_sse2_cvtdq2pd: 02142 case llvm::Intrinsic::x86_sse2_cvtps2pd: 02143 case llvm::Intrinsic::x86_sse_cvtps2pi: 02144 case llvm::Intrinsic::x86_sse_cvttps2pi: 02145 handleVectorConvertIntrinsic(I, 2); 02146 break; 02147 case llvm::Intrinsic::x86_avx512_psll_dq: 02148 case llvm::Intrinsic::x86_avx512_psrl_dq: 02149 case llvm::Intrinsic::x86_avx2_psll_w: 02150 case llvm::Intrinsic::x86_avx2_psll_d: 02151 case llvm::Intrinsic::x86_avx2_psll_q: 02152 case llvm::Intrinsic::x86_avx2_pslli_w: 02153 case llvm::Intrinsic::x86_avx2_pslli_d: 02154 case llvm::Intrinsic::x86_avx2_pslli_q: 02155 case llvm::Intrinsic::x86_avx2_psll_dq: 02156 case llvm::Intrinsic::x86_avx2_psrl_w: 02157 case llvm::Intrinsic::x86_avx2_psrl_d: 02158 case llvm::Intrinsic::x86_avx2_psrl_q: 02159 case llvm::Intrinsic::x86_avx2_psra_w: 02160 case llvm::Intrinsic::x86_avx2_psra_d: 02161 case llvm::Intrinsic::x86_avx2_psrli_w: 02162 case llvm::Intrinsic::x86_avx2_psrli_d: 02163 case llvm::Intrinsic::x86_avx2_psrli_q: 02164 case llvm::Intrinsic::x86_avx2_psrai_w: 02165 case llvm::Intrinsic::x86_avx2_psrai_d: 02166 case llvm::Intrinsic::x86_avx2_psrl_dq: 02167 case llvm::Intrinsic::x86_sse2_psll_w: 02168 case llvm::Intrinsic::x86_sse2_psll_d: 02169 case llvm::Intrinsic::x86_sse2_psll_q: 02170 case llvm::Intrinsic::x86_sse2_pslli_w: 02171 case llvm::Intrinsic::x86_sse2_pslli_d: 02172 case llvm::Intrinsic::x86_sse2_pslli_q: 02173 case llvm::Intrinsic::x86_sse2_psll_dq: 02174 case llvm::Intrinsic::x86_sse2_psrl_w: 02175 case llvm::Intrinsic::x86_sse2_psrl_d: 02176 case llvm::Intrinsic::x86_sse2_psrl_q: 02177 case llvm::Intrinsic::x86_sse2_psra_w: 02178 case llvm::Intrinsic::x86_sse2_psra_d: 02179 case llvm::Intrinsic::x86_sse2_psrli_w: 02180 case llvm::Intrinsic::x86_sse2_psrli_d: 02181 case llvm::Intrinsic::x86_sse2_psrli_q: 02182 case llvm::Intrinsic::x86_sse2_psrai_w: 02183 case llvm::Intrinsic::x86_sse2_psrai_d: 02184 case llvm::Intrinsic::x86_sse2_psrl_dq: 02185 case llvm::Intrinsic::x86_mmx_psll_w: 02186 case llvm::Intrinsic::x86_mmx_psll_d: 02187 case llvm::Intrinsic::x86_mmx_psll_q: 02188 case llvm::Intrinsic::x86_mmx_pslli_w: 02189 case llvm::Intrinsic::x86_mmx_pslli_d: 02190 case llvm::Intrinsic::x86_mmx_pslli_q: 02191 case llvm::Intrinsic::x86_mmx_psrl_w: 02192 case llvm::Intrinsic::x86_mmx_psrl_d: 02193 case llvm::Intrinsic::x86_mmx_psrl_q: 02194 case llvm::Intrinsic::x86_mmx_psra_w: 02195 case llvm::Intrinsic::x86_mmx_psra_d: 02196 case llvm::Intrinsic::x86_mmx_psrli_w: 02197 case llvm::Intrinsic::x86_mmx_psrli_d: 02198 case llvm::Intrinsic::x86_mmx_psrli_q: 02199 case llvm::Intrinsic::x86_mmx_psrai_w: 02200 case llvm::Intrinsic::x86_mmx_psrai_d: 02201 handleVectorShiftIntrinsic(I, /* Variable */ false); 02202 break; 02203 case llvm::Intrinsic::x86_avx2_psllv_d: 02204 case llvm::Intrinsic::x86_avx2_psllv_d_256: 02205 case llvm::Intrinsic::x86_avx2_psllv_q: 02206 case llvm::Intrinsic::x86_avx2_psllv_q_256: 02207 case llvm::Intrinsic::x86_avx2_psrlv_d: 02208 case llvm::Intrinsic::x86_avx2_psrlv_d_256: 02209 case llvm::Intrinsic::x86_avx2_psrlv_q: 02210 case llvm::Intrinsic::x86_avx2_psrlv_q_256: 02211 case llvm::Intrinsic::x86_avx2_psrav_d: 02212 case llvm::Intrinsic::x86_avx2_psrav_d_256: 02213 handleVectorShiftIntrinsic(I, /* Variable */ true); 02214 break; 02215 02216 // Byte shifts are not implemented. 02217 // case llvm::Intrinsic::x86_avx512_psll_dq_bs: 02218 // case llvm::Intrinsic::x86_avx512_psrl_dq_bs: 02219 // case llvm::Intrinsic::x86_avx2_psll_dq_bs: 02220 // case llvm::Intrinsic::x86_avx2_psrl_dq_bs: 02221 // case llvm::Intrinsic::x86_sse2_psll_dq_bs: 02222 // case llvm::Intrinsic::x86_sse2_psrl_dq_bs: 02223 02224 case llvm::Intrinsic::x86_sse2_packsswb_128: 02225 case llvm::Intrinsic::x86_sse2_packssdw_128: 02226 case llvm::Intrinsic::x86_sse2_packuswb_128: 02227 case llvm::Intrinsic::x86_sse41_packusdw: 02228 case llvm::Intrinsic::x86_avx2_packsswb: 02229 case llvm::Intrinsic::x86_avx2_packssdw: 02230 case llvm::Intrinsic::x86_avx2_packuswb: 02231 case llvm::Intrinsic::x86_avx2_packusdw: 02232 handleVectorPackIntrinsic(I); 02233 break; 02234 02235 case llvm::Intrinsic::x86_mmx_packsswb: 02236 case llvm::Intrinsic::x86_mmx_packuswb: 02237 handleVectorPackIntrinsic(I, 16); 02238 break; 02239 02240 case llvm::Intrinsic::x86_mmx_packssdw: 02241 handleVectorPackIntrinsic(I, 32); 02242 break; 02243 02244 case llvm::Intrinsic::x86_mmx_psad_bw: 02245 case llvm::Intrinsic::x86_sse2_psad_bw: 02246 case llvm::Intrinsic::x86_avx2_psad_bw: 02247 handleVectorSadIntrinsic(I); 02248 break; 02249 02250 case llvm::Intrinsic::x86_sse2_pmadd_wd: 02251 case llvm::Intrinsic::x86_avx2_pmadd_wd: 02252 case llvm::Intrinsic::x86_ssse3_pmadd_ub_sw_128: 02253 case llvm::Intrinsic::x86_avx2_pmadd_ub_sw: 02254 handleVectorPmaddIntrinsic(I); 02255 break; 02256 02257 case llvm::Intrinsic::x86_ssse3_pmadd_ub_sw: 02258 handleVectorPmaddIntrinsic(I, 8); 02259 break; 02260 02261 case llvm::Intrinsic::x86_mmx_pmadd_wd: 02262 handleVectorPmaddIntrinsic(I, 16); 02263 break; 02264 02265 default: 02266 if (!handleUnknownIntrinsic(I)) 02267 visitInstruction(I); 02268 break; 02269 } 02270 } 02271 02272 void visitCallSite(CallSite CS) { 02273 Instruction &I = *CS.getInstruction(); 02274 assert((CS.isCall() || CS.isInvoke()) && "Unknown type of CallSite"); 02275 if (CS.isCall()) { 02276 CallInst *Call = cast<CallInst>(&I); 02277 02278 // For inline asm, do the usual thing: check argument shadow and mark all 02279 // outputs as clean. Note that any side effects of the inline asm that are 02280 // not immediately visible in its constraints are not handled. 02281 if (Call->isInlineAsm()) { 02282 visitInstruction(I); 02283 return; 02284 } 02285 02286 assert(!isa<IntrinsicInst>(&I) && "intrinsics are handled elsewhere"); 02287 02288 // We are going to insert code that relies on the fact that the callee 02289 // will become a non-readonly function after it is instrumented by us. To 02290 // prevent this code from being optimized out, mark that function 02291 // non-readonly in advance. 02292 if (Function *Func = Call->getCalledFunction()) { 02293 // Clear out readonly/readnone attributes. 02294 AttrBuilder B; 02295 B.addAttribute(Attribute::ReadOnly) 02296 .addAttribute(Attribute::ReadNone); 02297 Func->removeAttributes(AttributeSet::FunctionIndex, 02298 AttributeSet::get(Func->getContext(), 02299 AttributeSet::FunctionIndex, 02300 B)); 02301 } 02302 } 02303 IRBuilder<> IRB(&I); 02304 02305 if (MS.WrapIndirectCalls && !CS.getCalledFunction()) 02306 IndirectCallList.push_back(CS); 02307 02308 unsigned ArgOffset = 0; 02309 DEBUG(dbgs() << " CallSite: " << I << "\n"); 02310 for (CallSite::arg_iterator ArgIt = CS.arg_begin(), End = CS.arg_end(); 02311 ArgIt != End; ++ArgIt) { 02312 Value *A = *ArgIt; 02313 unsigned i = ArgIt - CS.arg_begin(); 02314 if (!A->getType()->isSized()) { 02315 DEBUG(dbgs() << "Arg " << i << " is not sized: " << I << "\n"); 02316 continue; 02317 } 02318 unsigned Size = 0; 02319 Value *Store = nullptr; 02320 // Compute the Shadow for arg even if it is ByVal, because 02321 // in that case getShadow() will copy the actual arg shadow to 02322 // __msan_param_tls. 02323 Value *ArgShadow = getShadow(A); 02324 Value *ArgShadowBase = getShadowPtrForArgument(A, IRB, ArgOffset); 02325 DEBUG(dbgs() << " Arg#" << i << ": " << *A << 02326 " Shadow: " << *ArgShadow << "\n"); 02327 bool ArgIsInitialized = false; 02328 if (CS.paramHasAttr(i + 1, Attribute::ByVal)) { 02329 assert(A->getType()->isPointerTy() && 02330 "ByVal argument is not a pointer!"); 02331 Size = MS.DL->getTypeAllocSize(A->getType()->getPointerElementType()); 02332 unsigned Alignment = CS.getParamAlignment(i + 1); 02333 Store = IRB.CreateMemCpy(ArgShadowBase, 02334 getShadowPtr(A, Type::getInt8Ty(*MS.C), IRB), 02335 Size, Alignment); 02336 } else { 02337 Size = MS.DL->getTypeAllocSize(A->getType()); 02338 Store = IRB.CreateAlignedStore(ArgShadow, ArgShadowBase, 02339 kShadowTLSAlignment); 02340 Constant *Cst = dyn_cast<Constant>(ArgShadow); 02341 if (Cst && Cst->isNullValue()) ArgIsInitialized = true; 02342 } 02343 if (MS.TrackOrigins && !ArgIsInitialized) 02344 IRB.CreateStore(getOrigin(A), 02345 getOriginPtrForArgument(A, IRB, ArgOffset)); 02346 (void)Store; 02347 assert(Size != 0 && Store != nullptr); 02348 DEBUG(dbgs() << " Param:" << *Store << "\n"); 02349 ArgOffset += DataLayout::RoundUpAlignment(Size, 8); 02350 } 02351 DEBUG(dbgs() << " done with call args\n"); 02352 02353 FunctionType *FT = 02354 cast<FunctionType>(CS.getCalledValue()->getType()->getContainedType(0)); 02355 if (FT->isVarArg()) { 02356 VAHelper->visitCallSite(CS, IRB); 02357 } 02358 02359 // Now, get the shadow for the RetVal. 02360 if (!I.getType()->isSized()) return; 02361 IRBuilder<> IRBBefore(&I); 02362 // Until we have full dynamic coverage, make sure the retval shadow is 0. 02363 Value *Base = getShadowPtrForRetval(&I, IRBBefore); 02364 IRBBefore.CreateAlignedStore(getCleanShadow(&I), Base, kShadowTLSAlignment); 02365 Instruction *NextInsn = nullptr; 02366 if (CS.isCall()) { 02367 NextInsn = I.getNextNode(); 02368 } else { 02369 BasicBlock *NormalDest = cast<InvokeInst>(&I)->getNormalDest(); 02370 if (!NormalDest->getSinglePredecessor()) { 02371 // FIXME: this case is tricky, so we are just conservative here. 02372 // Perhaps we need to split the edge between this BB and NormalDest, 02373 // but a naive attempt to use SplitEdge leads to a crash. 02374 setShadow(&I, getCleanShadow(&I)); 02375 setOrigin(&I, getCleanOrigin()); 02376 return; 02377 } 02378 NextInsn = NormalDest->getFirstInsertionPt(); 02379 assert(NextInsn && 02380 "Could not find insertion point for retval shadow load"); 02381 } 02382 IRBuilder<> IRBAfter(NextInsn); 02383 Value *RetvalShadow = 02384 IRBAfter.CreateAlignedLoad(getShadowPtrForRetval(&I, IRBAfter), 02385 kShadowTLSAlignment, "_msret"); 02386 setShadow(&I, RetvalShadow); 02387 if (MS.TrackOrigins) 02388 setOrigin(&I, IRBAfter.CreateLoad(getOriginPtrForRetval(IRBAfter))); 02389 } 02390 02391 void visitReturnInst(ReturnInst &I) { 02392 IRBuilder<> IRB(&I); 02393 Value *RetVal = I.getReturnValue(); 02394 if (!RetVal) return; 02395 Value *ShadowPtr = getShadowPtrForRetval(RetVal, IRB); 02396 if (CheckReturnValue) { 02397 insertShadowCheck(RetVal, &I); 02398 Value *Shadow = getCleanShadow(RetVal); 02399 IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment); 02400 } else { 02401 Value *Shadow = getShadow(RetVal); 02402 IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment); 02403 // FIXME: make it conditional if ClStoreCleanOrigin==0 02404 if (MS.TrackOrigins) 02405 IRB.CreateStore(getOrigin(RetVal), getOriginPtrForRetval(IRB)); 02406 } 02407 } 02408 02409 void visitPHINode(PHINode &I) { 02410 IRBuilder<> IRB(&I); 02411 if (!PropagateShadow) { 02412 setShadow(&I, getCleanShadow(&I)); 02413 return; 02414 } 02415 02416 ShadowPHINodes.push_back(&I); 02417 setShadow(&I, IRB.CreatePHI(getShadowTy(&I), I.getNumIncomingValues(), 02418 "_msphi_s")); 02419 if (MS.TrackOrigins) 02420 setOrigin(&I, IRB.CreatePHI(MS.OriginTy, I.getNumIncomingValues(), 02421 "_msphi_o")); 02422 } 02423 02424 void visitAllocaInst(AllocaInst &I) { 02425 setShadow(&I, getCleanShadow(&I)); 02426 IRBuilder<> IRB(I.getNextNode()); 02427 uint64_t Size = MS.DL->getTypeAllocSize(I.getAllocatedType()); 02428 if (PoisonStack && ClPoisonStackWithCall) { 02429 IRB.CreateCall2(MS.MsanPoisonStackFn, 02430 IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()), 02431 ConstantInt::get(MS.IntptrTy, Size)); 02432 } else { 02433 Value *ShadowBase = getShadowPtr(&I, Type::getInt8PtrTy(*MS.C), IRB); 02434 Value *PoisonValue = IRB.getInt8(PoisonStack ? ClPoisonStackPattern : 0); 02435 IRB.CreateMemSet(ShadowBase, PoisonValue, Size, I.getAlignment()); 02436 } 02437 02438 if (PoisonStack && MS.TrackOrigins) { 02439 setOrigin(&I, getCleanOrigin()); 02440 SmallString<2048> StackDescriptionStorage; 02441 raw_svector_ostream StackDescription(StackDescriptionStorage); 02442 // We create a string with a description of the stack allocation and 02443 // pass it into __msan_set_alloca_origin. 02444 // It will be printed by the run-time if stack-originated UMR is found. 02445 // The first 4 bytes of the string are set to '----' and will be replaced 02446 // by __msan_va_arg_overflow_size_tls at the first call. 02447 StackDescription << "----" << I.getName() << "@" << F.getName(); 02448 Value *Descr = 02449 createPrivateNonConstGlobalForString(*F.getParent(), 02450 StackDescription.str()); 02451 02452 IRB.CreateCall4(MS.MsanSetAllocaOrigin4Fn, 02453 IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()), 02454 ConstantInt::get(MS.IntptrTy, Size), 02455 IRB.CreatePointerCast(Descr, IRB.getInt8PtrTy()), 02456 IRB.CreatePointerCast(&F, MS.IntptrTy)); 02457 } 02458 } 02459 02460 void visitSelectInst(SelectInst& I) { 02461 IRBuilder<> IRB(&I); 02462 // a = select b, c, d 02463 Value *B = I.getCondition(); 02464 Value *C = I.getTrueValue(); 02465 Value *D = I.getFalseValue(); 02466 Value *Sb = getShadow(B); 02467 Value *Sc = getShadow(C); 02468 Value *Sd = getShadow(D); 02469 02470 // Result shadow if condition shadow is 0. 02471 Value *Sa0 = IRB.CreateSelect(B, Sc, Sd); 02472 Value *Sa1; 02473 if (I.getType()->isAggregateType()) { 02474 // To avoid "sign extending" i1 to an arbitrary aggregate type, we just do 02475 // an extra "select". This results in much more compact IR. 02476 // Sa = select Sb, poisoned, (select b, Sc, Sd) 02477 Sa1 = getPoisonedShadow(getShadowTy(I.getType())); 02478 } else { 02479 // Sa = select Sb, [ (c^d) | Sc | Sd ], [ b ? Sc : Sd ] 02480 // If Sb (condition is poisoned), look for bits in c and d that are equal 02481 // and both unpoisoned. 02482 // If !Sb (condition is unpoisoned), simply pick one of Sc and Sd. 02483 02484 // Cast arguments to shadow-compatible type. 02485 C = CreateAppToShadowCast(IRB, C); 02486 D = CreateAppToShadowCast(IRB, D); 02487 02488 // Result shadow if condition shadow is 1. 02489 Sa1 = IRB.CreateOr(IRB.CreateXor(C, D), IRB.CreateOr(Sc, Sd)); 02490 } 02491 Value *Sa = IRB.CreateSelect(Sb, Sa1, Sa0, "_msprop_select"); 02492 setShadow(&I, Sa); 02493 if (MS.TrackOrigins) { 02494 // Origins are always i32, so any vector conditions must be flattened. 02495 // FIXME: consider tracking vector origins for app vectors? 02496 if (B->getType()->isVectorTy()) { 02497 Type *FlatTy = getShadowTyNoVec(B->getType()); 02498 B = IRB.CreateICmpNE(IRB.CreateBitCast(B, FlatTy), 02499 ConstantInt::getNullValue(FlatTy)); 02500 Sb = IRB.CreateICmpNE(IRB.CreateBitCast(Sb, FlatTy), 02501 ConstantInt::getNullValue(FlatTy)); 02502 } 02503 // a = select b, c, d 02504 // Oa = Sb ? Ob : (b ? Oc : Od) 02505 setOrigin(&I, IRB.CreateSelect( 02506 Sb, getOrigin(I.getCondition()), 02507 IRB.CreateSelect(B, getOrigin(C), getOrigin(D)))); 02508 } 02509 } 02510 02511 void visitLandingPadInst(LandingPadInst &I) { 02512 // Do nothing. 02513 // See http://code.google.com/p/memory-sanitizer/issues/detail?id=1 02514 setShadow(&I, getCleanShadow(&I)); 02515 setOrigin(&I, getCleanOrigin()); 02516 } 02517 02518 void visitGetElementPtrInst(GetElementPtrInst &I) { 02519 handleShadowOr(I); 02520 } 02521 02522 void visitExtractValueInst(ExtractValueInst &I) { 02523 IRBuilder<> IRB(&I); 02524 Value *Agg = I.getAggregateOperand(); 02525 DEBUG(dbgs() << "ExtractValue: " << I << "\n"); 02526 Value *AggShadow = getShadow(Agg); 02527 DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n"); 02528 Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices()); 02529 DEBUG(dbgs() << " ResShadow: " << *ResShadow << "\n"); 02530 setShadow(&I, ResShadow); 02531 setOriginForNaryOp(I); 02532 } 02533 02534 void visitInsertValueInst(InsertValueInst &I) { 02535 IRBuilder<> IRB(&I); 02536 DEBUG(dbgs() << "InsertValue: " << I << "\n"); 02537 Value *AggShadow = getShadow(I.getAggregateOperand()); 02538 Value *InsShadow = getShadow(I.getInsertedValueOperand()); 02539 DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n"); 02540 DEBUG(dbgs() << " InsShadow: " << *InsShadow << "\n"); 02541 Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices()); 02542 DEBUG(dbgs() << " Res: " << *Res << "\n"); 02543 setShadow(&I, Res); 02544 setOriginForNaryOp(I); 02545 } 02546 02547 void dumpInst(Instruction &I) { 02548 if (CallInst *CI = dyn_cast<CallInst>(&I)) { 02549 errs() << "ZZZ call " << CI->getCalledFunction()->getName() << "\n"; 02550 } else { 02551 errs() << "ZZZ " << I.getOpcodeName() << "\n"; 02552 } 02553 errs() << "QQQ " << I << "\n"; 02554 } 02555 02556 void visitResumeInst(ResumeInst &I) { 02557 DEBUG(dbgs() << "Resume: " << I << "\n"); 02558 // Nothing to do here. 02559 } 02560 02561 void visitInstruction(Instruction &I) { 02562 // Everything else: stop propagating and check for poisoned shadow. 02563 if (ClDumpStrictInstructions) 02564 dumpInst(I); 02565 DEBUG(dbgs() << "DEFAULT: " << I << "\n"); 02566 for (size_t i = 0, n = I.getNumOperands(); i < n; i++) 02567 insertShadowCheck(I.getOperand(i), &I); 02568 setShadow(&I, getCleanShadow(&I)); 02569 setOrigin(&I, getCleanOrigin()); 02570 } 02571 }; 02572 02573 /// \brief AMD64-specific implementation of VarArgHelper. 02574 struct VarArgAMD64Helper : public VarArgHelper { 02575 // An unfortunate workaround for asymmetric lowering of va_arg stuff. 02576 // See a comment in visitCallSite for more details. 02577 static const unsigned AMD64GpEndOffset = 48; // AMD64 ABI Draft 0.99.6 p3.5.7 02578 static const unsigned AMD64FpEndOffset = 176; 02579 02580 Function &F; 02581 MemorySanitizer &MS; 02582 MemorySanitizerVisitor &MSV; 02583 Value *VAArgTLSCopy; 02584 Value *VAArgOverflowSize; 02585 02586 SmallVector<CallInst*, 16> VAStartInstrumentationList; 02587 02588 VarArgAMD64Helper(Function &F, MemorySanitizer &MS, 02589 MemorySanitizerVisitor &MSV) 02590 : F(F), MS(MS), MSV(MSV), VAArgTLSCopy(nullptr), 02591 VAArgOverflowSize(nullptr) {} 02592 02593 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory }; 02594 02595 ArgKind classifyArgument(Value* arg) { 02596 // A very rough approximation of X86_64 argument classification rules. 02597 Type *T = arg->getType(); 02598 if (T->isFPOrFPVectorTy() || T->isX86_MMXTy()) 02599 return AK_FloatingPoint; 02600 if (T->isIntegerTy() && T->getPrimitiveSizeInBits() <= 64) 02601 return AK_GeneralPurpose; 02602 if (T->isPointerTy()) 02603 return AK_GeneralPurpose; 02604 return AK_Memory; 02605 } 02606 02607 // For VarArg functions, store the argument shadow in an ABI-specific format 02608 // that corresponds to va_list layout. 02609 // We do this because Clang lowers va_arg in the frontend, and this pass 02610 // only sees the low level code that deals with va_list internals. 02611 // A much easier alternative (provided that Clang emits va_arg instructions) 02612 // would have been to associate each live instance of va_list with a copy of 02613 // MSanParamTLS, and extract shadow on va_arg() call in the argument list 02614 // order. 02615 void visitCallSite(CallSite &CS, IRBuilder<> &IRB) override { 02616 unsigned GpOffset = 0; 02617 unsigned FpOffset = AMD64GpEndOffset; 02618 unsigned OverflowOffset = AMD64FpEndOffset; 02619 for (CallSite::arg_iterator ArgIt = CS.arg_begin(), End = CS.arg_end(); 02620 ArgIt != End; ++ArgIt) { 02621 Value *A = *ArgIt; 02622 unsigned ArgNo = CS.getArgumentNo(ArgIt); 02623 bool IsByVal = CS.paramHasAttr(ArgNo + 1, Attribute::ByVal); 02624 if (IsByVal) { 02625 // ByVal arguments always go to the overflow area. 02626 assert(A->getType()->isPointerTy()); 02627 Type *RealTy = A->getType()->getPointerElementType(); 02628 uint64_t ArgSize = MS.DL->getTypeAllocSize(RealTy); 02629 Value *Base = getShadowPtrForVAArgument(RealTy, IRB, OverflowOffset); 02630 OverflowOffset += DataLayout::RoundUpAlignment(ArgSize, 8); 02631 IRB.CreateMemCpy(Base, MSV.getShadowPtr(A, IRB.getInt8Ty(), IRB), 02632 ArgSize, kShadowTLSAlignment); 02633 } else { 02634 ArgKind AK = classifyArgument(A); 02635 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset) 02636 AK = AK_Memory; 02637 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset) 02638 AK = AK_Memory; 02639 Value *Base; 02640 switch (AK) { 02641 case AK_GeneralPurpose: 02642 Base = getShadowPtrForVAArgument(A->getType(), IRB, GpOffset); 02643 GpOffset += 8; 02644 break; 02645 case AK_FloatingPoint: 02646 Base = getShadowPtrForVAArgument(A->getType(), IRB, FpOffset); 02647 FpOffset += 16; 02648 break; 02649 case AK_Memory: 02650 uint64_t ArgSize = MS.DL->getTypeAllocSize(A->getType()); 02651 Base = getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset); 02652 OverflowOffset += DataLayout::RoundUpAlignment(ArgSize, 8); 02653 } 02654 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment); 02655 } 02656 } 02657 Constant *OverflowSize = 02658 ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AMD64FpEndOffset); 02659 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS); 02660 } 02661 02662 /// \brief Compute the shadow address for a given va_arg. 02663 Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB, 02664 int ArgOffset) { 02665 Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy); 02666 Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset)); 02667 return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0), 02668 "_msarg"); 02669 } 02670 02671 void visitVAStartInst(VAStartInst &I) override { 02672 IRBuilder<> IRB(&I); 02673 VAStartInstrumentationList.push_back(&I); 02674 Value *VAListTag = I.getArgOperand(0); 02675 Value *ShadowPtr = MSV.getShadowPtr(VAListTag, IRB.getInt8Ty(), IRB); 02676 02677 // Unpoison the whole __va_list_tag. 02678 // FIXME: magic ABI constants. 02679 IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()), 02680 /* size */24, /* alignment */8, false); 02681 } 02682 02683 void visitVACopyInst(VACopyInst &I) override { 02684 IRBuilder<> IRB(&I); 02685 Value *VAListTag = I.getArgOperand(0); 02686 Value *ShadowPtr = MSV.getShadowPtr(VAListTag, IRB.getInt8Ty(), IRB); 02687 02688 // Unpoison the whole __va_list_tag. 02689 // FIXME: magic ABI constants. 02690 IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()), 02691 /* size */24, /* alignment */8, false); 02692 } 02693 02694 void finalizeInstrumentation() override { 02695 assert(!VAArgOverflowSize && !VAArgTLSCopy && 02696 "finalizeInstrumentation called twice"); 02697 if (!VAStartInstrumentationList.empty()) { 02698 // If there is a va_start in this function, make a backup copy of 02699 // va_arg_tls somewhere in the function entry block. 02700 IRBuilder<> IRB(F.getEntryBlock().getFirstNonPHI()); 02701 VAArgOverflowSize = IRB.CreateLoad(MS.VAArgOverflowSizeTLS); 02702 Value *CopySize = 02703 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), 02704 VAArgOverflowSize); 02705 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize); 02706 IRB.CreateMemCpy(VAArgTLSCopy, MS.VAArgTLS, CopySize, 8); 02707 } 02708 02709 // Instrument va_start. 02710 // Copy va_list shadow from the backup copy of the TLS contents. 02711 for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) { 02712 CallInst *OrigInst = VAStartInstrumentationList[i]; 02713 IRBuilder<> IRB(OrigInst->getNextNode()); 02714 Value *VAListTag = OrigInst->getArgOperand(0); 02715 02716 Value *RegSaveAreaPtrPtr = 02717 IRB.CreateIntToPtr( 02718 IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy), 02719 ConstantInt::get(MS.IntptrTy, 16)), 02720 Type::getInt64PtrTy(*MS.C)); 02721 Value *RegSaveAreaPtr = IRB.CreateLoad(RegSaveAreaPtrPtr); 02722 Value *RegSaveAreaShadowPtr = 02723 MSV.getShadowPtr(RegSaveAreaPtr, IRB.getInt8Ty(), IRB); 02724 IRB.CreateMemCpy(RegSaveAreaShadowPtr, VAArgTLSCopy, 02725 AMD64FpEndOffset, 16); 02726 02727 Value *OverflowArgAreaPtrPtr = 02728 IRB.CreateIntToPtr( 02729 IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy), 02730 ConstantInt::get(MS.IntptrTy, 8)), 02731 Type::getInt64PtrTy(*MS.C)); 02732 Value *OverflowArgAreaPtr = IRB.CreateLoad(OverflowArgAreaPtrPtr); 02733 Value *OverflowArgAreaShadowPtr = 02734 MSV.getShadowPtr(OverflowArgAreaPtr, IRB.getInt8Ty(), IRB); 02735 Value *SrcPtr = IRB.CreateConstGEP1_32(VAArgTLSCopy, AMD64FpEndOffset); 02736 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, SrcPtr, VAArgOverflowSize, 16); 02737 } 02738 } 02739 }; 02740 02741 /// \brief A no-op implementation of VarArgHelper. 02742 struct VarArgNoOpHelper : public VarArgHelper { 02743 VarArgNoOpHelper(Function &F, MemorySanitizer &MS, 02744 MemorySanitizerVisitor &MSV) {} 02745 02746 void visitCallSite(CallSite &CS, IRBuilder<> &IRB) override {} 02747 02748 void visitVAStartInst(VAStartInst &I) override {} 02749 02750 void visitVACopyInst(VACopyInst &I) override {} 02751 02752 void finalizeInstrumentation() override {} 02753 }; 02754 02755 VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, 02756 MemorySanitizerVisitor &Visitor) { 02757 // VarArg handling is only implemented on AMD64. False positives are possible 02758 // on other platforms. 02759 llvm::Triple TargetTriple(Func.getParent()->getTargetTriple()); 02760 if (TargetTriple.getArch() == llvm::Triple::x86_64) 02761 return new VarArgAMD64Helper(Func, Msan, Visitor); 02762 else 02763 return new VarArgNoOpHelper(Func, Msan, Visitor); 02764 } 02765 02766 } // namespace 02767 02768 bool MemorySanitizer::runOnFunction(Function &F) { 02769 MemorySanitizerVisitor Visitor(F, *this); 02770 02771 // Clear out readonly/readnone attributes. 02772 AttrBuilder B; 02773 B.addAttribute(Attribute::ReadOnly) 02774 .addAttribute(Attribute::ReadNone); 02775 F.removeAttributes(AttributeSet::FunctionIndex, 02776 AttributeSet::get(F.getContext(), 02777 AttributeSet::FunctionIndex, B)); 02778 02779 return Visitor.runOnFunction(); 02780 }