LLVM 19.0.0git
MemorySanitizer.cpp
Go to the documentation of this file.
1//===- MemorySanitizer.cpp - detector of uninitialized reads --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// This file is a part of MemorySanitizer, a detector of uninitialized
11/// reads.
12///
13/// The algorithm of the tool is similar to Memcheck
14/// (http://goo.gl/QKbem). We associate a few shadow bits with every
15/// byte of the application memory, poison the shadow of the malloc-ed
16/// or alloca-ed memory, load the shadow bits on every memory read,
17/// propagate the shadow bits through some of the arithmetic
18/// instruction (including MOV), store the shadow bits on every memory
19/// write, report a bug on some other instructions (e.g. JMP) if the
20/// associated shadow is poisoned.
21///
22/// But there are differences too. The first and the major one:
23/// compiler instrumentation instead of binary instrumentation. This
24/// gives us much better register allocation, possible compiler
25/// optimizations and a fast start-up. But this brings the major issue
26/// as well: msan needs to see all program events, including system
27/// calls and reads/writes in system libraries, so we either need to
28/// compile *everything* with msan or use a binary translation
29/// component (e.g. DynamoRIO) to instrument pre-built libraries.
30/// Another difference from Memcheck is that we use 8 shadow bits per
31/// byte of application memory and use a direct shadow mapping. This
32/// greatly simplifies the instrumentation code and avoids races on
33/// shadow updates (Memcheck is single-threaded so races are not a
34/// concern there. Memcheck uses 2 shadow bits per byte with a slow
35/// path storage that uses 8 bits per byte).
36///
37/// The default value of shadow is 0, which means "clean" (not poisoned).
38///
39/// Every module initializer should call __msan_init to ensure that the
40/// shadow memory is ready. On error, __msan_warning is called. Since
41/// parameters and return values may be passed via registers, we have a
42/// specialized thread-local shadow for return values
43/// (__msan_retval_tls) and parameters (__msan_param_tls).
44///
45/// Origin tracking.
46///
47/// MemorySanitizer can track origins (allocation points) of all uninitialized
48/// values. This behavior is controlled with a flag (msan-track-origins) and is
49/// disabled by default.
50///
51/// Origins are 4-byte values created and interpreted by the runtime library.
52/// They are stored in a second shadow mapping, one 4-byte value for 4 bytes
53/// of application memory. Propagation of origins is basically a bunch of
54/// "select" instructions that pick the origin of a dirty argument, if an
55/// instruction has one.
56///
57/// Every 4 aligned, consecutive bytes of application memory have one origin
58/// value associated with them. If these bytes contain uninitialized data
59/// coming from 2 different allocations, the last store wins. Because of this,
60/// MemorySanitizer reports can show unrelated origins, but this is unlikely in
61/// practice.
62///
63/// Origins are meaningless for fully initialized values, so MemorySanitizer
64/// avoids storing origin to memory when a fully initialized value is stored.
65/// This way it avoids needless overwriting origin of the 4-byte region on
66/// a short (i.e. 1 byte) clean store, and it is also good for performance.
67///
68/// Atomic handling.
69///
70/// Ideally, every atomic store of application value should update the
71/// corresponding shadow location in an atomic way. Unfortunately, atomic store
72/// of two disjoint locations can not be done without severe slowdown.
73///
74/// Therefore, we implement an approximation that may err on the safe side.
75/// In this implementation, every atomically accessed location in the program
76/// may only change from (partially) uninitialized to fully initialized, but
77/// not the other way around. We load the shadow _after_ the application load,
78/// and we store the shadow _before_ the app store. Also, we always store clean
79/// shadow (if the application store is atomic). This way, if the store-load
80/// pair constitutes a happens-before arc, shadow store and load are correctly
81/// ordered such that the load will get either the value that was stored, or
82/// some later value (which is always clean).
83///
84/// This does not work very well with Compare-And-Swap (CAS) and
85/// Read-Modify-Write (RMW) operations. To follow the above logic, CAS and RMW
86/// must store the new shadow before the app operation, and load the shadow
87/// after the app operation. Computers don't work this way. Current
88/// implementation ignores the load aspect of CAS/RMW, always returning a clean
89/// value. It implements the store part as a simple atomic store by storing a
90/// clean shadow.
91///
92/// Instrumenting inline assembly.
93///
94/// For inline assembly code LLVM has little idea about which memory locations
95/// become initialized depending on the arguments. It can be possible to figure
96/// out which arguments are meant to point to inputs and outputs, but the
97/// actual semantics can be only visible at runtime. In the Linux kernel it's
98/// also possible that the arguments only indicate the offset for a base taken
99/// from a segment register, so it's dangerous to treat any asm() arguments as
100/// pointers. We take a conservative approach generating calls to
101/// __msan_instrument_asm_store(ptr, size)
102/// , which defer the memory unpoisoning to the runtime library.
103/// The latter can perform more complex address checks to figure out whether
104/// it's safe to touch the shadow memory.
105/// Like with atomic operations, we call __msan_instrument_asm_store() before
106/// the assembly call, so that changes to the shadow memory will be seen by
107/// other threads together with main memory initialization.
108///
109/// KernelMemorySanitizer (KMSAN) implementation.
110///
111/// The major differences between KMSAN and MSan instrumentation are:
112/// - KMSAN always tracks the origins and implies msan-keep-going=true;
113/// - KMSAN allocates shadow and origin memory for each page separately, so
114/// there are no explicit accesses to shadow and origin in the
115/// instrumentation.
116/// Shadow and origin values for a particular X-byte memory location
117/// (X=1,2,4,8) are accessed through pointers obtained via the
118/// __msan_metadata_ptr_for_load_X(ptr)
119/// __msan_metadata_ptr_for_store_X(ptr)
120/// functions. The corresponding functions check that the X-byte accesses
121/// are possible and returns the pointers to shadow and origin memory.
122/// Arbitrary sized accesses are handled with:
123/// __msan_metadata_ptr_for_load_n(ptr, size)
124/// __msan_metadata_ptr_for_store_n(ptr, size);
125/// Note that the sanitizer code has to deal with how shadow/origin pairs
126/// returned by the these functions are represented in different ABIs. In
127/// the X86_64 ABI they are returned in RDX:RAX, and in the SystemZ ABI they
128/// are written to memory pointed to by a hidden parameter.
129/// - TLS variables are stored in a single per-task struct. A call to a
130/// function __msan_get_context_state() returning a pointer to that struct
131/// is inserted into every instrumented function before the entry block;
132/// - __msan_warning() takes a 32-bit origin parameter;
133/// - local variables are poisoned with __msan_poison_alloca() upon function
134/// entry and unpoisoned with __msan_unpoison_alloca() before leaving the
135/// function;
136/// - the pass doesn't declare any global variables or add global constructors
137/// to the translation unit.
138///
139/// Also, KMSAN currently ignores uninitialized memory passed into inline asm
140/// calls, making sure we're on the safe side wrt. possible false positives.
141///
142/// KernelMemorySanitizer only supports X86_64 and SystemZ at the moment.
143///
144//
145// FIXME: This sanitizer does not yet handle scalable vectors
146//
147//===----------------------------------------------------------------------===//
148
150#include "llvm/ADT/APInt.h"
151#include "llvm/ADT/ArrayRef.h"
152#include "llvm/ADT/DenseMap.h"
154#include "llvm/ADT/SetVector.h"
155#include "llvm/ADT/SmallVector.h"
157#include "llvm/ADT/StringRef.h"
161#include "llvm/IR/Argument.h"
163#include "llvm/IR/Attributes.h"
164#include "llvm/IR/BasicBlock.h"
165#include "llvm/IR/CallingConv.h"
166#include "llvm/IR/Constant.h"
167#include "llvm/IR/Constants.h"
168#include "llvm/IR/DataLayout.h"
169#include "llvm/IR/DerivedTypes.h"
170#include "llvm/IR/Function.h"
171#include "llvm/IR/GlobalValue.h"
173#include "llvm/IR/IRBuilder.h"
174#include "llvm/IR/InlineAsm.h"
175#include "llvm/IR/InstVisitor.h"
176#include "llvm/IR/InstrTypes.h"
177#include "llvm/IR/Instruction.h"
178#include "llvm/IR/Instructions.h"
180#include "llvm/IR/Intrinsics.h"
181#include "llvm/IR/IntrinsicsX86.h"
182#include "llvm/IR/MDBuilder.h"
183#include "llvm/IR/Module.h"
184#include "llvm/IR/Type.h"
185#include "llvm/IR/Value.h"
186#include "llvm/IR/ValueMap.h"
189#include "llvm/Support/Casting.h"
191#include "llvm/Support/Debug.h"
200#include <algorithm>
201#include <cassert>
202#include <cstddef>
203#include <cstdint>
204#include <memory>
205#include <string>
206#include <tuple>
207
208using namespace llvm;
209
210#define DEBUG_TYPE "msan"
211
212DEBUG_COUNTER(DebugInsertCheck, "msan-insert-check",
213 "Controls which checks to insert");
214
215static const unsigned kOriginSize = 4;
218
219// These constants must be kept in sync with the ones in msan.h.
220static const unsigned kParamTLSSize = 800;
221static const unsigned kRetvalTLSSize = 800;
222
223// Accesses sizes are powers of two: 1, 2, 4, 8.
224static const size_t kNumberOfAccessSizes = 4;
225
226/// Track origins of uninitialized values.
227///
228/// Adds a section to MemorySanitizer report that points to the allocation
229/// (stack or heap) the uninitialized bits came from originally.
231 "msan-track-origins",
232 cl::desc("Track origins (allocation sites) of poisoned memory"), cl::Hidden,
233 cl::init(0));
234
235static cl::opt<bool> ClKeepGoing("msan-keep-going",
236 cl::desc("keep going after reporting a UMR"),
237 cl::Hidden, cl::init(false));
238
239static cl::opt<bool>
240 ClPoisonStack("msan-poison-stack",
241 cl::desc("poison uninitialized stack variables"), cl::Hidden,
242 cl::init(true));
243
245 "msan-poison-stack-with-call",
246 cl::desc("poison uninitialized stack variables with a call"), cl::Hidden,
247 cl::init(false));
248
250 "msan-poison-stack-pattern",
251 cl::desc("poison uninitialized stack variables with the given pattern"),
252 cl::Hidden, cl::init(0xff));
253
254static cl::opt<bool>
255 ClPrintStackNames("msan-print-stack-names",
256 cl::desc("Print name of local stack variable"),
257 cl::Hidden, cl::init(true));
258
259static cl::opt<bool> ClPoisonUndef("msan-poison-undef",
260 cl::desc("poison undef temps"), cl::Hidden,
261 cl::init(true));
262
263static cl::opt<bool>
264 ClHandleICmp("msan-handle-icmp",
265 cl::desc("propagate shadow through ICmpEQ and ICmpNE"),
266 cl::Hidden, cl::init(true));
267
268static cl::opt<bool>
269 ClHandleICmpExact("msan-handle-icmp-exact",
270 cl::desc("exact handling of relational integer ICmp"),
271 cl::Hidden, cl::init(false));
272
274 "msan-handle-lifetime-intrinsics",
275 cl::desc(
276 "when possible, poison scoped variables at the beginning of the scope "
277 "(slower, but more precise)"),
278 cl::Hidden, cl::init(true));
279
280// When compiling the Linux kernel, we sometimes see false positives related to
281// MSan being unable to understand that inline assembly calls may initialize
282// local variables.
283// This flag makes the compiler conservatively unpoison every memory location
284// passed into an assembly call. Note that this may cause false positives.
285// Because it's impossible to figure out the array sizes, we can only unpoison
286// the first sizeof(type) bytes for each type* pointer.
288 "msan-handle-asm-conservative",
289 cl::desc("conservative handling of inline assembly"), cl::Hidden,
290 cl::init(true));
291
292// This flag controls whether we check the shadow of the address
293// operand of load or store. Such bugs are very rare, since load from
294// a garbage address typically results in SEGV, but still happen
295// (e.g. only lower bits of address are garbage, or the access happens
296// early at program startup where malloc-ed memory is more likely to
297// be zeroed. As of 2012-08-28 this flag adds 20% slowdown.
299 "msan-check-access-address",
300 cl::desc("report accesses through a pointer which has poisoned shadow"),
301 cl::Hidden, cl::init(true));
302
304 "msan-eager-checks",
305 cl::desc("check arguments and return values at function call boundaries"),
306 cl::Hidden, cl::init(false));
307
309 "msan-dump-strict-instructions",
310 cl::desc("print out instructions with default strict semantics"),
311 cl::Hidden, cl::init(false));
312
314 "msan-instrumentation-with-call-threshold",
315 cl::desc(
316 "If the function being instrumented requires more than "
317 "this number of checks and origin stores, use callbacks instead of "
318 "inline checks (-1 means never use callbacks)."),
319 cl::Hidden, cl::init(3500));
320
321static cl::opt<bool>
322 ClEnableKmsan("msan-kernel",
323 cl::desc("Enable KernelMemorySanitizer instrumentation"),
324 cl::Hidden, cl::init(false));
325
326static cl::opt<bool>
327 ClDisableChecks("msan-disable-checks",
328 cl::desc("Apply no_sanitize to the whole file"), cl::Hidden,
329 cl::init(false));
330
331static cl::opt<bool>
332 ClCheckConstantShadow("msan-check-constant-shadow",
333 cl::desc("Insert checks for constant shadow values"),
334 cl::Hidden, cl::init(true));
335
336// This is off by default because of a bug in gold:
337// https://sourceware.org/bugzilla/show_bug.cgi?id=19002
338static cl::opt<bool>
339 ClWithComdat("msan-with-comdat",
340 cl::desc("Place MSan constructors in comdat sections"),
341 cl::Hidden, cl::init(false));
342
343// These options allow to specify custom memory map parameters
344// See MemoryMapParams for details.
345static cl::opt<uint64_t> ClAndMask("msan-and-mask",
346 cl::desc("Define custom MSan AndMask"),
347 cl::Hidden, cl::init(0));
348
349static cl::opt<uint64_t> ClXorMask("msan-xor-mask",
350 cl::desc("Define custom MSan XorMask"),
351 cl::Hidden, cl::init(0));
352
353static cl::opt<uint64_t> ClShadowBase("msan-shadow-base",
354 cl::desc("Define custom MSan ShadowBase"),
355 cl::Hidden, cl::init(0));
356
357static cl::opt<uint64_t> ClOriginBase("msan-origin-base",
358 cl::desc("Define custom MSan OriginBase"),
359 cl::Hidden, cl::init(0));
360
361static cl::opt<int>
362 ClDisambiguateWarning("msan-disambiguate-warning-threshold",
363 cl::desc("Define threshold for number of checks per "
364 "debug location to force origin update."),
365 cl::Hidden, cl::init(3));
366
367const char kMsanModuleCtorName[] = "msan.module_ctor";
368const char kMsanInitName[] = "__msan_init";
369
370namespace {
371
372// Memory map parameters used in application-to-shadow address calculation.
373// Offset = (Addr & ~AndMask) ^ XorMask
374// Shadow = ShadowBase + Offset
375// Origin = OriginBase + Offset
376struct MemoryMapParams {
377 uint64_t AndMask;
378 uint64_t XorMask;
379 uint64_t ShadowBase;
380 uint64_t OriginBase;
381};
382
383struct PlatformMemoryMapParams {
384 const MemoryMapParams *bits32;
385 const MemoryMapParams *bits64;
386};
387
388} // end anonymous namespace
389
390// i386 Linux
391static const MemoryMapParams Linux_I386_MemoryMapParams = {
392 0x000080000000, // AndMask
393 0, // XorMask (not used)
394 0, // ShadowBase (not used)
395 0x000040000000, // OriginBase
396};
397
398// x86_64 Linux
399static const MemoryMapParams Linux_X86_64_MemoryMapParams = {
400 0, // AndMask (not used)
401 0x500000000000, // XorMask
402 0, // ShadowBase (not used)
403 0x100000000000, // OriginBase
404};
405
406// mips64 Linux
407static const MemoryMapParams Linux_MIPS64_MemoryMapParams = {
408 0, // AndMask (not used)
409 0x008000000000, // XorMask
410 0, // ShadowBase (not used)
411 0x002000000000, // OriginBase
412};
413
414// ppc64 Linux
415static const MemoryMapParams Linux_PowerPC64_MemoryMapParams = {
416 0xE00000000000, // AndMask
417 0x100000000000, // XorMask
418 0x080000000000, // ShadowBase
419 0x1C0000000000, // OriginBase
420};
421
422// s390x Linux
423static const MemoryMapParams Linux_S390X_MemoryMapParams = {
424 0xC00000000000, // AndMask
425 0, // XorMask (not used)
426 0x080000000000, // ShadowBase
427 0x1C0000000000, // OriginBase
428};
429
430// aarch64 Linux
431static const MemoryMapParams Linux_AArch64_MemoryMapParams = {
432 0, // AndMask (not used)
433 0x0B00000000000, // XorMask
434 0, // ShadowBase (not used)
435 0x0200000000000, // OriginBase
436};
437
438// loongarch64 Linux
439static const MemoryMapParams Linux_LoongArch64_MemoryMapParams = {
440 0, // AndMask (not used)
441 0x500000000000, // XorMask
442 0, // ShadowBase (not used)
443 0x100000000000, // OriginBase
444};
445
446// aarch64 FreeBSD
447static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams = {
448 0x1800000000000, // AndMask
449 0x0400000000000, // XorMask
450 0x0200000000000, // ShadowBase
451 0x0700000000000, // OriginBase
452};
453
454// i386 FreeBSD
455static const MemoryMapParams FreeBSD_I386_MemoryMapParams = {
456 0x000180000000, // AndMask
457 0x000040000000, // XorMask
458 0x000020000000, // ShadowBase
459 0x000700000000, // OriginBase
460};
461
462// x86_64 FreeBSD
463static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams = {
464 0xc00000000000, // AndMask
465 0x200000000000, // XorMask
466 0x100000000000, // ShadowBase
467 0x380000000000, // OriginBase
468};
469
470// x86_64 NetBSD
471static const MemoryMapParams NetBSD_X86_64_MemoryMapParams = {
472 0, // AndMask
473 0x500000000000, // XorMask
474 0, // ShadowBase
475 0x100000000000, // OriginBase
476};
477
478static const PlatformMemoryMapParams Linux_X86_MemoryMapParams = {
481};
482
483static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams = {
484 nullptr,
486};
487
488static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams = {
489 nullptr,
491};
492
493static const PlatformMemoryMapParams Linux_S390_MemoryMapParams = {
494 nullptr,
496};
497
498static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams = {
499 nullptr,
501};
502
503static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams = {
504 nullptr,
506};
507
508static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams = {
509 nullptr,
511};
512
513static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams = {
516};
517
518static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams = {
519 nullptr,
521};
522
523namespace {
524
525/// Instrument functions of a module to detect uninitialized reads.
526///
527/// Instantiating MemorySanitizer inserts the msan runtime library API function
528/// declarations into the module if they don't exist already. Instantiating
529/// ensures the __msan_init function is in the list of global constructors for
530/// the module.
531class MemorySanitizer {
532public:
533 MemorySanitizer(Module &M, MemorySanitizerOptions Options)
534 : CompileKernel(Options.Kernel), TrackOrigins(Options.TrackOrigins),
535 Recover(Options.Recover), EagerChecks(Options.EagerChecks) {
536 initializeModule(M);
537 }
538
539 // MSan cannot be moved or copied because of MapParams.
540 MemorySanitizer(MemorySanitizer &&) = delete;
541 MemorySanitizer &operator=(MemorySanitizer &&) = delete;
542 MemorySanitizer(const MemorySanitizer &) = delete;
543 MemorySanitizer &operator=(const MemorySanitizer &) = delete;
544
545 bool sanitizeFunction(Function &F, TargetLibraryInfo &TLI);
546
547private:
548 friend struct MemorySanitizerVisitor;
549 friend struct VarArgHelperBase;
550 friend struct VarArgAMD64Helper;
551 friend struct VarArgMIPS64Helper;
552 friend struct VarArgAArch64Helper;
553 friend struct VarArgPowerPC64Helper;
554 friend struct VarArgSystemZHelper;
555
556 void initializeModule(Module &M);
557 void initializeCallbacks(Module &M, const TargetLibraryInfo &TLI);
558 void createKernelApi(Module &M, const TargetLibraryInfo &TLI);
559 void createUserspaceApi(Module &M, const TargetLibraryInfo &TLI);
560
561 template <typename... ArgsTy>
562 FunctionCallee getOrInsertMsanMetadataFunction(Module &M, StringRef Name,
563 ArgsTy... Args);
564
565 /// True if we're compiling the Linux kernel.
566 bool CompileKernel;
567 /// Track origins (allocation points) of uninitialized values.
568 int TrackOrigins;
569 bool Recover;
570 bool EagerChecks;
571
572 Triple TargetTriple;
573 LLVMContext *C;
574 Type *IntptrTy; ///< Integer type with the size of a ptr in default AS.
575 Type *OriginTy;
576 PointerType *PtrTy; ///< Integer type with the size of a ptr in default AS.
577
578 // XxxTLS variables represent the per-thread state in MSan and per-task state
579 // in KMSAN.
580 // For the userspace these point to thread-local globals. In the kernel land
581 // they point to the members of a per-task struct obtained via a call to
582 // __msan_get_context_state().
583
584 /// Thread-local shadow storage for function parameters.
585 Value *ParamTLS;
586
587 /// Thread-local origin storage for function parameters.
588 Value *ParamOriginTLS;
589
590 /// Thread-local shadow storage for function return value.
591 Value *RetvalTLS;
592
593 /// Thread-local origin storage for function return value.
594 Value *RetvalOriginTLS;
595
596 /// Thread-local shadow storage for in-register va_arg function.
597 Value *VAArgTLS;
598
599 /// Thread-local shadow storage for in-register va_arg function.
600 Value *VAArgOriginTLS;
601
602 /// Thread-local shadow storage for va_arg overflow area.
603 Value *VAArgOverflowSizeTLS;
604
605 /// Are the instrumentation callbacks set up?
606 bool CallbacksInitialized = false;
607
608 /// The run-time callback to print a warning.
609 FunctionCallee WarningFn;
610
611 // These arrays are indexed by log2(AccessSize).
612 FunctionCallee MaybeWarningFn[kNumberOfAccessSizes];
613 FunctionCallee MaybeStoreOriginFn[kNumberOfAccessSizes];
614
615 /// Run-time helper that generates a new origin value for a stack
616 /// allocation.
617 FunctionCallee MsanSetAllocaOriginWithDescriptionFn;
618 // No description version
619 FunctionCallee MsanSetAllocaOriginNoDescriptionFn;
620
621 /// Run-time helper that poisons stack on function entry.
622 FunctionCallee MsanPoisonStackFn;
623
624 /// Run-time helper that records a store (or any event) of an
625 /// uninitialized value and returns an updated origin id encoding this info.
626 FunctionCallee MsanChainOriginFn;
627
628 /// Run-time helper that paints an origin over a region.
629 FunctionCallee MsanSetOriginFn;
630
631 /// MSan runtime replacements for memmove, memcpy and memset.
632 FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
633
634 /// KMSAN callback for task-local function argument shadow.
635 StructType *MsanContextStateTy;
636 FunctionCallee MsanGetContextStateFn;
637
638 /// Functions for poisoning/unpoisoning local variables
639 FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
640
641 /// Pair of shadow/origin pointers.
642 Type *MsanMetadata;
643
644 /// Each of the MsanMetadataPtrXxx functions returns a MsanMetadata.
645 FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
646 FunctionCallee MsanMetadataPtrForLoad_1_8[4];
647 FunctionCallee MsanMetadataPtrForStore_1_8[4];
648 FunctionCallee MsanInstrumentAsmStoreFn;
649
650 /// Storage for return values of the MsanMetadataPtrXxx functions.
651 Value *MsanMetadataAlloca;
652
653 /// Helper to choose between different MsanMetadataPtrXxx().
654 FunctionCallee getKmsanShadowOriginAccessFn(bool isStore, int size);
655
656 /// Memory map parameters used in application-to-shadow calculation.
657 const MemoryMapParams *MapParams;
658
659 /// Custom memory map parameters used when -msan-shadow-base or
660 // -msan-origin-base is provided.
661 MemoryMapParams CustomMapParams;
662
663 MDNode *ColdCallWeights;
664
665 /// Branch weights for origin store.
666 MDNode *OriginStoreWeights;
667};
668
669void insertModuleCtor(Module &M) {
672 /*InitArgTypes=*/{},
673 /*InitArgs=*/{},
674 // This callback is invoked when the functions are created the first
675 // time. Hook them into the global ctors list in that case:
676 [&](Function *Ctor, FunctionCallee) {
677 if (!ClWithComdat) {
678 appendToGlobalCtors(M, Ctor, 0);
679 return;
680 }
681 Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
682 Ctor->setComdat(MsanCtorComdat);
683 appendToGlobalCtors(M, Ctor, 0, Ctor);
684 });
685}
686
687template <class T> T getOptOrDefault(const cl::opt<T> &Opt, T Default) {
688 return (Opt.getNumOccurrences() > 0) ? Opt : Default;
689}
690
691} // end anonymous namespace
692
694 bool EagerChecks)
695 : Kernel(getOptOrDefault(ClEnableKmsan, K)),
696 TrackOrigins(getOptOrDefault(ClTrackOrigins, Kernel ? 2 : TO)),
697 Recover(getOptOrDefault(ClKeepGoing, Kernel || R)),
698 EagerChecks(getOptOrDefault(ClEagerChecks, EagerChecks)) {}
699
702 bool Modified = false;
703 if (!Options.Kernel) {
704 insertModuleCtor(M);
705 Modified = true;
706 }
707
708 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
709 for (Function &F : M) {
710 if (F.empty())
711 continue;
712 MemorySanitizer Msan(*F.getParent(), Options);
713 Modified |=
714 Msan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F));
715 }
716
717 if (!Modified)
718 return PreservedAnalyses::all();
719
721 // GlobalsAA is considered stateless and does not get invalidated unless
722 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
723 // make changes that require GlobalsAA to be invalidated.
724 PA.abandon<GlobalsAA>();
725 return PA;
726}
727
729 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
731 OS, MapClassName2PassName);
732 OS << '<';
733 if (Options.Recover)
734 OS << "recover;";
735 if (Options.Kernel)
736 OS << "kernel;";
737 if (Options.EagerChecks)
738 OS << "eager-checks;";
739 OS << "track-origins=" << Options.TrackOrigins;
740 OS << '>';
741}
742
743/// Create a non-const global initialized with the given string.
744///
745/// Creates a writable global for Str so that we can pass it to the
746/// run-time lib. Runtime uses first 4 bytes of the string to store the
747/// frame ID, so the string needs to be mutable.
749 StringRef Str) {
750 Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
751 return new GlobalVariable(M, StrConst->getType(), /*isConstant=*/true,
752 GlobalValue::PrivateLinkage, StrConst, "");
753}
754
755template <typename... ArgsTy>
757MemorySanitizer::getOrInsertMsanMetadataFunction(Module &M, StringRef Name,
758 ArgsTy... Args) {
759 if (TargetTriple.getArch() == Triple::systemz) {
760 // SystemZ ABI: shadow/origin pair is returned via a hidden parameter.
761 return M.getOrInsertFunction(Name, Type::getVoidTy(*C),
762 PointerType::get(MsanMetadata, 0),
763 std::forward<ArgsTy>(Args)...);
764 }
765
766 return M.getOrInsertFunction(Name, MsanMetadata,
767 std::forward<ArgsTy>(Args)...);
768}
769
770/// Create KMSAN API callbacks.
771void MemorySanitizer::createKernelApi(Module &M, const TargetLibraryInfo &TLI) {
772 IRBuilder<> IRB(*C);
773
774 // These will be initialized in insertKmsanPrologue().
775 RetvalTLS = nullptr;
776 RetvalOriginTLS = nullptr;
777 ParamTLS = nullptr;
778 ParamOriginTLS = nullptr;
779 VAArgTLS = nullptr;
780 VAArgOriginTLS = nullptr;
781 VAArgOverflowSizeTLS = nullptr;
782
783 WarningFn = M.getOrInsertFunction("__msan_warning",
784 TLI.getAttrList(C, {0}, /*Signed=*/false),
785 IRB.getVoidTy(), IRB.getInt32Ty());
786
787 // Requests the per-task context state (kmsan_context_state*) from the
788 // runtime library.
789 MsanContextStateTy = StructType::get(
790 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
791 ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8),
792 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
793 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), /* va_arg_origin */
794 IRB.getInt64Ty(), ArrayType::get(OriginTy, kParamTLSSize / 4), OriginTy,
795 OriginTy);
796 MsanGetContextStateFn = M.getOrInsertFunction(
797 "__msan_get_context_state", PointerType::get(MsanContextStateTy, 0));
798
799 MsanMetadata = StructType::get(PointerType::get(IRB.getInt8Ty(), 0),
800 PointerType::get(IRB.getInt32Ty(), 0));
801
802 for (int ind = 0, size = 1; ind < 4; ind++, size <<= 1) {
803 std::string name_load =
804 "__msan_metadata_ptr_for_load_" + std::to_string(size);
805 std::string name_store =
806 "__msan_metadata_ptr_for_store_" + std::to_string(size);
807 MsanMetadataPtrForLoad_1_8[ind] = getOrInsertMsanMetadataFunction(
808 M, name_load, PointerType::get(IRB.getInt8Ty(), 0));
809 MsanMetadataPtrForStore_1_8[ind] = getOrInsertMsanMetadataFunction(
810 M, name_store, PointerType::get(IRB.getInt8Ty(), 0));
811 }
812
813 MsanMetadataPtrForLoadN = getOrInsertMsanMetadataFunction(
814 M, "__msan_metadata_ptr_for_load_n", PointerType::get(IRB.getInt8Ty(), 0),
815 IRB.getInt64Ty());
816 MsanMetadataPtrForStoreN = getOrInsertMsanMetadataFunction(
817 M, "__msan_metadata_ptr_for_store_n",
818 PointerType::get(IRB.getInt8Ty(), 0), IRB.getInt64Ty());
819
820 // Functions for poisoning and unpoisoning memory.
821 MsanPoisonAllocaFn = M.getOrInsertFunction(
822 "__msan_poison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
823 MsanUnpoisonAllocaFn = M.getOrInsertFunction(
824 "__msan_unpoison_alloca", IRB.getVoidTy(), PtrTy, IntptrTy);
825}
826
828 return M.getOrInsertGlobal(Name, Ty, [&] {
829 return new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
830 nullptr, Name, nullptr,
832 });
833}
834
835/// Insert declarations for userspace-specific functions and globals.
836void MemorySanitizer::createUserspaceApi(Module &M, const TargetLibraryInfo &TLI) {
837 IRBuilder<> IRB(*C);
838
839 // Create the callback.
840 // FIXME: this function should have "Cold" calling conv,
841 // which is not yet implemented.
842 if (TrackOrigins) {
843 StringRef WarningFnName = Recover ? "__msan_warning_with_origin"
844 : "__msan_warning_with_origin_noreturn";
845 WarningFn = M.getOrInsertFunction(WarningFnName,
846 TLI.getAttrList(C, {0}, /*Signed=*/false),
847 IRB.getVoidTy(), IRB.getInt32Ty());
848 } else {
849 StringRef WarningFnName =
850 Recover ? "__msan_warning" : "__msan_warning_noreturn";
851 WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
852 }
853
854 // Create the global TLS variables.
855 RetvalTLS =
856 getOrInsertGlobal(M, "__msan_retval_tls",
857 ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8));
858
859 RetvalOriginTLS = getOrInsertGlobal(M, "__msan_retval_origin_tls", OriginTy);
860
861 ParamTLS =
862 getOrInsertGlobal(M, "__msan_param_tls",
863 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
864
865 ParamOriginTLS =
866 getOrInsertGlobal(M, "__msan_param_origin_tls",
867 ArrayType::get(OriginTy, kParamTLSSize / 4));
868
869 VAArgTLS =
870 getOrInsertGlobal(M, "__msan_va_arg_tls",
871 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
872
873 VAArgOriginTLS =
874 getOrInsertGlobal(M, "__msan_va_arg_origin_tls",
875 ArrayType::get(OriginTy, kParamTLSSize / 4));
876
877 VAArgOverflowSizeTLS =
878 getOrInsertGlobal(M, "__msan_va_arg_overflow_size_tls", IRB.getInt64Ty());
879
880 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
881 AccessSizeIndex++) {
882 unsigned AccessSize = 1 << AccessSizeIndex;
883 std::string FunctionName = "__msan_maybe_warning_" + itostr(AccessSize);
884 MaybeWarningFn[AccessSizeIndex] = M.getOrInsertFunction(
885 FunctionName, TLI.getAttrList(C, {0, 1}, /*Signed=*/false),
886 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
887
888 FunctionName = "__msan_maybe_store_origin_" + itostr(AccessSize);
889 MaybeStoreOriginFn[AccessSizeIndex] = M.getOrInsertFunction(
890 FunctionName, TLI.getAttrList(C, {0, 2}, /*Signed=*/false),
891 IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), PtrTy,
892 IRB.getInt32Ty());
893 }
894
895 MsanSetAllocaOriginWithDescriptionFn =
896 M.getOrInsertFunction("__msan_set_alloca_origin_with_descr",
897 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy, PtrTy);
898 MsanSetAllocaOriginNoDescriptionFn =
899 M.getOrInsertFunction("__msan_set_alloca_origin_no_descr",
900 IRB.getVoidTy(), PtrTy, IntptrTy, PtrTy);
901 MsanPoisonStackFn = M.getOrInsertFunction("__msan_poison_stack",
902 IRB.getVoidTy(), PtrTy, IntptrTy);
903}
904
905/// Insert extern declaration of runtime-provided functions and globals.
906void MemorySanitizer::initializeCallbacks(Module &M, const TargetLibraryInfo &TLI) {
907 // Only do this once.
908 if (CallbacksInitialized)
909 return;
910
911 IRBuilder<> IRB(*C);
912 // Initialize callbacks that are common for kernel and userspace
913 // instrumentation.
914 MsanChainOriginFn = M.getOrInsertFunction(
915 "__msan_chain_origin",
916 TLI.getAttrList(C, {0}, /*Signed=*/false, /*Ret=*/true), IRB.getInt32Ty(),
917 IRB.getInt32Ty());
918 MsanSetOriginFn = M.getOrInsertFunction(
919 "__msan_set_origin", TLI.getAttrList(C, {2}, /*Signed=*/false),
920 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
921 MemmoveFn =
922 M.getOrInsertFunction("__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
923 MemcpyFn =
924 M.getOrInsertFunction("__msan_memcpy", PtrTy, PtrTy, PtrTy, IntptrTy);
925 MemsetFn = M.getOrInsertFunction("__msan_memset",
926 TLI.getAttrList(C, {1}, /*Signed=*/true),
927 PtrTy, PtrTy, IRB.getInt32Ty(), IntptrTy);
928
929 MsanInstrumentAsmStoreFn =
930 M.getOrInsertFunction("__msan_instrument_asm_store", IRB.getVoidTy(),
931 PointerType::get(IRB.getInt8Ty(), 0), IntptrTy);
932
933 if (CompileKernel) {
934 createKernelApi(M, TLI);
935 } else {
936 createUserspaceApi(M, TLI);
937 }
938 CallbacksInitialized = true;
939}
940
941FunctionCallee MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore,
942 int size) {
943 FunctionCallee *Fns =
944 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
945 switch (size) {
946 case 1:
947 return Fns[0];
948 case 2:
949 return Fns[1];
950 case 4:
951 return Fns[2];
952 case 8:
953 return Fns[3];
954 default:
955 return nullptr;
956 }
957}
958
959/// Module-level initialization.
960///
961/// inserts a call to __msan_init to the module's constructor list.
962void MemorySanitizer::initializeModule(Module &M) {
963 auto &DL = M.getDataLayout();
964
965 TargetTriple = Triple(M.getTargetTriple());
966
967 bool ShadowPassed = ClShadowBase.getNumOccurrences() > 0;
968 bool OriginPassed = ClOriginBase.getNumOccurrences() > 0;
969 // Check the overrides first
970 if (ShadowPassed || OriginPassed) {
971 CustomMapParams.AndMask = ClAndMask;
972 CustomMapParams.XorMask = ClXorMask;
973 CustomMapParams.ShadowBase = ClShadowBase;
974 CustomMapParams.OriginBase = ClOriginBase;
975 MapParams = &CustomMapParams;
976 } else {
977 switch (TargetTriple.getOS()) {
978 case Triple::FreeBSD:
979 switch (TargetTriple.getArch()) {
980 case Triple::aarch64:
981 MapParams = FreeBSD_ARM_MemoryMapParams.bits64;
982 break;
983 case Triple::x86_64:
984 MapParams = FreeBSD_X86_MemoryMapParams.bits64;
985 break;
986 case Triple::x86:
987 MapParams = FreeBSD_X86_MemoryMapParams.bits32;
988 break;
989 default:
990 report_fatal_error("unsupported architecture");
991 }
992 break;
993 case Triple::NetBSD:
994 switch (TargetTriple.getArch()) {
995 case Triple::x86_64:
996 MapParams = NetBSD_X86_MemoryMapParams.bits64;
997 break;
998 default:
999 report_fatal_error("unsupported architecture");
1000 }
1001 break;
1002 case Triple::Linux:
1003 switch (TargetTriple.getArch()) {
1004 case Triple::x86_64:
1005 MapParams = Linux_X86_MemoryMapParams.bits64;
1006 break;
1007 case Triple::x86:
1008 MapParams = Linux_X86_MemoryMapParams.bits32;
1009 break;
1010 case Triple::mips64:
1011 case Triple::mips64el:
1012 MapParams = Linux_MIPS_MemoryMapParams.bits64;
1013 break;
1014 case Triple::ppc64:
1015 case Triple::ppc64le:
1016 MapParams = Linux_PowerPC_MemoryMapParams.bits64;
1017 break;
1018 case Triple::systemz:
1019 MapParams = Linux_S390_MemoryMapParams.bits64;
1020 break;
1021 case Triple::aarch64:
1022 case Triple::aarch64_be:
1023 MapParams = Linux_ARM_MemoryMapParams.bits64;
1024 break;
1026 MapParams = Linux_LoongArch_MemoryMapParams.bits64;
1027 break;
1028 default:
1029 report_fatal_error("unsupported architecture");
1030 }
1031 break;
1032 default:
1033 report_fatal_error("unsupported operating system");
1034 }
1035 }
1036
1037 C = &(M.getContext());
1038 IRBuilder<> IRB(*C);
1039 IntptrTy = IRB.getIntPtrTy(DL);
1040 OriginTy = IRB.getInt32Ty();
1041 PtrTy = IRB.getPtrTy();
1042
1043 ColdCallWeights = MDBuilder(*C).createUnlikelyBranchWeights();
1044 OriginStoreWeights = MDBuilder(*C).createUnlikelyBranchWeights();
1045
1046 if (!CompileKernel) {
1047 if (TrackOrigins)
1048 M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] {
1049 return new GlobalVariable(
1050 M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
1051 IRB.getInt32(TrackOrigins), "__msan_track_origins");
1052 });
1053
1054 if (Recover)
1055 M.getOrInsertGlobal("__msan_keep_going", IRB.getInt32Ty(), [&] {
1056 return new GlobalVariable(M, IRB.getInt32Ty(), true,
1057 GlobalValue::WeakODRLinkage,
1058 IRB.getInt32(Recover), "__msan_keep_going");
1059 });
1060 }
1061}
1062
1063namespace {
1064
1065/// A helper class that handles instrumentation of VarArg
1066/// functions on a particular platform.
1067///
1068/// Implementations are expected to insert the instrumentation
1069/// necessary to propagate argument shadow through VarArg function
1070/// calls. Visit* methods are called during an InstVisitor pass over
1071/// the function, and should avoid creating new basic blocks. A new
1072/// instance of this class is created for each instrumented function.
1073struct VarArgHelper {
1074 virtual ~VarArgHelper() = default;
1075
1076 /// Visit a CallBase.
1077 virtual void visitCallBase(CallBase &CB, IRBuilder<> &IRB) = 0;
1078
1079 /// Visit a va_start call.
1080 virtual void visitVAStartInst(VAStartInst &I) = 0;
1081
1082 /// Visit a va_copy call.
1083 virtual void visitVACopyInst(VACopyInst &I) = 0;
1084
1085 /// Finalize function instrumentation.
1086 ///
1087 /// This method is called after visiting all interesting (see above)
1088 /// instructions in a function.
1089 virtual void finalizeInstrumentation() = 0;
1090};
1091
1092struct MemorySanitizerVisitor;
1093
1094} // end anonymous namespace
1095
1096static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
1097 MemorySanitizerVisitor &Visitor);
1098
1099static unsigned TypeSizeToSizeIndex(TypeSize TS) {
1100 if (TS.isScalable())
1101 // Scalable types unconditionally take slowpaths.
1102 return kNumberOfAccessSizes;
1103 unsigned TypeSizeFixed = TS.getFixedValue();
1104 if (TypeSizeFixed <= 8)
1105 return 0;
1106 return Log2_32_Ceil((TypeSizeFixed + 7) / 8);
1107}
1108
1109namespace {
1110
1111/// Helper class to attach debug information of the given instruction onto new
1112/// instructions inserted after.
1113class NextNodeIRBuilder : public IRBuilder<> {
1114public:
1115 explicit NextNodeIRBuilder(Instruction *IP) : IRBuilder<>(IP->getNextNode()) {
1116 SetCurrentDebugLocation(IP->getDebugLoc());
1117 }
1118};
1119
1120/// This class does all the work for a given function. Store and Load
1121/// instructions store and load corresponding shadow and origin
1122/// values. Most instructions propagate shadow from arguments to their
1123/// return values. Certain instructions (most importantly, BranchInst)
1124/// test their argument shadow and print reports (with a runtime call) if it's
1125/// non-zero.
1126struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
1127 Function &F;
1128 MemorySanitizer &MS;
1129 SmallVector<PHINode *, 16> ShadowPHINodes, OriginPHINodes;
1130 ValueMap<Value *, Value *> ShadowMap, OriginMap;
1131 std::unique_ptr<VarArgHelper> VAHelper;
1132 const TargetLibraryInfo *TLI;
1133 Instruction *FnPrologueEnd;
1134
1135 // The following flags disable parts of MSan instrumentation based on
1136 // exclusion list contents and command-line options.
1137 bool InsertChecks;
1138 bool PropagateShadow;
1139 bool PoisonStack;
1140 bool PoisonUndef;
1141
1142 struct ShadowOriginAndInsertPoint {
1143 Value *Shadow;
1144 Value *Origin;
1145 Instruction *OrigIns;
1146
1147 ShadowOriginAndInsertPoint(Value *S, Value *O, Instruction *I)
1148 : Shadow(S), Origin(O), OrigIns(I) {}
1149 };
1151 DenseMap<const DILocation *, int> LazyWarningDebugLocationCount;
1152 bool InstrumentLifetimeStart = ClHandleLifetimeIntrinsics;
1156 int64_t SplittableBlocksCount = 0;
1157
1158 MemorySanitizerVisitor(Function &F, MemorySanitizer &MS,
1159 const TargetLibraryInfo &TLI)
1160 : F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)), TLI(&TLI) {
1161 bool SanitizeFunction =
1162 F.hasFnAttribute(Attribute::SanitizeMemory) && !ClDisableChecks;
1163 InsertChecks = SanitizeFunction;
1164 PropagateShadow = SanitizeFunction;
1165 PoisonStack = SanitizeFunction && ClPoisonStack;
1166 PoisonUndef = SanitizeFunction && ClPoisonUndef;
1167
1168 // In the presence of unreachable blocks, we may see Phi nodes with
1169 // incoming nodes from such blocks. Since InstVisitor skips unreachable
1170 // blocks, such nodes will not have any shadow value associated with them.
1171 // It's easier to remove unreachable blocks than deal with missing shadow.
1173
1174 MS.initializeCallbacks(*F.getParent(), TLI);
1175 FnPrologueEnd = IRBuilder<>(F.getEntryBlock().getFirstNonPHI())
1176 .CreateIntrinsic(Intrinsic::donothing, {}, {});
1177
1178 if (MS.CompileKernel) {
1179 IRBuilder<> IRB(FnPrologueEnd);
1180 insertKmsanPrologue(IRB);
1181 }
1182
1183 LLVM_DEBUG(if (!InsertChecks) dbgs()
1184 << "MemorySanitizer is not inserting checks into '"
1185 << F.getName() << "'\n");
1186 }
1187
1188 bool instrumentWithCalls(Value *V) {
1189 // Constants likely will be eliminated by follow-up passes.
1190 if (isa<Constant>(V))
1191 return false;
1192
1193 ++SplittableBlocksCount;
1195 SplittableBlocksCount > ClInstrumentationWithCallThreshold;
1196 }
1197
1198 bool isInPrologue(Instruction &I) {
1199 return I.getParent() == FnPrologueEnd->getParent() &&
1200 (&I == FnPrologueEnd || I.comesBefore(FnPrologueEnd));
1201 }
1202
1203 // Creates a new origin and records the stack trace. In general we can call
1204 // this function for any origin manipulation we like. However it will cost
1205 // runtime resources. So use this wisely only if it can provide additional
1206 // information helpful to a user.
1207 Value *updateOrigin(Value *V, IRBuilder<> &IRB) {
1208 if (MS.TrackOrigins <= 1)
1209 return V;
1210 return IRB.CreateCall(MS.MsanChainOriginFn, V);
1211 }
1212
1213 Value *originToIntptr(IRBuilder<> &IRB, Value *Origin) {
1214 const DataLayout &DL = F.getParent()->getDataLayout();
1215 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
1216 if (IntptrSize == kOriginSize)
1217 return Origin;
1218 assert(IntptrSize == kOriginSize * 2);
1219 Origin = IRB.CreateIntCast(Origin, MS.IntptrTy, /* isSigned */ false);
1220 return IRB.CreateOr(Origin, IRB.CreateShl(Origin, kOriginSize * 8));
1221 }
1222
1223 /// Fill memory range with the given origin value.
1224 void paintOrigin(IRBuilder<> &IRB, Value *Origin, Value *OriginPtr,
1225 TypeSize TS, Align Alignment) {
1226 const DataLayout &DL = F.getParent()->getDataLayout();
1227 const Align IntptrAlignment = DL.getABITypeAlign(MS.IntptrTy);
1228 unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
1229 assert(IntptrAlignment >= kMinOriginAlignment);
1230 assert(IntptrSize >= kOriginSize);
1231
1232 // Note: The loop based formation works for fixed length vectors too,
1233 // however we prefer to unroll and specialize alignment below.
1234 if (TS.isScalable()) {
1235 Value *Size = IRB.CreateTypeSize(IRB.getInt32Ty(), TS);
1236 Value *RoundUp = IRB.CreateAdd(Size, IRB.getInt32(kOriginSize - 1));
1237 Value *End = IRB.CreateUDiv(RoundUp, IRB.getInt32(kOriginSize));
1238 auto [InsertPt, Index] =
1240 IRB.SetInsertPoint(InsertPt);
1241
1242 Value *GEP = IRB.CreateGEP(MS.OriginTy, OriginPtr, Index);
1244 return;
1245 }
1246
1247 unsigned Size = TS.getFixedValue();
1248
1249 unsigned Ofs = 0;
1250 Align CurrentAlignment = Alignment;
1251 if (Alignment >= IntptrAlignment && IntptrSize > kOriginSize) {
1252 Value *IntptrOrigin = originToIntptr(IRB, Origin);
1253 Value *IntptrOriginPtr =
1254 IRB.CreatePointerCast(OriginPtr, PointerType::get(MS.IntptrTy, 0));
1255 for (unsigned i = 0; i < Size / IntptrSize; ++i) {
1256 Value *Ptr = i ? IRB.CreateConstGEP1_32(MS.IntptrTy, IntptrOriginPtr, i)
1257 : IntptrOriginPtr;
1258 IRB.CreateAlignedStore(IntptrOrigin, Ptr, CurrentAlignment);
1259 Ofs += IntptrSize / kOriginSize;
1260 CurrentAlignment = IntptrAlignment;
1261 }
1262 }
1263
1264 for (unsigned i = Ofs; i < (Size + kOriginSize - 1) / kOriginSize; ++i) {
1265 Value *GEP =
1266 i ? IRB.CreateConstGEP1_32(MS.OriginTy, OriginPtr, i) : OriginPtr;
1267 IRB.CreateAlignedStore(Origin, GEP, CurrentAlignment);
1268 CurrentAlignment = kMinOriginAlignment;
1269 }
1270 }
1271
1272 void storeOrigin(IRBuilder<> &IRB, Value *Addr, Value *Shadow, Value *Origin,
1273 Value *OriginPtr, Align Alignment) {
1274 const DataLayout &DL = F.getParent()->getDataLayout();
1275 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
1276 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
1277 Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1278 if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1279 if (!ClCheckConstantShadow || ConstantShadow->isZeroValue()) {
1280 // Origin is not needed: value is initialized or const shadow is
1281 // ignored.
1282 return;
1283 }
1284 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1285 // Copy origin as the value is definitely uninitialized.
1286 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1287 OriginAlignment);
1288 return;
1289 }
1290 // Fallback to runtime check, which still can be optimized out later.
1291 }
1292
1293 TypeSize TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
1294 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
1295 if (instrumentWithCalls(ConvertedShadow) &&
1296 SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
1297 FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1298 Value *ConvertedShadow2 =
1299 IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1300 CallBase *CB = IRB.CreateCall(Fn, {ConvertedShadow2, Addr, Origin});
1301 CB->addParamAttr(0, Attribute::ZExt);
1302 CB->addParamAttr(2, Attribute::ZExt);
1303 } else {
1304 Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
1306 Cmp, &*IRB.GetInsertPoint(), false, MS.OriginStoreWeights);
1307 IRBuilder<> IRBNew(CheckTerm);
1308 paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
1309 OriginAlignment);
1310 }
1311 }
1312
1313 void materializeStores() {
1314 for (StoreInst *SI : StoreList) {
1315 IRBuilder<> IRB(SI);
1316 Value *Val = SI->getValueOperand();
1317 Value *Addr = SI->getPointerOperand();
1318 Value *Shadow = SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
1319 Value *ShadowPtr, *OriginPtr;
1320 Type *ShadowTy = Shadow->getType();
1321 const Align Alignment = SI->getAlign();
1322 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
1323 std::tie(ShadowPtr, OriginPtr) =
1324 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ true);
1325
1326 StoreInst *NewSI = IRB.CreateAlignedStore(Shadow, ShadowPtr, Alignment);
1327 LLVM_DEBUG(dbgs() << " STORE: " << *NewSI << "\n");
1328 (void)NewSI;
1329
1330 if (SI->isAtomic())
1331 SI->setOrdering(addReleaseOrdering(SI->getOrdering()));
1332
1333 if (MS.TrackOrigins && !SI->isAtomic())
1334 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1335 OriginAlignment);
1336 }
1337 }
1338
1339 // Returns true if Debug Location curresponds to multiple warnings.
1340 bool shouldDisambiguateWarningLocation(const DebugLoc &DebugLoc) {
1341 if (MS.TrackOrigins < 2)
1342 return false;
1343
1344 if (LazyWarningDebugLocationCount.empty())
1345 for (const auto &I : InstrumentationList)
1346 ++LazyWarningDebugLocationCount[I.OrigIns->getDebugLoc()];
1347
1348 return LazyWarningDebugLocationCount[DebugLoc] >= ClDisambiguateWarning;
1349 }
1350
1351 /// Helper function to insert a warning at IRB's current insert point.
1352 void insertWarningFn(IRBuilder<> &IRB, Value *Origin) {
1353 if (!Origin)
1354 Origin = (Value *)IRB.getInt32(0);
1355 assert(Origin->getType()->isIntegerTy());
1356
1357 if (shouldDisambiguateWarningLocation(IRB.getCurrentDebugLocation())) {
1358 // Try to create additional origin with debug info of the last origin
1359 // instruction. It may provide additional information to the user.
1360 if (Instruction *OI = dyn_cast_or_null<Instruction>(Origin)) {
1361 assert(MS.TrackOrigins);
1362 auto NewDebugLoc = OI->getDebugLoc();
1363 // Origin update with missing or the same debug location provides no
1364 // additional value.
1365 if (NewDebugLoc && NewDebugLoc != IRB.getCurrentDebugLocation()) {
1366 // Insert update just before the check, so we call runtime only just
1367 // before the report.
1368 IRBuilder<> IRBOrigin(&*IRB.GetInsertPoint());
1369 IRBOrigin.SetCurrentDebugLocation(NewDebugLoc);
1370 Origin = updateOrigin(Origin, IRBOrigin);
1371 }
1372 }
1373 }
1374
1375 if (MS.CompileKernel || MS.TrackOrigins)
1376 IRB.CreateCall(MS.WarningFn, Origin)->setCannotMerge();
1377 else
1378 IRB.CreateCall(MS.WarningFn)->setCannotMerge();
1379 // FIXME: Insert UnreachableInst if !MS.Recover?
1380 // This may invalidate some of the following checks and needs to be done
1381 // at the very end.
1382 }
1383
1384 void materializeOneCheck(IRBuilder<> &IRB, Value *ConvertedShadow,
1385 Value *Origin) {
1386 const DataLayout &DL = F.getParent()->getDataLayout();
1387 TypeSize TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
1388 unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
1389 if (instrumentWithCalls(ConvertedShadow) &&
1390 SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
1391 FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
1392 Value *ConvertedShadow2 =
1393 IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1394 CallBase *CB = IRB.CreateCall(
1395 Fn, {ConvertedShadow2,
1396 MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32(0)});
1397 CB->addParamAttr(0, Attribute::ZExt);
1398 CB->addParamAttr(1, Attribute::ZExt);
1399 } else {
1400 Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
1402 Cmp, &*IRB.GetInsertPoint(),
1403 /* Unreachable */ !MS.Recover, MS.ColdCallWeights);
1404
1405 IRB.SetInsertPoint(CheckTerm);
1406 insertWarningFn(IRB, Origin);
1407 LLVM_DEBUG(dbgs() << " CHECK: " << *Cmp << "\n");
1408 }
1409 }
1410
1411 void materializeInstructionChecks(
1412 ArrayRef<ShadowOriginAndInsertPoint> InstructionChecks) {
1413 const DataLayout &DL = F.getParent()->getDataLayout();
1414 // Disable combining in some cases. TrackOrigins checks each shadow to pick
1415 // correct origin.
1416 bool Combine = !MS.TrackOrigins;
1417 Instruction *Instruction = InstructionChecks.front().OrigIns;
1418 Value *Shadow = nullptr;
1419 for (const auto &ShadowData : InstructionChecks) {
1420 assert(ShadowData.OrigIns == Instruction);
1422
1423 Value *ConvertedShadow = ShadowData.Shadow;
1424
1425 if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
1426 if (!ClCheckConstantShadow || ConstantShadow->isZeroValue()) {
1427 // Skip, value is initialized or const shadow is ignored.
1428 continue;
1429 }
1430 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1431 // Report as the value is definitely uninitialized.
1432 insertWarningFn(IRB, ShadowData.Origin);
1433 if (!MS.Recover)
1434 return; // Always fail and stop here, not need to check the rest.
1435 // Skip entire instruction,
1436 continue;
1437 }
1438 // Fallback to runtime check, which still can be optimized out later.
1439 }
1440
1441 if (!Combine) {
1442 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1443 continue;
1444 }
1445
1446 if (!Shadow) {
1447 Shadow = ConvertedShadow;
1448 continue;
1449 }
1450
1451 Shadow = convertToBool(Shadow, IRB, "_mscmp");
1452 ConvertedShadow = convertToBool(ConvertedShadow, IRB, "_mscmp");
1453 Shadow = IRB.CreateOr(Shadow, ConvertedShadow, "_msor");
1454 }
1455
1456 if (Shadow) {
1457 assert(Combine);
1459 materializeOneCheck(IRB, Shadow, nullptr);
1460 }
1461 }
1462
1463 void materializeChecks() {
1464 llvm::stable_sort(InstrumentationList,
1465 [](const ShadowOriginAndInsertPoint &L,
1466 const ShadowOriginAndInsertPoint &R) {
1467 return L.OrigIns < R.OrigIns;
1468 });
1469
1470 for (auto I = InstrumentationList.begin();
1471 I != InstrumentationList.end();) {
1472 auto J =
1473 std::find_if(I + 1, InstrumentationList.end(),
1474 [L = I->OrigIns](const ShadowOriginAndInsertPoint &R) {
1475 return L != R.OrigIns;
1476 });
1477 // Process all checks of instruction at once.
1478 materializeInstructionChecks(ArrayRef<ShadowOriginAndInsertPoint>(I, J));
1479 I = J;
1480 }
1481
1482 LLVM_DEBUG(dbgs() << "DONE:\n" << F);
1483 }
1484
1485 // Returns the last instruction in the new prologue
1486 void insertKmsanPrologue(IRBuilder<> &IRB) {
1487 Value *ContextState = IRB.CreateCall(MS.MsanGetContextStateFn, {});
1488 Constant *Zero = IRB.getInt32(0);
1489 MS.ParamTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1490 {Zero, IRB.getInt32(0)}, "param_shadow");
1491 MS.RetvalTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1492 {Zero, IRB.getInt32(1)}, "retval_shadow");
1493 MS.VAArgTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1494 {Zero, IRB.getInt32(2)}, "va_arg_shadow");
1495 MS.VAArgOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1496 {Zero, IRB.getInt32(3)}, "va_arg_origin");
1497 MS.VAArgOverflowSizeTLS =
1498 IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1499 {Zero, IRB.getInt32(4)}, "va_arg_overflow_size");
1500 MS.ParamOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1501 {Zero, IRB.getInt32(5)}, "param_origin");
1502 MS.RetvalOriginTLS =
1503 IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
1504 {Zero, IRB.getInt32(6)}, "retval_origin");
1505 if (MS.TargetTriple.getArch() == Triple::systemz)
1506 MS.MsanMetadataAlloca = IRB.CreateAlloca(MS.MsanMetadata, 0u);
1507 }
1508
1509 /// Add MemorySanitizer instrumentation to a function.
1510 bool runOnFunction() {
1511 // Iterate all BBs in depth-first order and create shadow instructions
1512 // for all instructions (where applicable).
1513 // For PHI nodes we create dummy shadow PHIs which will be finalized later.
1514 for (BasicBlock *BB : depth_first(FnPrologueEnd->getParent()))
1515 visit(*BB);
1516
1517 // Finalize PHI nodes.
1518 for (PHINode *PN : ShadowPHINodes) {
1519 PHINode *PNS = cast<PHINode>(getShadow(PN));
1520 PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : nullptr;
1521 size_t NumValues = PN->getNumIncomingValues();
1522 for (size_t v = 0; v < NumValues; v++) {
1523 PNS->addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
1524 if (PNO)
1525 PNO->addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
1526 }
1527 }
1528
1529 VAHelper->finalizeInstrumentation();
1530
1531 // Poison llvm.lifetime.start intrinsics, if we haven't fallen back to
1532 // instrumenting only allocas.
1533 if (InstrumentLifetimeStart) {
1534 for (auto Item : LifetimeStartList) {
1535 instrumentAlloca(*Item.second, Item.first);
1536 AllocaSet.remove(Item.second);
1537 }
1538 }
1539 // Poison the allocas for which we didn't instrument the corresponding
1540 // lifetime intrinsics.
1541 for (AllocaInst *AI : AllocaSet)
1542 instrumentAlloca(*AI);
1543
1544 // Insert shadow value checks.
1545 materializeChecks();
1546
1547 // Delayed instrumentation of StoreInst.
1548 // This may not add new address checks.
1549 materializeStores();
1550
1551 return true;
1552 }
1553
1554 /// Compute the shadow type that corresponds to a given Value.
1555 Type *getShadowTy(Value *V) { return getShadowTy(V->getType()); }
1556
1557 /// Compute the shadow type that corresponds to a given Type.
1558 Type *getShadowTy(Type *OrigTy) {
1559 if (!OrigTy->isSized()) {
1560 return nullptr;
1561 }
1562 // For integer type, shadow is the same as the original type.
1563 // This may return weird-sized types like i1.
1564 if (IntegerType *IT = dyn_cast<IntegerType>(OrigTy))
1565 return IT;
1566 const DataLayout &DL = F.getParent()->getDataLayout();
1567 if (VectorType *VT = dyn_cast<VectorType>(OrigTy)) {
1568 uint32_t EltSize = DL.getTypeSizeInBits(VT->getElementType());
1569 return VectorType::get(IntegerType::get(*MS.C, EltSize),
1570 VT->getElementCount());
1571 }
1572 if (ArrayType *AT = dyn_cast<ArrayType>(OrigTy)) {
1573 return ArrayType::get(getShadowTy(AT->getElementType()),
1574 AT->getNumElements());
1575 }
1576 if (StructType *ST = dyn_cast<StructType>(OrigTy)) {
1578 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
1579 Elements.push_back(getShadowTy(ST->getElementType(i)));
1580 StructType *Res = StructType::get(*MS.C, Elements, ST->isPacked());
1581 LLVM_DEBUG(dbgs() << "getShadowTy: " << *ST << " ===> " << *Res << "\n");
1582 return Res;
1583 }
1584 uint32_t TypeSize = DL.getTypeSizeInBits(OrigTy);
1585 return IntegerType::get(*MS.C, TypeSize);
1586 }
1587
1588 /// Extract combined shadow of struct elements as a bool
1589 Value *collapseStructShadow(StructType *Struct, Value *Shadow,
1590 IRBuilder<> &IRB) {
1591 Value *FalseVal = IRB.getIntN(/* width */ 1, /* value */ 0);
1592 Value *Aggregator = FalseVal;
1593
1594 for (unsigned Idx = 0; Idx < Struct->getNumElements(); Idx++) {
1595 // Combine by ORing together each element's bool shadow
1596 Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1597 Value *ShadowBool = convertToBool(ShadowItem, IRB);
1598
1599 if (Aggregator != FalseVal)
1600 Aggregator = IRB.CreateOr(Aggregator, ShadowBool);
1601 else
1602 Aggregator = ShadowBool;
1603 }
1604
1605 return Aggregator;
1606 }
1607
1608 // Extract combined shadow of array elements
1609 Value *collapseArrayShadow(ArrayType *Array, Value *Shadow,
1610 IRBuilder<> &IRB) {
1611 if (!Array->getNumElements())
1612 return IRB.getIntN(/* width */ 1, /* value */ 0);
1613
1614 Value *FirstItem = IRB.CreateExtractValue(Shadow, 0);
1615 Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1616
1617 for (unsigned Idx = 1; Idx < Array->getNumElements(); Idx++) {
1618 Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1619 Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1620 Aggregator = IRB.CreateOr(Aggregator, ShadowInner);
1621 }
1622 return Aggregator;
1623 }
1624
1625 /// Convert a shadow value to it's flattened variant. The resulting
1626 /// shadow may not necessarily have the same bit width as the input
1627 /// value, but it will always be comparable to zero.
1628 Value *convertShadowToScalar(Value *V, IRBuilder<> &IRB) {
1629 if (StructType *Struct = dyn_cast<StructType>(V->getType()))
1630 return collapseStructShadow(Struct, V, IRB);
1631 if (ArrayType *Array = dyn_cast<ArrayType>(V->getType()))
1632 return collapseArrayShadow(Array, V, IRB);
1633 if (isa<VectorType>(V->getType())) {
1634 if (isa<ScalableVectorType>(V->getType()))
1635 return convertShadowToScalar(IRB.CreateOrReduce(V), IRB);
1636 unsigned BitWidth =
1637 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1638 return IRB.CreateBitCast(V, IntegerType::get(*MS.C, BitWidth));
1639 }
1640 return V;
1641 }
1642
1643 // Convert a scalar value to an i1 by comparing with 0
1644 Value *convertToBool(Value *V, IRBuilder<> &IRB, const Twine &name = "") {
1645 Type *VTy = V->getType();
1646 if (!VTy->isIntegerTy())
1647 return convertToBool(convertShadowToScalar(V, IRB), IRB, name);
1648 if (VTy->getIntegerBitWidth() == 1)
1649 // Just converting a bool to a bool, so do nothing.
1650 return V;
1651 return IRB.CreateICmpNE(V, ConstantInt::get(VTy, 0), name);
1652 }
1653
1654 Type *ptrToIntPtrType(Type *PtrTy) const {
1655 if (VectorType *VectTy = dyn_cast<VectorType>(PtrTy)) {
1656 return VectorType::get(ptrToIntPtrType(VectTy->getElementType()),
1657 VectTy->getElementCount());
1658 }
1659 assert(PtrTy->isIntOrPtrTy());
1660 return MS.IntptrTy;
1661 }
1662
1663 Type *getPtrToShadowPtrType(Type *IntPtrTy, Type *ShadowTy) const {
1664 if (VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1665 return VectorType::get(
1666 getPtrToShadowPtrType(VectTy->getElementType(), ShadowTy),
1667 VectTy->getElementCount());
1668 }
1669 assert(IntPtrTy == MS.IntptrTy);
1670 return PointerType::get(*MS.C, 0);
1671 }
1672
1673 Constant *constToIntPtr(Type *IntPtrTy, uint64_t C) const {
1674 if (VectorType *VectTy = dyn_cast<VectorType>(IntPtrTy)) {
1676 VectTy->getElementCount(), constToIntPtr(VectTy->getElementType(), C));
1677 }
1678 assert(IntPtrTy == MS.IntptrTy);
1679 return ConstantInt::get(MS.IntptrTy, C);
1680 }
1681
1682 /// Compute the integer shadow offset that corresponds to a given
1683 /// application address.
1684 ///
1685 /// Offset = (Addr & ~AndMask) ^ XorMask
1686 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1687 /// a single pointee.
1688 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1689 Value *getShadowPtrOffset(Value *Addr, IRBuilder<> &IRB) {
1690 Type *IntptrTy = ptrToIntPtrType(Addr->getType());
1691 Value *OffsetLong = IRB.CreatePointerCast(Addr, IntptrTy);
1692
1693 if (uint64_t AndMask = MS.MapParams->AndMask)
1694 OffsetLong = IRB.CreateAnd(OffsetLong, constToIntPtr(IntptrTy, ~AndMask));
1695
1696 if (uint64_t XorMask = MS.MapParams->XorMask)
1697 OffsetLong = IRB.CreateXor(OffsetLong, constToIntPtr(IntptrTy, XorMask));
1698 return OffsetLong;
1699 }
1700
1701 /// Compute the shadow and origin addresses corresponding to a given
1702 /// application address.
1703 ///
1704 /// Shadow = ShadowBase + Offset
1705 /// Origin = (OriginBase + Offset) & ~3ULL
1706 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1707 /// a single pointee.
1708 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1709 std::pair<Value *, Value *>
1710 getShadowOriginPtrUserspace(Value *Addr, IRBuilder<> &IRB, Type *ShadowTy,
1711 MaybeAlign Alignment) {
1712 VectorType *VectTy = dyn_cast<VectorType>(Addr->getType());
1713 if (!VectTy) {
1714 assert(Addr->getType()->isPointerTy());
1715 } else {
1716 assert(VectTy->getElementType()->isPointerTy());
1717 }
1718 Type *IntptrTy = ptrToIntPtrType(Addr->getType());
1719 Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
1720 Value *ShadowLong = ShadowOffset;
1721 if (uint64_t ShadowBase = MS.MapParams->ShadowBase) {
1722 ShadowLong =
1723 IRB.CreateAdd(ShadowLong, constToIntPtr(IntptrTy, ShadowBase));
1724 }
1725 Value *ShadowPtr = IRB.CreateIntToPtr(
1726 ShadowLong, getPtrToShadowPtrType(IntptrTy, ShadowTy));
1727
1728 Value *OriginPtr = nullptr;
1729 if (MS.TrackOrigins) {
1730 Value *OriginLong = ShadowOffset;
1731 uint64_t OriginBase = MS.MapParams->OriginBase;
1732 if (OriginBase != 0)
1733 OriginLong =
1734 IRB.CreateAdd(OriginLong, constToIntPtr(IntptrTy, OriginBase));
1735 if (!Alignment || *Alignment < kMinOriginAlignment) {
1737 OriginLong = IRB.CreateAnd(OriginLong, constToIntPtr(IntptrTy, ~Mask));
1738 }
1739 OriginPtr = IRB.CreateIntToPtr(
1740 OriginLong, getPtrToShadowPtrType(IntptrTy, MS.OriginTy));
1741 }
1742 return std::make_pair(ShadowPtr, OriginPtr);
1743 }
1744
1745 template <typename... ArgsTy>
1746 Value *createMetadataCall(IRBuilder<> &IRB, FunctionCallee Callee,
1747 ArgsTy... Args) {
1748 if (MS.TargetTriple.getArch() == Triple::systemz) {
1749 IRB.CreateCall(Callee,
1750 {MS.MsanMetadataAlloca, std::forward<ArgsTy>(Args)...});
1751 return IRB.CreateLoad(MS.MsanMetadata, MS.MsanMetadataAlloca);
1752 }
1753
1754 return IRB.CreateCall(Callee, {std::forward<ArgsTy>(Args)...});
1755 }
1756
1757 std::pair<Value *, Value *> getShadowOriginPtrKernelNoVec(Value *Addr,
1758 IRBuilder<> &IRB,
1759 Type *ShadowTy,
1760 bool isStore) {
1761 Value *ShadowOriginPtrs;
1762 const DataLayout &DL = F.getParent()->getDataLayout();
1763 TypeSize Size = DL.getTypeStoreSize(ShadowTy);
1764
1765 FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(isStore, Size);
1766 Value *AddrCast =
1767 IRB.CreatePointerCast(Addr, PointerType::get(IRB.getInt8Ty(), 0));
1768 if (Getter) {
1769 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1770 } else {
1771 Value *SizeVal = ConstantInt::get(MS.IntptrTy, Size);
1772 ShadowOriginPtrs = createMetadataCall(
1773 IRB,
1774 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1775 AddrCast, SizeVal);
1776 }
1777 Value *ShadowPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 0);
1778 ShadowPtr = IRB.CreatePointerCast(ShadowPtr, PointerType::get(ShadowTy, 0));
1779 Value *OriginPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 1);
1780
1781 return std::make_pair(ShadowPtr, OriginPtr);
1782 }
1783
1784 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1785 /// a single pointee.
1786 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1787 std::pair<Value *, Value *> getShadowOriginPtrKernel(Value *Addr,
1788 IRBuilder<> &IRB,
1789 Type *ShadowTy,
1790 bool isStore) {
1791 VectorType *VectTy = dyn_cast<VectorType>(Addr->getType());
1792 if (!VectTy) {
1793 assert(Addr->getType()->isPointerTy());
1794 return getShadowOriginPtrKernelNoVec(Addr, IRB, ShadowTy, isStore);
1795 }
1796
1797 // TODO: Support callbacs with vectors of addresses.
1798 unsigned NumElements = cast<FixedVectorType>(VectTy)->getNumElements();
1799 Value *ShadowPtrs = ConstantInt::getNullValue(
1800 FixedVectorType::get(IRB.getPtrTy(), NumElements));
1801 Value *OriginPtrs = nullptr;
1802 if (MS.TrackOrigins)
1803 OriginPtrs = ConstantInt::getNullValue(
1804 FixedVectorType::get(IRB.getPtrTy(), NumElements));
1805 for (unsigned i = 0; i < NumElements; ++i) {
1806 Value *OneAddr =
1807 IRB.CreateExtractElement(Addr, ConstantInt::get(IRB.getInt32Ty(), i));
1808 auto [ShadowPtr, OriginPtr] =
1809 getShadowOriginPtrKernelNoVec(OneAddr, IRB, ShadowTy, isStore);
1810
1811 ShadowPtrs = IRB.CreateInsertElement(
1812 ShadowPtrs, ShadowPtr, ConstantInt::get(IRB.getInt32Ty(), i));
1813 if (MS.TrackOrigins)
1814 OriginPtrs = IRB.CreateInsertElement(
1815 OriginPtrs, OriginPtr, ConstantInt::get(IRB.getInt32Ty(), i));
1816 }
1817 return {ShadowPtrs, OriginPtrs};
1818 }
1819
1820 std::pair<Value *, Value *> getShadowOriginPtr(Value *Addr, IRBuilder<> &IRB,
1821 Type *ShadowTy,
1822 MaybeAlign Alignment,
1823 bool isStore) {
1824 if (MS.CompileKernel)
1825 return getShadowOriginPtrKernel(Addr, IRB, ShadowTy, isStore);
1826 return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
1827 }
1828
1829 /// Compute the shadow address for a given function argument.
1830 ///
1831 /// Shadow = ParamTLS+ArgOffset.
1832 Value *getShadowPtrForArgument(IRBuilder<> &IRB, int ArgOffset) {
1833 Value *Base = IRB.CreatePointerCast(MS.ParamTLS, MS.IntptrTy);
1834 if (ArgOffset)
1835 Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
1836 return IRB.CreateIntToPtr(Base, IRB.getPtrTy(0), "_msarg");
1837 }
1838
1839 /// Compute the origin address for a given function argument.
1840 Value *getOriginPtrForArgument(IRBuilder<> &IRB, int ArgOffset) {
1841 if (!MS.TrackOrigins)
1842 return nullptr;
1843 Value *Base = IRB.CreatePointerCast(MS.ParamOriginTLS, MS.IntptrTy);
1844 if (ArgOffset)
1845 Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
1846 return IRB.CreateIntToPtr(Base, IRB.getPtrTy(0), "_msarg_o");
1847 }
1848
1849 /// Compute the shadow address for a retval.
1850 Value *getShadowPtrForRetval(IRBuilder<> &IRB) {
1851 return IRB.CreatePointerCast(MS.RetvalTLS, IRB.getPtrTy(0), "_msret");
1852 }
1853
1854 /// Compute the origin address for a retval.
1855 Value *getOriginPtrForRetval() {
1856 // We keep a single origin for the entire retval. Might be too optimistic.
1857 return MS.RetvalOriginTLS;
1858 }
1859
1860 /// Set SV to be the shadow value for V.
1861 void setShadow(Value *V, Value *SV) {
1862 assert(!ShadowMap.count(V) && "Values may only have one shadow");
1863 ShadowMap[V] = PropagateShadow ? SV : getCleanShadow(V);
1864 }
1865
1866 /// Set Origin to be the origin value for V.
1867 void setOrigin(Value *V, Value *Origin) {
1868 if (!MS.TrackOrigins)
1869 return;
1870 assert(!OriginMap.count(V) && "Values may only have one origin");
1871 LLVM_DEBUG(dbgs() << "ORIGIN: " << *V << " ==> " << *Origin << "\n");
1872 OriginMap[V] = Origin;
1873 }
1874
1875 Constant *getCleanShadow(Type *OrigTy) {
1876 Type *ShadowTy = getShadowTy(OrigTy);
1877 if (!ShadowTy)
1878 return nullptr;
1879 return Constant::getNullValue(ShadowTy);
1880 }
1881
1882 /// Create a clean shadow value for a given value.
1883 ///
1884 /// Clean shadow (all zeroes) means all bits of the value are defined
1885 /// (initialized).
1886 Constant *getCleanShadow(Value *V) { return getCleanShadow(V->getType()); }
1887
1888 /// Create a dirty shadow of a given shadow type.
1889 Constant *getPoisonedShadow(Type *ShadowTy) {
1890 assert(ShadowTy);
1891 if (isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy))
1892 return Constant::getAllOnesValue(ShadowTy);
1893 if (ArrayType *AT = dyn_cast<ArrayType>(ShadowTy)) {
1894 SmallVector<Constant *, 4> Vals(AT->getNumElements(),
1895 getPoisonedShadow(AT->getElementType()));
1896 return ConstantArray::get(AT, Vals);
1897 }
1898 if (StructType *ST = dyn_cast<StructType>(ShadowTy)) {
1900 for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
1901 Vals.push_back(getPoisonedShadow(ST->getElementType(i)));
1902 return ConstantStruct::get(ST, Vals);
1903 }
1904 llvm_unreachable("Unexpected shadow type");
1905 }
1906
1907 /// Create a dirty shadow for a given value.
1908 Constant *getPoisonedShadow(Value *V) {
1909 Type *ShadowTy = getShadowTy(V);
1910 if (!ShadowTy)
1911 return nullptr;
1912 return getPoisonedShadow(ShadowTy);
1913 }
1914
1915 /// Create a clean (zero) origin.
1916 Value *getCleanOrigin() { return Constant::getNullValue(MS.OriginTy); }
1917
1918 /// Get the shadow value for a given Value.
1919 ///
1920 /// This function either returns the value set earlier with setShadow,
1921 /// or extracts if from ParamTLS (for function arguments).
1922 Value *getShadow(Value *V) {
1923 if (Instruction *I = dyn_cast<Instruction>(V)) {
1924 if (!PropagateShadow || I->getMetadata(LLVMContext::MD_nosanitize))
1925 return getCleanShadow(V);
1926 // For instructions the shadow is already stored in the map.
1927 Value *Shadow = ShadowMap[V];
1928 if (!Shadow) {
1929 LLVM_DEBUG(dbgs() << "No shadow: " << *V << "\n" << *(I->getParent()));
1930 (void)I;
1931 assert(Shadow && "No shadow for a value");
1932 }
1933 return Shadow;
1934 }
1935 if (UndefValue *U = dyn_cast<UndefValue>(V)) {
1936 Value *AllOnes = (PropagateShadow && PoisonUndef) ? getPoisonedShadow(V)
1937 : getCleanShadow(V);
1938 LLVM_DEBUG(dbgs() << "Undef: " << *U << " ==> " << *AllOnes << "\n");
1939 (void)U;
1940 return AllOnes;
1941 }
1942 if (Argument *A = dyn_cast<Argument>(V)) {
1943 // For arguments we compute the shadow on demand and store it in the map.
1944 Value *&ShadowPtr = ShadowMap[V];
1945 if (ShadowPtr)
1946 return ShadowPtr;
1947 Function *F = A->getParent();
1948 IRBuilder<> EntryIRB(FnPrologueEnd);
1949 unsigned ArgOffset = 0;
1950 const DataLayout &DL = F->getParent()->getDataLayout();
1951 for (auto &FArg : F->args()) {
1952 if (!FArg.getType()->isSized()) {
1953 LLVM_DEBUG(dbgs() << "Arg is not sized\n");
1954 continue;
1955 }
1956
1957 unsigned Size = FArg.hasByValAttr()
1958 ? DL.getTypeAllocSize(FArg.getParamByValType())
1959 : DL.getTypeAllocSize(FArg.getType());
1960
1961 if (A == &FArg) {
1962 bool Overflow = ArgOffset + Size > kParamTLSSize;
1963 if (FArg.hasByValAttr()) {
1964 // ByVal pointer itself has clean shadow. We copy the actual
1965 // argument shadow to the underlying memory.
1966 // Figure out maximal valid memcpy alignment.
1967 const Align ArgAlign = DL.getValueOrABITypeAlignment(
1968 FArg.getParamAlign(), FArg.getParamByValType());
1969 Value *CpShadowPtr, *CpOriginPtr;
1970 std::tie(CpShadowPtr, CpOriginPtr) =
1971 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
1972 /*isStore*/ true);
1973 if (!PropagateShadow || Overflow) {
1974 // ParamTLS overflow.
1975 EntryIRB.CreateMemSet(
1976 CpShadowPtr, Constant::getNullValue(EntryIRB.getInt8Ty()),
1977 Size, ArgAlign);
1978 } else {
1979 Value *Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
1980 const Align CopyAlign = std::min(ArgAlign, kShadowTLSAlignment);
1981 Value *Cpy = EntryIRB.CreateMemCpy(CpShadowPtr, CopyAlign, Base,
1982 CopyAlign, Size);
1983 LLVM_DEBUG(dbgs() << " ByValCpy: " << *Cpy << "\n");
1984 (void)Cpy;
1985
1986 if (MS.TrackOrigins) {
1987 Value *OriginPtr =
1988 getOriginPtrForArgument(EntryIRB, ArgOffset);
1989 // FIXME: OriginSize should be:
1990 // alignTo(V % kMinOriginAlignment + Size, kMinOriginAlignment)
1991 unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
1992 EntryIRB.CreateMemCpy(
1993 CpOriginPtr,
1994 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginPtr,
1995 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
1996 OriginSize);
1997 }
1998 }
1999 }
2000
2001 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
2002 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
2003 ShadowPtr = getCleanShadow(V);
2004 setOrigin(A, getCleanOrigin());
2005 } else {
2006 // Shadow over TLS
2007 Value *Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2008 ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg), Base,
2010 if (MS.TrackOrigins) {
2011 Value *OriginPtr =
2012 getOriginPtrForArgument(EntryIRB, ArgOffset);
2013 setOrigin(A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
2014 }
2015 }
2017 << " ARG: " << FArg << " ==> " << *ShadowPtr << "\n");
2018 break;
2019 }
2020
2021 ArgOffset += alignTo(Size, kShadowTLSAlignment);
2022 }
2023 assert(ShadowPtr && "Could not find shadow for an argument");
2024 return ShadowPtr;
2025 }
2026 // For everything else the shadow is zero.
2027 return getCleanShadow(V);
2028 }
2029
2030 /// Get the shadow for i-th argument of the instruction I.
2031 Value *getShadow(Instruction *I, int i) {
2032 return getShadow(I->getOperand(i));
2033 }
2034
2035 /// Get the origin for a value.
2036 Value *getOrigin(Value *V) {
2037 if (!MS.TrackOrigins)
2038 return nullptr;
2039 if (!PropagateShadow || isa<Constant>(V) || isa<InlineAsm>(V))
2040 return getCleanOrigin();
2041 assert((isa<Instruction>(V) || isa<Argument>(V)) &&
2042 "Unexpected value type in getOrigin()");
2043 if (Instruction *I = dyn_cast<Instruction>(V)) {
2044 if (I->getMetadata(LLVMContext::MD_nosanitize))
2045 return getCleanOrigin();
2046 }
2047 Value *Origin = OriginMap[V];
2048 assert(Origin && "Missing origin");
2049 return Origin;
2050 }
2051
2052 /// Get the origin for i-th argument of the instruction I.
2053 Value *getOrigin(Instruction *I, int i) {
2054 return getOrigin(I->getOperand(i));
2055 }
2056
2057 /// Remember the place where a shadow check should be inserted.
2058 ///
2059 /// This location will be later instrumented with a check that will print a
2060 /// UMR warning in runtime if the shadow value is not 0.
2061 void insertShadowCheck(Value *Shadow, Value *Origin, Instruction *OrigIns) {
2062 assert(Shadow);
2063 if (!InsertChecks)
2064 return;
2065
2066 if (!DebugCounter::shouldExecute(DebugInsertCheck)) {
2067 LLVM_DEBUG(dbgs() << "Skipping check of " << *Shadow << " before "
2068 << *OrigIns << "\n");
2069 return;
2070 }
2071#ifndef NDEBUG
2072 Type *ShadowTy = Shadow->getType();
2073 assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy) ||
2074 isa<StructType>(ShadowTy) || isa<ArrayType>(ShadowTy)) &&
2075 "Can only insert checks for integer, vector, and aggregate shadow "
2076 "types");
2077#endif
2078 InstrumentationList.push_back(
2079 ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
2080 }
2081
2082 /// Remember the place where a shadow check should be inserted.
2083 ///
2084 /// This location will be later instrumented with a check that will print a
2085 /// UMR warning in runtime if the value is not fully defined.
2086 void insertShadowCheck(Value *Val, Instruction *OrigIns) {
2087 assert(Val);
2088 Value *Shadow, *Origin;
2090 Shadow = getShadow(Val);
2091 if (!Shadow)
2092 return;
2093 Origin = getOrigin(Val);
2094 } else {
2095 Shadow = dyn_cast_or_null<Instruction>(getShadow(Val));
2096 if (!Shadow)
2097 return;
2098 Origin = dyn_cast_or_null<Instruction>(getOrigin(Val));
2099 }
2100 insertShadowCheck(Shadow, Origin, OrigIns);
2101 }
2102
2104 switch (a) {
2105 case AtomicOrdering::NotAtomic:
2106 return AtomicOrdering::NotAtomic;
2107 case AtomicOrdering::Unordered:
2108 case AtomicOrdering::Monotonic:
2109 case AtomicOrdering::Release:
2110 return AtomicOrdering::Release;
2111 case AtomicOrdering::Acquire:
2112 case AtomicOrdering::AcquireRelease:
2113 return AtomicOrdering::AcquireRelease;
2114 case AtomicOrdering::SequentiallyConsistent:
2115 return AtomicOrdering::SequentiallyConsistent;
2116 }
2117 llvm_unreachable("Unknown ordering");
2118 }
2119
2120 Value *makeAddReleaseOrderingTable(IRBuilder<> &IRB) {
2121 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2122 uint32_t OrderingTable[NumOrderings] = {};
2123
2124 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2125 OrderingTable[(int)AtomicOrderingCABI::release] =
2126 (int)AtomicOrderingCABI::release;
2127 OrderingTable[(int)AtomicOrderingCABI::consume] =
2128 OrderingTable[(int)AtomicOrderingCABI::acquire] =
2129 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2130 (int)AtomicOrderingCABI::acq_rel;
2131 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2132 (int)AtomicOrderingCABI::seq_cst;
2133
2134 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
2135 }
2136
2138 switch (a) {
2139 case AtomicOrdering::NotAtomic:
2140 return AtomicOrdering::NotAtomic;
2141 case AtomicOrdering::Unordered:
2142 case AtomicOrdering::Monotonic:
2143 case AtomicOrdering::Acquire:
2144 return AtomicOrdering::Acquire;
2145 case AtomicOrdering::Release:
2146 case AtomicOrdering::AcquireRelease:
2147 return AtomicOrdering::AcquireRelease;
2148 case AtomicOrdering::SequentiallyConsistent:
2149 return AtomicOrdering::SequentiallyConsistent;
2150 }
2151 llvm_unreachable("Unknown ordering");
2152 }
2153
2154 Value *makeAddAcquireOrderingTable(IRBuilder<> &IRB) {
2155 constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
2156 uint32_t OrderingTable[NumOrderings] = {};
2157
2158 OrderingTable[(int)AtomicOrderingCABI::relaxed] =
2159 OrderingTable[(int)AtomicOrderingCABI::acquire] =
2160 OrderingTable[(int)AtomicOrderingCABI::consume] =
2161 (int)AtomicOrderingCABI::acquire;
2162 OrderingTable[(int)AtomicOrderingCABI::release] =
2163 OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
2164 (int)AtomicOrderingCABI::acq_rel;
2165 OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
2166 (int)AtomicOrderingCABI::seq_cst;
2167
2168 return ConstantDataVector::get(IRB.getContext(), OrderingTable);
2169 }
2170
2171 // ------------------- Visitors.
2172 using InstVisitor<MemorySanitizerVisitor>::visit;
2173 void visit(Instruction &I) {
2174 if (I.getMetadata(LLVMContext::MD_nosanitize))
2175 return;
2176 // Don't want to visit if we're in the prologue
2177 if (isInPrologue(I))
2178 return;
2180 }
2181
2182 /// Instrument LoadInst
2183 ///
2184 /// Loads the corresponding shadow and (optionally) origin.
2185 /// Optionally, checks that the load address is fully defined.
2186 void visitLoadInst(LoadInst &I) {
2187 assert(I.getType()->isSized() && "Load type must have size");
2188 assert(!I.getMetadata(LLVMContext::MD_nosanitize));
2189 NextNodeIRBuilder IRB(&I);
2190 Type *ShadowTy = getShadowTy(&I);
2191 Value *Addr = I.getPointerOperand();
2192 Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
2193 const Align Alignment = I.getAlign();
2194 if (PropagateShadow) {
2195 std::tie(ShadowPtr, OriginPtr) =
2196 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
2197 setShadow(&I,
2198 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
2199 } else {
2200 setShadow(&I, getCleanShadow(&I));
2201 }
2202
2204 insertShadowCheck(I.getPointerOperand(), &I);
2205
2206 if (I.isAtomic())
2207 I.setOrdering(addAcquireOrdering(I.getOrdering()));
2208
2209 if (MS.TrackOrigins) {
2210 if (PropagateShadow) {
2211 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
2212 setOrigin(
2213 &I, IRB.CreateAlignedLoad(MS.OriginTy, OriginPtr, OriginAlignment));
2214 } else {
2215 setOrigin(&I, getCleanOrigin());
2216 }
2217 }
2218 }
2219
2220 /// Instrument StoreInst
2221 ///
2222 /// Stores the corresponding shadow and (optionally) origin.
2223 /// Optionally, checks that the store address is fully defined.
2224 void visitStoreInst(StoreInst &I) {
2225 StoreList.push_back(&I);
2227 insertShadowCheck(I.getPointerOperand(), &I);
2228 }
2229
2230 void handleCASOrRMW(Instruction &I) {
2231 assert(isa<AtomicRMWInst>(I) || isa<AtomicCmpXchgInst>(I));
2232
2233 IRBuilder<> IRB(&I);
2234 Value *Addr = I.getOperand(0);
2235 Value *Val = I.getOperand(1);
2236 Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, getShadowTy(Val), Align(1),
2237 /*isStore*/ true)
2238 .first;
2239
2241 insertShadowCheck(Addr, &I);
2242
2243 // Only test the conditional argument of cmpxchg instruction.
2244 // The other argument can potentially be uninitialized, but we can not
2245 // detect this situation reliably without possible false positives.
2246 if (isa<AtomicCmpXchgInst>(I))
2247 insertShadowCheck(Val, &I);
2248
2249 IRB.CreateStore(getCleanShadow(Val), ShadowPtr);
2250
2251 setShadow(&I, getCleanShadow(&I));
2252 setOrigin(&I, getCleanOrigin());
2253 }
2254
2255 void visitAtomicRMWInst(AtomicRMWInst &I) {
2256 handleCASOrRMW(I);
2257 I.setOrdering(addReleaseOrdering(I.getOrdering()));
2258 }
2259
2260 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
2261 handleCASOrRMW(I);
2262 I.setSuccessOrdering(addReleaseOrdering(I.getSuccessOrdering()));
2263 }
2264
2265 // Vector manipulation.
2266 void visitExtractElementInst(ExtractElementInst &I) {
2267 insertShadowCheck(I.getOperand(1), &I);
2268 IRBuilder<> IRB(&I);
2269 setShadow(&I, IRB.CreateExtractElement(getShadow(&I, 0), I.getOperand(1),
2270 "_msprop"));
2271 setOrigin(&I, getOrigin(&I, 0));
2272 }
2273
2274 void visitInsertElementInst(InsertElementInst &I) {
2275 insertShadowCheck(I.getOperand(2), &I);
2276 IRBuilder<> IRB(&I);
2277 auto *Shadow0 = getShadow(&I, 0);
2278 auto *Shadow1 = getShadow(&I, 1);
2279 setShadow(&I, IRB.CreateInsertElement(Shadow0, Shadow1, I.getOperand(2),
2280 "_msprop"));
2281 setOriginForNaryOp(I);
2282 }
2283
2284 void visitShuffleVectorInst(ShuffleVectorInst &I) {
2285 IRBuilder<> IRB(&I);
2286 auto *Shadow0 = getShadow(&I, 0);
2287 auto *Shadow1 = getShadow(&I, 1);
2288 setShadow(&I, IRB.CreateShuffleVector(Shadow0, Shadow1, I.getShuffleMask(),
2289 "_msprop"));
2290 setOriginForNaryOp(I);
2291 }
2292
2293 // Casts.
2294 void visitSExtInst(SExtInst &I) {
2295 IRBuilder<> IRB(&I);
2296 setShadow(&I, IRB.CreateSExt(getShadow(&I, 0), I.getType(), "_msprop"));
2297 setOrigin(&I, getOrigin(&I, 0));
2298 }
2299
2300 void visitZExtInst(ZExtInst &I) {
2301 IRBuilder<> IRB(&I);
2302 setShadow(&I, IRB.CreateZExt(getShadow(&I, 0), I.getType(), "_msprop"));
2303 setOrigin(&I, getOrigin(&I, 0));
2304 }
2305
2306 void visitTruncInst(TruncInst &I) {
2307 IRBuilder<> IRB(&I);
2308 setShadow(&I, IRB.CreateTrunc(getShadow(&I, 0), I.getType(), "_msprop"));
2309 setOrigin(&I, getOrigin(&I, 0));
2310 }
2311
2312 void visitBitCastInst(BitCastInst &I) {
2313 // Special case: if this is the bitcast (there is exactly 1 allowed) between
2314 // a musttail call and a ret, don't instrument. New instructions are not
2315 // allowed after a musttail call.
2316 if (auto *CI = dyn_cast<CallInst>(I.getOperand(0)))
2317 if (CI->isMustTailCall())
2318 return;
2319 IRBuilder<> IRB(&I);
2320 setShadow(&I, IRB.CreateBitCast(getShadow(&I, 0), getShadowTy(&I)));
2321 setOrigin(&I, getOrigin(&I, 0));
2322 }
2323
2324 void visitPtrToIntInst(PtrToIntInst &I) {
2325 IRBuilder<> IRB(&I);
2326 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2327 "_msprop_ptrtoint"));
2328 setOrigin(&I, getOrigin(&I, 0));
2329 }
2330
2331 void visitIntToPtrInst(IntToPtrInst &I) {
2332 IRBuilder<> IRB(&I);
2333 setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
2334 "_msprop_inttoptr"));
2335 setOrigin(&I, getOrigin(&I, 0));
2336 }
2337
2338 void visitFPToSIInst(CastInst &I) { handleShadowOr(I); }
2339 void visitFPToUIInst(CastInst &I) { handleShadowOr(I); }
2340 void visitSIToFPInst(CastInst &I) { handleShadowOr(I); }
2341 void visitUIToFPInst(CastInst &I) { handleShadowOr(I); }
2342 void visitFPExtInst(CastInst &I) { handleShadowOr(I); }
2343 void visitFPTruncInst(CastInst &I) { handleShadowOr(I); }
2344
2345 /// Propagate shadow for bitwise AND.
2346 ///
2347 /// This code is exact, i.e. if, for example, a bit in the left argument
2348 /// is defined and 0, then neither the value not definedness of the
2349 /// corresponding bit in B don't affect the resulting shadow.
2350 void visitAnd(BinaryOperator &I) {
2351 IRBuilder<> IRB(&I);
2352 // "And" of 0 and a poisoned value results in unpoisoned value.
2353 // 1&1 => 1; 0&1 => 0; p&1 => p;
2354 // 1&0 => 0; 0&0 => 0; p&0 => 0;
2355 // 1&p => p; 0&p => 0; p&p => p;
2356 // S = (S1 & S2) | (V1 & S2) | (S1 & V2)
2357 Value *S1 = getShadow(&I, 0);
2358 Value *S2 = getShadow(&I, 1);
2359 Value *V1 = I.getOperand(0);
2360 Value *V2 = I.getOperand(1);
2361 if (V1->getType() != S1->getType()) {
2362 V1 = IRB.CreateIntCast(V1, S1->getType(), false);
2363 V2 = IRB.CreateIntCast(V2, S2->getType(), false);
2364 }
2365 Value *S1S2 = IRB.CreateAnd(S1, S2);
2366 Value *V1S2 = IRB.CreateAnd(V1, S2);
2367 Value *S1V2 = IRB.CreateAnd(S1, V2);
2368 setShadow(&I, IRB.CreateOr({S1S2, V1S2, S1V2}));
2369 setOriginForNaryOp(I);
2370 }
2371
2372 void visitOr(BinaryOperator &I) {
2373 IRBuilder<> IRB(&I);
2374 // "Or" of 1 and a poisoned value results in unpoisoned value.
2375 // 1|1 => 1; 0|1 => 1; p|1 => 1;
2376 // 1|0 => 1; 0|0 => 0; p|0 => p;
2377 // 1|p => 1; 0|p => p; p|p => p;
2378 // S = (S1 & S2) | (~V1 & S2) | (S1 & ~V2)
2379 Value *S1 = getShadow(&I, 0);
2380 Value *S2 = getShadow(&I, 1);
2381 Value *V1 = IRB.CreateNot(I.getOperand(0));
2382 Value *V2 = IRB.CreateNot(I.getOperand(1));
2383 if (V1->getType() != S1->getType()) {
2384 V1 = IRB.CreateIntCast(V1, S1->getType(), false);
2385 V2 = IRB.CreateIntCast(V2, S2->getType(), false);
2386 }
2387 Value *S1S2 = IRB.CreateAnd(S1, S2);
2388 Value *V1S2 = IRB.CreateAnd(V1, S2);
2389 Value *S1V2 = IRB.CreateAnd(S1, V2);
2390 setShadow(&I, IRB.CreateOr({S1S2, V1S2, S1V2}));
2391 setOriginForNaryOp(I);
2392 }
2393
2394 /// Default propagation of shadow and/or origin.
2395 ///
2396 /// This class implements the general case of shadow propagation, used in all
2397 /// cases where we don't know and/or don't care about what the operation
2398 /// actually does. It converts all input shadow values to a common type
2399 /// (extending or truncating as necessary), and bitwise OR's them.
2400 ///
2401 /// This is much cheaper than inserting checks (i.e. requiring inputs to be
2402 /// fully initialized), and less prone to false positives.
2403 ///
2404 /// This class also implements the general case of origin propagation. For a
2405 /// Nary operation, result origin is set to the origin of an argument that is
2406 /// not entirely initialized. If there is more than one such arguments, the
2407 /// rightmost of them is picked. It does not matter which one is picked if all
2408 /// arguments are initialized.
2409 template <bool CombineShadow> class Combiner {
2410 Value *Shadow = nullptr;
2411 Value *Origin = nullptr;
2412 IRBuilder<> &IRB;
2413 MemorySanitizerVisitor *MSV;
2414
2415 public:
2416 Combiner(MemorySanitizerVisitor *MSV, IRBuilder<> &IRB)
2417 : IRB(IRB), MSV(MSV) {}
2418
2419 /// Add a pair of shadow and origin values to the mix.
2420 Combiner &Add(Value *OpShadow, Value *OpOrigin) {
2421 if (CombineShadow) {
2422 assert(OpShadow);
2423 if (!Shadow)
2424 Shadow = OpShadow;
2425 else {
2426 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2427 Shadow = IRB.CreateOr(Shadow, OpShadow, "_msprop");
2428 }
2429 }
2430
2431 if (MSV->MS.TrackOrigins) {
2432 assert(OpOrigin);
2433 if (!Origin) {
2434 Origin = OpOrigin;
2435 } else {
2436 Constant *ConstOrigin = dyn_cast<Constant>(OpOrigin);
2437 // No point in adding something that might result in 0 origin value.
2438 if (!ConstOrigin || !ConstOrigin->isNullValue()) {
2439 Value *Cond = MSV->convertToBool(OpShadow, IRB);
2440 Origin = IRB.CreateSelect(Cond, OpOrigin, Origin);
2441 }
2442 }
2443 }
2444 return *this;
2445 }
2446
2447 /// Add an application value to the mix.
2448 Combiner &Add(Value *V) {
2449 Value *OpShadow = MSV->getShadow(V);
2450 Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) : nullptr;
2451 return Add(OpShadow, OpOrigin);
2452 }
2453
2454 /// Set the current combined values as the given instruction's shadow
2455 /// and origin.
2456 void Done(Instruction *I) {
2457 if (CombineShadow) {
2458 assert(Shadow);
2459 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(I));
2460 MSV->setShadow(I, Shadow);
2461 }
2462 if (MSV->MS.TrackOrigins) {
2463 assert(Origin);
2464 MSV->setOrigin(I, Origin);
2465 }
2466 }
2467 };
2468
2469 using ShadowAndOriginCombiner = Combiner<true>;
2470 using OriginCombiner = Combiner<false>;
2471
2472 /// Propagate origin for arbitrary operation.
2473 void setOriginForNaryOp(Instruction &I) {
2474 if (!MS.TrackOrigins)
2475 return;
2476 IRBuilder<> IRB(&I);
2477 OriginCombiner OC(this, IRB);
2478 for (Use &Op : I.operands())
2479 OC.Add(Op.get());
2480 OC.Done(&I);
2481 }
2482
2483 size_t VectorOrPrimitiveTypeSizeInBits(Type *Ty) {
2484 assert(!(Ty->isVectorTy() && Ty->getScalarType()->isPointerTy()) &&
2485 "Vector of pointers is not a valid shadow type");
2486 return Ty->isVectorTy() ? cast<FixedVectorType>(Ty)->getNumElements() *
2488 : Ty->getPrimitiveSizeInBits();
2489 }
2490
2491 /// Cast between two shadow types, extending or truncating as
2492 /// necessary.
2493 Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy,
2494 bool Signed = false) {
2495 Type *srcTy = V->getType();
2496 size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
2497 size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
2498 if (srcSizeInBits > 1 && dstSizeInBits == 1)
2499 return IRB.CreateICmpNE(V, getCleanShadow(V));
2500
2501 if (dstTy->isIntegerTy() && srcTy->isIntegerTy())
2502 return IRB.CreateIntCast(V, dstTy, Signed);
2503 if (dstTy->isVectorTy() && srcTy->isVectorTy() &&
2504 cast<VectorType>(dstTy)->getElementCount() ==
2505 cast<VectorType>(srcTy)->getElementCount())
2506 return IRB.CreateIntCast(V, dstTy, Signed);
2507 Value *V1 = IRB.CreateBitCast(V, Type::getIntNTy(*MS.C, srcSizeInBits));
2508 Value *V2 =
2509 IRB.CreateIntCast(V1, Type::getIntNTy(*MS.C, dstSizeInBits), Signed);
2510 return IRB.CreateBitCast(V2, dstTy);
2511 // TODO: handle struct types.
2512 }
2513
2514 /// Cast an application value to the type of its own shadow.
2515 Value *CreateAppToShadowCast(IRBuilder<> &IRB, Value *V) {
2516 Type *ShadowTy = getShadowTy(V);
2517 if (V->getType() == ShadowTy)
2518 return V;
2519 if (V->getType()->isPtrOrPtrVectorTy())
2520 return IRB.CreatePtrToInt(V, ShadowTy);
2521 else
2522 return IRB.CreateBitCast(V, ShadowTy);
2523 }
2524
2525 /// Propagate shadow for arbitrary operation.
2526 void handleShadowOr(Instruction &I) {
2527 IRBuilder<> IRB(&I);
2528 ShadowAndOriginCombiner SC(this, IRB);
2529 for (Use &Op : I.operands())
2530 SC.Add(Op.get());
2531 SC.Done(&I);
2532 }
2533
2534 void visitFNeg(UnaryOperator &I) { handleShadowOr(I); }
2535
2536 // Handle multiplication by constant.
2537 //
2538 // Handle a special case of multiplication by constant that may have one or
2539 // more zeros in the lower bits. This makes corresponding number of lower bits
2540 // of the result zero as well. We model it by shifting the other operand
2541 // shadow left by the required number of bits. Effectively, we transform
2542 // (X * (A * 2**B)) to ((X << B) * A) and instrument (X << B) as (Sx << B).
2543 // We use multiplication by 2**N instead of shift to cover the case of
2544 // multiplication by 0, which may occur in some elements of a vector operand.
2545 void handleMulByConstant(BinaryOperator &I, Constant *ConstArg,
2546 Value *OtherArg) {
2547 Constant *ShadowMul;
2548 Type *Ty = ConstArg->getType();
2549 if (auto *VTy = dyn_cast<VectorType>(Ty)) {
2550 unsigned NumElements = cast<FixedVectorType>(VTy)->getNumElements();
2551 Type *EltTy = VTy->getElementType();
2553 for (unsigned Idx = 0; Idx < NumElements; ++Idx) {
2554 if (ConstantInt *Elt =
2555 dyn_cast<ConstantInt>(ConstArg->getAggregateElement(Idx))) {
2556 const APInt &V = Elt->getValue();
2557 APInt V2 = APInt(V.getBitWidth(), 1) << V.countr_zero();
2558 Elements.push_back(ConstantInt::get(EltTy, V2));
2559 } else {
2560 Elements.push_back(ConstantInt::get(EltTy, 1));
2561 }
2562 }
2563 ShadowMul = ConstantVector::get(Elements);
2564 } else {
2565 if (ConstantInt *Elt = dyn_cast<ConstantInt>(ConstArg)) {
2566 const APInt &V = Elt->getValue();
2567 APInt V2 = APInt(V.getBitWidth(), 1) << V.countr_zero();
2568 ShadowMul = ConstantInt::get(Ty, V2);
2569 } else {
2570 ShadowMul = ConstantInt::get(Ty, 1);
2571 }
2572 }
2573
2574 IRBuilder<> IRB(&I);
2575 setShadow(&I,
2576 IRB.CreateMul(getShadow(OtherArg), ShadowMul, "msprop_mul_cst"));
2577 setOrigin(&I, getOrigin(OtherArg));
2578 }
2579
2580 void visitMul(BinaryOperator &I) {
2581 Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0));
2582 Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1));
2583 if (constOp0 && !constOp1)
2584 handleMulByConstant(I, constOp0, I.getOperand(1));
2585 else if (constOp1 && !constOp0)
2586 handleMulByConstant(I, constOp1, I.getOperand(0));
2587 else
2588 handleShadowOr(I);
2589 }
2590
2591 void visitFAdd(BinaryOperator &I) { handleShadowOr(I); }
2592 void visitFSub(BinaryOperator &I) { handleShadowOr(I); }
2593 void visitFMul(BinaryOperator &I) { handleShadowOr(I); }
2594 void visitAdd(BinaryOperator &I) { handleShadowOr(I); }
2595 void visitSub(BinaryOperator &I) { handleShadowOr(I); }
2596 void visitXor(BinaryOperator &I) { handleShadowOr(I); }
2597
2598 void handleIntegerDiv(Instruction &I) {
2599 IRBuilder<> IRB(&I);
2600 // Strict on the second argument.
2601 insertShadowCheck(I.getOperand(1), &I);
2602 setShadow(&I, getShadow(&I, 0));
2603 setOrigin(&I, getOrigin(&I, 0));
2604 }
2605
2606 void visitUDiv(BinaryOperator &I) { handleIntegerDiv(I); }
2607 void visitSDiv(BinaryOperator &I) { handleIntegerDiv(I); }
2608 void visitURem(BinaryOperator &I) { handleIntegerDiv(I); }
2609 void visitSRem(BinaryOperator &I) { handleIntegerDiv(I); }
2610
2611 // Floating point division is side-effect free. We can not require that the
2612 // divisor is fully initialized and must propagate shadow. See PR37523.
2613 void visitFDiv(BinaryOperator &I) { handleShadowOr(I); }
2614 void visitFRem(BinaryOperator &I) { handleShadowOr(I); }
2615
2616 /// Instrument == and != comparisons.
2617 ///
2618 /// Sometimes the comparison result is known even if some of the bits of the
2619 /// arguments are not.
2620 void handleEqualityComparison(ICmpInst &I) {
2621 IRBuilder<> IRB(&I);
2622 Value *A = I.getOperand(0);
2623 Value *B = I.getOperand(1);
2624 Value *Sa = getShadow(A);
2625 Value *Sb = getShadow(B);
2626
2627 // Get rid of pointers and vectors of pointers.
2628 // For ints (and vectors of ints), types of A and Sa match,
2629 // and this is a no-op.
2630 A = IRB.CreatePointerCast(A, Sa->getType());
2631 B = IRB.CreatePointerCast(B, Sb->getType());
2632
2633 // A == B <==> (C = A^B) == 0
2634 // A != B <==> (C = A^B) != 0
2635 // Sc = Sa | Sb
2636 Value *C = IRB.CreateXor(A, B);
2637 Value *Sc = IRB.CreateOr(Sa, Sb);
2638 // Now dealing with i = (C == 0) comparison (or C != 0, does not matter now)
2639 // Result is defined if one of the following is true
2640 // * there is a defined 1 bit in C
2641 // * C is fully defined
2642 // Si = !(C & ~Sc) && Sc
2644 Value *MinusOne = Constant::getAllOnesValue(Sc->getType());
2645 Value *LHS = IRB.CreateICmpNE(Sc, Zero);
2646 Value *RHS =
2647 IRB.CreateICmpEQ(IRB.CreateAnd(IRB.CreateXor(Sc, MinusOne), C), Zero);
2648 Value *Si = IRB.CreateAnd(LHS, RHS);
2649 Si->setName("_msprop_icmp");
2650 setShadow(&I, Si);
2651 setOriginForNaryOp(I);
2652 }
2653
2654 /// Build the lowest possible value of V, taking into account V's
2655 /// uninitialized bits.
2656 Value *getLowestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
2657 bool isSigned) {
2658 if (isSigned) {
2659 // Split shadow into sign bit and other bits.
2660 Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
2661 Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
2662 // Maximise the undefined shadow bit, minimize other undefined bits.
2663 return IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaOtherBits)),
2664 SaSignBit);
2665 } else {
2666 // Minimize undefined bits.
2667 return IRB.CreateAnd(A, IRB.CreateNot(Sa));
2668 }
2669 }
2670
2671 /// Build the highest possible value of V, taking into account V's
2672 /// uninitialized bits.
2673 Value *getHighestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
2674 bool isSigned) {
2675 if (isSigned) {
2676 // Split shadow into sign bit and other bits.
2677 Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
2678 Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
2679 // Minimise the undefined shadow bit, maximise other undefined bits.
2680 return IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaSignBit)),
2681 SaOtherBits);
2682 } else {
2683 // Maximize undefined bits.
2684 return IRB.CreateOr(A, Sa);
2685 }
2686 }
2687
2688 /// Instrument relational comparisons.
2689 ///
2690 /// This function does exact shadow propagation for all relational
2691 /// comparisons of integers, pointers and vectors of those.
2692 /// FIXME: output seems suboptimal when one of the operands is a constant
2693 void handleRelationalComparisonExact(ICmpInst &I) {
2694 IRBuilder<> IRB(&I);
2695 Value *A = I.getOperand(0);
2696 Value *B = I.getOperand(1);
2697 Value *Sa = getShadow(A);
2698 Value *Sb = getShadow(B);
2699
2700 // Get rid of pointers and vectors of pointers.
2701 // For ints (and vectors of ints), types of A and Sa match,
2702 // and this is a no-op.
2703 A = IRB.CreatePointerCast(A, Sa->getType());
2704 B = IRB.CreatePointerCast(B, Sb->getType());
2705
2706 // Let [a0, a1] be the interval of possible values of A, taking into account
2707 // its undefined bits. Let [b0, b1] be the interval of possible values of B.
2708 // Then (A cmp B) is defined iff (a0 cmp b1) == (a1 cmp b0).
2709 bool IsSigned = I.isSigned();
2710 Value *S1 = IRB.CreateICmp(I.getPredicate(),
2711 getLowestPossibleValue(IRB, A, Sa, IsSigned),
2712 getHighestPossibleValue(IRB, B, Sb, IsSigned));
2713 Value *S2 = IRB.CreateICmp(I.getPredicate(),
2714 getHighestPossibleValue(IRB, A, Sa, IsSigned),
2715 getLowestPossibleValue(IRB, B, Sb, IsSigned));
2716 Value *Si = IRB.CreateXor(S1, S2);
2717 setShadow(&I, Si);
2718 setOriginForNaryOp(I);
2719 }
2720
2721 /// Instrument signed relational comparisons.
2722 ///
2723 /// Handle sign bit tests: x<0, x>=0, x<=-1, x>-1 by propagating the highest
2724 /// bit of the shadow. Everything else is delegated to handleShadowOr().
2725 void handleSignedRelationalComparison(ICmpInst &I) {
2726 Constant *constOp;
2727 Value *op = nullptr;
2729 if ((constOp = dyn_cast<Constant>(I.getOperand(1)))) {
2730 op = I.getOperand(0);
2731 pre = I.getPredicate();
2732 } else if ((constOp = dyn_cast<Constant>(I.getOperand(0)))) {
2733 op = I.getOperand(1);
2734 pre = I.getSwappedPredicate();
2735 } else {
2736 handleShadowOr(I);
2737 return;
2738 }
2739
2740 if ((constOp->isNullValue() &&
2741 (pre == CmpInst::ICMP_SLT || pre == CmpInst::ICMP_SGE)) ||
2742 (constOp->isAllOnesValue() &&
2743 (pre == CmpInst::ICMP_SGT || pre == CmpInst::ICMP_SLE))) {
2744 IRBuilder<> IRB(&I);
2745 Value *Shadow = IRB.CreateICmpSLT(getShadow(op), getCleanShadow(op),
2746 "_msprop_icmp_s");
2747 setShadow(&I, Shadow);
2748 setOrigin(&I, getOrigin(op));
2749 } else {
2750 handleShadowOr(I);
2751 }
2752 }
2753
2754 void visitICmpInst(ICmpInst &I) {
2755 if (!ClHandleICmp) {
2756 handleShadowOr(I);
2757 return;
2758 }
2759 if (I.isEquality()) {
2760 handleEqualityComparison(I);
2761 return;
2762 }
2763
2764 assert(I.isRelational());
2765 if (ClHandleICmpExact) {
2766 handleRelationalComparisonExact(I);
2767 return;
2768 }
2769 if (I.isSigned()) {
2770 handleSignedRelationalComparison(I);
2771 return;
2772 }
2773
2774 assert(I.isUnsigned());
2775 if ((isa<Constant>(I.getOperand(0)) || isa<Constant>(I.getOperand(1)))) {
2776 handleRelationalComparisonExact(I);
2777 return;
2778 }
2779
2780 handleShadowOr(I);
2781 }
2782
2783 void visitFCmpInst(FCmpInst &I) { handleShadowOr(I); }
2784
2785 void handleShift(BinaryOperator &I) {
2786 IRBuilder<> IRB(&I);
2787 // If any of the S2 bits are poisoned, the whole thing is poisoned.
2788 // Otherwise perform the same shift on S1.
2789 Value *S1 = getShadow(&I, 0);
2790 Value *S2 = getShadow(&I, 1);
2791 Value *S2Conv =
2792 IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)), S2->getType());
2793 Value *V2 = I.getOperand(1);
2794 Value *Shift = IRB.CreateBinOp(I.getOpcode(), S1, V2);
2795 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
2796 setOriginForNaryOp(I);
2797 }
2798
2799 void visitShl(BinaryOperator &I) { handleShift(I); }
2800 void visitAShr(BinaryOperator &I) { handleShift(I); }
2801 void visitLShr(BinaryOperator &I) { handleShift(I); }
2802
2803 void handleFunnelShift(IntrinsicInst &I) {
2804 IRBuilder<> IRB(&I);
2805 // If any of the S2 bits are poisoned, the whole thing is poisoned.
2806 // Otherwise perform the same shift on S0 and S1.
2807 Value *S0 = getShadow(&I, 0);
2808 Value *S1 = getShadow(&I, 1);
2809 Value *S2 = getShadow(&I, 2);
2810 Value *S2Conv =
2811 IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)), S2->getType());
2812 Value *V2 = I.getOperand(2);
2814 I.getModule(), I.getIntrinsicID(), S2Conv->getType());
2815 Value *Shift = IRB.CreateCall(Intrin, {S0, S1, V2});
2816 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
2817 setOriginForNaryOp(I);
2818 }
2819
2820 /// Instrument llvm.memmove
2821 ///
2822 /// At this point we don't know if llvm.memmove will be inlined or not.
2823 /// If we don't instrument it and it gets inlined,
2824 /// our interceptor will not kick in and we will lose the memmove.
2825 /// If we instrument the call here, but it does not get inlined,
2826 /// we will memove the shadow twice: which is bad in case
2827 /// of overlapping regions. So, we simply lower the intrinsic to a call.
2828 ///
2829 /// Similar situation exists for memcpy and memset.
2830 void visitMemMoveInst(MemMoveInst &I) {
2831 getShadow(I.getArgOperand(1)); // Ensure shadow initialized
2832 IRBuilder<> IRB(&I);
2833 IRB.CreateCall(MS.MemmoveFn,
2834 {I.getArgOperand(0), I.getArgOperand(1),
2835 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
2836 I.eraseFromParent();
2837 }
2838
2839 /// Instrument memcpy
2840 ///
2841 /// Similar to memmove: avoid copying shadow twice. This is somewhat
2842 /// unfortunate as it may slowdown small constant memcpys.
2843 /// FIXME: consider doing manual inline for small constant sizes and proper
2844 /// alignment.
2845 ///
2846 /// Note: This also handles memcpy.inline, which promises no calls to external
2847 /// functions as an optimization. However, with instrumentation enabled this
2848 /// is difficult to promise; additionally, we know that the MSan runtime
2849 /// exists and provides __msan_memcpy(). Therefore, we assume that with
2850 /// instrumentation it's safe to turn memcpy.inline into a call to
2851 /// __msan_memcpy(). Should this be wrong, such as when implementing memcpy()
2852 /// itself, instrumentation should be disabled with the no_sanitize attribute.
2853 void visitMemCpyInst(MemCpyInst &I) {
2854 getShadow(I.getArgOperand(1)); // Ensure shadow initialized
2855 IRBuilder<> IRB(&I);
2856 IRB.CreateCall(MS.MemcpyFn,
2857 {I.getArgOperand(0), I.getArgOperand(1),
2858 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
2859 I.eraseFromParent();
2860 }
2861
2862 // Same as memcpy.
2863 void visitMemSetInst(MemSetInst &I) {
2864 IRBuilder<> IRB(&I);
2865 IRB.CreateCall(
2866 MS.MemsetFn,
2867 {I.getArgOperand(0),
2868 IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
2869 IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
2870 I.eraseFromParent();
2871 }
2872
2873 void visitVAStartInst(VAStartInst &I) { VAHelper->visitVAStartInst(I); }
2874
2875 void visitVACopyInst(VACopyInst &I) { VAHelper->visitVACopyInst(I); }
2876
2877 /// Handle vector store-like intrinsics.
2878 ///
2879 /// Instrument intrinsics that look like a simple SIMD store: writes memory,
2880 /// has 1 pointer argument and 1 vector argument, returns void.
2881 bool handleVectorStoreIntrinsic(IntrinsicInst &I) {
2882 IRBuilder<> IRB(&I);
2883 Value *Addr = I.getArgOperand(0);
2884 Value *Shadow = getShadow(&I, 1);
2885 Value *ShadowPtr, *OriginPtr;
2886
2887 // We don't know the pointer alignment (could be unaligned SSE store!).
2888 // Have to assume to worst case.
2889 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
2890 Addr, IRB, Shadow->getType(), Align(1), /*isStore*/ true);
2891 IRB.CreateAlignedStore(Shadow, ShadowPtr, Align(1));
2892
2894 insertShadowCheck(Addr, &I);
2895
2896 // FIXME: factor out common code from materializeStores
2897 if (MS.TrackOrigins)
2898 IRB.CreateStore(getOrigin(&I, 1), OriginPtr);
2899 return true;
2900 }
2901
2902 /// Handle vector load-like intrinsics.
2903 ///
2904 /// Instrument intrinsics that look like a simple SIMD load: reads memory,
2905 /// has 1 pointer argument, returns a vector.
2906 bool handleVectorLoadIntrinsic(IntrinsicInst &I) {
2907 IRBuilder<> IRB(&I);
2908 Value *Addr = I.getArgOperand(0);
2909
2910 Type *ShadowTy = getShadowTy(&I);
2911 Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
2912 if (PropagateShadow) {
2913 // We don't know the pointer alignment (could be unaligned SSE load!).
2914 // Have to assume to worst case.
2915 const Align Alignment = Align(1);
2916 std::tie(ShadowPtr, OriginPtr) =
2917 getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
2918 setShadow(&I,
2919 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
2920 } else {
2921 setShadow(&I, getCleanShadow(&I));
2922 }
2923
2925 insertShadowCheck(Addr, &I);
2926
2927 if (MS.TrackOrigins) {
2928 if (PropagateShadow)
2929 setOrigin(&I, IRB.CreateLoad(MS.OriginTy, OriginPtr));
2930 else
2931 setOrigin(&I, getCleanOrigin());
2932 }
2933 return true;
2934 }
2935
2936 /// Handle (SIMD arithmetic)-like intrinsics.
2937 ///
2938 /// Instrument intrinsics with any number of arguments of the same type,
2939 /// equal to the return type. The type should be simple (no aggregates or
2940 /// pointers; vectors are fine).
2941 /// Caller guarantees that this intrinsic does not access memory.
2942 bool maybeHandleSimpleNomemIntrinsic(IntrinsicInst &I) {
2943 Type *RetTy = I.getType();
2944 if (!(RetTy->isIntOrIntVectorTy() || RetTy->isFPOrFPVectorTy() ||
2945 RetTy->isX86_MMXTy()))
2946 return false;
2947
2948 unsigned NumArgOperands = I.arg_size();
2949 for (unsigned i = 0; i < NumArgOperands; ++i) {
2950 Type *Ty = I.getArgOperand(i)->getType();
2951 if (Ty != RetTy)
2952 return false;
2953 }
2954
2955 IRBuilder<> IRB(&I);
2956 ShadowAndOriginCombiner SC(this, IRB);
2957 for (unsigned i = 0; i < NumArgOperands; ++i)
2958 SC.Add(I.getArgOperand(i));
2959 SC.Done(&I);
2960
2961 return true;
2962 }
2963
2964 /// Heuristically instrument unknown intrinsics.
2965 ///
2966 /// The main purpose of this code is to do something reasonable with all
2967 /// random intrinsics we might encounter, most importantly - SIMD intrinsics.
2968 /// We recognize several classes of intrinsics by their argument types and
2969 /// ModRefBehaviour and apply special instrumentation when we are reasonably
2970 /// sure that we know what the intrinsic does.
2971 ///
2972 /// We special-case intrinsics where this approach fails. See llvm.bswap
2973 /// handling as an example of that.
2974 bool handleUnknownIntrinsic(IntrinsicInst &I) {
2975 unsigned NumArgOperands = I.arg_size();
2976 if (NumArgOperands == 0)
2977 return false;
2978
2979 if (NumArgOperands == 2 && I.getArgOperand(0)->getType()->isPointerTy() &&
2980 I.getArgOperand(1)->getType()->isVectorTy() &&
2981 I.getType()->isVoidTy() && !I.onlyReadsMemory()) {
2982 // This looks like a vector store.
2983 return handleVectorStoreIntrinsic(I);
2984 }
2985
2986 if (NumArgOperands == 1 && I.getArgOperand(0)->getType()->isPointerTy() &&
2987 I.getType()->isVectorTy() && I.onlyReadsMemory()) {
2988 // This looks like a vector load.
2989 return handleVectorLoadIntrinsic(I);
2990 }
2991
2992 if (I.doesNotAccessMemory())
2993 if (maybeHandleSimpleNomemIntrinsic(I))
2994 return true;
2995
2996 // FIXME: detect and handle SSE maskstore/maskload
2997 return false;
2998 }
2999
3000 void handleInvariantGroup(IntrinsicInst &I) {
3001 setShadow(&I, getShadow(&I, 0));
3002 setOrigin(&I, getOrigin(&I, 0));
3003 }
3004
3005 void handleLifetimeStart(IntrinsicInst &I) {
3006 if (!PoisonStack)
3007 return;
3008 AllocaInst *AI = llvm::findAllocaForValue(I.getArgOperand(1));
3009 if (!AI)
3010 InstrumentLifetimeStart = false;
3011 LifetimeStartList.push_back(std::make_pair(&I, AI));
3012 }
3013
3014 void handleBswap(IntrinsicInst &I) {
3015 IRBuilder<> IRB(&I);
3016 Value *Op = I.getArgOperand(0);
3017 Type *OpType = Op->getType();
3019 F.getParent(), Intrinsic::bswap, ArrayRef(&OpType, 1));
3020 setShadow(&I, IRB.CreateCall(BswapFunc, getShadow(Op)));
3021 setOrigin(&I, getOrigin(Op));
3022 }
3023
3024 void handleCountZeroes(IntrinsicInst &I) {
3025 IRBuilder<> IRB(&I);
3026 Value *Src = I.getArgOperand(0);
3027
3028 // Set the Output shadow based on input Shadow
3029 Value *BoolShadow = IRB.CreateIsNotNull(getShadow(Src), "_mscz_bs");
3030
3031 // If zero poison is requested, mix in with the shadow
3032 Constant *IsZeroPoison = cast<Constant>(I.getOperand(1));
3033 if (!IsZeroPoison->isZeroValue()) {
3034 Value *BoolZeroPoison = IRB.CreateIsNull(Src, "_mscz_bzp");
3035 BoolShadow = IRB.CreateOr(BoolShadow, BoolZeroPoison, "_mscz_bs");
3036 }
3037
3038 Value *OutputShadow =
3039 IRB.CreateSExt(BoolShadow, getShadowTy(Src), "_mscz_os");
3040
3041 setShadow(&I, OutputShadow);
3042 setOriginForNaryOp(I);
3043 }
3044
3045 // Instrument vector convert intrinsic.
3046 //
3047 // This function instruments intrinsics like cvtsi2ss:
3048 // %Out = int_xxx_cvtyyy(%ConvertOp)
3049 // or
3050 // %Out = int_xxx_cvtyyy(%CopyOp, %ConvertOp)
3051 // Intrinsic converts \p NumUsedElements elements of \p ConvertOp to the same
3052 // number \p Out elements, and (if has 2 arguments) copies the rest of the
3053 // elements from \p CopyOp.
3054 // In most cases conversion involves floating-point value which may trigger a
3055 // hardware exception when not fully initialized. For this reason we require
3056 // \p ConvertOp[0:NumUsedElements] to be fully initialized and trap otherwise.
3057 // We copy the shadow of \p CopyOp[NumUsedElements:] to \p
3058 // Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always
3059 // return a fully initialized value.
3060 void handleVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements,
3061 bool HasRoundingMode = false) {
3062 IRBuilder<> IRB(&I);
3063 Value *CopyOp, *ConvertOp;
3064
3065 assert((!HasRoundingMode ||
3066 isa<ConstantInt>(I.getArgOperand(I.arg_size() - 1))) &&
3067 "Invalid rounding mode");
3068
3069 switch (I.arg_size() - HasRoundingMode) {
3070 case 2:
3071 CopyOp = I.getArgOperand(0);
3072 ConvertOp = I.getArgOperand(1);
3073 break;
3074 case 1:
3075 ConvertOp = I.getArgOperand(0);
3076 CopyOp = nullptr;
3077 break;
3078 default:
3079 llvm_unreachable("Cvt intrinsic with unsupported number of arguments.");
3080 }
3081
3082 // The first *NumUsedElements* elements of ConvertOp are converted to the
3083 // same number of output elements. The rest of the output is copied from
3084 // CopyOp, or (if not available) filled with zeroes.
3085 // Combine shadow for elements of ConvertOp that are used in this operation,
3086 // and insert a check.
3087 // FIXME: consider propagating shadow of ConvertOp, at least in the case of
3088 // int->any conversion.
3089 Value *ConvertShadow = getShadow(ConvertOp);
3090 Value *AggShadow = nullptr;
3091 if (ConvertOp->getType()->isVectorTy()) {
3092 AggShadow = IRB.CreateExtractElement(
3093 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), 0));
3094 for (int i = 1; i < NumUsedElements; ++i) {
3095 Value *MoreShadow = IRB.CreateExtractElement(
3096 ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), i));
3097 AggShadow = IRB.CreateOr(AggShadow, MoreShadow);
3098 }
3099 } else {
3100 AggShadow = ConvertShadow;
3101 }
3102 assert(AggShadow->getType()->isIntegerTy());
3103 insertShadowCheck(AggShadow, getOrigin(ConvertOp), &I);
3104
3105 // Build result shadow by zero-filling parts of CopyOp shadow that come from
3106 // ConvertOp.
3107 if (CopyOp) {
3108 assert(CopyOp->getType() == I.getType());
3109 assert(CopyOp->getType()->isVectorTy());
3110 Value *ResultShadow = getShadow(CopyOp);
3111 Type *EltTy = cast<VectorType>(ResultShadow->getType())->getElementType();
3112 for (int i = 0; i < NumUsedElements; ++i) {
3113 ResultShadow = IRB.CreateInsertElement(
3114 ResultShadow, ConstantInt::getNullValue(EltTy),
3115 ConstantInt::get(IRB.getInt32Ty(), i));
3116 }
3117 setShadow(&I, ResultShadow);
3118 setOrigin(&I, getOrigin(CopyOp));
3119 } else {
3120 setShadow(&I, getCleanShadow(&I));
3121 setOrigin(&I, getCleanOrigin());
3122 }
3123 }
3124
3125 // Given a scalar or vector, extract lower 64 bits (or less), and return all
3126 // zeroes if it is zero, and all ones otherwise.
3127 Value *Lower64ShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
3128 if (S->getType()->isVectorTy())
3129 S = CreateShadowCast(IRB, S, IRB.getInt64Ty(), /* Signed */ true);
3130 assert(S->getType()->getPrimitiveSizeInBits() <= 64);
3131 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
3132 return CreateShadowCast(IRB, S2, T, /* Signed */ true);
3133 }
3134
3135 // Given a vector, extract its first element, and return all
3136 // zeroes if it is zero, and all ones otherwise.
3137 Value *LowerElementShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
3138 Value *S1 = IRB.CreateExtractElement(S, (uint64_t)0);
3139 Value *S2 = IRB.CreateICmpNE(S1, getCleanShadow(S1));
3140 return CreateShadowCast(IRB, S2, T, /* Signed */ true);
3141 }
3142
3143 Value *VariableShadowExtend(IRBuilder<> &IRB, Value *S) {
3144 Type *T = S->getType();
3145 assert(T->isVectorTy());
3146 Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
3147 return IRB.CreateSExt(S2, T);
3148 }
3149
3150 // Instrument vector shift intrinsic.
3151 //
3152 // This function instruments intrinsics like int_x86_avx2_psll_w.
3153 // Intrinsic shifts %In by %ShiftSize bits.
3154 // %ShiftSize may be a vector. In that case the lower 64 bits determine shift
3155 // size, and the rest is ignored. Behavior is defined even if shift size is
3156 // greater than register (or field) width.
3157 void handleVectorShiftIntrinsic(IntrinsicInst &I, bool Variable) {
3158 assert(I.arg_size() == 2);
3159 IRBuilder<> IRB(&I);
3160 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3161 // Otherwise perform the same shift on S1.
3162 Value *S1 = getShadow(&I, 0);
3163 Value *S2 = getShadow(&I, 1);
3164 Value *S2Conv = Variable ? VariableShadowExtend(IRB, S2)
3165 : Lower64ShadowExtend(IRB, S2, getShadowTy(&I));
3166 Value *V1 = I.getOperand(0);
3167 Value *V2 = I.getOperand(1);
3168 Value *Shift = IRB.CreateCall(I.getFunctionType(), I.getCalledOperand(),
3169 {IRB.CreateBitCast(S1, V1->getType()), V2});
3170 Shift = IRB.CreateBitCast(Shift, getShadowTy(&I));
3171 setShadow(&I, IRB.CreateOr(Shift, S2Conv));
3172 setOriginForNaryOp(I);
3173 }
3174
3175 // Get an X86_MMX-sized vector type.
3176 Type *getMMXVectorTy(unsigned EltSizeInBits) {
3177 const unsigned X86_MMXSizeInBits = 64;
3178 assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
3179 "Illegal MMX vector element size");
3180 return FixedVectorType::get(IntegerType::get(*MS.C, EltSizeInBits),
3181 X86_MMXSizeInBits / EltSizeInBits);
3182 }
3183
3184 // Returns a signed counterpart for an (un)signed-saturate-and-pack
3185 // intrinsic.
3186 Intrinsic::ID getSignedPackIntrinsic(Intrinsic::ID id) {
3187 switch (id) {
3188 case Intrinsic::x86_sse2_packsswb_128:
3189 case Intrinsic::x86_sse2_packuswb_128:
3190 return Intrinsic::x86_sse2_packsswb_128;
3191
3192 case Intrinsic::x86_sse2_packssdw_128:
3193 case Intrinsic::x86_sse41_packusdw:
3194 return Intrinsic::x86_sse2_packssdw_128;
3195
3196 case Intrinsic::x86_avx2_packsswb:
3197 case Intrinsic::x86_avx2_packuswb:
3198 return Intrinsic::x86_avx2_packsswb;
3199
3200 case Intrinsic::x86_avx2_packssdw:
3201 case Intrinsic::x86_avx2_packusdw:
3202 return Intrinsic::x86_avx2_packssdw;
3203
3204 case Intrinsic::x86_mmx_packsswb:
3205 case Intrinsic::x86_mmx_packuswb:
3206 return Intrinsic::x86_mmx_packsswb;
3207
3208 case Intrinsic::x86_mmx_packssdw:
3209 return Intrinsic::x86_mmx_packssdw;
3210 default:
3211 llvm_unreachable("unexpected intrinsic id");
3212 }
3213 }
3214
3215 // Instrument vector pack intrinsic.
3216 //
3217 // This function instruments intrinsics like x86_mmx_packsswb, that
3218 // packs elements of 2 input vectors into half as many bits with saturation.
3219 // Shadow is propagated with the signed variant of the same intrinsic applied
3220 // to sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
3221 // EltSizeInBits is used only for x86mmx arguments.
3222 void handleVectorPackIntrinsic(IntrinsicInst &I, unsigned EltSizeInBits = 0) {
3223 assert(I.arg_size() == 2);
3224 bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy();
3225 IRBuilder<> IRB(&I);
3226 Value *S1 = getShadow(&I, 0);
3227 Value *S2 = getShadow(&I, 1);
3228 assert(isX86_MMX || S1->getType()->isVectorTy());
3229
3230 // SExt and ICmpNE below must apply to individual elements of input vectors.
3231 // In case of x86mmx arguments, cast them to appropriate vector types and
3232 // back.
3233 Type *T = isX86_MMX ? getMMXVectorTy(EltSizeInBits) : S1->getType();
3234 if (isX86_MMX) {
3235 S1 = IRB.CreateBitCast(S1, T);
3236 S2 = IRB.CreateBitCast(S2, T);
3237 }
3238 Value *S1_ext =
3240 Value *S2_ext =
3242 if (isX86_MMX) {
3243 Type *X86_MMXTy = Type::getX86_MMXTy(*MS.C);
3244 S1_ext = IRB.CreateBitCast(S1_ext, X86_MMXTy);
3245 S2_ext = IRB.CreateBitCast(S2_ext, X86_MMXTy);
3246 }
3247
3249 F.getParent(), getSignedPackIntrinsic(I.getIntrinsicID()));
3250
3251 Value *S =
3252 IRB.CreateCall(ShadowFn, {S1_ext, S2_ext}, "_msprop_vector_pack");
3253 if (isX86_MMX)
3254 S = IRB.CreateBitCast(S, getShadowTy(&I));
3255 setShadow(&I, S);
3256 setOriginForNaryOp(I);
3257 }
3258
3259 // Instrument sum-of-absolute-differences intrinsic.
3260 void handleVectorSadIntrinsic(IntrinsicInst &I) {
3261 const unsigned SignificantBitsPerResultElement = 16;
3262 bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy();
3263 Type *ResTy = isX86_MMX ? IntegerType::get(*MS.C, 64) : I.getType();
3264 unsigned ZeroBitsPerResultElement =
3265 ResTy->getScalarSizeInBits() - SignificantBitsPerResultElement;
3266
3267 IRBuilder<> IRB(&I);
3268 auto *Shadow0 = getShadow(&I, 0);
3269 auto *Shadow1 = getShadow(&I, 1);
3270 Value *S = IRB.CreateOr(Shadow0, Shadow1);
3271 S = IRB.CreateBitCast(S, ResTy);
3272 S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)),
3273 ResTy);
3274 S = IRB.CreateLShr(S, ZeroBitsPerResultElement);
3275 S = IRB.CreateBitCast(S, getShadowTy(&I));
3276 setShadow(&I, S);
3277 setOriginForNaryOp(I);
3278 }
3279
3280 // Instrument multiply-add intrinsic.
3281 void handleVectorPmaddIntrinsic(IntrinsicInst &I,
3282 unsigned EltSizeInBits = 0) {
3283 bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy();
3284 Type *ResTy = isX86_MMX ? getMMXVectorTy(EltSizeInBits * 2) : I.getType();
3285 IRBuilder<> IRB(&I);
3286 auto *Shadow0 = getShadow(&I, 0);
3287 auto *Shadow1 = getShadow(&I, 1);
3288 Value *S = IRB.CreateOr(Shadow0, Shadow1);
3289 S = IRB.CreateBitCast(S, ResTy);
3290 S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)),
3291 ResTy);
3292 S = IRB.CreateBitCast(S, getShadowTy(&I));
3293 setShadow(&I, S);
3294 setOriginForNaryOp(I);
3295 }
3296
3297 // Instrument compare-packed intrinsic.
3298 // Basically, an or followed by sext(icmp ne 0) to end up with all-zeros or
3299 // all-ones shadow.
3300 void handleVectorComparePackedIntrinsic(IntrinsicInst &I) {
3301 IRBuilder<> IRB(&I);
3302 Type *ResTy = getShadowTy(&I);
3303 auto *Shadow0 = getShadow(&I, 0);
3304 auto *Shadow1 = getShadow(&I, 1);
3305 Value *S0 = IRB.CreateOr(Shadow0, Shadow1);
3306 Value *S = IRB.CreateSExt(
3307 IRB.CreateICmpNE(S0, Constant::getNullValue(ResTy)), ResTy);
3308 setShadow(&I, S);
3309 setOriginForNaryOp(I);
3310 }
3311
3312 // Instrument compare-scalar intrinsic.
3313 // This handles both cmp* intrinsics which return the result in the first
3314 // element of a vector, and comi* which return the result as i32.
3315 void handleVectorCompareScalarIntrinsic(IntrinsicInst &I) {
3316 IRBuilder<> IRB(&I);
3317 auto *Shadow0 = getShadow(&I, 0);
3318 auto *Shadow1 = getShadow(&I, 1);
3319 Value *S0 = IRB.CreateOr(Shadow0, Shadow1);
3320 Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&I));
3321 setShadow(&I, S);
3322 setOriginForNaryOp(I);
3323 }
3324
3325 // Instrument generic vector reduction intrinsics
3326 // by ORing together all their fields.
3327 void handleVectorReduceIntrinsic(IntrinsicInst &I) {
3328 IRBuilder<> IRB(&I);
3329 Value *S = IRB.CreateOrReduce(getShadow(&I, 0));
3330 setShadow(&I, S);
3331 setOrigin(&I, getOrigin(&I, 0));
3332 }
3333
3334 // Instrument vector.reduce.or intrinsic.
3335 // Valid (non-poisoned) set bits in the operand pull low the
3336 // corresponding shadow bits.
3337 void handleVectorReduceOrIntrinsic(IntrinsicInst &I) {
3338 IRBuilder<> IRB(&I);
3339 Value *OperandShadow = getShadow(&I, 0);
3340 Value *OperandUnsetBits = IRB.CreateNot(I.getOperand(0));
3341 Value *OperandUnsetOrPoison = IRB.CreateOr(OperandUnsetBits, OperandShadow);
3342 // Bit N is clean if any field's bit N is 1 and unpoison
3343 Value *OutShadowMask = IRB.CreateAndReduce(OperandUnsetOrPoison);
3344 // Otherwise, it is clean if every field's bit N is unpoison
3345 Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
3346 Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
3347
3348 setShadow(&I, S);
3349 setOrigin(&I, getOrigin(&I, 0));
3350 }
3351
3352 // Instrument vector.reduce.and intrinsic.
3353 // Valid (non-poisoned) unset bits in the operand pull down the
3354 // corresponding shadow bits.
3355 void handleVectorReduceAndIntrinsic(IntrinsicInst &I) {
3356 IRBuilder<> IRB(&I);
3357 Value *OperandShadow = getShadow(&I, 0);
3358 Value *OperandSetOrPoison = IRB.CreateOr(I.getOperand(0), OperandShadow);
3359 // Bit N is clean if any field's bit N is 0 and unpoison
3360 Value *OutShadowMask = IRB.CreateAndReduce(OperandSetOrPoison);
3361 // Otherwise, it is clean if every field's bit N is unpoison
3362 Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
3363 Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
3364
3365 setShadow(&I, S);
3366 setOrigin(&I, getOrigin(&I, 0));
3367 }
3368
3369 void handleStmxcsr(IntrinsicInst &I) {
3370 IRBuilder<> IRB(&I);
3371 Value *Addr = I.getArgOperand(0);
3372 Type *Ty = IRB.getInt32Ty();
3373 Value *ShadowPtr =
3374 getShadowOriginPtr(Addr, IRB, Ty, Align(1), /*isStore*/ true).first;
3375
3376 IRB.CreateStore(getCleanShadow(Ty), ShadowPtr);
3377
3379 insertShadowCheck(Addr, &I);
3380 }
3381
3382 void handleLdmxcsr(IntrinsicInst &I) {
3383 if (!InsertChecks)
3384 return;
3385
3386 IRBuilder<> IRB(&I);
3387 Value *Addr = I.getArgOperand(0);
3388 Type *Ty = IRB.getInt32Ty();
3389 const Align Alignment = Align(1);
3390 Value *ShadowPtr, *OriginPtr;
3391 std::tie(ShadowPtr, OriginPtr) =
3392 getShadowOriginPtr(Addr, IRB, Ty, Alignment, /*isStore*/ false);
3393
3395 insertShadowCheck(Addr, &I);
3396
3397 Value *Shadow = IRB.CreateAlignedLoad(Ty, ShadowPtr, Alignment, "_ldmxcsr");
3398 Value *Origin = MS.TrackOrigins ? IRB.CreateLoad(MS.OriginTy, OriginPtr)
3399 : getCleanOrigin();
3400 insertShadowCheck(Shadow, Origin, &I);
3401 }
3402
3403 void handleMaskedExpandLoad(IntrinsicInst &I) {
3404 IRBuilder<> IRB(&I);
3405 Value *Ptr = I.getArgOperand(0);
3406 Value *Mask = I.getArgOperand(1);
3407 Value *PassThru = I.getArgOperand(2);
3408
3410 insertShadowCheck(Ptr, &I);
3411 insertShadowCheck(Mask, &I);
3412 }
3413
3414 if (!PropagateShadow) {
3415 setShadow(&I, getCleanShadow(&I));
3416 setOrigin(&I, getCleanOrigin());
3417 return;
3418 }
3419
3420 Type *ShadowTy = getShadowTy(&I);
3421 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
3422 auto [ShadowPtr, OriginPtr] =
3423 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, {}, /*isStore*/ false);
3424
3425 Value *Shadow = IRB.CreateMaskedExpandLoad(
3426 ShadowTy, ShadowPtr, Mask, getShadow(PassThru), "_msmaskedexpload");
3427
3428 setShadow(&I, Shadow);
3429
3430 // TODO: Store origins.
3431 setOrigin(&I, getCleanOrigin());
3432 }
3433
3434 void handleMaskedCompressStore(IntrinsicInst &I) {
3435 IRBuilder<> IRB(&I);
3436 Value *Values = I.getArgOperand(0);
3437 Value *Ptr = I.getArgOperand(1);
3438 Value *Mask = I.getArgOperand(2);
3439
3441 insertShadowCheck(Ptr, &I);
3442 insertShadowCheck(Mask, &I);
3443 }
3444
3445 Value *Shadow = getShadow(Values);
3446 Type *ElementShadowTy =
3447 getShadowTy(cast<VectorType>(Values->getType())->getElementType());
3448 auto [ShadowPtr, OriginPtrs] =
3449 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, {}, /*isStore*/ true);
3450
3451 IRB.CreateMaskedCompressStore(Shadow, ShadowPtr, Mask);
3452
3453 // TODO: Store origins.
3454 }
3455
3456 void handleMaskedGather(IntrinsicInst &I) {
3457 IRBuilder<> IRB(&I);
3458 Value *Ptrs = I.getArgOperand(0);
3459 const Align Alignment(
3460 cast<ConstantInt>(I.getArgOperand(1))->getZExtValue());
3461 Value *Mask = I.getArgOperand(2);
3462 Value *PassThru = I.getArgOperand(3);
3463
3464 Type *PtrsShadowTy = getShadowTy(Ptrs);
3466 insertShadowCheck(Mask, &I);
3467 Value *MaskedPtrShadow = IRB.CreateSelect(
3468 Mask, getShadow(Ptrs), Constant::getNullValue((PtrsShadowTy)),
3469 "_msmaskedptrs");
3470 insertShadowCheck(MaskedPtrShadow, getOrigin(Ptrs), &I);
3471 }
3472
3473 if (!PropagateShadow) {
3474 setShadow(&I, getCleanShadow(&I));
3475 setOrigin(&I, getCleanOrigin());
3476 return;
3477 }
3478
3479 Type *ShadowTy = getShadowTy(&I);
3480 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
3481 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
3482 Ptrs, IRB, ElementShadowTy, Alignment, /*isStore*/ false);
3483
3484 Value *Shadow =
3485 IRB.CreateMaskedGather(ShadowTy, ShadowPtrs, Alignment, Mask,
3486 getShadow(PassThru), "_msmaskedgather");
3487
3488 setShadow(&I, Shadow);
3489
3490 // TODO: Store origins.
3491 setOrigin(&I, getCleanOrigin());
3492 }
3493
3494 void handleMaskedScatter(IntrinsicInst &I) {
3495 IRBuilder<> IRB(&I);
3496 Value *Values = I.getArgOperand(0);
3497 Value *Ptrs = I.getArgOperand(1);
3498 const Align Alignment(
3499 cast<ConstantInt>(I.getArgOperand(2))->getZExtValue());
3500 Value *Mask = I.getArgOperand(3);
3501
3502 Type *PtrsShadowTy = getShadowTy(Ptrs);
3504 insertShadowCheck(Mask, &I);
3505 Value *MaskedPtrShadow = IRB.CreateSelect(
3506 Mask, getShadow(Ptrs), Constant::getNullValue((PtrsShadowTy)),
3507 "_msmaskedptrs");
3508 insertShadowCheck(MaskedPtrShadow, getOrigin(Ptrs), &I);
3509 }
3510
3511 Value *Shadow = getShadow(Values);
3512 Type *ElementShadowTy =
3513 getShadowTy(cast<VectorType>(Values->getType())->getElementType());
3514 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
3515 Ptrs, IRB, ElementShadowTy, Alignment, /*isStore*/ true);
3516
3517 IRB.CreateMaskedScatter(Shadow, ShadowPtrs, Alignment, Mask);
3518
3519 // TODO: Store origin.
3520 }
3521
3522 void handleMaskedStore(IntrinsicInst &I) {
3523 IRBuilder<> IRB(&I);
3524 Value *V = I.getArgOperand(0);
3525 Value *Ptr = I.getArgOperand(1);
3526 const Align Alignment(
3527 cast<ConstantInt>(I.getArgOperand(2))->getZExtValue());
3528 Value *Mask = I.getArgOperand(3);
3529 Value *Shadow = getShadow(V);
3530
3532 insertShadowCheck(Ptr, &I);
3533 insertShadowCheck(Mask, &I);
3534 }
3535
3536 Value *ShadowPtr;
3537 Value *OriginPtr;
3538 std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3539 Ptr, IRB, Shadow->getType(), Alignment, /*isStore*/ true);
3540
3541 IRB.CreateMaskedStore(Shadow, ShadowPtr, Alignment, Mask);
3542
3543 if (!MS.TrackOrigins)
3544 return;
3545
3546 auto &DL = F.getParent()->getDataLayout();
3547 paintOrigin(IRB, getOrigin(V), OriginPtr,
3548 DL.getTypeStoreSize(Shadow->getType()),
3549 std::max(Alignment, kMinOriginAlignment));
3550 }
3551
3552 void handleMaskedLoad(IntrinsicInst &I) {
3553 IRBuilder<> IRB(&I);
3554 Value *Ptr = I.getArgOperand(0);
3555 const Align Alignment(
3556 cast<ConstantInt>(I.getArgOperand(1))->getZExtValue());
3557 Value *Mask = I.getArgOperand(2);
3558 Value *PassThru = I.getArgOperand(3);
3559
3561 insertShadowCheck(Ptr, &I);
3562 insertShadowCheck(Mask, &I);
3563 }
3564
3565 if (!PropagateShadow) {
3566 setShadow(&I, getCleanShadow(&I));
3567 setOrigin(&I, getCleanOrigin());
3568 return;
3569 }
3570
3571 Type *ShadowTy = getShadowTy(&I);
3572 Value *ShadowPtr, *OriginPtr;
3573 std::tie(ShadowPtr, OriginPtr) =
3574 getShadowOriginPtr(Ptr, IRB, ShadowTy, Alignment, /*isStore*/ false);
3575 setShadow(&I, IRB.CreateMaskedLoad(ShadowTy, ShadowPtr, Alignment, Mask,
3576 getShadow(PassThru), "_msmaskedld"));
3577
3578 if (!MS.TrackOrigins)
3579 return;
3580
3581 // Choose between PassThru's and the loaded value's origins.
3582 Value *MaskedPassThruShadow = IRB.CreateAnd(
3583 getShadow(PassThru), IRB.CreateSExt(IRB.CreateNeg(Mask), ShadowTy));
3584
3585 Value *NotNull = convertToBool(MaskedPassThruShadow, IRB, "_mscmp");
3586
3587 Value *PtrOrigin = IRB.CreateLoad(MS.OriginTy, OriginPtr);
3588 Value *Origin = IRB.CreateSelect(NotNull, getOrigin(PassThru), PtrOrigin);
3589
3590 setOrigin(&I, Origin);
3591 }
3592
3593 // Instrument BMI / BMI2 intrinsics.
3594 // All of these intrinsics are Z = I(X, Y)
3595 // where the types of all operands and the result match, and are either i32 or
3596 // i64. The following instrumentation happens to work for all of them:
3597 // Sz = I(Sx, Y) | (sext (Sy != 0))
3598 void handleBmiIntrinsic(IntrinsicInst &I) {
3599 IRBuilder<> IRB(&I);
3600 Type *ShadowTy = getShadowTy(&I);
3601
3602 // If any bit of the mask operand is poisoned, then the whole thing is.
3603 Value *SMask = getShadow(&I, 1);
3604 SMask = IRB.CreateSExt(IRB.CreateICmpNE(SMask, getCleanShadow(ShadowTy)),
3605 ShadowTy);
3606 // Apply the same intrinsic to the shadow of the first operand.
3607 Value *S = IRB.CreateCall(I.getCalledFunction(),
3608 {getShadow(&I, 0), I.getOperand(1)});
3609 S = IRB.CreateOr(SMask, S);
3610 setShadow(&I, S);
3611 setOriginForNaryOp(I);
3612 }
3613
3614 SmallVector<int, 8> getPclmulMask(unsigned Width, bool OddElements) {
3616 for (unsigned X = OddElements ? 1 : 0; X < Width; X += 2) {
3617 Mask.append(2, X);
3618 }
3619 return Mask;
3620 }
3621
3622 // Instrument pclmul intrinsics.
3623 // These intrinsics operate either on odd or on even elements of the input
3624 // vectors, depending on the constant in the 3rd argument, ignoring the rest.
3625 // Replace the unused elements with copies of the used ones, ex:
3626 // (0, 1, 2, 3) -> (0, 0, 2, 2) (even case)
3627 // or
3628 // (0, 1, 2, 3) -> (1, 1, 3, 3) (odd case)
3629 // and then apply the usual shadow combining logic.
3630 void handlePclmulIntrinsic(IntrinsicInst &I) {
3631 IRBuilder<> IRB(&I);
3632 unsigned Width =
3633 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
3634 assert(isa<ConstantInt>(I.getArgOperand(2)) &&
3635 "pclmul 3rd operand must be a constant");
3636 unsigned Imm = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
3637 Value *Shuf0 = IRB.CreateShuffleVector(getShadow(&I, 0),
3638 getPclmulMask(Width, Imm & 0x01));
3639 Value *Shuf1 = IRB.CreateShuffleVector(getShadow(&I, 1),
3640 getPclmulMask(Width, Imm & 0x10));
3641 ShadowAndOriginCombiner SOC(this, IRB);
3642 SOC.Add(Shuf0, getOrigin(&I, 0));
3643 SOC.Add(Shuf1, getOrigin(&I, 1));
3644 SOC.Done(&I);
3645 }
3646
3647 // Instrument _mm_*_sd|ss intrinsics
3648 void handleUnarySdSsIntrinsic(IntrinsicInst &I) {
3649 IRBuilder<> IRB(&I);
3650 unsigned Width =
3651 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
3652 Value *First = getShadow(&I, 0);
3653 Value *Second = getShadow(&I, 1);
3654 // First element of second operand, remaining elements of first operand
3656 Mask.push_back(Width);
3657 for (unsigned i = 1; i < Width; i++)
3658 Mask.push_back(i);
3659 Value *Shadow = IRB.CreateShuffleVector(First, Second, Mask);
3660
3661 setShadow(&I, Shadow);
3662 setOriginForNaryOp(I);
3663 }
3664
3665 void handleVtestIntrinsic(IntrinsicInst &I) {
3666 IRBuilder<> IRB(&I);
3667 Value *Shadow0 = getShadow(&I, 0);
3668 Value *Shadow1 = getShadow(&I, 1);
3669 Value *Or = IRB.CreateOr(Shadow0, Shadow1);
3670 Value *NZ = IRB.CreateICmpNE(Or, Constant::getNullValue(Or->getType()));
3671 Value *Scalar = convertShadowToScalar(NZ, IRB);
3672 Value *Shadow = IRB.CreateZExt(Scalar, getShadowTy(&I));
3673
3674 setShadow(&I, Shadow);
3675 setOriginForNaryOp(I);
3676 }
3677
3678 void handleBinarySdSsIntrinsic(IntrinsicInst &I) {
3679 IRBuilder<> IRB(&I);
3680 unsigned Width =
3681 cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
3682 Value *First = getShadow(&I, 0);
3683 Value *Second = getShadow(&I, 1);
3684 Value *OrShadow = IRB.CreateOr(First, Second);
3685 // First element of both OR'd together, remaining elements of first operand
3687 Mask.push_back(Width);
3688 for (unsigned i = 1; i < Width; i++)
3689 Mask.push_back(i);
3690 Value *Shadow = IRB.CreateShuffleVector(First, OrShadow, Mask);
3691
3692 setShadow(&I, Shadow);
3693 setOriginForNaryOp(I);
3694 }
3695
3696 // Instrument abs intrinsic.
3697 // handleUnknownIntrinsic can't handle it because of the last
3698 // is_int_min_poison argument which does not match the result type.
3699 void handleAbsIntrinsic(IntrinsicInst &I) {
3700 assert(I.getType()->isIntOrIntVectorTy());
3701 assert(I.getArgOperand(0)->getType() == I.getType());
3702
3703 // FIXME: Handle is_int_min_poison.
3704 IRBuilder<> IRB(&I);
3705 setShadow(&I, getShadow(&I, 0));
3706 setOrigin(&I, getOrigin(&I, 0));
3707 }
3708
3709 void handleIsFpClass(IntrinsicInst &I) {
3710 IRBuilder<> IRB(&I);
3711 Value *Shadow = getShadow(&I, 0);
3712 setShadow(&I, IRB.CreateICmpNE(Shadow, getCleanShadow(Shadow)));
3713 setOrigin(&I, getOrigin(&I, 0));
3714 }
3715
3716 void handleArithmeticWithOverflow(IntrinsicInst &I) {
3717 IRBuilder<> IRB(&I);
3718 Value *Shadow0 = getShadow(&I, 0);
3719 Value *Shadow1 = getShadow(&I, 1);
3720 Value *ShadowElt0 = IRB.CreateOr(Shadow0, Shadow1);
3721 Value *ShadowElt1 =
3722 IRB.CreateICmpNE(ShadowElt0, getCleanShadow(ShadowElt0));
3723
3724 Value *Shadow = PoisonValue::get(getShadowTy(&I));
3725 Shadow = IRB.CreateInsertValue(Shadow, ShadowElt0, 0);
3726 Shadow = IRB.CreateInsertValue(Shadow, ShadowElt1, 1);
3727
3728 setShadow(&I, Shadow);
3729 setOriginForNaryOp(I);
3730 }
3731
3732 void visitIntrinsicInst(IntrinsicInst &I) {
3733 switch (I.getIntrinsicID()) {
3734 case Intrinsic::uadd_with_overflow:
3735 case Intrinsic::sadd_with_overflow:
3736 case Intrinsic::usub_with_overflow:
3737 case Intrinsic::ssub_with_overflow:
3738 case Intrinsic::umul_with_overflow:
3739 case Intrinsic::smul_with_overflow:
3740 handleArithmeticWithOverflow(I);
3741 break;
3742 case Intrinsic::abs:
3743 handleAbsIntrinsic(I);
3744 break;
3745 case Intrinsic::is_fpclass:
3746 handleIsFpClass(I);
3747 break;
3748 case Intrinsic::lifetime_start:
3749 handleLifetimeStart(I);
3750 break;
3751 case Intrinsic::launder_invariant_group:
3752 case Intrinsic::strip_invariant_group:
3753 handleInvariantGroup(I);
3754 break;
3755 case Intrinsic::bswap:
3756 handleBswap(I);
3757 break;
3758 case Intrinsic::ctlz:
3759 case Intrinsic::cttz:
3760 handleCountZeroes(I);
3761 break;
3762 case Intrinsic::masked_compressstore:
3763 handleMaskedCompressStore(I);
3764 break;
3765 case Intrinsic::masked_expandload:
3766 handleMaskedExpandLoad(I);
3767 break;
3768 case Intrinsic::masked_gather:
3769 handleMaskedGather(I);
3770 break;
3771 case Intrinsic::masked_scatter:
3772 handleMaskedScatter(I);
3773 break;
3774 case Intrinsic::masked_store:
3775 handleMaskedStore(I);
3776 break;
3777 case Intrinsic::masked_load:
3778 handleMaskedLoad(I);
3779 break;
3780 case Intrinsic::vector_reduce_and:
3781 handleVectorReduceAndIntrinsic(I);
3782 break;
3783 case Intrinsic::vector_reduce_or:
3784 handleVectorReduceOrIntrinsic(I);
3785 break;
3786 case Intrinsic::vector_reduce_add:
3787 case Intrinsic::vector_reduce_xor:
3788 case Intrinsic::vector_reduce_mul:
3789 handleVectorReduceIntrinsic(I);
3790 break;
3791 case Intrinsic::x86_sse_stmxcsr:
3792 handleStmxcsr(I);
3793 break;
3794 case Intrinsic::x86_sse_ldmxcsr:
3795 handleLdmxcsr(I);
3796 break;
3797 case Intrinsic::x86_avx512_vcvtsd2usi64:
3798 case Intrinsic::x86_avx512_vcvtsd2usi32:
3799 case Intrinsic::x86_avx512_vcvtss2usi64:
3800 case Intrinsic::x86_avx512_vcvtss2usi32:
3801 case Intrinsic::x86_avx512_cvttss2usi64:
3802 case Intrinsic::x86_avx512_cvttss2usi:
3803 case Intrinsic::x86_avx512_cvttsd2usi64:
3804 case Intrinsic::x86_avx512_cvttsd2usi:
3805 case Intrinsic::x86_avx512_cvtusi2ss:
3806 case Intrinsic::x86_avx512_cvtusi642sd:
3807 case Intrinsic::x86_avx512_cvtusi642ss:
3808 handleVectorConvertIntrinsic(I, 1, true);
3809 break;
3810 case Intrinsic::x86_sse2_cvtsd2si64:
3811 case Intrinsic::x86_sse2_cvtsd2si:
3812 case Intrinsic::x86_sse2_cvtsd2ss:
3813 case Intrinsic::x86_sse2_cvttsd2si64:
3814 case Intrinsic::x86_sse2_cvttsd2si:
3815 case Intrinsic::x86_sse_cvtss2si64:
3816 case Intrinsic::x86_sse_cvtss2si:
3817 case Intrinsic::x86_sse_cvttss2si64:
3818 case Intrinsic::x86_sse_cvttss2si:
3819 handleVectorConvertIntrinsic(I, 1);
3820 break;
3821 case Intrinsic::x86_sse_cvtps2pi:
3822 case Intrinsic::x86_sse_cvttps2pi:
3823 handleVectorConvertIntrinsic(I, 2);
3824 break;
3825
3826 case Intrinsic::x86_avx512_psll_w_512:
3827 case Intrinsic::x86_avx512_psll_d_512:
3828 case Intrinsic::x86_avx512_psll_q_512:
3829 case Intrinsic::x86_avx512_pslli_w_512:
3830 case Intrinsic::x86_avx512_pslli_d_512:
3831 case Intrinsic::x86_avx512_pslli_q_512:
3832 case Intrinsic::x86_avx512_psrl_w_512:
3833 case Intrinsic::x86_avx512_psrl_d_512:
3834 case Intrinsic::x86_avx512_psrl_q_512:
3835 case Intrinsic::x86_avx512_psra_w_512:
3836 case Intrinsic::x86_avx512_psra_d_512:
3837 case Intrinsic::x86_avx512_psra_q_512:
3838 case Intrinsic::x86_avx512_psrli_w_512:
3839 case Intrinsic::x86_avx512_psrli_d_512:
3840 case Intrinsic::x86_avx512_psrli_q_512:
3841 case Intrinsic::x86_avx512_psrai_w_512:
3842 case Intrinsic::x86_avx512_psrai_d_512:
3843 case Intrinsic::x86_avx512_psrai_q_512:
3844 case Intrinsic::x86_avx512_psra_q_256:
3845 case Intrinsic::x86_avx512_psra_q_128:
3846 case Intrinsic::x86_avx512_psrai_q_256:
3847 case Intrinsic::x86_avx512_psrai_q_128:
3848 case Intrinsic::x86_avx2_psll_w:
3849 case Intrinsic::x86_avx2_psll_d:
3850 case Intrinsic::x86_avx2_psll_q:
3851 case Intrinsic::x86_avx2_pslli_w:
3852 case Intrinsic::x86_avx2_pslli_d:
3853 case Intrinsic::x86_avx2_pslli_q:
3854 case Intrinsic::x86_avx2_psrl_w:
3855 case Intrinsic::x86_avx2_psrl_d:
3856 case Intrinsic::x86_avx2_psrl_q:
3857 case Intrinsic::x86_avx2_psra_w:
3858 case Intrinsic::x86_avx2_psra_d:
3859 case Intrinsic::x86_avx2_psrli_w:
3860 case Intrinsic::x86_avx2_psrli_d:
3861 case Intrinsic::x86_avx2_psrli_q:
3862 case Intrinsic::x86_avx2_psrai_w:
3863 case Intrinsic::x86_avx2_psrai_d:
3864 case Intrinsic::x86_sse2_psll_w:
3865 case Intrinsic::x86_sse2_psll_d:
3866 case Intrinsic::x86_sse2_psll_q:
3867 case Intrinsic::x86_sse2_pslli_w:
3868 case Intrinsic::x86_sse2_pslli_d:
3869 case Intrinsic::x86_sse2_pslli_q:
3870 case Intrinsic::x86_sse2_psrl_w:
3871 case Intrinsic::x86_sse2_psrl_d:
3872 case Intrinsic::x86_sse2_psrl_q:
3873 case Intrinsic::x86_sse2_psra_w:
3874 case Intrinsic::x86_sse2_psra_d:
3875 case Intrinsic::x86_sse2_psrli_w:
3876 case Intrinsic::x86_sse2_psrli_d:
3877 case Intrinsic::x86_sse2_psrli_q:
3878 case Intrinsic::x86_sse2_psrai_w:
3879 case Intrinsic::x86_sse2_psrai_d:
3880 case Intrinsic::x86_mmx_psll_w:
3881 case Intrinsic::x86_mmx_psll_d:
3882 case Intrinsic::x86_mmx_psll_q:
3883 case Intrinsic::x86_mmx_pslli_w:
3884 case Intrinsic::x86_mmx_pslli_d:
3885 case Intrinsic::x86_mmx_pslli_q:
3886 case Intrinsic::x86_mmx_psrl_w:
3887 case Intrinsic::x86_mmx_psrl_d:
3888 case Intrinsic::x86_mmx_psrl_q:
3889 case Intrinsic::x86_mmx_psra_w:
3890 case Intrinsic::x86_mmx_psra_d:
3891 case Intrinsic::x86_mmx_psrli_w:
3892 case Intrinsic::x86_mmx_psrli_d:
3893 case Intrinsic::x86_mmx_psrli_q:
3894 case Intrinsic::x86_mmx_psrai_w:
3895 case Intrinsic::x86_mmx_psrai_d:
3896 handleVectorShiftIntrinsic(I, /* Variable */ false);
3897 break;
3898 case Intrinsic::x86_avx2_psllv_d:
3899 case Intrinsic::x86_avx2_psllv_d_256:
3900 case Intrinsic::x86_avx512_psllv_d_512:
3901 case Intrinsic::x86_avx2_psllv_q:
3902 case Intrinsic::x86_avx2_psllv_q_256:
3903 case Intrinsic::x86_avx512_psllv_q_512:
3904 case Intrinsic::x86_avx2_psrlv_d:
3905 case Intrinsic::x86_avx2_psrlv_d_256:
3906 case Intrinsic::x86_avx512_psrlv_d_512:
3907 case Intrinsic::x86_avx2_psrlv_q:
3908 case Intrinsic::x86_avx2_psrlv_q_256:
3909 case Intrinsic::x86_avx512_psrlv_q_512:
3910 case Intrinsic::x86_avx2_psrav_d:
3911 case Intrinsic::x86_avx2_psrav_d_256:
3912 case Intrinsic::x86_avx512_psrav_d_512:
3913 case Intrinsic::x86_avx512_psrav_q_128:
3914 case Intrinsic::x86_avx512_psrav_q_256:
3915 case Intrinsic::x86_avx512_psrav_q_512:
3916 handleVectorShiftIntrinsic(I, /* Variable */ true);
3917 break;
3918
3919 case Intrinsic::x86_sse2_packsswb_128:
3920 case Intrinsic::x86_sse2_packssdw_128:
3921 case Intrinsic::x86_sse2_packuswb_128:
3922 case Intrinsic::x86_sse41_packusdw:
3923 case Intrinsic::x86_avx2_packsswb:
3924 case Intrinsic::x86_avx2_packssdw:
3925 case Intrinsic::x86_avx2_packuswb:
3926 case Intrinsic::x86_avx2_packusdw:
3927 handleVectorPackIntrinsic(I);
3928 break;
3929
3930 case Intrinsic::x86_mmx_packsswb:
3931 case Intrinsic::x86_mmx_packuswb:
3932 handleVectorPackIntrinsic(I, 16);
3933 break;
3934
3935 case Intrinsic::x86_mmx_packssdw:
3936 handleVectorPackIntrinsic(I, 32);
3937 break;
3938
3939 case Intrinsic::x86_mmx_psad_bw:
3940 case Intrinsic::x86_sse2_psad_bw:
3941 case Intrinsic::x86_avx2_psad_bw:
3942 handleVectorSadIntrinsic(I);
3943 break;
3944
3945 case Intrinsic::x86_sse2_pmadd_wd:
3946 case Intrinsic::x86_avx2_pmadd_wd:
3947 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
3948 case Intrinsic::x86_avx2_pmadd_ub_sw:
3949 handleVectorPmaddIntrinsic(I);
3950 break;
3951
3952 case Intrinsic::x86_ssse3_pmadd_ub_sw:
3953 handleVectorPmaddIntrinsic(I, 8);
3954 break;
3955
3956 case Intrinsic::x86_mmx_pmadd_wd:
3957 handleVectorPmaddIntrinsic(I, 16);
3958 break;
3959
3960 case Intrinsic::x86_sse_cmp_ss:
3961 case Intrinsic::x86_sse2_cmp_sd:
3962 case Intrinsic::x86_sse_comieq_ss:
3963 case Intrinsic::x86_sse_comilt_ss:
3964 case Intrinsic::x86_sse_comile_ss:
3965 case Intrinsic::x86_sse_comigt_ss:
3966 case Intrinsic::x86_sse_comige_ss:
3967 case Intrinsic::x86_sse_comineq_ss:
3968 case Intrinsic::x86_sse_ucomieq_ss:
3969 case Intrinsic::x86_sse_ucomilt_ss:
3970 case Intrinsic::x86_sse_ucomile_ss:
3971 case Intrinsic::x86_sse_ucomigt_ss:
3972 case Intrinsic::x86_sse_ucomige_ss:
3973 case Intrinsic::x86_sse_ucomineq_ss:
3974 case Intrinsic::x86_sse2_comieq_sd:
3975 case Intrinsic::x86_sse2_comilt_sd:
3976 case Intrinsic::x86_sse2_comile_sd:
3977 case Intrinsic::x86_sse2_comigt_sd:
3978 case Intrinsic::x86_sse2_comige_sd:
3979 case Intrinsic::x86_sse2_comineq_sd:
3980 case Intrinsic::x86_sse2_ucomieq_sd:
3981 case Intrinsic::x86_sse2_ucomilt_sd:
3982 case Intrinsic::x86_sse2_ucomile_sd:
3983 case Intrinsic::x86_sse2_ucomigt_sd:
3984 case Intrinsic::x86_sse2_ucomige_sd:
3985 case Intrinsic::x86_sse2_ucomineq_sd:
3986 handleVectorCompareScalarIntrinsic(I);
3987 break;
3988
3989 case Intrinsic::x86_avx_cmp_pd_256:
3990 case Intrinsic::x86_avx_cmp_ps_256:
3991 case Intrinsic::x86_sse2_cmp_pd:
3992 case Intrinsic::x86_sse_cmp_ps:
3993 handleVectorComparePackedIntrinsic(I);
3994 break;
3995
3996 case Intrinsic::x86_bmi_bextr_32:
3997 case Intrinsic::x86_bmi_bextr_64:
3998 case Intrinsic::x86_bmi_bzhi_32:
3999 case Intrinsic::x86_bmi_bzhi_64:
4000 case Intrinsic::x86_bmi_pdep_32:
4001 case Intrinsic::x86_bmi_pdep_64:
4002 case Intrinsic::x86_bmi_pext_32:
4003 case Intrinsic::x86_bmi_pext_64:
4004 handleBmiIntrinsic(I);
4005 break;
4006
4007 case Intrinsic::x86_pclmulqdq:
4008 case Intrinsic::x86_pclmulqdq_256:
4009 case Intrinsic::x86_pclmulqdq_512:
4010 handlePclmulIntrinsic(I);
4011 break;
4012
4013 case Intrinsic::x86_sse41_round_sd:
4014 case Intrinsic::x86_sse41_round_ss:
4015 handleUnarySdSsIntrinsic(I);
4016 break;
4017 case Intrinsic::x86_sse2_max_sd:
4018 case Intrinsic::x86_sse_max_ss:
4019 case Intrinsic::x86_sse2_min_sd:
4020 case Intrinsic::x86_sse_min_ss:
4021 handleBinarySdSsIntrinsic(I);
4022 break;
4023
4024 case Intrinsic::x86_avx_vtestc_pd:
4025 case Intrinsic::x86_avx_vtestc_pd_256:
4026 case Intrinsic::x86_avx_vtestc_ps:
4027 case Intrinsic::x86_avx_vtestc_ps_256:
4028 case Intrinsic::x86_avx_vtestnzc_pd:
4029 case Intrinsic::x86_avx_vtestnzc_pd_256:
4030 case Intrinsic::x86_avx_vtestnzc_ps:
4031 case Intrinsic::x86_avx_vtestnzc_ps_256:
4032 case Intrinsic::x86_avx_vtestz_pd:
4033 case Intrinsic::x86_avx_vtestz_pd_256:
4034 case Intrinsic::x86_avx_vtestz_ps:
4035 case Intrinsic::x86_avx_vtestz_ps_256:
4036 case Intrinsic::x86_avx_ptestc_256:
4037 case Intrinsic::x86_avx_ptestnzc_256:
4038 case Intrinsic::x86_avx_ptestz_256:
4039 case Intrinsic::x86_sse41_ptestc:
4040 case Intrinsic::x86_sse41_ptestnzc:
4041 case Intrinsic::x86_sse41_ptestz:
4042 handleVtestIntrinsic(I);
4043 break;
4044
4045 case Intrinsic::fshl:
4046 case Intrinsic::fshr:
4047 handleFunnelShift(I);
4048 break;
4049
4050 case Intrinsic::is_constant:
4051 // The result of llvm.is.constant() is always defined.
4052 setShadow(&I, getCleanShadow(&I));
4053 setOrigin(&I, getCleanOrigin());
4054 break;
4055
4056 default:
4057 if (!handleUnknownIntrinsic(I))
4058 visitInstruction(I);
4059 break;
4060 }
4061 }
4062
4063 void visitLibAtomicLoad(CallBase &CB) {
4064 // Since we use getNextNode here, we can't have CB terminate the BB.
4065 assert(isa<CallInst>(CB));
4066
4067 IRBuilder<> IRB(&CB);
4068 Value *Size = CB.getArgOperand(0);
4069 Value *SrcPtr = CB.getArgOperand(1);
4070 Value *DstPtr = CB.getArgOperand(2);
4071 Value *Ordering = CB.getArgOperand(3);
4072 // Convert the call to have at least Acquire ordering to make sure
4073 // the shadow operations aren't reordered before it.
4074 Value *NewOrdering =
4075 IRB.CreateExtractElement(makeAddAcquireOrderingTable(IRB), Ordering);
4076 CB.setArgOperand(3, NewOrdering);
4077
4078 NextNodeIRBuilder NextIRB(&CB);
4079 Value *SrcShadowPtr, *SrcOriginPtr;
4080 std::tie(SrcShadowPtr, SrcOriginPtr) =
4081 getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
4082 /*isStore*/ false);
4083 Value *DstShadowPtr =
4084 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
4085 /*isStore*/ true)
4086 .first;
4087
4088 NextIRB.CreateMemCpy(DstShadowPtr, Align(1), SrcShadowPtr, Align(1), Size);
4089 if (MS.TrackOrigins) {
4090 Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
4092 Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
4093 NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
4094 }
4095 }
4096
4097 void visitLibAtomicStore(CallBase &CB) {
4098 IRBuilder<> IRB(&CB);
4099 Value *Size = CB.getArgOperand(0);
4100 Value *DstPtr = CB.getArgOperand(2);
4101 Value *Ordering = CB.getArgOperand(3);
4102 // Convert the call to have at least Release ordering to make sure
4103 // the shadow operations aren't reordered after it.
4104 Value *NewOrdering =
4105 IRB.CreateExtractElement(makeAddReleaseOrderingTable(IRB), Ordering);
4106 CB.setArgOperand(3, NewOrdering);
4107
4108 Value *DstShadowPtr =
4109 getShadowOriginPtr(DstPtr, IRB, IRB.getInt8Ty(), Align(1),
4110 /*isStore*/ true)
4111 .first;
4112
4113 // Atomic store always paints clean shadow/origin. See file header.
4114 IRB.CreateMemSet(DstShadowPtr, getCleanShadow(IRB.getInt8Ty()), Size,
4115 Align(1));
4116 }
4117
4118 void visitCallBase(CallBase &CB) {
4119 assert(!CB.getMetadata(LLVMContext::MD_nosanitize));
4120 if (CB.isInlineAsm()) {
4121 // For inline asm (either a call to asm function, or callbr instruction),
4122 // do the usual thing: check argument shadow and mark all outputs as
4123 // clean. Note that any side effects of the inline asm that are not
4124 // immediately visible in its constraints are not handled.
4126 visitAsmInstruction(CB);
4127 else
4128 visitInstruction(CB);
4129 return;
4130 }
4131 LibFunc LF;
4132 if (TLI->getLibFunc(CB, LF)) {
4133 // libatomic.a functions need to have special handling because there isn't
4134 // a good way to intercept them or compile the library with
4135 // instrumentation.
4136 switch (LF) {
4137 case LibFunc_atomic_load:
4138 if (!isa<CallInst>(CB)) {
4139 llvm::errs() << "MSAN -- cannot instrument invoke of libatomic load."
4140 "Ignoring!\n";
4141 break;
4142 }
4143 visitLibAtomicLoad(CB);
4144 return;
4145 case LibFunc_atomic_store:
4146 visitLibAtomicStore(CB);
4147 return;
4148 default:
4149 break;
4150 }
4151 }
4152
4153 if (auto *Call = dyn_cast<CallInst>(&CB)) {
4154 assert(!isa<IntrinsicInst>(Call) && "intrinsics are handled elsewhere");
4155
4156 // We are going to insert code that relies on the fact that the callee
4157 // will become a non-readonly function after it is instrumented by us. To
4158 // prevent this code from being optimized out, mark that function
4159 // non-readonly in advance.
4160 // TODO: We can likely do better than dropping memory() completely here.
4162 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
4163
4164 Call->removeFnAttrs(B);
4165 if (Function *Func = Call->getCalledFunction()) {
4166 Func->removeFnAttrs(B);
4167 }
4168
4170 }
4171 IRBuilder<> IRB(&CB);
4172 bool MayCheckCall = MS.EagerChecks;
4173 if (Function *Func = CB.getCalledFunction()) {
4174 // __sanitizer_unaligned_{load,store} functions may be called by users
4175 // and always expects shadows in the TLS. So don't check them.
4176 MayCheckCall &= !Func->getName().starts_with("__sanitizer_unaligned_");
4177 }
4178
4179 unsigned ArgOffset = 0;
4180 LLVM_DEBUG(dbgs() << " CallSite: " << CB << "\n");
4181 for (const auto &[i, A] : llvm::enumerate(CB.args())) {
4182 if (!A->getType()->isSized()) {
4183 LLVM_DEBUG(dbgs() << "Arg " << i << " is not sized: " << CB << "\n");
4184 continue;
4185 }
4186 unsigned Size = 0;
4187 const DataLayout &DL = F.getParent()->getDataLayout();
4188
4189 bool ByVal = CB.paramHasAttr(i, Attribute::ByVal);
4190 bool NoUndef = CB.paramHasAttr(i, Attribute::NoUndef);
4191 bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
4192
4193 if (EagerCheck) {
4194 insertShadowCheck(A, &CB);
4195 Size = DL.getTypeAllocSize(A->getType());
4196 } else {
4197 Value *Store = nullptr;
4198 // Compute the Shadow for arg even if it is ByVal, because
4199 // in that case getShadow() will copy the actual arg shadow to
4200 // __msan_param_tls.
4201 Value *ArgShadow = getShadow(A);
4202 Value *ArgShadowBase = getShadowPtrForArgument(IRB, ArgOffset);
4203 LLVM_DEBUG(dbgs() << " Arg#" << i << ": " << *A
4204 << " Shadow: " << *ArgShadow << "\n");
4205 if (ByVal) {
4206 // ByVal requires some special handling as it's too big for a single
4207 // load
4208 assert(A->getType()->isPointerTy() &&
4209 "ByVal argument is not a pointer!");
4210 Size = DL.getTypeAllocSize(CB.getParamByValType(i));
4211 if (ArgOffset + Size > kParamTLSSize)
4212 break;
4213 const MaybeAlign ParamAlignment(CB.getParamAlign(i));
4214 MaybeAlign Alignment = std::nullopt;
4215 if (ParamAlignment)
4216 Alignment = std::min(*ParamAlignment, kShadowTLSAlignment);
4217 Value *AShadowPtr, *AOriginPtr;
4218 std::tie(AShadowPtr, AOriginPtr) =
4219 getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), Alignment,
4220 /*isStore*/ false);
4221 if (!PropagateShadow) {
4222 Store = IRB.CreateMemSet(ArgShadowBase,
4224 Size, Alignment);
4225 } else {
4226 Store = IRB.CreateMemCpy(ArgShadowBase, Alignment, AShadowPtr,
4227 Alignment, Size);
4228 if (MS.TrackOrigins) {
4229 Value *ArgOriginBase = getOriginPtrForArgument(IRB, ArgOffset);
4230 // FIXME: OriginSize should be:
4231 // alignTo(A % kMinOriginAlignment + Size, kMinOriginAlignment)
4232 unsigned OriginSize = alignTo(Size, kMinOriginAlignment);
4233 IRB.CreateMemCpy(
4234 ArgOriginBase,
4235 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
4236 AOriginPtr,
4237 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginSize);
4238 }
4239 }
4240 } else {
4241 // Any other parameters mean we need bit-grained tracking of uninit
4242 // data
4243 Size = DL.getTypeAllocSize(A->getType());
4244 if (ArgOffset + Size > kParamTLSSize)
4245 break;
4246 Store = IRB.CreateAlignedStore(ArgShadow, ArgShadowBase,
4248 Constant *Cst = dyn_cast<Constant>(ArgShadow);
4249 if (MS.TrackOrigins && !(Cst && Cst->isNullValue())) {
4250 IRB.CreateStore(getOrigin(A),
4251 getOriginPtrForArgument(IRB, ArgOffset));
4252 }
4253 }
4254 (void)Store;
4255 assert(Store != nullptr);
4256 LLVM_DEBUG(dbgs() << " Param:" << *Store << "\n");
4257 }
4258 assert(Size != 0);
4259 ArgOffset += alignTo(Size, kShadowTLSAlignment);
4260 }
4261 LLVM_DEBUG(dbgs() << " done with call args\n");
4262
4263 FunctionType *FT = CB.getFunctionType();
4264 if (FT->isVarArg()) {
4265 VAHelper->visitCallBase(CB, IRB);
4266 }
4267
4268 // Now, get the shadow for the RetVal.
4269 if (!CB.getType()->isSized())
4270 return;
4271 // Don't emit the epilogue for musttail call returns.
4272 if (isa<CallInst>(CB) && cast<CallInst>(CB).isMustTailCall())
4273 return;
4274
4275 if (MayCheckCall && CB.hasRetAttr(Attribute::NoUndef)) {
4276 setShadow(&CB, getCleanShadow(&CB));
4277 setOrigin(&CB, getCleanOrigin());
4278 return;
4279 }
4280
4281 IRBuilder<> IRBBefore(&CB);
4282 // Until we have full dynamic coverage, make sure the retval shadow is 0.
4283 Value *Base = getShadowPtrForRetval(IRBBefore);
4284 IRBBefore.CreateAlignedStore(getCleanShadow(&CB), Base,
4286 BasicBlock::iterator NextInsn;
4287 if (isa<CallInst>(CB)) {
4288 NextInsn = ++CB.getIterator();
4289 assert(NextInsn != CB.getParent()->end());
4290 } else {
4291 BasicBlock *NormalDest = cast<InvokeInst>(CB).getNormalDest();
4292 if (!NormalDest->getSinglePredecessor()) {
4293 // FIXME: this case is tricky, so we are just conservative here.
4294 // Perhaps we need to split the edge between this BB and NormalDest,
4295 // but a naive attempt to use SplitEdge leads to a crash.
4296 setShadow(&CB, getCleanShadow(&CB));
4297 setOrigin(&CB, getCleanOrigin());
4298 return;
4299 }
4300 // FIXME: NextInsn is likely in a basic block that has not been visited
4301 // yet. Anything inserted there will be instrumented by MSan later!
4302 NextInsn = NormalDest->getFirstInsertionPt();
4303 assert(NextInsn != NormalDest->end() &&
4304 "Could not find insertion point for retval shadow load");
4305 }
4306 IRBuilder<> IRBAfter(&*NextInsn);
4307 Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
4308 getShadowTy(&CB), getShadowPtrForRetval(IRBAfter),
4309 kShadowTLSAlignment, "_msret");
4310 setShadow(&CB, RetvalShadow);
4311 if (MS.TrackOrigins)
4312 setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy,
4313 getOriginPtrForRetval()));
4314 }
4315
4316 bool isAMustTailRetVal(Value *RetVal) {
4317 if (auto *I = dyn_cast<BitCastInst>(RetVal)) {
4318 RetVal = I->getOperand(0);
4319 }
4320 if (auto *I = dyn_cast<CallInst>(RetVal)) {
4321 return I->isMustTailCall();
4322 }
4323 return false;
4324 }
4325
4326 void visitReturnInst(ReturnInst &I) {
4327 IRBuilder<> IRB(&I);
4328 Value *RetVal = I.getReturnValue();
4329 if (!RetVal)
4330 return;
4331 // Don't emit the epilogue for musttail call returns.
4332 if (isAMustTailRetVal(RetVal))
4333 return;
4334 Value *ShadowPtr = getShadowPtrForRetval(IRB);
4335 bool HasNoUndef = F.hasRetAttribute(Attribute::NoUndef);
4336 bool StoreShadow = !(MS.EagerChecks && HasNoUndef);
4337 // FIXME: Consider using SpecialCaseList to specify a list of functions that
4338 // must always return fully initialized values. For now, we hardcode "main".
4339 bool EagerCheck = (MS.EagerChecks && HasNoUndef) || (F.getName() == "main");
4340
4341 Value *Shadow = getShadow(RetVal);
4342 bool StoreOrigin = true;
4343 if (EagerCheck) {
4344 insertShadowCheck(RetVal, &I);
4345 Shadow = getCleanShadow(RetVal);
4346 StoreOrigin = false;
4347 }
4348
4349 // The caller may still expect information passed over TLS if we pass our
4350 // check
4351 if (StoreShadow) {
4352 IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment);
4353 if (MS.TrackOrigins && StoreOrigin)
4354 IRB.CreateStore(getOrigin(RetVal), getOriginPtrForRetval());
4355 }
4356 }
4357
4358 void visitPHINode(PHINode &I) {
4359 IRBuilder<> IRB(&I);
4360 if (!PropagateShadow) {
4361 setShadow(&I, getCleanShadow(&I));
4362 setOrigin(&I, getCleanOrigin());
4363 return;
4364 }
4365
4366 ShadowPHINodes.push_back(&I);
4367 setShadow(&I, IRB.CreatePHI(getShadowTy(&I), I.getNumIncomingValues(),
4368 "_msphi_s"));
4369 if (MS.TrackOrigins)
4370 setOrigin(
4371 &I, IRB.CreatePHI(MS.OriginTy, I.getNumIncomingValues(), "_msphi_o"));
4372 }
4373
4374 Value *getLocalVarIdptr(AllocaInst &I) {
4375 ConstantInt *IntConst =
4376 ConstantInt::get(Type::getInt32Ty((*F.getParent()).getContext()), 0);
4377 return new GlobalVariable(*F.getParent(), IntConst->getType(),
4378 /*isConstant=*/false, GlobalValue::PrivateLinkage,
4379 IntConst);
4380 }
4381
4382 Value *getLocalVarDescription(AllocaInst &I) {
4383 return createPrivateConstGlobalForString(*F.getParent(), I.getName());
4384 }
4385
4386 void poisonAllocaUserspace(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
4387 if (PoisonStack && ClPoisonStackWithCall) {
4388 IRB.CreateCall(MS.MsanPoisonStackFn, {&I, Len});
4389 } else {
4390 Value *ShadowBase, *OriginBase;
4391 std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
4392 &I, IRB, IRB.getInt8Ty(), Align(1), /*isStore*/ true);
4393
4394 Value *PoisonValue = IRB.getInt8(PoisonStack ? ClPoisonStackPattern : 0);
4395 IRB.CreateMemSet(ShadowBase, PoisonValue, Len, I.getAlign());
4396 }
4397
4398 if (PoisonStack && MS.TrackOrigins) {
4399 Value *Idptr = getLocalVarIdptr(I);
4400 if (ClPrintStackNames) {
4401 Value *Descr = getLocalVarDescription(I);
4402 IRB.CreateCall(MS.MsanSetAllocaOriginWithDescriptionFn,
4403 {&I, Len, Idptr, Descr});
4404 } else {
4405 IRB.CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
4406 }
4407 }
4408 }
4409
4410 void poisonAllocaKmsan(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
4411 Value *Descr = getLocalVarDescription(I);
4412 if (PoisonStack) {
4413 IRB.CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
4414 } else {
4415 IRB.CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
4416 }
4417 }
4418
4419 void instrumentAlloca(AllocaInst &I, Instruction *InsPoint = nullptr) {
4420 if (!InsPoint)
4421 InsPoint = &I;
4422 NextNodeIRBuilder IRB(InsPoint);
4423 const DataLayout &DL = F.getParent()->getDataLayout();
4424 uint64_t TypeSize = DL.getTypeAllocSize(I.getAllocatedType());
4425 Value *Len = ConstantInt::get(MS.IntptrTy, TypeSize);
4426 if (I.isArrayAllocation())
4427 Len = IRB.CreateMul(Len,
4428 IRB.CreateZExtOrTrunc(I.getArraySize(), MS.IntptrTy));
4429
4430 if (MS.CompileKernel)
4431 poisonAllocaKmsan(I, IRB, Len);
4432 else
4433 poisonAllocaUserspace(I, IRB, Len);
4434 }
4435
4436 void visitAllocaInst(AllocaInst &I) {
4437 setShadow(&I, getCleanShadow(&I));
4438 setOrigin(&I, getCleanOrigin());
4439 // We'll get to this alloca later unless it's poisoned at the corresponding
4440 // llvm.lifetime.start.
4441 AllocaSet.insert(&I);
4442 }
4443
4444 void visitSelectInst(SelectInst &I) {
4445 IRBuilder<> IRB(&I);
4446 // a = select b, c, d
4447 Value *B = I.getCondition();
4448 Value *C = I.getTrueValue();
4449 Value *D = I.getFalseValue();
4450 Value *Sb = getShadow(B);
4451 Value *Sc = getShadow(C);
4452 Value *Sd = getShadow(D);
4453
4454 // Result shadow if condition shadow is 0.
4455 Value *Sa0 = IRB.CreateSelect(B, Sc, Sd);
4456 Value *Sa1;
4457 if (I.getType()->isAggregateType()) {
4458 // To avoid "sign extending" i1 to an arbitrary aggregate type, we just do
4459 // an extra "select". This results in much more compact IR.
4460 // Sa = select Sb, poisoned, (select b, Sc, Sd)
4461 Sa1 = getPoisonedShadow(getShadowTy(I.getType()));
4462 } else {
4463 // Sa = select Sb, [ (c^d) | Sc | Sd ], [ b ? Sc : Sd ]
4464 // If Sb (condition is poisoned), look for bits in c and d that are equal
4465 // and both unpoisoned.
4466 // If !Sb (condition is unpoisoned), simply pick one of Sc and Sd.
4467
4468 // Cast arguments to shadow-compatible type.
4469 C = CreateAppToShadowCast(IRB, C);
4470 D = CreateAppToShadowCast(IRB, D);
4471
4472 // Result shadow if condition shadow is 1.
4473 Sa1 = IRB.CreateOr({IRB.CreateXor(C, D), Sc, Sd});
4474 }
4475 Value *Sa = IRB.CreateSelect(Sb, Sa1, Sa0, "_msprop_select");
4476 setShadow(&I, Sa);
4477 if (MS.TrackOrigins) {
4478 // Origins are always i32, so any vector conditions must be flattened.
4479 // FIXME: consider tracking vector origins for app vectors?
4480 if (B->getType()->isVectorTy()) {
4481 B = convertToBool(B, IRB);
4482 Sb = convertToBool(Sb, IRB);
4483 }
4484 // a = select b, c, d
4485 // Oa = Sb ? Ob : (b ? Oc : Od)
4486 setOrigin(
4487 &I, IRB.CreateSelect(Sb, getOrigin(I.getCondition()),
4488 IRB.CreateSelect(B, getOrigin(I.getTrueValue()),
4489 getOrigin(I.getFalseValue()))));
4490 }
4491 }
4492
4493 void visitLandingPadInst(LandingPadInst &I) {
4494 // Do nothing.
4495 // See https://github.com/google/sanitizers/issues/504
4496 setShadow(&I, getCleanShadow(&I));
4497 setOrigin(&I, getCleanOrigin());
4498 }
4499
4500 void visitCatchSwitchInst(CatchSwitchInst &I) {
4501 setShadow(&I, getCleanShadow(&I));
4502 setOrigin(&I, getCleanOrigin());
4503 }
4504
4505 void visitFuncletPadInst(FuncletPadInst &I) {
4506 setShadow(&I, getCleanShadow(&I));
4507 setOrigin(&I, getCleanOrigin());
4508 }
4509
4510 void visitGetElementPtrInst(GetElementPtrInst &I) { handleShadowOr(I); }
4511
4512 void visitExtractValueInst(ExtractValueInst &I) {
4513 IRBuilder<> IRB(&I);
4514 Value *Agg = I.getAggregateOperand();
4515 LLVM_DEBUG(dbgs() << "ExtractValue: " << I << "\n");
4516 Value *AggShadow = getShadow(Agg);
4517 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n");
4518 Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices());
4519 LLVM_DEBUG(dbgs() << " ResShadow: " << *ResShadow << "\n");
4520 setShadow(&I, ResShadow);
4521 setOriginForNaryOp(I);
4522 }
4523
4524 void visitInsertValueInst(InsertValueInst &I) {
4525 IRBuilder<> IRB(&I);
4526 LLVM_DEBUG(dbgs() << "InsertValue: " << I << "\n");
4527 Value *AggShadow = getShadow(I.getAggregateOperand());
4528 Value *InsShadow = getShadow(I.getInsertedValueOperand());
4529 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow << "\n");
4530 LLVM_DEBUG(dbgs() << " InsShadow: " << *InsShadow << "\n");
4531 Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices());
4532 LLVM_DEBUG(dbgs() << " Res: " << *Res << "\n");
4533 setShadow(&I, Res);
4534 setOriginForNaryOp(I);
4535 }
4536
4537 void dumpInst(Instruction &I) {
4538 if (CallInst *CI = dyn_cast<CallInst>(&I)) {
4539 errs() << "ZZZ call " << CI->getCalledFunction()->getName() << "\n";
4540 } else {
4541 errs() << "ZZZ " << I.getOpcodeName() << "\n";
4542 }
4543 errs() << "QQQ " << I << "\n";
4544 }
4545
4546 void visitResumeInst(ResumeInst &I) {
4547 LLVM_DEBUG(dbgs() << "Resume: " << I << "\n");
4548 // Nothing to do here.
4549 }
4550
4551 void visitCleanupReturnInst(CleanupReturnInst &CRI) {
4552 LLVM_DEBUG(dbgs() << "CleanupReturn: " << CRI << "\n");
4553 // Nothing to do here.
4554 }
4555
4556 void visitCatchReturnInst(CatchReturnInst &CRI) {
4557 LLVM_DEBUG(dbgs() << "CatchReturn: " << CRI << "\n");
4558 // Nothing to do here.
4559 }
4560
4561 void instrumentAsmArgument(Value *Operand, Type *ElemTy, Instruction &I,
4562 IRBuilder<> &IRB, const DataLayout &DL,
4563 bool isOutput) {
4564 // For each assembly argument, we check its value for being initialized.
4565 // If the argument is a pointer, we assume it points to a single element
4566 // of the corresponding type (or to a 8-byte word, if the type is unsized).
4567 // Each such pointer is instrumented with a call to the runtime library.
4568 Type *OpType = Operand->getType();
4569 // Check the operand value itself.
4570 insertShadowCheck(Operand, &I);
4571 if (!OpType->isPointerTy() || !isOutput) {
4572 assert(!isOutput);
4573 return;
4574 }
4575 if (!ElemTy->isSized())
4576 return;
4577 auto Size = DL.getTypeStoreSize(ElemTy);
4578 Value *SizeVal = IRB.CreateTypeSize(MS.IntptrTy, Size);
4579 if (MS.CompileKernel) {
4580 IRB.CreateCall(MS.MsanInstrumentAsmStoreFn, {Operand, SizeVal});
4581 } else {
4582 // ElemTy, derived from elementtype(), does not encode the alignment of
4583 // the pointer. Conservatively assume that the shadow memory is unaligned.
4584 // When Size is large, avoid StoreInst as it would expand to many
4585 // instructions.
4586 auto [ShadowPtr, _] =
4587 getShadowOriginPtrUserspace(Operand, IRB, IRB.getInt8Ty(), Align(1));
4588 if (Size <= 32)
4589 IRB.CreateAlignedStore(getCleanShadow(ElemTy), ShadowPtr, Align(1));
4590 else
4591 IRB.CreateMemSet(ShadowPtr, ConstantInt::getNullValue(IRB.getInt8Ty()),
4592 SizeVal, Align(1));
4593 }
4594 }
4595
4596 /// Get the number of output arguments returned by pointers.
4597 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
4598 int NumRetOutputs = 0;
4599 int NumOutputs = 0;
4600 Type *RetTy = cast<Value>(CB)->getType();
4601 if (!RetTy->isVoidTy()) {
4602 // Register outputs are returned via the CallInst return value.
4603 auto *ST = dyn_cast<StructType>(RetTy);
4604 if (ST)
4605 NumRetOutputs = ST->getNumElements();
4606 else
4607 NumRetOutputs = 1;
4608 }
4609 InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints();
4610 for (const InlineAsm::ConstraintInfo &Info : Constraints) {
4611 switch (Info.Type) {
4613 NumOutputs++;
4614 break;
4615 default:
4616 break;
4617 }
4618 }
4619 return NumOutputs - NumRetOutputs;
4620 }
4621
4622 void visitAsmInstruction(Instruction &I) {
4623 // Conservative inline assembly handling: check for poisoned shadow of
4624 // asm() arguments, then unpoison the result and all the memory locations
4625 // pointed to by those arguments.
4626 // An inline asm() statement in C++ contains lists of input and output
4627 // arguments used by the assembly code. These are mapped to operands of the
4628 // CallInst as follows:
4629 // - nR register outputs ("=r) are returned by value in a single structure
4630 // (SSA value of the CallInst);
4631 // - nO other outputs ("=m" and others) are returned by pointer as first
4632 // nO operands of the CallInst;
4633 // - nI inputs ("r", "m" and others) are passed to CallInst as the
4634 // remaining nI operands.
4635 // The total number of asm() arguments in the source is nR+nO+nI, and the
4636 // corresponding CallInst has nO+nI+1 operands (the last operand is the
4637 // function to be called).
4638 const DataLayout &DL = F.getParent()->getDataLayout();
4639 CallBase *CB = cast<CallBase>(&I);
4640 IRBuilder<> IRB(&I);
4641 InlineAsm *IA = cast<InlineAsm>(CB->getCalledOperand());
4642 int OutputArgs = getNumOutputArgs(IA, CB);
4643 // The last operand of a CallInst is the function itself.
4644 int NumOperands = CB->getNumOperands() - 1;
4645
4646 // Check input arguments. Doing so before unpoisoning output arguments, so
4647 // that we won't overwrite uninit values before checking them.
4648 for (int i = OutputArgs; i < NumOperands; i++) {
4649 Value *Operand = CB->getOperand(i);
4650 instrumentAsmArgument(Operand, CB->getParamElementType(i), I, IRB, DL,
4651 /*isOutput*/ false);
4652 }
4653 // Unpoison output arguments. This must happen before the actual InlineAsm
4654 // call, so that the shadow for memory published in the asm() statement
4655 // remains valid.
4656 for (int i = 0; i < OutputArgs; i++) {
4657 Value *Operand = CB->getOperand(i);
4658 instrumentAsmArgument(Operand, CB->getParamElementType(i), I, IRB, DL,
4659 /*isOutput*/ true);
4660 }
4661
4662 setShadow(&I, getCleanShadow(&I));
4663 setOrigin(&I, getCleanOrigin());
4664 }
4665
4666 void visitFreezeInst(FreezeInst &I) {
4667 // Freeze always returns a fully defined value.
4668 setShadow(&I, getCleanShadow(&I));
4669 setOrigin(&I, getCleanOrigin());
4670 }
4671
4672 void visitInstruction(Instruction &I) {
4673 // Everything else: stop propagating and check for poisoned shadow.
4675 dumpInst(I);
4676 LLVM_DEBUG(dbgs() << "DEFAULT: " << I << "\n");
4677 for (size_t i = 0, n = I.getNumOperands(); i < n; i++) {
4678 Value *Operand = I.getOperand(i);
4679 if (Operand->getType()->isSized())
4680 insertShadowCheck(Operand, &I);
4681 }
4682 setShadow(&I, getCleanShadow(&I));
4683 setOrigin(&I, getCleanOrigin());
4684 }
4685};
4686
4687struct VarArgHelperBase : public VarArgHelper {
4688 Function &F;
4689 MemorySanitizer &MS;
4690 MemorySanitizerVisitor &MSV;
4691 SmallVector<CallInst *, 16> VAStartInstrumentationList;
4692 const unsigned VAListTagSize;
4693
4694 VarArgHelperBase(Function &F, MemorySanitizer &MS,
4695 MemorySanitizerVisitor &MSV, unsigned VAListTagSize)
4696 : F(F), MS(MS), MSV(MSV), VAListTagSize(VAListTagSize) {}
4697
4698 Value *getShadowAddrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
4699 Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
4700 return IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
4701 }
4702
4703 /// Compute the shadow address for a given va_arg.
4704 Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB,
4705 unsigned ArgOffset) {
4706 Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
4707 Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
4708 return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0),
4709 "_msarg_va_s");
4710 }
4711
4712 /// Compute the shadow address for a given va_arg.
4713 Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB,
4714 unsigned ArgOffset, unsigned ArgSize) {
4715 // Make sure we don't overflow __msan_va_arg_tls.
4716 if (ArgOffset + ArgSize > kParamTLSSize)
4717 return nullptr;
4718 return getShadowPtrForVAArgument(Ty, IRB, ArgOffset);
4719 }
4720
4721 /// Compute the origin address for a given va_arg.
4722 Value *getOriginPtrForVAArgument(IRBuilder<> &IRB, int ArgOffset) {
4723 Value *Base = IRB.CreatePointerCast(MS.VAArgOriginTLS, MS.IntptrTy);
4724 // getOriginPtrForVAArgument() is always called after
4725 // getShadowPtrForVAArgument(), so __msan_va_arg_origin_tls can never
4726 // overflow.
4727 Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
4728 return IRB.CreateIntToPtr(Base, PointerType::get(MS.OriginTy, 0),
4729 "_msarg_va_o");
4730 }
4731
4732 void CleanUnusedTLS(IRBuilder<> &IRB, Value *ShadowBase,
4733 unsigned BaseOffset) {
4734 // The tails of __msan_va_arg_tls is not large enough to fit full
4735 // value shadow, but it will be copied to backup anyway. Make it
4736 // clean.
4737 if (BaseOffset >= kParamTLSSize)
4738 return;
4739 Value *TailSize =
4740 ConstantInt::getSigned(IRB.getInt32Ty(), kParamTLSSize - BaseOffset);
4741 IRB.CreateMemSet(ShadowBase, ConstantInt::getNullValue(IRB.getInt8Ty()),
4742 TailSize, Align(8));
4743 }
4744
4745 void unpoisonVAListTagForInst(IntrinsicInst &I) {
4746 IRBuilder<> IRB(&I);
4747 Value *VAListTag = I.getArgOperand(0);
4748 const Align Alignment = Align(8);
4749 auto [ShadowPtr, OriginPtr] = MSV.getShadowOriginPtr(
4750 VAListTag, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ true);
4751 // Unpoison the whole __va_list_tag.
4752 IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
4753 VAListTagSize, Alignment, false);
4754 }
4755
4756 void visitVAStartInst(VAStartInst &I) override {
4757 if (F.getCallingConv() == CallingConv::Win64)
4758 return;
4759 VAStartInstrumentationList.push_back(&I);
4760 unpoisonVAListTagForInst(I);
4761 }
4762
4763 void visitVACopyInst(VACopyInst &I) override {
4764 if (F.getCallingConv() == CallingConv::Win64)
4765 return;
4766 unpoisonVAListTagForInst(I);
4767 }
4768};
4769
4770/// AMD64-specific implementation of VarArgHelper.
4771struct VarArgAMD64Helper : public VarArgHelperBase {
4772 // An unfortunate workaround for asymmetric lowering of va_arg stuff.
4773 // See a comment in visitCallBase for more details.
4774 static const unsigned AMD64GpEndOffset = 48; // AMD64 ABI Draft 0.99.6 p3.5.7
4775 static const unsigned AMD64FpEndOffsetSSE = 176;
4776 // If SSE is disabled, fp_offset in va_list is zero.
4777 static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
4778
4779 unsigned AMD64FpEndOffset;
4780 AllocaInst *VAArgTLSCopy = nullptr;
4781 AllocaInst *VAArgTLSOriginCopy = nullptr;
4782 Value *VAArgOverflowSize = nullptr;
4783
4784 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
4785
4786 VarArgAMD64Helper(Function &F, MemorySanitizer &MS,
4787 MemorySanitizerVisitor &MSV)
4788 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/24) {
4789 AMD64FpEndOffset = AMD64FpEndOffsetSSE;
4790 for (const auto &Attr : F.getAttributes().getFnAttrs()) {
4791 if (Attr.isStringAttribute() &&
4792 (Attr.getKindAsString() == "target-features")) {
4793 if (Attr.getValueAsString().contains("-sse"))
4794 AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
4795 break;
4796 }
4797 }
4798 }
4799
4800 ArgKind classifyArgument(Value *arg) {
4801 // A very rough approximation of X86_64 argument classification rules.
4802 Type *T = arg->getType();
4803 if (T->isX86_FP80Ty())
4804 return AK_Memory;
4805 if (T->isFPOrFPVectorTy() || T->isX86_MMXTy())
4806 return AK_FloatingPoint;
4807 if (T->isIntegerTy() && T->getPrimitiveSizeInBits() <= 64)
4808 return AK_GeneralPurpose;
4809 if (T->isPointerTy())
4810 return AK_GeneralPurpose;
4811 return AK_Memory;
4812 }
4813
4814 // For VarArg functions, store the argument shadow in an ABI-specific format
4815 // that corresponds to va_list layout.
4816 // We do this because Clang lowers va_arg in the frontend, and this pass
4817 // only sees the low level code that deals with va_list internals.
4818 // A much easier alternative (provided that Clang emits va_arg instructions)
4819 // would have been to associate each live instance of va_list with a copy of
4820 // MSanParamTLS, and extract shadow on va_arg() call in the argument list
4821 // order.
4822 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
4823 unsigned GpOffset = 0;
4824 unsigned FpOffset = AMD64GpEndOffset;
4825 unsigned OverflowOffset = AMD64FpEndOffset;
4826 const DataLayout &DL = F.getParent()->getDataLayout();
4827
4828 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
4829 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
4830 bool IsByVal = CB.paramHasAttr(ArgNo, Attribute::ByVal);
4831 if (IsByVal) {
4832 // ByVal arguments always go to the overflow area.
4833 // Fixed arguments passed through the overflow area will be stepped
4834 // over by va_start, so don't count them towards the offset.
4835 if (IsFixed)
4836 continue;
4837 assert(A->getType()->isPointerTy());
4838 Type *RealTy = CB.getParamByValType(ArgNo);
4839 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
4840 uint64_t AlignedSize = alignTo(ArgSize, 8);
4841 unsigned BaseOffset = OverflowOffset;
4842 Value *ShadowBase =
4843 getShadowPtrForVAArgument(RealTy, IRB, OverflowOffset);
4844 Value *OriginBase = nullptr;
4845 if (MS.TrackOrigins)
4846 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
4847 OverflowOffset += AlignedSize;
4848
4849 if (OverflowOffset > kParamTLSSize) {
4850 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
4851 continue; // We have no space to copy shadow there.
4852 }
4853
4854 Value *ShadowPtr, *OriginPtr;
4855 std::tie(ShadowPtr, OriginPtr) =
4856 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), kShadowTLSAlignment,
4857 /*isStore*/ false);
4858 IRB.CreateMemCpy(ShadowBase, kShadowTLSAlignment, ShadowPtr,
4859 kShadowTLSAlignment, ArgSize);
4860 if (MS.TrackOrigins)
4861 IRB.CreateMemCpy(OriginBase, kShadowTLSAlignment, OriginPtr,
4862 kShadowTLSAlignment, ArgSize);
4863 } else {
4864 ArgKind AK = classifyArgument(A);
4865 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
4866 AK = AK_Memory;
4867 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
4868 AK = AK_Memory;
4869 Value *ShadowBase, *OriginBase = nullptr;
4870 switch (AK) {
4871 case AK_GeneralPurpose:
4872 ShadowBase = getShadowPtrForVAArgument(A->getType(), IRB, GpOffset);
4873 if (MS.TrackOrigins)
4874 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
4875 GpOffset += 8;
4876 assert(GpOffset <= kParamTLSSize);
4877 break;
4878 case AK_FloatingPoint:
4879 ShadowBase = getShadowPtrForVAArgument(A->getType(), IRB, FpOffset);
4880 if (MS.TrackOrigins)
4881 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
4882 FpOffset += 16;
4883 assert(FpOffset <= kParamTLSSize);
4884 break;
4885 case AK_Memory:
4886 if (IsFixed)
4887 continue;
4888 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
4889 uint64_t AlignedSize = alignTo(ArgSize, 8);
4890 unsigned BaseOffset = OverflowOffset;
4891 ShadowBase =
4892 getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset);
4893 if (MS.TrackOrigins) {
4894 OriginBase = getOriginPtrForVAArgument(IRB, OverflowOffset);
4895 }
4896 OverflowOffset += AlignedSize;
4897 if (OverflowOffset > kParamTLSSize) {
4898 // We have no space to copy shadow there.
4899 CleanUnusedTLS(IRB, ShadowBase, BaseOffset);
4900 continue;
4901 }
4902 }
4903 // Take fixed arguments into account for GpOffset and FpOffset,
4904 // but don't actually store shadows for them.
4905 // TODO(glider): don't call get*PtrForVAArgument() for them.
4906 if (IsFixed)
4907 continue;
4908 Value *Shadow = MSV.getShadow(A);
4909 IRB.CreateAlignedStore(Shadow, ShadowBase, kShadowTLSAlignment);
4910 if (MS.TrackOrigins) {
4911 Value *Origin = MSV.getOrigin(A);
4912 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
4913 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
4915 }
4916 }
4917 }
4918 Constant *OverflowSize =
4919 ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
4920 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
4921 }
4922
4923 void finalizeInstrumentation() override {
4924 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
4925 "finalizeInstrumentation called twice");
4926 if (!VAStartInstrumentationList.empty()) {
4927 // If there is a va_start in this function, make a backup copy of
4928 // va_arg_tls somewhere in the function entry block.
4929 IRBuilder<> IRB(MSV.FnPrologueEnd);
4930 VAArgOverflowSize =
4931 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
4932 Value *CopySize = IRB.CreateAdd(
4933 ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset), VAArgOverflowSize);
4934 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
4935 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
4936 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
4937 CopySize, kShadowTLSAlignment, false);
4938
4939 Value *SrcSize = IRB.CreateBinaryIntrinsic(
4940 Intrinsic::umin, CopySize,
4941 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
4942 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
4943 kShadowTLSAlignment, SrcSize);
4944 if (MS.TrackOrigins) {
4945 VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
4946 VAArgTLSOriginCopy->setAlignment(kShadowTLSAlignment);
4947 IRB.CreateMemCpy(VAArgTLSOriginCopy, kShadowTLSAlignment,
4948 MS.VAArgOriginTLS, kShadowTLSAlignment, SrcSize);
4949 }
4950 }
4951
4952 // Instrument va_start.
4953 // Copy va_list shadow from the backup copy of the TLS contents.
4954 for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) {
4955 CallInst *OrigInst = VAStartInstrumentationList[i];
4956 NextNodeIRBuilder IRB(OrigInst);
4957 Value *VAListTag = OrigInst->getArgOperand(0);
4958
4959 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
4960 Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr(
4961 IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
4962 ConstantInt::get(MS.IntptrTy, 16)),
4963 PointerType::get(RegSaveAreaPtrTy, 0));
4964 Value *RegSaveAreaPtr =
4965 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
4966 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
4967 const Align Alignment = Align(16);
4968 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
4969 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
4970 Alignment, /*isStore*/ true);
4971 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
4972 AMD64FpEndOffset);
4973 if (MS.TrackOrigins)
4974 IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
4975 Alignment, AMD64FpEndOffset);
4976 Type *OverflowArgAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
4977 Value *OverflowArgAreaPtrPtr = IRB.CreateIntToPtr(
4978 IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
4979 ConstantInt::get(MS.IntptrTy, 8)),
4980 PointerType::get(OverflowArgAreaPtrTy, 0));
4981 Value *OverflowArgAreaPtr =
4982 IRB.CreateLoad(OverflowArgAreaPtrTy, OverflowArgAreaPtrPtr);
4983 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
4984 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
4985 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
4986 Alignment, /*isStore*/ true);
4987 Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
4988 AMD64FpEndOffset);
4989 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
4990 VAArgOverflowSize);
4991 if (MS.TrackOrigins) {
4992 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
4993 AMD64FpEndOffset);
4994 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
4995 VAArgOverflowSize);
4996 }
4997 }
4998 }
4999};
5000
5001/// MIPS64-specific implementation of VarArgHelper.
5002/// NOTE: This is also used for LoongArch64.
5003struct VarArgMIPS64Helper : public VarArgHelperBase {
5004 AllocaInst *VAArgTLSCopy = nullptr;
5005 Value *VAArgSize = nullptr;
5006
5007 VarArgMIPS64Helper(Function &F, MemorySanitizer &MS,
5008 MemorySanitizerVisitor &MSV)
5009 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/8) {}
5010
5011 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
5012 unsigned VAArgOffset = 0;
5013 const DataLayout &DL = F.getParent()->getDataLayout();
5014 for (Value *A :
5016 Triple TargetTriple(F.getParent()->getTargetTriple());
5017 Value *Base;
5018 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
5019 if (TargetTriple.getArch() == Triple::mips64) {
5020 // Adjusting the shadow for argument with size < 8 to match the
5021 // placement of bits in big endian system
5022 if (ArgSize < 8)
5023 VAArgOffset += (8 - ArgSize);
5024 }
5025 Base = getShadowPtrForVAArgument(A->getType(), IRB, VAArgOffset, ArgSize);
5026 VAArgOffset += ArgSize;
5027 VAArgOffset = alignTo(VAArgOffset, 8);
5028 if (!Base)
5029 continue;
5030 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
5031 }
5032
5033 Constant *TotalVAArgSize = ConstantInt::get(IRB.getInt64Ty(), VAArgOffset);
5034 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
5035 // a new class member i.e. it is the total size of all VarArgs.
5036 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
5037 }
5038
5039 void finalizeInstrumentation() override {
5040 assert(!VAArgSize && !VAArgTLSCopy &&
5041 "finalizeInstrumentation called twice");
5042 IRBuilder<> IRB(MSV.FnPrologueEnd);
5043 VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
5044 Value *CopySize =
5045 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize);
5046
5047 if (!VAStartInstrumentationList.empty()) {
5048 // If there is a va_start in this function, make a backup copy of
5049 // va_arg_tls somewhere in the function entry block.
5050 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5051 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
5052 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
5053 CopySize, kShadowTLSAlignment, false);
5054
5055 Value *SrcSize = IRB.CreateBinaryIntrinsic(
5056 Intrinsic::umin, CopySize,
5057 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
5058 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
5059 kShadowTLSAlignment, SrcSize);
5060 }
5061
5062 // Instrument va_start.
5063 // Copy va_list shadow from the backup copy of the TLS contents.
5064 for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) {
5065 CallInst *OrigInst = VAStartInstrumentationList[i];
5066 NextNodeIRBuilder IRB(OrigInst);
5067 Value *VAListTag = OrigInst->getArgOperand(0);
5068 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
5069 Value *RegSaveAreaPtrPtr =
5070 IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5071 PointerType::get(RegSaveAreaPtrTy, 0));
5072 Value *RegSaveAreaPtr =
5073 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5074 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5075 const Align Alignment = Align(8);
5076 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5077 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
5078 Alignment, /*isStore*/ true);
5079 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5080 CopySize);
5081 }
5082 }
5083};
5084
5085/// AArch64-specific implementation of VarArgHelper.
5086struct VarArgAArch64Helper : public VarArgHelperBase {
5087 static const unsigned kAArch64GrArgSize = 64;
5088 static const unsigned kAArch64VrArgSize = 128;
5089
5090 static const unsigned AArch64GrBegOffset = 0;
5091 static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
5092 // Make VR space aligned to 16 bytes.
5093 static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
5094 static const unsigned AArch64VrEndOffset =
5095 AArch64VrBegOffset + kAArch64VrArgSize;
5096 static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
5097
5098 AllocaInst *VAArgTLSCopy = nullptr;
5099 Value *VAArgOverflowSize = nullptr;
5100
5101 enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
5102
5103 VarArgAArch64Helper(Function &F, MemorySanitizer &MS,
5104 MemorySanitizerVisitor &MSV)
5105 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/32) {}
5106
5107 // A very rough approximation of aarch64 argument classification rules.
5108 std::pair<ArgKind, uint64_t> classifyArgument(Type *T) {
5109 if (T->isIntOrPtrTy() && T->getPrimitiveSizeInBits() <= 64)
5110 return {AK_GeneralPurpose, 1};
5111 if (T->isFloatingPointTy() && T->getPrimitiveSizeInBits() <= 128)
5112 return {AK_FloatingPoint, 1};
5113
5114 if (T->isArrayTy()) {
5115 auto R = classifyArgument(T->getArrayElementType());
5116 R.second *= T->getScalarType()->getArrayNumElements();
5117 return R;
5118 }
5119
5120 if (const FixedVectorType *FV = dyn_cast<FixedVectorType>(T)) {
5121 auto R = classifyArgument(FV->getScalarType());
5122 R.second *= FV->getNumElements();
5123 return R;
5124 }
5125
5126 LLVM_DEBUG(errs() << "Unknown vararg type: " << *T << "\n");
5127 return {AK_Memory, 0};
5128 }
5129
5130 // The instrumentation stores the argument shadow in a non ABI-specific
5131 // format because it does not know which argument is named (since Clang,
5132 // like x86_64 case, lowers the va_args in the frontend and this pass only
5133 // sees the low level code that deals with va_list internals).
5134 // The first seven GR registers are saved in the first 56 bytes of the
5135 // va_arg tls arra, followed by the first 8 FP/SIMD registers, and then
5136 // the remaining arguments.
5137 // Using constant offset within the va_arg TLS array allows fast copy
5138 // in the finalize instrumentation.
5139 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
5140 unsigned GrOffset = AArch64GrBegOffset;
5141 unsigned VrOffset = AArch64VrBegOffset;
5142 unsigned OverflowOffset = AArch64VAEndOffset;
5143
5144 const DataLayout &DL = F.getParent()->getDataLayout();
5145 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
5146 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
5147 auto [AK, RegNum] = classifyArgument(A->getType());
5148 if (AK == AK_GeneralPurpose &&
5149 (GrOffset + RegNum * 8) > AArch64GrEndOffset)
5150 AK = AK_Memory;
5151 if (AK == AK_FloatingPoint &&
5152 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
5153 AK = AK_Memory;
5154 Value *Base;
5155 switch (AK) {
5156 case AK_GeneralPurpose:
5157 Base = getShadowPtrForVAArgument(A->getType(), IRB, GrOffset);
5158 GrOffset += 8 * RegNum;
5159 break;
5160 case AK_FloatingPoint:
5161 Base = getShadowPtrForVAArgument(A->getType(), IRB, VrOffset);
5162 VrOffset += 16 * RegNum;
5163 break;
5164 case AK_Memory:
5165 // Don't count fixed arguments in the overflow area - va_start will
5166 // skip right over them.
5167 if (IsFixed)
5168 continue;
5169 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
5170 uint64_t AlignedSize = alignTo(ArgSize, 8);
5171 unsigned BaseOffset = OverflowOffset;
5172 Base = getShadowPtrForVAArgument(A->getType(), IRB, BaseOffset);
5173 OverflowOffset += AlignedSize;
5174 if (OverflowOffset > kParamTLSSize) {
5175 // We have no space to copy shadow there.
5176 CleanUnusedTLS(IRB, Base, BaseOffset);
5177 continue;
5178 }
5179 break;
5180 }
5181 // Count Gp/Vr fixed arguments to their respective offsets, but don't
5182 // bother to actually store a shadow.
5183 if (IsFixed)
5184 continue;
5185 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
5186 }
5187 Constant *OverflowSize =
5188 ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
5189 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
5190 }
5191
5192 // Retrieve a va_list field of 'void*' size.
5193 Value *getVAField64(IRBuilder<> &IRB, Value *VAListTag, int offset) {
5194 Value *SaveAreaPtrPtr = IRB.CreateIntToPtr(
5195 IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5196 ConstantInt::get(MS.IntptrTy, offset)),
5197 PointerType::get(*MS.C, 0));
5198 return IRB.CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
5199 }
5200
5201 // Retrieve a va_list field of 'int' size.
5202 Value *getVAField32(IRBuilder<> &IRB, Value *VAListTag, int offset) {
5203 Value *SaveAreaPtr = IRB.CreateIntToPtr(
5204 IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5205 ConstantInt::get(MS.IntptrTy, offset)),
5206 PointerType::get(*MS.C, 0));
5207 Value *SaveArea32 = IRB.CreateLoad(IRB.getInt32Ty(), SaveAreaPtr);
5208 return IRB.CreateSExt(SaveArea32, MS.IntptrTy);
5209 }
5210
5211 void finalizeInstrumentation() override {
5212 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
5213 "finalizeInstrumentation called twice");
5214 if (!VAStartInstrumentationList.empty()) {
5215 // If there is a va_start in this function, make a backup copy of
5216 // va_arg_tls somewhere in the function entry block.
5217 IRBuilder<> IRB(MSV.FnPrologueEnd);
5218 VAArgOverflowSize =
5219 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
5220 Value *CopySize = IRB.CreateAdd(
5221 ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset), VAArgOverflowSize);
5222 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5223 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
5224 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
5225 CopySize, kShadowTLSAlignment, false);
5226
5227 Value *SrcSize = IRB.CreateBinaryIntrinsic(
5228 Intrinsic::umin, CopySize,
5229 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
5230 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
5231 kShadowTLSAlignment, SrcSize);
5232 }
5233
5234 Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
5235 Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
5236
5237 // Instrument va_start, copy va_list shadow from the backup copy of
5238 // the TLS contents.
5239 for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) {
5240 CallInst *OrigInst = VAStartInstrumentationList[i];
5241 NextNodeIRBuilder IRB(OrigInst);
5242
5243 Value *VAListTag = OrigInst->getArgOperand(0);
5244
5245 // The variadic ABI for AArch64 creates two areas to save the incoming
5246 // argument registers (one for 64-bit general register xn-x7 and another
5247 // for 128-bit FP/SIMD vn-v7).
5248 // We need then to propagate the shadow arguments on both regions
5249 // 'va::__gr_top + va::__gr_offs' and 'va::__vr_top + va::__vr_offs'.
5250 // The remaining arguments are saved on shadow for 'va::stack'.
5251 // One caveat is it requires only to propagate the non-named arguments,
5252 // however on the call site instrumentation 'all' the arguments are
5253 // saved. So to copy the shadow values from the va_arg TLS array
5254 // we need to adjust the offset for both GR and VR fields based on
5255 // the __{gr,vr}_offs value (since they are stores based on incoming
5256 // named arguments).
5257 Type *RegSaveAreaPtrTy = IRB.getPtrTy();
5258
5259 // Read the stack pointer from the va_list.
5260 Value *StackSaveAreaPtr =
5261 IRB.CreateIntToPtr(getVAField64(IRB, VAListTag, 0), RegSaveAreaPtrTy);
5262
5263 // Read both the __gr_top and __gr_off and add them up.
5264 Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
5265 Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
5266
5267 Value *GrRegSaveAreaPtr = IRB.CreateIntToPtr(
5268 IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea), RegSaveAreaPtrTy);
5269
5270 // Read both the __vr_top and __vr_off and add them up.
5271 Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
5272 Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
5273
5274 Value *VrRegSaveAreaPtr = IRB.CreateIntToPtr(
5275 IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea), RegSaveAreaPtrTy);
5276
5277 // It does not know how many named arguments is being used and, on the
5278 // callsite all the arguments were saved. Since __gr_off is defined as
5279 // '0 - ((8 - named_gr) * 8)', the idea is to just propagate the variadic
5280 // argument by ignoring the bytes of shadow from named arguments.
5281 Value *GrRegSaveAreaShadowPtrOff =
5282 IRB.CreateAdd(GrArgSize, GrOffSaveArea);
5283
5284 Value *GrRegSaveAreaShadowPtr =
5285 MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
5286 Align(8), /*isStore*/ true)
5287 .first;
5288
5289 Value *GrSrcPtr =
5290 IRB.CreateInBoundsPtrAdd(VAArgTLSCopy, GrRegSaveAreaShadowPtrOff);
5291 Value *GrCopySize = IRB.CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
5292
5293 IRB.CreateMemCpy(GrRegSaveAreaShadowPtr, Align(8), GrSrcPtr, Align(8),
5294 GrCopySize);
5295
5296 // Again, but for FP/SIMD values.
5297 Value *VrRegSaveAreaShadowPtrOff =
5298 IRB.CreateAdd(VrArgSize, VrOffSaveArea);
5299
5300 Value *VrRegSaveAreaShadowPtr =
5301 MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
5302 Align(8), /*isStore*/ true)
5303 .first;
5304
5305 Value *VrSrcPtr = IRB.CreateInBoundsPtrAdd(
5306 IRB.CreateInBoundsPtrAdd(VAArgTLSCopy,
5307 IRB.getInt32(AArch64VrBegOffset)),
5308 VrRegSaveAreaShadowPtrOff);
5309 Value *VrCopySize = IRB.CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
5310
5311 IRB.CreateMemCpy(VrRegSaveAreaShadowPtr, Align(8), VrSrcPtr, Align(8),
5312 VrCopySize);
5313
5314 // And finally for remaining arguments.
5315 Value *StackSaveAreaShadowPtr =
5316 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.getInt8Ty(),
5317 Align(16), /*isStore*/ true)
5318 .first;
5319
5320 Value *StackSrcPtr = IRB.CreateInBoundsPtrAdd(
5321 VAArgTLSCopy, IRB.getInt32(AArch64VAEndOffset));
5322
5323 IRB.CreateMemCpy(StackSaveAreaShadowPtr, Align(16), StackSrcPtr,
5324 Align(16), VAArgOverflowSize);
5325 }
5326 }
5327};
5328
5329/// PowerPC64-specific implementation of VarArgHelper.
5330struct VarArgPowerPC64Helper : public VarArgHelperBase {
5331 AllocaInst *VAArgTLSCopy = nullptr;
5332 Value *VAArgSize = nullptr;
5333
5334 VarArgPowerPC64Helper(Function &F, MemorySanitizer &MS,
5335 MemorySanitizerVisitor &MSV)
5336 : VarArgHelperBase(F, MS, MSV, /*VAListTagSize=*/8) {}
5337
5338 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
5339 // For PowerPC, we need to deal with alignment of stack arguments -
5340 // they are mostly aligned to 8 bytes, but vectors and i128 arrays
5341 // are aligned to 16 bytes, byvals can be aligned to 8 or 16 bytes,
5342 // For that reason, we compute current offset from stack pointer (which is
5343 // always properly aligned), and offset for the first vararg, then subtract
5344 // them.
5345 unsigned VAArgBase;
5346 Triple TargetTriple(F.getParent()->getTargetTriple());
5347 // Parameter save area starts at 48 bytes from frame pointer for ABIv1,
5348 // and 32 bytes for ABIv2. This is usually determined by target
5349 // endianness, but in theory could be overridden by function attribute.
5350 if (TargetTriple.getArch() == Triple::ppc64)
5351 VAArgBase = 48;
5352 else
5353 VAArgBase = 32;
5354 unsigned VAArgOffset = VAArgBase;
5355 const DataLayout &DL = F.getParent()->getDataLayout();
5356 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
5357 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
5358 bool IsByVal = CB.paramHasAttr(ArgNo, Attribute::ByVal);
5359 if (IsByVal) {
5360 assert(A->getType()->isPointerTy());
5361 Type *RealTy = CB.getParamByValType(ArgNo);
5362 uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
5363 Align ArgAlign = CB.getParamAlign(ArgNo).value_or(Align(8));
5364 if (ArgAlign < 8)
5365 ArgAlign = Align(8);
5366 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
5367 if (!IsFixed) {
5368 Value *Base = getShadowPtrForVAArgument(
5369 RealTy, IRB, VAArgOffset - VAArgBase, ArgSize);
5370 if (Base) {
5371 Value *AShadowPtr, *AOriginPtr;
5372 std::tie(AShadowPtr, AOriginPtr) =
5373 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
5374 kShadowTLSAlignment, /*isStore*/ false);
5375
5376 IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
5377 kShadowTLSAlignment, ArgSize);
5378 }
5379 }
5380 VAArgOffset += alignTo(ArgSize, Align(8));
5381 } else {
5382 Value *Base;
5383 uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
5384 Align ArgAlign = Align(8);
5385 if (A->getType()->isArrayTy()) {
5386 // Arrays are aligned to element size, except for long double
5387 // arrays, which are aligned to 8 bytes.
5388 Type *ElementTy = A->getType()->getArrayElementType();
5389 if (!ElementTy->isPPC_FP128Ty())
5390 ArgAlign = Align(DL.getTypeAllocSize(ElementTy));
5391 } else if (A->getType()->isVectorTy()) {
5392 // Vectors are naturally aligned.
5393 ArgAlign = Align(ArgSize);
5394 }
5395 if (ArgAlign < 8)
5396 ArgAlign = Align(8);
5397 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
5398 if (DL.isBigEndian()) {
5399 // Adjusting the shadow for argument with size < 8 to match the
5400 // placement of bits in big endian system
5401 if (ArgSize < 8)
5402 VAArgOffset += (8 - ArgSize);
5403 }
5404 if (!IsFixed) {
5405 Base = getShadowPtrForVAArgument(A->getType(), IRB,
5406 VAArgOffset - VAArgBase, ArgSize);
5407 if (Base)
5408 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
5409 }
5410 VAArgOffset += ArgSize;
5411 VAArgOffset = alignTo(VAArgOffset, Align(8));
5412 }
5413 if (IsFixed)
5414 VAArgBase = VAArgOffset;
5415 }
5416
5417 Constant *TotalVAArgSize =
5418 ConstantInt::get(IRB.getInt64Ty(), VAArgOffset - VAArgBase);
5419 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
5420 // a new class member i.e. it is the total size of all VarArgs.
5421 IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
5422 }
5423
5424 void finalizeInstrumentation() override {
5425 assert(!VAArgSize && !VAArgTLSCopy &&
5426 "finalizeInstrumentation called twice");
5427 IRBuilder<> IRB(MSV.FnPrologueEnd);
5428 VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
5429 Value *CopySize =
5430 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0), VAArgSize);
5431
5432 if (!VAStartInstrumentationList.empty()) {
5433 // If there is a va_start in this function, make a backup copy of
5434 // va_arg_tls somewhere in the function entry block.
5435
5436 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5437 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
5438 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
5439 CopySize, kShadowTLSAlignment, false);
5440
5441 Value *SrcSize = IRB.CreateBinaryIntrinsic(
5442 Intrinsic::umin, CopySize,
5443 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
5444 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
5445 kShadowTLSAlignment, SrcSize);
5446 }
5447
5448 // Instrument va_start.
5449 // Copy va_list shadow from the backup copy of the TLS contents.
5450 for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) {
5451 CallInst *OrigInst = VAStartInstrumentationList[i];
5452 NextNodeIRBuilder IRB(OrigInst);
5453 Value *VAListTag = OrigInst->getArgOperand(0);
5454 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
5455 Value *RegSaveAreaPtrPtr =
5456 IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5457 PointerType::get(RegSaveAreaPtrTy, 0));
5458 Value *RegSaveAreaPtr =
5459 IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5460 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5461 const Align Alignment = Align(8);
5462 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5463 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
5464 Alignment, /*isStore*/ true);
5465 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5466 CopySize);
5467 }
5468 }
5469};
5470
5471/// SystemZ-specific implementation of VarArgHelper.
5472struct VarArgSystemZHelper : public VarArgHelperBase {
5473 static const unsigned SystemZGpOffset = 16;
5474 static const unsigned SystemZGpEndOffset = 56;
5475 static const unsigned SystemZFpOffset = 128;
5476 static const unsigned SystemZFpEndOffset = 160;
5477 static const unsigned SystemZMaxVrArgs = 8;
5478 static const unsigned SystemZRegSaveAreaSize = 160;
5479 static const unsigned SystemZOverflowOffset = 160;
5480 static const unsigned SystemZVAListTagSize = 32;
5481 static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
5482 static const unsigned SystemZRegSaveAreaPtrOffset = 24;
5483
5484 bool IsSoftFloatABI;
5485 AllocaInst *VAArgTLSCopy = nullptr;
5486 AllocaInst *VAArgTLSOriginCopy = nullptr;
5487 Value *VAArgOverflowSize = nullptr;
5488
5489 enum class ArgKind {
5490 GeneralPurpose,
5491 FloatingPoint,
5492 Vector,
5493 Memory,
5494 Indirect,
5495 };
5496
5497 enum class ShadowExtension { None, Zero, Sign };
5498
5499 VarArgSystemZHelper(Function &F, MemorySanitizer &MS,
5500 MemorySanitizerVisitor &MSV)
5501 : VarArgHelperBase(F, MS, MSV, SystemZVAListTagSize),
5502 IsSoftFloatABI(F.getFnAttribute("use-soft-float").getValueAsBool()) {}
5503
5504 ArgKind classifyArgument(Type *T) {
5505 // T is a SystemZABIInfo::classifyArgumentType() output, and there are
5506 // only a few possibilities of what it can be. In particular, enums, single
5507 // element structs and large types have already been taken care of.
5508
5509 // Some i128 and fp128 arguments are converted to pointers only in the
5510 // back end.
5511 if (T->isIntegerTy(128) || T->isFP128Ty())
5512 return ArgKind::Indirect;
5513 if (T->isFloatingPointTy())
5514 return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
5515 if (T->isIntegerTy() || T->isPointerTy())
5516 return ArgKind::GeneralPurpose;
5517 if (T->isVectorTy())
5518 return ArgKind::Vector;
5519 return ArgKind::Memory;
5520 }
5521
5522 ShadowExtension getShadowExtension(const CallBase &CB, unsigned ArgNo) {
5523 // ABI says: "One of the simple integer types no more than 64 bits wide.
5524 // ... If such an argument is shorter than 64 bits, replace it by a full
5525 // 64-bit integer representing the same number, using sign or zero
5526 // extension". Shadow for an integer argument has the same type as the
5527 // argument itself, so it can be sign or zero extended as well.
5528 bool ZExt = CB.paramHasAttr(ArgNo, Attribute::ZExt);
5529 bool SExt = CB.paramHasAttr(ArgNo, Attribute::SExt);
5530 if (ZExt) {
5531 assert(!SExt);
5532 return ShadowExtension::Zero;
5533 }
5534 if (SExt) {
5535 assert(!ZExt);
5536 return ShadowExtension::Sign;
5537 }
5538 return ShadowExtension::None;
5539 }
5540
5541 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
5542 unsigned GpOffset = SystemZGpOffset;
5543 unsigned FpOffset = SystemZFpOffset;
5544 unsigned VrIndex = 0;
5545 unsigned OverflowOffset = SystemZOverflowOffset;
5546 const DataLayout &DL = F.getParent()->getDataLayout();
5547 for (const auto &[ArgNo, A] : llvm::enumerate(CB.args())) {
5548 bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
5549 // SystemZABIInfo does not produce ByVal parameters.
5550 assert(!CB.paramHasAttr(ArgNo, Attribute::ByVal));
5551 Type *T = A->getType();
5552 ArgKind AK = classifyArgument(T);
5553 if (AK == ArgKind::Indirect) {
5554 T = PointerType::get(T, 0);
5555 AK = ArgKind::GeneralPurpose;
5556 }
5557 if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
5558 AK = ArgKind::Memory;
5559 if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
5560 AK = ArgKind::Memory;
5561 if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
5562 AK = ArgKind::Memory;
5563 Value *ShadowBase = nullptr;
5564 Value *OriginBase = nullptr;
5565 ShadowExtension SE = ShadowExtension::None;
5566 switch (AK) {
5567 case ArgKind::GeneralPurpose: {
5568 // Always keep track of GpOffset, but store shadow only for varargs.
5569 uint64_t ArgSize = 8;
5570 if (GpOffset + ArgSize <= kParamTLSSize) {
5571 if (!IsFixed) {
5572 SE = getShadowExtension(CB, ArgNo);
5573 uint64_t GapSize = 0;
5574 if (SE == ShadowExtension::None) {
5575 uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
5576 assert(ArgAllocSize <= ArgSize);
5577 GapSize = ArgSize - ArgAllocSize;
5578 }
5579 ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
5580 if (MS.TrackOrigins)
5581 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
5582 }
5583 GpOffset += ArgSize;
5584 } else {
5585 GpOffset = kParamTLSSize;
5586 }
5587 break;
5588 }
5589 case ArgKind::FloatingPoint: {
5590 // Always keep track of FpOffset, but store shadow only for varargs.
5591 uint64_t ArgSize = 8;
5592 if (FpOffset + ArgSize <= kParamTLSSize) {
5593 if (!IsFixed) {
5594 // PoP says: "A short floating-point datum requires only the
5595 // left-most 32 bit positions of a floating-point register".
5596 // Therefore, in contrast to AK_GeneralPurpose and AK_Memory,
5597 // don't extend shadow and don't mind the gap.
5598 ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
5599 if (MS.TrackOrigins)
5600 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
5601 }
5602 FpOffset += ArgSize;
5603 } else {
5604 FpOffset = kParamTLSSize;
5605 }
5606 break;
5607 }
5608 case ArgKind::Vector: {
5609 // Keep track of VrIndex. No need to store shadow, since vector varargs
5610 // go through AK_Memory.
5611 assert(IsFixed);
5612 VrIndex++;
5613 break;
5614 }
5615 case ArgKind::Memory: {
5616 // Keep track of OverflowOffset and store shadow only for varargs.
5617 // Ignore fixed args, since we need to copy only the vararg portion of
5618 // the overflow area shadow.
5619 if (!IsFixed) {
5620 uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
5621 uint64_t ArgSize = alignTo(ArgAllocSize, 8);
5622 if (OverflowOffset + ArgSize <= kParamTLSSize) {
5623 SE = getShadowExtension(CB, ArgNo);
5624 uint64_t GapSize =
5625 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
5626 ShadowBase =
5627 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
5628 if (MS.TrackOrigins)
5629 OriginBase =
5630 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
5631 OverflowOffset += ArgSize;
5632 } else {
5633 OverflowOffset = kParamTLSSize;
5634 }
5635 }
5636 break;
5637 }
5638 case ArgKind::Indirect:
5639 llvm_unreachable("Indirect must be converted to GeneralPurpose");
5640 }
5641 if (ShadowBase == nullptr)
5642 continue;
5643 Value *Shadow = MSV.getShadow(A);
5644 if (SE != ShadowExtension::None)
5645 Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.getInt64Ty(),
5646 /*Signed*/ SE == ShadowExtension::Sign);
5647 ShadowBase = IRB.CreateIntToPtr(
5648 ShadowBase, PointerType::get(Shadow->getType(), 0), "_msarg_va_s");
5649 IRB.CreateStore(Shadow, ShadowBase);
5650 if (MS.TrackOrigins) {
5651 Value *Origin = MSV.getOrigin(A);
5652 TypeSize StoreSize = DL.getTypeStoreSize(Shadow->getType());
5653 MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
5655 }
5656 }
5657 Constant *OverflowSize = ConstantInt::get(
5658 IRB.getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
5659 IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
5660 }
5661
5662 void copyRegSaveArea(IRBuilder<> &IRB, Value *VAListTag) {
5663 Type *RegSaveAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
5664 Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr(
5665 IRB.CreateAdd(
5666 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5667 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
5668 PointerType::get(RegSaveAreaPtrTy, 0));
5669 Value *RegSaveAreaPtr = IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5670 Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5671 const Align Alignment = Align(8);
5672 std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5673 MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(), Alignment,
5674 /*isStore*/ true);
5675 // TODO(iii): copy only fragments filled by visitCallBase()
5676 // TODO(iii): support packed-stack && !use-soft-float
5677 // For use-soft-float functions, it is enough to copy just the GPRs.
5678 unsigned RegSaveAreaSize =
5679 IsSoftFloatABI ? SystemZGpEndOffset : SystemZRegSaveAreaSize;
5680 IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5681 RegSaveAreaSize);
5682 if (MS.TrackOrigins)
5683 IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
5684 Alignment, RegSaveAreaSize);
5685 }
5686
5687 // FIXME: This implementation limits OverflowOffset to kParamTLSSize, so we
5688 // don't know real overflow size and can't clear shadow beyond kParamTLSSize.
5689 void copyOverflowArea(IRBuilder<> &IRB, Value *VAListTag) {
5690 Type *OverflowArgAreaPtrTy = PointerType::getUnqual(*MS.C); // i64*
5691 Value *OverflowArgAreaPtrPtr = IRB.CreateIntToPtr(
5692 IRB.CreateAdd(
5693 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5694 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
5695 PointerType::get(OverflowArgAreaPtrTy, 0));
5696 Value *OverflowArgAreaPtr =
5697 IRB.CreateLoad(OverflowArgAreaPtrTy, OverflowArgAreaPtrPtr);
5698 Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
5699 const Align Alignment = Align(8);
5700 std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
5701 MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
5702 Alignment, /*isStore*/ true);
5703 Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
5704 SystemZOverflowOffset);
5705 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
5706 VAArgOverflowSize);
5707 if (MS.TrackOrigins) {
5708 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
5709 SystemZOverflowOffset);
5710 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
5711 VAArgOverflowSize);
5712 }
5713 }
5714
5715 void finalizeInstrumentation() override {
5716 assert(!VAArgOverflowSize && !VAArgTLSCopy &&
5717 "finalizeInstrumentation called twice");
5718 if (!VAStartInstrumentationList.empty()) {
5719 // If there is a va_start in this function, make a backup copy of
5720 // va_arg_tls somewhere in the function entry block.
5721 IRBuilder<> IRB(MSV.FnPrologueEnd);
5722 VAArgOverflowSize =
5723 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
5724 Value *CopySize =
5725 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
5726 VAArgOverflowSize);
5727 VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5728 VAArgTLSCopy->setAlignment(kShadowTLSAlignment);
5729 IRB.CreateMemSet(VAArgTLSCopy, Constant::getNullValue(IRB.getInt8Ty()),
5730 CopySize, kShadowTLSAlignment, false);
5731
5732 Value *SrcSize = IRB.CreateBinaryIntrinsic(
5733 Intrinsic::umin, CopySize,
5734 ConstantInt::get(MS.IntptrTy, kParamTLSSize));
5735 IRB.CreateMemCpy(VAArgTLSCopy, kShadowTLSAlignment, MS.VAArgTLS,
5736 kShadowTLSAlignment, SrcSize);
5737 if (MS.TrackOrigins) {
5738 VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5739 VAArgTLSOriginCopy->setAlignment(kShadowTLSAlignment);
5740 IRB.CreateMemCpy(VAArgTLSOriginCopy, kShadowTLSAlignment,
5741 MS.VAArgOriginTLS, kShadowTLSAlignment, SrcSize);
5742 }
5743 }
5744
5745 // Instrument va_start.
5746 // Copy va_list shadow from the backup copy of the TLS contents.
5747 for (size_t VaStartNo = 0, VaStartNum = VAStartInstrumentationList.size();
5748 VaStartNo < VaStartNum; VaStartNo++) {
5749 CallInst *OrigInst = VAStartInstrumentationList[VaStartNo];
5750 NextNodeIRBuilder IRB(OrigInst);
5751 Value *VAListTag = OrigInst->getArgOperand(0);
5752 copyRegSaveArea(IRB, VAListTag);
5753 copyOverflowArea(IRB, VAListTag);
5754 }
5755 }
5756};
5757
5758// Loongarch64 is not a MIPS, but the current vargs calling convention matches
5759// the MIPS.
5760using VarArgLoongArch64Helper = VarArgMIPS64Helper;
5761
5762/// A no-op implementation of VarArgHelper.
5763struct VarArgNoOpHelper : public VarArgHelper {
5764 VarArgNoOpHelper(Function &F, MemorySanitizer &MS,
5765 MemorySanitizerVisitor &MSV) {}
5766
5767 void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {}
5768
5769 void visitVAStartInst(VAStartInst &I) override {}
5770
5771 void visitVACopyInst(VACopyInst &I) override {}
5772
5773 void finalizeInstrumentation() override {}
5774};
5775
5776} // end anonymous namespace
5777
5778static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
5779 MemorySanitizerVisitor &Visitor) {
5780 // VarArg handling is only implemented on AMD64. False positives are possible
5781 // on other platforms.
5782 Triple TargetTriple(Func.getParent()->getTargetTriple());
5783 if (TargetTriple.getArch() == Triple::x86_64)
5784 return new VarArgAMD64Helper(Func, Msan, Visitor);
5785 else if (TargetTriple.isMIPS64())
5786 return new VarArgMIPS64Helper(Func, Msan, Visitor);
5787 else if (TargetTriple.getArch() == Triple::aarch64)
5788 return new VarArgAArch64Helper(Func, Msan, Visitor);
5789 else if (TargetTriple.getArch() == Triple::ppc64 ||
5790 TargetTriple.getArch() == Triple::ppc64le)
5791 return new VarArgPowerPC64Helper(Func, Msan, Visitor);
5792 else if (TargetTriple.getArch() == Triple::systemz)
5793 return new VarArgSystemZHelper(Func, Msan, Visitor);
5794 else if (TargetTriple.isLoongArch64())
5795 return new VarArgLoongArch64Helper(Func, Msan, Visitor);
5796 else
5797 return new VarArgNoOpHelper(Func, Msan, Visitor);
5798}
5799
5800bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
5801 if (!CompileKernel && F.getName() == kMsanModuleCtorName)
5802 return false;
5803
5804 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
5805 return false;
5806
5807 MemorySanitizerVisitor Visitor(F, *this, TLI);
5808
5809 // Clear out memory attributes.
5811 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
5812 F.removeFnAttrs(B);
5813
5814 return Visitor.runOnFunction();
5815}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const LLT S1
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isStore(int Opcode)
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static const size_t kNumberOfAccessSizes
VarLocInsertPt getNextNode(const DbgRecord *DVR)
Atomic ordering constants.
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static AtomicOrdering addReleaseOrdering(AtomicOrdering AO)
static AtomicOrdering addAcquireOrdering(AtomicOrdering AO)
static bool isAMustTailRetVal(Value *RetVal)
return RetTy
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
Definition: DebugCounter.h:182
#define LLVM_DEBUG(X)
Definition: Debug.h:101
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
@ Default
Definition: DwarfDebug.cpp:87
uint64_t Addr
std::string Name
uint64_t Size
bool End
Definition: ELF_riscv.cpp:480
static bool runOnFunction(Function &F, bool PostInlining)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool isSigned(unsigned int Opcode)
This is the interface for a simple mod/ref and alias analysis over globals.
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
#define op(i)
Hexagon Common GEP
#define _
Hexagon Vector Combine
static LVOptions Options
Definition: LVOptions.cpp:25
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
static const MemoryMapParams Linux_LoongArch64_MemoryMapParams
static const PlatformMemoryMapParams Linux_S390_MemoryMapParams
static const Align kMinOriginAlignment
static const MemoryMapParams Linux_X86_64_MemoryMapParams
static cl::opt< uint64_t > ClShadowBase("msan-shadow-base", cl::desc("Define custom MSan ShadowBase"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClDumpStrictInstructions("msan-dump-strict-instructions", cl::desc("print out instructions with default strict semantics"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClHandleICmpExact("msan-handle-icmp-exact", cl::desc("exact handling of relational integer ICmp"), cl::Hidden, cl::init(false))
static const PlatformMemoryMapParams Linux_X86_MemoryMapParams
static cl::opt< uint64_t > ClOriginBase("msan-origin-base", cl::desc("Define custom MSan OriginBase"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClCheckConstantShadow("msan-check-constant-shadow", cl::desc("Insert checks for constant shadow values"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams
static const MemoryMapParams NetBSD_X86_64_MemoryMapParams
static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
static const unsigned kOriginSize
static cl::opt< bool > ClWithComdat("msan-with-comdat", cl::desc("Place MSan constructors in comdat sections"), cl::Hidden, cl::init(false))
static cl::opt< int > ClTrackOrigins("msan-track-origins", cl::desc("Track origins (allocation sites) of poisoned memory"), cl::Hidden, cl::init(0))
Track origins of uninitialized values.
static cl::opt< int > ClInstrumentationWithCallThreshold("msan-instrumentation-with-call-threshold", cl::desc("If the function being instrumented requires more than " "this number of checks and origin stores, use callbacks instead of " "inline checks (-1 means never use callbacks)."), cl::Hidden, cl::init(3500))
static cl::opt< int > ClPoisonStackPattern("msan-poison-stack-pattern", cl::desc("poison uninitialized stack variables with the given pattern"), cl::Hidden, cl::init(0xff))
static const Align kShadowTLSAlignment
static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
static Constant * getOrInsertGlobal(Module &M, StringRef Name, Type *Ty)
static const MemoryMapParams Linux_S390X_MemoryMapParams
static cl::opt< bool > ClPoisonUndef("msan-poison-undef", cl::desc("poison undef temps"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClPoisonStack("msan-poison-stack", cl::desc("poison uninitialized stack variables"), cl::Hidden, cl::init(true))
static const MemoryMapParams Linux_I386_MemoryMapParams
const char kMsanInitName[]
static cl::opt< bool > ClPrintStackNames("msan-print-stack-names", cl::desc("Print name of local stack variable"), cl::Hidden, cl::init(true))
static const MemoryMapParams Linux_AArch64_MemoryMapParams
static cl::opt< uint64_t > ClAndMask("msan-and-mask", cl::desc("Define custom MSan AndMask"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClHandleLifetimeIntrinsics("msan-handle-lifetime-intrinsics", cl::desc("when possible, poison scoped variables at the beginning of the scope " "(slower, but more precise)"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClKeepGoing("msan-keep-going", cl::desc("keep going after reporting a UMR"), cl::Hidden, cl::init(false))
static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams
static GlobalVariable * createPrivateConstGlobalForString(Module &M, StringRef Str)
Create a non-const global initialized with the given string.
static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams
static const size_t kNumberOfAccessSizes
static cl::opt< bool > ClEagerChecks("msan-eager-checks", cl::desc("check arguments and return values at function call boundaries"), cl::Hidden, cl::init(false))
static cl::opt< int > ClDisambiguateWarning("msan-disambiguate-warning-threshold", cl::desc("Define threshold for number of checks per " "debug location to force origin update."), cl::Hidden, cl::init(3))
static VarArgHelper * CreateVarArgHelper(Function &Func, MemorySanitizer &Msan, MemorySanitizerVisitor &Visitor)
static const MemoryMapParams Linux_MIPS64_MemoryMapParams
static const MemoryMapParams Linux_PowerPC64_MemoryMapParams
static cl::opt< uint64_t > ClXorMask("msan-xor-mask", cl::desc("Define custom MSan XorMask"), cl::Hidden, cl::init(0))
static cl::opt< bool > ClHandleAsmConservative("msan-handle-asm-conservative", cl::desc("conservative handling of inline assembly"), cl::Hidden, cl::init(true))
static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams
static const unsigned kParamTLSSize
static cl::opt< bool > ClHandleICmp("msan-handle-icmp", cl::desc("propagate shadow through ICmpEQ and ICmpNE"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClEnableKmsan("msan-kernel", cl::desc("Enable KernelMemorySanitizer instrumentation"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClPoisonStackWithCall("msan-poison-stack-with-call", cl::desc("poison uninitialized stack variables with a call"), cl::Hidden, cl::init(false))
static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams
static const unsigned kRetvalTLSSize
static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams
const char kMsanModuleCtorName[]
static const MemoryMapParams FreeBSD_I386_MemoryMapParams
static cl::opt< bool > ClCheckAccessAddress("msan-check-access-address", cl::desc("report accesses through a pointer which has poisoned shadow"), cl::Hidden, cl::init(true))
static cl::opt< bool > ClDisableChecks("msan-disable-checks", cl::desc("Apply no_sanitize to the whole file"), cl::Hidden, cl::init(false))
Module.h This file contains the declarations for the Module class.
FunctionAnalysisManager FAM
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static const char * name
Definition: SMEABIPass.cpp:49
raw_pwrite_stream & OS
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
This file contains some functions that are useful when dealing with strings.
static SymbolRef::Type getType(const Symbol *Sym)
Definition: TapiFile.cpp:40
@ Struct
@ None
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition: APInt.h:76
an instruction to allocate memory on the stack
Definition: Instructions.h:59
void setAlignment(Align Align)
Definition: Instructions.h:136
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:321
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:473
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
const T & front() const
front - Get the first element.
Definition: ArrayRef.h:168
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Definition: Type.cpp:647
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:539
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:748
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
iterator end()
Definition: BasicBlock.h:443
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
Definition: BasicBlock.cpp:409
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
Definition: BasicBlock.cpp:452
InstListType::iterator iterator
Instruction iterators...
Definition: BasicBlock.h:165
This class represents a no-op cast from one type to another.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1494
bool isInlineAsm() const
Check if this call is an inline asm statement.
Definition: InstrTypes.h:1809
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1742
bool hasRetAttr(Attribute::AttrKind Kind) const
Determine whether the return value has the given attribute.
Definition: InstrTypes.h:1945
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
void setCannotMerge()
Definition: InstrTypes.h:2281
MaybeAlign getParamAlign(unsigned ArgNo) const
Extract the alignment for a call or parameter (0=unknown).
Definition: InstrTypes.h:2104
Type * getParamByValType(unsigned ArgNo) const
Extract the byval type for a call or parameter.
Definition: InstrTypes.h:2113
Value * getCalledOperand() const
Definition: InstrTypes.h:1735
Type * getParamElementType(unsigned ArgNo) const
Extract the elementtype type for a parameter.
Definition: InstrTypes.h:2151
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1687
void setArgOperand(unsigned i, Value *v)
Definition: InstrTypes.h:1692
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1600
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
Definition: InstrTypes.h:1678
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Adds the attribute to the indicated argument.
Definition: InstrTypes.h:1871
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
Definition: InstrTypes.h:601
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:993
@ ICMP_SLT
signed less than
Definition: InstrTypes.h:1022
@ ICMP_SLE
signed less or equal
Definition: InstrTypes.h:1023
@ ICMP_SGT
signed greater than
Definition: InstrTypes.h:1020
@ ICMP_SGE
signed greater or equal
Definition: InstrTypes.h:1021
Combiner implementation.
Definition: Combiner.h:34
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1291
static Constant * getString(LLVMContext &Context, StringRef Initializer, bool AddNull=true)
This method constructs a CDS and initializes it with a text string.
Definition: Constants.cpp:2881
static Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with vector type with an element count and element type matchi...
Definition: Constants.cpp:2897
This is the shared class of boolean and integer constants.
Definition: Constants.h:80
static ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
Definition: Constants.h:123
static Constant * get(StructType *T, ArrayRef< Constant * > V)
Definition: Constants.cpp:1356
static Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
Definition: Constants.cpp:1449
static Constant * get(ArrayRef< Constant * > V)
Definition: Constants.cpp:1398
This is an important base class in LLVM.
Definition: Constant.h:41
static Constant * getAllOnesValue(Type *Ty)
Definition: Constants.cpp:417
bool isAllOnesValue() const
Return true if this is the value that would be returned by getAllOnesValue.
Definition: Constants.cpp:107
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:370
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
Definition: Constants.cpp:432
bool isZeroValue() const
Return true if the value is negative zero or null value.
Definition: Constants.cpp:76
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
Definition: Constants.cpp:90
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:110
static bool shouldExecute(unsigned CounterName)
Definition: DebugCounter.h:72
A debug info location.
Definition: DebugLoc.h:33
bool empty() const
Definition: DenseMap.h:98
This instruction extracts a single (scalar) element from a VectorType value.
This instruction extracts a struct member or array element value from an aggregate value.
This instruction compares its operands according to the predicate given to the constructor.
Class to represent fixed width SIMD vectors.
Definition: DerivedTypes.h:539
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition: Type.cpp:692
This class represents a freeze function that returns random concrete value if an operand is either a ...
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:168
unsigned getNumParams() const
Return the number of fixed parameters this function type requires.
Definition: DerivedTypes.h:142
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:973
void setComdat(Comdat *C)
Definition: Globals.cpp:197
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:60
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:52
Analysis pass providing a never-invalidated alias analysis result.
This instruction compares its operands according to the predicate given to the constructor.
CallInst * CreateMaskedCompressStore(Value *Val, Value *Ptr, Value *Mask=nullptr)
Create a call to Masked Compress Store intrinsic.
Definition: IRBuilder.cpp:704
CallInst * CreateMaskedExpandLoad(Type *Ty, Value *Ptr, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Expand Load intrinsic.
Definition: IRBuilder.cpp:686
Value * CreateBinaryIntrinsic(Intrinsic::ID ID, Value *LHS, Value *RHS, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with 2 operands which is mangled on the first type.
Definition: IRBuilder.cpp:921
Value * CreateInsertElement(Type *VecTy, Value *NewElt, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2472
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
Definition: IRBuilder.h:1881
AllocaInst * CreateAlloca(Type *Ty, unsigned AddrSpace, Value *ArraySize=nullptr, const Twine &Name="")
Definition: IRBuilder.h:1773
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2523
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Definition: IRBuilder.h:2460
IntegerType * getIntNTy(unsigned N)
Fetch the type representing an N-bit integer.
Definition: IRBuilder.h:539
LoadInst * CreateAlignedLoad(Type *Ty, Value *Ptr, MaybeAlign Align, const char *Name)
Definition: IRBuilder.h:1807
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
Definition: IRBuilder.h:2039
CallInst * CreateAndReduce(Value *Src)
Create a vector int AND reduction intrinsic of the source vector.
Definition: IRBuilder.cpp:441
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2170
Value * CreateExtractValue(Value *Agg, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition: IRBuilder.h:2516
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
Definition: IRBuilder.cpp:932
CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
Definition: IRBuilder.cpp:578
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memset to the specified pointer and the specified value.
Definition: IRBuilder.h:595
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Definition: IRBuilder.cpp:1110
BasicBlock::iterator GetInsertPoint() const
Definition: IRBuilder.h:175
Value * CreateSExt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2033
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2122
Value * CreateTypeSize(Type *DstType, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Definition: IRBuilder.cpp:104
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1437
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition: IRBuilder.h:526
ConstantInt * getInt8(uint8_t C)
Get a constant 8-bit value.
Definition: IRBuilder.h:476
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Definition: IRBuilder.h:531
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1378
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2245
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Definition: IRBuilder.h:1721
CallInst * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
Definition: IRBuilder.cpp:445
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
Definition: IRBuilder.h:486
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition: IRBuilder.h:2397
Value * CreateNot(Value *V, const Twine &Name="")
Definition: IRBuilder.h:1749
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2241
DebugLoc getCurrentDebugLocation() const
Get location information used by debugging information.
Definition: IRBuilder.cpp:63
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1344
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2127
ConstantInt * getIntN(unsigned N, uint64_t C)
Get a constant N-bit value, zero extended or truncated from a 64-bit value.
Definition: IRBuilder.h:497
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition: IRBuilder.h:1790
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1416
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition: IRBuilder.h:2021
Value * CreateShuffleVector(Value *V1, Value *V2, Value *Mask, const Twine &Name="")
Definition: IRBuilder.h:2494
LLVMContext & getContext() const
Definition: IRBuilder.h:176
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1475
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1803
CallInst * CreateMaskedStore(Value *Val, Value *Ptr, Align Alignment, Value *Mask)
Create a call to Masked Store intrinsic.
Definition: IRBuilder.cpp:598
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1327
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2117
Value * CreateIsNotNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg != 0.
Definition: IRBuilder.h:2549
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition: IRBuilder.h:2007
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1497
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Definition: IRBuilder.h:569
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:1666
Value * CreateICmpSLT(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2273
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition: IRBuilder.h:2196
Value * CreateIsNull(Value *Arg, const Twine &Name="")
Return a boolean value testing if Arg == 0.
Definition: IRBuilder.h:2544
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition: IRBuilder.h:180
StoreInst * CreateAlignedStore(Value *Val, Value *Ptr, MaybeAlign Align, bool isVolatile=false)
Definition: IRBuilder.h:1826
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2412
Value * CreateInBoundsPtrAdd(Value *Ptr, Value *Offset, const Twine &Name="")
Definition: IRBuilder.h:1983
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1519
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", bool IsInBounds=false)
Definition: IRBuilder.h:1866
Value * CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2351
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition: IRBuilder.h:516
CallInst * CreateMemCpy(Value *Dst, MaybeAlign DstAlign, Value *Src, MaybeAlign SrcAlign, uint64_t Size, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *TBAAStructTag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memcpy between the specified pointers.
Definition: IRBuilder.h:659
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1361
CallInst * CreateMaskedScatter(Value *Val, Value *Ptrs, Align Alignment, Value *Mask=nullptr)
Create a call to Masked Scatter intrinsic.
Definition: IRBuilder.cpp:661
CallInst * CreateMaskedGather(Type *Ty, Value *Ptrs, Align Alignment, Value *Mask=nullptr, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Gather intrinsic.
Definition: IRBuilder.cpp:630
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2666
std::vector< ConstraintInfo > ConstraintInfoVector
Definition: InlineAsm.h:121
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:631
This instruction inserts a single (scalar) element into a VectorType value.
This instruction inserts a struct field of array element value into an aggregate value.
Base class for instruction visitors.
Definition: InstVisitor.h:78
void visit(Iterator Start, Iterator End)
Definition: InstVisitor.h:87
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:454
const BasicBlock * getParent() const
Definition: Instruction.h:152
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:359
This class represents a cast from an integer to a pointer.
Class to represent integer types.
Definition: DerivedTypes.h:40
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:278
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:47
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
The landingpad instruction holds all of the information necessary to generate correct exception handl...
An instruction for reading from memory.
Definition: Instructions.h:184
MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
Definition: MDBuilder.cpp:47
Metadata node.
Definition: Metadata.h:1067
This class wraps the llvm.memcpy intrinsic.
This class wraps the llvm.memmove intrinsic.
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
In order to facilitate speculative execution, many instructions do not invoke immediate undefined beh...
Definition: Constants.h:1396
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1827
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:109
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:115
void abandon()
Mark an analysis as abandoned.
Definition: Analysis.h:162
This class represents a cast from a pointer to an integer.
Resume the propagation of an exception.
Return a value (possibly void), from a function.
This class represents a sign extension of integer types.
This class represents the LLVM 'select' instruction.
bool remove(const value_type &X)
Remove an item from the set vector.
Definition: SetVector.h:188
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
This instruction constructs a fixed permutation of two input vectors.
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:370
bool empty() const
Definition: SmallVector.h:94
size_t size() const
Definition: SmallVector.h:91
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
An instruction for storing to memory.
Definition: Instructions.h:317
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Class to represent struct types.
Definition: DerivedTypes.h:216
static StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition: Type.cpp:373
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
AttributeList getAttrList(LLVMContext *C, ArrayRef< unsigned > ArgNos, bool Signed, bool Ret=false, AttributeList AL=AttributeList()) const
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
bool isMIPS64() const
Tests whether the target is MIPS 64-bit (little and big endian).
Definition: Triple.h:938
@ aarch64_be
Definition: Triple.h:52
@ loongarch64
Definition: Triple.h:62
@ mips64el
Definition: Triple.h:67
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition: Triple.h:372
bool isLoongArch64() const
Tests whether the target is 64-bit LoongArch.
Definition: Triple.h:927
This class represents a truncation of integer types.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
unsigned getIntegerBitWidth() const
bool isVectorTy() const
True if this is an instance of VectorType.
Definition: Type.h:265
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:255
bool isPPC_FP128Ty() const
Return true if this is powerpc long double.
Definition: Type.h:166
static Type * getX86_MMXTy(LLVMContext &C)
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
static Type * getVoidTy(LLVMContext &C)
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:302
static IntegerType * getInt8Ty(LLVMContext &C)
bool isIntOrPtrTy() const
Return true if this is an integer type or a pointer type.
Definition: Type.h:243
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:228
TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition: Type.h:348
'undef' values are things that do not have specified contents.
Definition: Constants.h:1348
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
Value * getOperand(unsigned i) const
Definition: User.h:169
unsigned getNumOperands() const
Definition: User.h:191
This represents the llvm.va_copy intrinsic.
This represents the llvm.va_start intrinsic.
See the file comment.
Definition: ValueMap.h:84
size_type count(const KeyT &Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: ValueMap.h:151
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:377
This class represents zero extension of integer types.
int getNumOccurrences() const
Definition: CommandLine.h:406
constexpr ScalarTy getFixedValue() const
Definition: TypeSize.h:187
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition: TypeSize.h:171
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
Definition: ilist_node.h:109
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This class provides various memory handling functions that manipulate MemoryBlock instances.
Definition: Memory.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:121
@ Win64
The C convention as implemented on Windows/x86-64 and AArch64.
Definition: CallingConv.h:159
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1465
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:450
Function * Kernel
Summary of a kernel (=entry point for target offloading).
Definition: OpenMPOpt.h:21
NodeAddr< FuncNode * > Func
Definition: RDFGraph.h:393
@ FalseVal
Definition: TGLexer.h:59
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition: MathExtras.h:337
void stable_sort(R &&Range)
Definition: STLExtras.h:1995
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1680
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are are tuples (A,...
Definition: STLExtras.h:2406
AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
@ Done
Definition: Threading.h:61
std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef(), bool Weak=false)
Creates sanitizer constructor function lazily.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:156
bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
AtomicOrdering
Atomic ordering for LLVM's memory model.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
@ Or
Bitwise or logical OR of integers.
@ Add
Sum of integers.
std::pair< Instruction *, Value * > SplitBlockAndInsertSimpleForLoop(Value *End, Instruction *SplitBefore)
Insert a for (int i = 0; i < End; i++) loop structure (with the exception that End is assumed > 0,...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:191
void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
Definition: ModuleUtils.cpp:73
iterator_range< df_iterator< T > > depth_first(const T &G)
Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
Definition: Local.cpp:4040
bool removeUnreachableBlocks(Function &F, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Remove all blocks that can not be reached from the function's entry.
Definition: Local.cpp:3197
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:74