1 //===- MemorySanitizer.cpp - detector of uninitialized reads --------------===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file is a part of MemorySanitizer, a detector of uninitialized
13 /// The algorithm of the tool is similar to Memcheck
14 /// (https://static.usenix.org/event/usenix05/tech/general/full_papers/seward/seward_html/usenix2005.html)
15 /// We associate a few shadow bits with every byte of the application memory,
16 /// poison the shadow of the malloc-ed or alloca-ed memory, load the shadow,
17 /// bits on every memory read, propagate the shadow bits through some of the
18 /// arithmetic instruction (including MOV), store the shadow bits on every
19 /// memory write, report a bug on some other instructions (e.g. JMP) if the
20 /// associated shadow is poisoned.
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).
37 /// The default value of shadow is 0, which means "clean" (not poisoned).
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).
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.
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.
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
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.
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.
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).
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
92 /// Instrumenting inline assembly.
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.
109 /// KernelMemorySanitizer (KMSAN) implementation.
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
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, in PowerPC64 they are
128 /// returned in r3 and r4, and in the SystemZ ABI they are written to memory
129 /// pointed to by a hidden parameter.
130 /// - TLS variables are stored in a single per-task struct. A call to a
131 /// function __msan_get_context_state() returning a pointer to that struct
132 /// is inserted into every instrumented function before the entry block;
133 /// - __msan_warning() takes a 32-bit origin parameter;
134 /// - local variables are poisoned with __msan_poison_alloca() upon function
135 /// entry and unpoisoned with __msan_unpoison_alloca() before leaving the
137 /// - the pass doesn't declare any global variables or add global constructors
138 /// to the translation unit.
140 /// Also, KMSAN currently ignores uninitialized memory passed into inline asm
141 /// calls, making sure we're on the safe side wrt. possible false positives.
143 /// KernelMemorySanitizer only supports X86_64, SystemZ and PowerPC64 at the
147 // FIXME: This sanitizer does not yet handle scalable vectors
149 //===----------------------------------------------------------------------===//
151 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
152 #include "llvm/ADT/APInt.h"
153 #include "llvm/ADT/ArrayRef.h"
154 #include "llvm/ADT/DenseMap.h"
155 #include "llvm/ADT/DepthFirstIterator.h"
156 #include "llvm/ADT/SetVector.h"
157 #include "llvm/ADT/SmallPtrSet.h"
158 #include "llvm/ADT/SmallVector.h"
159 #include "llvm/ADT/StringExtras.h"
160 #include "llvm/ADT/StringRef.h"
161 #include "llvm/Analysis/GlobalsModRef.h"
162 #include "llvm/Analysis/TargetLibraryInfo.h"
163 #include "llvm/Analysis/ValueTracking.h"
164 #include "llvm/IR/Argument.h"
165 #include "llvm/IR/AttributeMask.h"
166 #include "llvm/IR/Attributes.h"
167 #include "llvm/IR/BasicBlock.h"
168 #include "llvm/IR/CallingConv.h"
169 #include "llvm/IR/Constant.h"
170 #include "llvm/IR/Constants.h"
171 #include "llvm/IR/DataLayout.h"
172 #include "llvm/IR/DerivedTypes.h"
173 #include "llvm/IR/Function.h"
174 #include "llvm/IR/GlobalValue.h"
175 #include "llvm/IR/GlobalVariable.h"
176 #include "llvm/IR/IRBuilder.h"
177 #include "llvm/IR/InlineAsm.h"
178 #include "llvm/IR/InstVisitor.h"
179 #include "llvm/IR/InstrTypes.h"
180 #include "llvm/IR/Instruction.h"
181 #include "llvm/IR/Instructions.h"
182 #include "llvm/IR/IntrinsicInst.h"
183 #include "llvm/IR/Intrinsics.h"
184 #include "llvm/IR/IntrinsicsAArch64.h"
185 #include "llvm/IR/IntrinsicsX86.h"
186 #include "llvm/IR/MDBuilder.h"
187 #include "llvm/IR/Module.h"
188 #include "llvm/IR/Type.h"
189 #include "llvm/IR/Value.h"
190 #include "llvm/IR/ValueMap.h"
191 #include "llvm/Support/Alignment.h"
192 #include "llvm/Support/AtomicOrdering.h"
193 #include "llvm/Support/Casting.h"
194 #include "llvm/Support/CommandLine.h"
195 #include "llvm/Support/Debug.h"
196 #include "llvm/Support/DebugCounter.h"
197 #include "llvm/Support/ErrorHandling.h"
198 #include "llvm/Support/MathExtras.h"
199 #include "llvm/Support/raw_ostream.h"
200 #include "llvm/TargetParser/Triple.h"
201 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
202 #include "llvm/Transforms/Utils/Instrumentation.h"
203 #include "llvm/Transforms/Utils/Local.h"
204 #include "llvm/Transforms/Utils/ModuleUtils.h"
213 using namespace llvm
;
215 #define DEBUG_TYPE "msan"
217 DEBUG_COUNTER(DebugInsertCheck
, "msan-insert-check",
218 "Controls which checks to insert");
220 DEBUG_COUNTER(DebugInstrumentInstruction
, "msan-instrument-instruction",
221 "Controls which instruction to instrument");
223 static const unsigned kOriginSize
= 4;
224 static const Align kMinOriginAlignment
= Align(4);
225 static const Align kShadowTLSAlignment
= Align(8);
227 // These constants must be kept in sync with the ones in msan.h.
228 static const unsigned kParamTLSSize
= 800;
229 static const unsigned kRetvalTLSSize
= 800;
231 // Accesses sizes are powers of two: 1, 2, 4, 8.
232 static const size_t kNumberOfAccessSizes
= 4;
234 /// Track origins of uninitialized values.
236 /// Adds a section to MemorySanitizer report that points to the allocation
237 /// (stack or heap) the uninitialized bits came from originally.
238 static cl::opt
<int> ClTrackOrigins(
239 "msan-track-origins",
240 cl::desc("Track origins (allocation sites) of poisoned memory"), cl::Hidden
,
243 static cl::opt
<bool> ClKeepGoing("msan-keep-going",
244 cl::desc("keep going after reporting a UMR"),
245 cl::Hidden
, cl::init(false));
248 ClPoisonStack("msan-poison-stack",
249 cl::desc("poison uninitialized stack variables"), cl::Hidden
,
252 static cl::opt
<bool> ClPoisonStackWithCall(
253 "msan-poison-stack-with-call",
254 cl::desc("poison uninitialized stack variables with a call"), cl::Hidden
,
257 static cl::opt
<int> ClPoisonStackPattern(
258 "msan-poison-stack-pattern",
259 cl::desc("poison uninitialized stack variables with the given pattern"),
260 cl::Hidden
, cl::init(0xff));
263 ClPrintStackNames("msan-print-stack-names",
264 cl::desc("Print name of local stack variable"),
265 cl::Hidden
, cl::init(true));
267 static cl::opt
<bool> ClPoisonUndef("msan-poison-undef",
268 cl::desc("poison undef temps"), cl::Hidden
,
272 ClHandleICmp("msan-handle-icmp",
273 cl::desc("propagate shadow through ICmpEQ and ICmpNE"),
274 cl::Hidden
, cl::init(true));
277 ClHandleICmpExact("msan-handle-icmp-exact",
278 cl::desc("exact handling of relational integer ICmp"),
279 cl::Hidden
, cl::init(true));
281 static cl::opt
<bool> ClHandleLifetimeIntrinsics(
282 "msan-handle-lifetime-intrinsics",
284 "when possible, poison scoped variables at the beginning of the scope "
285 "(slower, but more precise)"),
286 cl::Hidden
, cl::init(true));
288 // When compiling the Linux kernel, we sometimes see false positives related to
289 // MSan being unable to understand that inline assembly calls may initialize
291 // This flag makes the compiler conservatively unpoison every memory location
292 // passed into an assembly call. Note that this may cause false positives.
293 // Because it's impossible to figure out the array sizes, we can only unpoison
294 // the first sizeof(type) bytes for each type* pointer.
295 static cl::opt
<bool> ClHandleAsmConservative(
296 "msan-handle-asm-conservative",
297 cl::desc("conservative handling of inline assembly"), cl::Hidden
,
300 // This flag controls whether we check the shadow of the address
301 // operand of load or store. Such bugs are very rare, since load from
302 // a garbage address typically results in SEGV, but still happen
303 // (e.g. only lower bits of address are garbage, or the access happens
304 // early at program startup where malloc-ed memory is more likely to
305 // be zeroed. As of 2012-08-28 this flag adds 20% slowdown.
306 static cl::opt
<bool> ClCheckAccessAddress(
307 "msan-check-access-address",
308 cl::desc("report accesses through a pointer which has poisoned shadow"),
309 cl::Hidden
, cl::init(true));
311 static cl::opt
<bool> ClEagerChecks(
313 cl::desc("check arguments and return values at function call boundaries"),
314 cl::Hidden
, cl::init(false));
316 static cl::opt
<bool> ClDumpStrictInstructions(
317 "msan-dump-strict-instructions",
318 cl::desc("print out instructions with default strict semantics"),
319 cl::Hidden
, cl::init(false));
321 static cl::opt
<bool> ClDumpStrictIntrinsics(
322 "msan-dump-strict-intrinsics",
323 cl::desc("Prints 'unknown' intrinsics that were handled heuristically. "
324 "Use -msan-dump-strict-instructions to print intrinsics that "
325 "could not be handled exactly nor heuristically."),
326 cl::Hidden
, cl::init(false));
328 static cl::opt
<int> ClInstrumentationWithCallThreshold(
329 "msan-instrumentation-with-call-threshold",
331 "If the function being instrumented requires more than "
332 "this number of checks and origin stores, use callbacks instead of "
333 "inline checks (-1 means never use callbacks)."),
334 cl::Hidden
, cl::init(3500));
337 ClEnableKmsan("msan-kernel",
338 cl::desc("Enable KernelMemorySanitizer instrumentation"),
339 cl::Hidden
, cl::init(false));
342 ClDisableChecks("msan-disable-checks",
343 cl::desc("Apply no_sanitize to the whole file"), cl::Hidden
,
347 ClCheckConstantShadow("msan-check-constant-shadow",
348 cl::desc("Insert checks for constant shadow values"),
349 cl::Hidden
, cl::init(true));
351 // This is off by default because of a bug in gold:
352 // https://sourceware.org/bugzilla/show_bug.cgi?id=19002
354 ClWithComdat("msan-with-comdat",
355 cl::desc("Place MSan constructors in comdat sections"),
356 cl::Hidden
, cl::init(false));
358 // These options allow to specify custom memory map parameters
359 // See MemoryMapParams for details.
360 static cl::opt
<uint64_t> ClAndMask("msan-and-mask",
361 cl::desc("Define custom MSan AndMask"),
362 cl::Hidden
, cl::init(0));
364 static cl::opt
<uint64_t> ClXorMask("msan-xor-mask",
365 cl::desc("Define custom MSan XorMask"),
366 cl::Hidden
, cl::init(0));
368 static cl::opt
<uint64_t> ClShadowBase("msan-shadow-base",
369 cl::desc("Define custom MSan ShadowBase"),
370 cl::Hidden
, cl::init(0));
372 static cl::opt
<uint64_t> ClOriginBase("msan-origin-base",
373 cl::desc("Define custom MSan OriginBase"),
374 cl::Hidden
, cl::init(0));
377 ClDisambiguateWarning("msan-disambiguate-warning-threshold",
378 cl::desc("Define threshold for number of checks per "
379 "debug location to force origin update."),
380 cl::Hidden
, cl::init(3));
382 const char kMsanModuleCtorName
[] = "msan.module_ctor";
383 const char kMsanInitName
[] = "__msan_init";
387 // Memory map parameters used in application-to-shadow address calculation.
388 // Offset = (Addr & ~AndMask) ^ XorMask
389 // Shadow = ShadowBase + Offset
390 // Origin = OriginBase + Offset
391 struct MemoryMapParams
{
398 struct PlatformMemoryMapParams
{
399 const MemoryMapParams
*bits32
;
400 const MemoryMapParams
*bits64
;
403 } // end anonymous namespace
406 static const MemoryMapParams Linux_I386_MemoryMapParams
= {
407 0x000080000000, // AndMask
408 0, // XorMask (not used)
409 0, // ShadowBase (not used)
410 0x000040000000, // OriginBase
414 static const MemoryMapParams Linux_X86_64_MemoryMapParams
= {
415 0, // AndMask (not used)
416 0x500000000000, // XorMask
417 0, // ShadowBase (not used)
418 0x100000000000, // OriginBase
422 // FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
423 // after picking good constants
426 static const MemoryMapParams Linux_MIPS64_MemoryMapParams
= {
427 0, // AndMask (not used)
428 0x008000000000, // XorMask
429 0, // ShadowBase (not used)
430 0x002000000000, // OriginBase
434 // FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
435 // after picking good constants
438 static const MemoryMapParams Linux_PowerPC64_MemoryMapParams
= {
439 0xE00000000000, // AndMask
440 0x100000000000, // XorMask
441 0x080000000000, // ShadowBase
442 0x1C0000000000, // OriginBase
446 static const MemoryMapParams Linux_S390X_MemoryMapParams
= {
447 0xC00000000000, // AndMask
448 0, // XorMask (not used)
449 0x080000000000, // ShadowBase
450 0x1C0000000000, // OriginBase
454 // FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
455 // after picking good constants
458 static const MemoryMapParams Linux_AArch64_MemoryMapParams
= {
459 0, // AndMask (not used)
460 0x0B00000000000, // XorMask
461 0, // ShadowBase (not used)
462 0x0200000000000, // OriginBase
466 static const MemoryMapParams Linux_LoongArch64_MemoryMapParams
= {
467 0, // AndMask (not used)
468 0x500000000000, // XorMask
469 0, // ShadowBase (not used)
470 0x100000000000, // OriginBase
474 // FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
475 // after picking good constants
478 static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams
= {
479 0x1800000000000, // AndMask
480 0x0400000000000, // XorMask
481 0x0200000000000, // ShadowBase
482 0x0700000000000, // OriginBase
486 static const MemoryMapParams FreeBSD_I386_MemoryMapParams
= {
487 0x000180000000, // AndMask
488 0x000040000000, // XorMask
489 0x000020000000, // ShadowBase
490 0x000700000000, // OriginBase
494 static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams
= {
495 0xc00000000000, // AndMask
496 0x200000000000, // XorMask
497 0x100000000000, // ShadowBase
498 0x380000000000, // OriginBase
502 static const MemoryMapParams NetBSD_X86_64_MemoryMapParams
= {
504 0x500000000000, // XorMask
506 0x100000000000, // OriginBase
509 static const PlatformMemoryMapParams Linux_X86_MemoryMapParams
= {
510 &Linux_I386_MemoryMapParams
,
511 &Linux_X86_64_MemoryMapParams
,
514 static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams
= {
516 &Linux_MIPS64_MemoryMapParams
,
519 static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams
= {
521 &Linux_PowerPC64_MemoryMapParams
,
524 static const PlatformMemoryMapParams Linux_S390_MemoryMapParams
= {
526 &Linux_S390X_MemoryMapParams
,
529 static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams
= {
531 &Linux_AArch64_MemoryMapParams
,
534 static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams
= {
536 &Linux_LoongArch64_MemoryMapParams
,
539 static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams
= {
541 &FreeBSD_AArch64_MemoryMapParams
,
544 static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams
= {
545 &FreeBSD_I386_MemoryMapParams
,
546 &FreeBSD_X86_64_MemoryMapParams
,
549 static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams
= {
551 &NetBSD_X86_64_MemoryMapParams
,
556 /// Instrument functions of a module to detect uninitialized reads.
558 /// Instantiating MemorySanitizer inserts the msan runtime library API function
559 /// declarations into the module if they don't exist already. Instantiating
560 /// ensures the __msan_init function is in the list of global constructors for
562 class MemorySanitizer
{
564 MemorySanitizer(Module
&M
, MemorySanitizerOptions Options
)
565 : CompileKernel(Options
.Kernel
), TrackOrigins(Options
.TrackOrigins
),
566 Recover(Options
.Recover
), EagerChecks(Options
.EagerChecks
) {
570 // MSan cannot be moved or copied because of MapParams.
571 MemorySanitizer(MemorySanitizer
&&) = delete;
572 MemorySanitizer
&operator=(MemorySanitizer
&&) = delete;
573 MemorySanitizer(const MemorySanitizer
&) = delete;
574 MemorySanitizer
&operator=(const MemorySanitizer
&) = delete;
576 bool sanitizeFunction(Function
&F
, TargetLibraryInfo
&TLI
);
579 friend struct MemorySanitizerVisitor
;
580 friend struct VarArgHelperBase
;
581 friend struct VarArgAMD64Helper
;
582 friend struct VarArgAArch64Helper
;
583 friend struct VarArgPowerPCHelper
;
584 friend struct VarArgSystemZHelper
;
585 friend struct VarArgI386Helper
;
586 friend struct VarArgGenericHelper
;
588 void initializeModule(Module
&M
);
589 void initializeCallbacks(Module
&M
, const TargetLibraryInfo
&TLI
);
590 void createKernelApi(Module
&M
, const TargetLibraryInfo
&TLI
);
591 void createUserspaceApi(Module
&M
, const TargetLibraryInfo
&TLI
);
593 template <typename
... ArgsTy
>
594 FunctionCallee
getOrInsertMsanMetadataFunction(Module
&M
, StringRef Name
,
597 /// True if we're compiling the Linux kernel.
599 /// Track origins (allocation points) of uninitialized values.
606 Type
*IntptrTy
; ///< Integer type with the size of a ptr in default AS.
608 PointerType
*PtrTy
; ///< Integer type with the size of a ptr in default AS.
610 // XxxTLS variables represent the per-thread state in MSan and per-task state
612 // For the userspace these point to thread-local globals. In the kernel land
613 // they point to the members of a per-task struct obtained via a call to
614 // __msan_get_context_state().
616 /// Thread-local shadow storage for function parameters.
619 /// Thread-local origin storage for function parameters.
620 Value
*ParamOriginTLS
;
622 /// Thread-local shadow storage for function return value.
625 /// Thread-local origin storage for function return value.
626 Value
*RetvalOriginTLS
;
628 /// Thread-local shadow storage for in-register va_arg function.
631 /// Thread-local shadow storage for in-register va_arg function.
632 Value
*VAArgOriginTLS
;
634 /// Thread-local shadow storage for va_arg overflow area.
635 Value
*VAArgOverflowSizeTLS
;
637 /// Are the instrumentation callbacks set up?
638 bool CallbacksInitialized
= false;
640 /// The run-time callback to print a warning.
641 FunctionCallee WarningFn
;
643 // These arrays are indexed by log2(AccessSize).
644 FunctionCallee MaybeWarningFn
[kNumberOfAccessSizes
];
645 FunctionCallee MaybeStoreOriginFn
[kNumberOfAccessSizes
];
647 /// Run-time helper that generates a new origin value for a stack
649 FunctionCallee MsanSetAllocaOriginWithDescriptionFn
;
650 // No description version
651 FunctionCallee MsanSetAllocaOriginNoDescriptionFn
;
653 /// Run-time helper that poisons stack on function entry.
654 FunctionCallee MsanPoisonStackFn
;
656 /// Run-time helper that records a store (or any event) of an
657 /// uninitialized value and returns an updated origin id encoding this info.
658 FunctionCallee MsanChainOriginFn
;
660 /// Run-time helper that paints an origin over a region.
661 FunctionCallee MsanSetOriginFn
;
663 /// MSan runtime replacements for memmove, memcpy and memset.
664 FunctionCallee MemmoveFn
, MemcpyFn
, MemsetFn
;
666 /// KMSAN callback for task-local function argument shadow.
667 StructType
*MsanContextStateTy
;
668 FunctionCallee MsanGetContextStateFn
;
670 /// Functions for poisoning/unpoisoning local variables
671 FunctionCallee MsanPoisonAllocaFn
, MsanUnpoisonAllocaFn
;
673 /// Pair of shadow/origin pointers.
676 /// Each of the MsanMetadataPtrXxx functions returns a MsanMetadata.
677 FunctionCallee MsanMetadataPtrForLoadN
, MsanMetadataPtrForStoreN
;
678 FunctionCallee MsanMetadataPtrForLoad_1_8
[4];
679 FunctionCallee MsanMetadataPtrForStore_1_8
[4];
680 FunctionCallee MsanInstrumentAsmStoreFn
;
682 /// Storage for return values of the MsanMetadataPtrXxx functions.
683 Value
*MsanMetadataAlloca
;
685 /// Helper to choose between different MsanMetadataPtrXxx().
686 FunctionCallee
getKmsanShadowOriginAccessFn(bool isStore
, int size
);
688 /// Memory map parameters used in application-to-shadow calculation.
689 const MemoryMapParams
*MapParams
;
691 /// Custom memory map parameters used when -msan-shadow-base or
692 // -msan-origin-base is provided.
693 MemoryMapParams CustomMapParams
;
695 MDNode
*ColdCallWeights
;
697 /// Branch weights for origin store.
698 MDNode
*OriginStoreWeights
;
701 void insertModuleCtor(Module
&M
) {
702 getOrCreateSanitizerCtorAndInitFunctions(
703 M
, kMsanModuleCtorName
, kMsanInitName
,
706 // This callback is invoked when the functions are created the first
707 // time. Hook them into the global ctors list in that case:
708 [&](Function
*Ctor
, FunctionCallee
) {
710 appendToGlobalCtors(M
, Ctor
, 0);
713 Comdat
*MsanCtorComdat
= M
.getOrInsertComdat(kMsanModuleCtorName
);
714 Ctor
->setComdat(MsanCtorComdat
);
715 appendToGlobalCtors(M
, Ctor
, 0, Ctor
);
719 template <class T
> T
getOptOrDefault(const cl::opt
<T
> &Opt
, T Default
) {
720 return (Opt
.getNumOccurrences() > 0) ? Opt
: Default
;
723 } // end anonymous namespace
725 MemorySanitizerOptions::MemorySanitizerOptions(int TO
, bool R
, bool K
,
727 : Kernel(getOptOrDefault(ClEnableKmsan
, K
)),
728 TrackOrigins(getOptOrDefault(ClTrackOrigins
, Kernel
? 2 : TO
)),
729 Recover(getOptOrDefault(ClKeepGoing
, Kernel
|| R
)),
730 EagerChecks(getOptOrDefault(ClEagerChecks
, EagerChecks
)) {}
732 PreservedAnalyses
MemorySanitizerPass::run(Module
&M
,
733 ModuleAnalysisManager
&AM
) {
734 // Return early if nosanitize_memory module flag is present for the module.
735 if (checkIfAlreadyInstrumented(M
, "nosanitize_memory"))
736 return PreservedAnalyses::all();
737 bool Modified
= false;
738 if (!Options
.Kernel
) {
743 auto &FAM
= AM
.getResult
<FunctionAnalysisManagerModuleProxy
>(M
).getManager();
744 for (Function
&F
: M
) {
747 MemorySanitizer
Msan(*F
.getParent(), Options
);
749 Msan
.sanitizeFunction(F
, FAM
.getResult
<TargetLibraryAnalysis
>(F
));
753 return PreservedAnalyses::all();
755 PreservedAnalyses PA
= PreservedAnalyses::none();
756 // GlobalsAA is considered stateless and does not get invalidated unless
757 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
758 // make changes that require GlobalsAA to be invalidated.
759 PA
.abandon
<GlobalsAA
>();
763 void MemorySanitizerPass::printPipeline(
764 raw_ostream
&OS
, function_ref
<StringRef(StringRef
)> MapClassName2PassName
) {
765 static_cast<PassInfoMixin
<MemorySanitizerPass
> *>(this)->printPipeline(
766 OS
, MapClassName2PassName
);
772 if (Options
.EagerChecks
)
773 OS
<< "eager-checks;";
774 OS
<< "track-origins=" << Options
.TrackOrigins
;
778 /// Create a non-const global initialized with the given string.
780 /// Creates a writable global for Str so that we can pass it to the
781 /// run-time lib. Runtime uses first 4 bytes of the string to store the
782 /// frame ID, so the string needs to be mutable.
783 static GlobalVariable
*createPrivateConstGlobalForString(Module
&M
,
785 Constant
*StrConst
= ConstantDataArray::getString(M
.getContext(), Str
);
786 return new GlobalVariable(M
, StrConst
->getType(), /*isConstant=*/true,
787 GlobalValue::PrivateLinkage
, StrConst
, "");
790 template <typename
... ArgsTy
>
792 MemorySanitizer::getOrInsertMsanMetadataFunction(Module
&M
, StringRef Name
,
794 if (TargetTriple
.getArch() == Triple::systemz
) {
795 // SystemZ ABI: shadow/origin pair is returned via a hidden parameter.
796 return M
.getOrInsertFunction(Name
, Type::getVoidTy(*C
), PtrTy
,
797 std::forward
<ArgsTy
>(Args
)...);
800 return M
.getOrInsertFunction(Name
, MsanMetadata
,
801 std::forward
<ArgsTy
>(Args
)...);
804 /// Create KMSAN API callbacks.
805 void MemorySanitizer::createKernelApi(Module
&M
, const TargetLibraryInfo
&TLI
) {
808 // These will be initialized in insertKmsanPrologue().
810 RetvalOriginTLS
= nullptr;
812 ParamOriginTLS
= nullptr;
814 VAArgOriginTLS
= nullptr;
815 VAArgOverflowSizeTLS
= nullptr;
817 WarningFn
= M
.getOrInsertFunction("__msan_warning",
818 TLI
.getAttrList(C
, {0}, /*Signed=*/false),
819 IRB
.getVoidTy(), IRB
.getInt32Ty());
821 // Requests the per-task context state (kmsan_context_state*) from the
823 MsanContextStateTy
= StructType::get(
824 ArrayType::get(IRB
.getInt64Ty(), kParamTLSSize
/ 8),
825 ArrayType::get(IRB
.getInt64Ty(), kRetvalTLSSize
/ 8),
826 ArrayType::get(IRB
.getInt64Ty(), kParamTLSSize
/ 8),
827 ArrayType::get(IRB
.getInt64Ty(), kParamTLSSize
/ 8), /* va_arg_origin */
828 IRB
.getInt64Ty(), ArrayType::get(OriginTy
, kParamTLSSize
/ 4), OriginTy
,
830 MsanGetContextStateFn
=
831 M
.getOrInsertFunction("__msan_get_context_state", PtrTy
);
833 MsanMetadata
= StructType::get(PtrTy
, PtrTy
);
835 for (int ind
= 0, size
= 1; ind
< 4; ind
++, size
<<= 1) {
836 std::string name_load
=
837 "__msan_metadata_ptr_for_load_" + std::to_string(size
);
838 std::string name_store
=
839 "__msan_metadata_ptr_for_store_" + std::to_string(size
);
840 MsanMetadataPtrForLoad_1_8
[ind
] =
841 getOrInsertMsanMetadataFunction(M
, name_load
, PtrTy
);
842 MsanMetadataPtrForStore_1_8
[ind
] =
843 getOrInsertMsanMetadataFunction(M
, name_store
, PtrTy
);
846 MsanMetadataPtrForLoadN
= getOrInsertMsanMetadataFunction(
847 M
, "__msan_metadata_ptr_for_load_n", PtrTy
, IRB
.getInt64Ty());
848 MsanMetadataPtrForStoreN
= getOrInsertMsanMetadataFunction(
849 M
, "__msan_metadata_ptr_for_store_n", PtrTy
, IRB
.getInt64Ty());
851 // Functions for poisoning and unpoisoning memory.
852 MsanPoisonAllocaFn
= M
.getOrInsertFunction(
853 "__msan_poison_alloca", IRB
.getVoidTy(), PtrTy
, IntptrTy
, PtrTy
);
854 MsanUnpoisonAllocaFn
= M
.getOrInsertFunction(
855 "__msan_unpoison_alloca", IRB
.getVoidTy(), PtrTy
, IntptrTy
);
858 static Constant
*getOrInsertGlobal(Module
&M
, StringRef Name
, Type
*Ty
) {
859 return M
.getOrInsertGlobal(Name
, Ty
, [&] {
860 return new GlobalVariable(M
, Ty
, false, GlobalVariable::ExternalLinkage
,
861 nullptr, Name
, nullptr,
862 GlobalVariable::InitialExecTLSModel
);
866 /// Insert declarations for userspace-specific functions and globals.
867 void MemorySanitizer::createUserspaceApi(Module
&M
,
868 const TargetLibraryInfo
&TLI
) {
871 // Create the callback.
872 // FIXME: this function should have "Cold" calling conv,
873 // which is not yet implemented.
875 StringRef WarningFnName
= Recover
? "__msan_warning_with_origin"
876 : "__msan_warning_with_origin_noreturn";
877 WarningFn
= M
.getOrInsertFunction(WarningFnName
,
878 TLI
.getAttrList(C
, {0}, /*Signed=*/false),
879 IRB
.getVoidTy(), IRB
.getInt32Ty());
881 StringRef WarningFnName
=
882 Recover
? "__msan_warning" : "__msan_warning_noreturn";
883 WarningFn
= M
.getOrInsertFunction(WarningFnName
, IRB
.getVoidTy());
886 // Create the global TLS variables.
888 getOrInsertGlobal(M
, "__msan_retval_tls",
889 ArrayType::get(IRB
.getInt64Ty(), kRetvalTLSSize
/ 8));
891 RetvalOriginTLS
= getOrInsertGlobal(M
, "__msan_retval_origin_tls", OriginTy
);
894 getOrInsertGlobal(M
, "__msan_param_tls",
895 ArrayType::get(IRB
.getInt64Ty(), kParamTLSSize
/ 8));
898 getOrInsertGlobal(M
, "__msan_param_origin_tls",
899 ArrayType::get(OriginTy
, kParamTLSSize
/ 4));
902 getOrInsertGlobal(M
, "__msan_va_arg_tls",
903 ArrayType::get(IRB
.getInt64Ty(), kParamTLSSize
/ 8));
906 getOrInsertGlobal(M
, "__msan_va_arg_origin_tls",
907 ArrayType::get(OriginTy
, kParamTLSSize
/ 4));
909 VAArgOverflowSizeTLS
=
910 getOrInsertGlobal(M
, "__msan_va_arg_overflow_size_tls", IRB
.getInt64Ty());
912 for (size_t AccessSizeIndex
= 0; AccessSizeIndex
< kNumberOfAccessSizes
;
914 unsigned AccessSize
= 1 << AccessSizeIndex
;
915 std::string FunctionName
= "__msan_maybe_warning_" + itostr(AccessSize
);
916 MaybeWarningFn
[AccessSizeIndex
] = M
.getOrInsertFunction(
917 FunctionName
, TLI
.getAttrList(C
, {0, 1}, /*Signed=*/false),
918 IRB
.getVoidTy(), IRB
.getIntNTy(AccessSize
* 8), IRB
.getInt32Ty());
920 FunctionName
= "__msan_maybe_store_origin_" + itostr(AccessSize
);
921 MaybeStoreOriginFn
[AccessSizeIndex
] = M
.getOrInsertFunction(
922 FunctionName
, TLI
.getAttrList(C
, {0, 2}, /*Signed=*/false),
923 IRB
.getVoidTy(), IRB
.getIntNTy(AccessSize
* 8), PtrTy
,
927 MsanSetAllocaOriginWithDescriptionFn
=
928 M
.getOrInsertFunction("__msan_set_alloca_origin_with_descr",
929 IRB
.getVoidTy(), PtrTy
, IntptrTy
, PtrTy
, PtrTy
);
930 MsanSetAllocaOriginNoDescriptionFn
=
931 M
.getOrInsertFunction("__msan_set_alloca_origin_no_descr",
932 IRB
.getVoidTy(), PtrTy
, IntptrTy
, PtrTy
);
933 MsanPoisonStackFn
= M
.getOrInsertFunction("__msan_poison_stack",
934 IRB
.getVoidTy(), PtrTy
, IntptrTy
);
937 /// Insert extern declaration of runtime-provided functions and globals.
938 void MemorySanitizer::initializeCallbacks(Module
&M
,
939 const TargetLibraryInfo
&TLI
) {
940 // Only do this once.
941 if (CallbacksInitialized
)
945 // Initialize callbacks that are common for kernel and userspace
947 MsanChainOriginFn
= M
.getOrInsertFunction(
948 "__msan_chain_origin",
949 TLI
.getAttrList(C
, {0}, /*Signed=*/false, /*Ret=*/true), IRB
.getInt32Ty(),
951 MsanSetOriginFn
= M
.getOrInsertFunction(
952 "__msan_set_origin", TLI
.getAttrList(C
, {2}, /*Signed=*/false),
953 IRB
.getVoidTy(), PtrTy
, IntptrTy
, IRB
.getInt32Ty());
955 M
.getOrInsertFunction("__msan_memmove", PtrTy
, PtrTy
, PtrTy
, IntptrTy
);
957 M
.getOrInsertFunction("__msan_memcpy", PtrTy
, PtrTy
, PtrTy
, IntptrTy
);
958 MemsetFn
= M
.getOrInsertFunction("__msan_memset",
959 TLI
.getAttrList(C
, {1}, /*Signed=*/true),
960 PtrTy
, PtrTy
, IRB
.getInt32Ty(), IntptrTy
);
962 MsanInstrumentAsmStoreFn
= M
.getOrInsertFunction(
963 "__msan_instrument_asm_store", IRB
.getVoidTy(), PtrTy
, IntptrTy
);
966 createKernelApi(M
, TLI
);
968 createUserspaceApi(M
, TLI
);
970 CallbacksInitialized
= true;
973 FunctionCallee
MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore
,
975 FunctionCallee
*Fns
=
976 isStore
? MsanMetadataPtrForStore_1_8
: MsanMetadataPtrForLoad_1_8
;
991 /// Module-level initialization.
993 /// inserts a call to __msan_init to the module's constructor list.
994 void MemorySanitizer::initializeModule(Module
&M
) {
995 auto &DL
= M
.getDataLayout();
997 TargetTriple
= Triple(M
.getTargetTriple());
999 bool ShadowPassed
= ClShadowBase
.getNumOccurrences() > 0;
1000 bool OriginPassed
= ClOriginBase
.getNumOccurrences() > 0;
1001 // Check the overrides first
1002 if (ShadowPassed
|| OriginPassed
) {
1003 CustomMapParams
.AndMask
= ClAndMask
;
1004 CustomMapParams
.XorMask
= ClXorMask
;
1005 CustomMapParams
.ShadowBase
= ClShadowBase
;
1006 CustomMapParams
.OriginBase
= ClOriginBase
;
1007 MapParams
= &CustomMapParams
;
1009 switch (TargetTriple
.getOS()) {
1010 case Triple::FreeBSD
:
1011 switch (TargetTriple
.getArch()) {
1012 case Triple::aarch64
:
1013 MapParams
= FreeBSD_ARM_MemoryMapParams
.bits64
;
1015 case Triple::x86_64
:
1016 MapParams
= FreeBSD_X86_MemoryMapParams
.bits64
;
1019 MapParams
= FreeBSD_X86_MemoryMapParams
.bits32
;
1022 report_fatal_error("unsupported architecture");
1025 case Triple::NetBSD
:
1026 switch (TargetTriple
.getArch()) {
1027 case Triple::x86_64
:
1028 MapParams
= NetBSD_X86_MemoryMapParams
.bits64
;
1031 report_fatal_error("unsupported architecture");
1035 switch (TargetTriple
.getArch()) {
1036 case Triple::x86_64
:
1037 MapParams
= Linux_X86_MemoryMapParams
.bits64
;
1040 MapParams
= Linux_X86_MemoryMapParams
.bits32
;
1042 case Triple::mips64
:
1043 case Triple::mips64el
:
1044 MapParams
= Linux_MIPS_MemoryMapParams
.bits64
;
1047 case Triple::ppc64le
:
1048 MapParams
= Linux_PowerPC_MemoryMapParams
.bits64
;
1050 case Triple::systemz
:
1051 MapParams
= Linux_S390_MemoryMapParams
.bits64
;
1053 case Triple::aarch64
:
1054 case Triple::aarch64_be
:
1055 MapParams
= Linux_ARM_MemoryMapParams
.bits64
;
1057 case Triple::loongarch64
:
1058 MapParams
= Linux_LoongArch_MemoryMapParams
.bits64
;
1061 report_fatal_error("unsupported architecture");
1065 report_fatal_error("unsupported operating system");
1069 C
= &(M
.getContext());
1070 IRBuilder
<> IRB(*C
);
1071 IntptrTy
= IRB
.getIntPtrTy(DL
);
1072 OriginTy
= IRB
.getInt32Ty();
1073 PtrTy
= IRB
.getPtrTy();
1075 ColdCallWeights
= MDBuilder(*C
).createUnlikelyBranchWeights();
1076 OriginStoreWeights
= MDBuilder(*C
).createUnlikelyBranchWeights();
1078 if (!CompileKernel
) {
1080 M
.getOrInsertGlobal("__msan_track_origins", IRB
.getInt32Ty(), [&] {
1081 return new GlobalVariable(
1082 M
, IRB
.getInt32Ty(), true, GlobalValue::WeakODRLinkage
,
1083 IRB
.getInt32(TrackOrigins
), "__msan_track_origins");
1087 M
.getOrInsertGlobal("__msan_keep_going", IRB
.getInt32Ty(), [&] {
1088 return new GlobalVariable(M
, IRB
.getInt32Ty(), true,
1089 GlobalValue::WeakODRLinkage
,
1090 IRB
.getInt32(Recover
), "__msan_keep_going");
1097 /// A helper class that handles instrumentation of VarArg
1098 /// functions on a particular platform.
1100 /// Implementations are expected to insert the instrumentation
1101 /// necessary to propagate argument shadow through VarArg function
1102 /// calls. Visit* methods are called during an InstVisitor pass over
1103 /// the function, and should avoid creating new basic blocks. A new
1104 /// instance of this class is created for each instrumented function.
1105 struct VarArgHelper
{
1106 virtual ~VarArgHelper() = default;
1108 /// Visit a CallBase.
1109 virtual void visitCallBase(CallBase
&CB
, IRBuilder
<> &IRB
) = 0;
1111 /// Visit a va_start call.
1112 virtual void visitVAStartInst(VAStartInst
&I
) = 0;
1114 /// Visit a va_copy call.
1115 virtual void visitVACopyInst(VACopyInst
&I
) = 0;
1117 /// Finalize function instrumentation.
1119 /// This method is called after visiting all interesting (see above)
1120 /// instructions in a function.
1121 virtual void finalizeInstrumentation() = 0;
1124 struct MemorySanitizerVisitor
;
1126 } // end anonymous namespace
1128 static VarArgHelper
*CreateVarArgHelper(Function
&Func
, MemorySanitizer
&Msan
,
1129 MemorySanitizerVisitor
&Visitor
);
1131 static unsigned TypeSizeToSizeIndex(TypeSize TS
) {
1132 if (TS
.isScalable())
1133 // Scalable types unconditionally take slowpaths.
1134 return kNumberOfAccessSizes
;
1135 unsigned TypeSizeFixed
= TS
.getFixedValue();
1136 if (TypeSizeFixed
<= 8)
1138 return Log2_32_Ceil((TypeSizeFixed
+ 7) / 8);
1143 /// Helper class to attach debug information of the given instruction onto new
1144 /// instructions inserted after.
1145 class NextNodeIRBuilder
: public IRBuilder
<> {
1147 explicit NextNodeIRBuilder(Instruction
*IP
) : IRBuilder
<>(IP
->getNextNode()) {
1148 SetCurrentDebugLocation(IP
->getDebugLoc());
1152 /// This class does all the work for a given function. Store and Load
1153 /// instructions store and load corresponding shadow and origin
1154 /// values. Most instructions propagate shadow from arguments to their
1155 /// return values. Certain instructions (most importantly, BranchInst)
1156 /// test their argument shadow and print reports (with a runtime call) if it's
1158 struct MemorySanitizerVisitor
: public InstVisitor
<MemorySanitizerVisitor
> {
1160 MemorySanitizer
&MS
;
1161 SmallVector
<PHINode
*, 16> ShadowPHINodes
, OriginPHINodes
;
1162 ValueMap
<Value
*, Value
*> ShadowMap
, OriginMap
;
1163 std::unique_ptr
<VarArgHelper
> VAHelper
;
1164 const TargetLibraryInfo
*TLI
;
1165 Instruction
*FnPrologueEnd
;
1166 SmallVector
<Instruction
*, 16> Instructions
;
1168 // The following flags disable parts of MSan instrumentation based on
1169 // exclusion list contents and command-line options.
1171 bool PropagateShadow
;
1175 struct ShadowOriginAndInsertPoint
{
1178 Instruction
*OrigIns
;
1180 ShadowOriginAndInsertPoint(Value
*S
, Value
*O
, Instruction
*I
)
1181 : Shadow(S
), Origin(O
), OrigIns(I
) {}
1183 SmallVector
<ShadowOriginAndInsertPoint
, 16> InstrumentationList
;
1184 DenseMap
<const DILocation
*, int> LazyWarningDebugLocationCount
;
1185 bool InstrumentLifetimeStart
= ClHandleLifetimeIntrinsics
;
1186 SmallSetVector
<AllocaInst
*, 16> AllocaSet
;
1187 SmallVector
<std::pair
<IntrinsicInst
*, AllocaInst
*>, 16> LifetimeStartList
;
1188 SmallVector
<StoreInst
*, 16> StoreList
;
1189 int64_t SplittableBlocksCount
= 0;
1191 MemorySanitizerVisitor(Function
&F
, MemorySanitizer
&MS
,
1192 const TargetLibraryInfo
&TLI
)
1193 : F(F
), MS(MS
), VAHelper(CreateVarArgHelper(F
, MS
, *this)), TLI(&TLI
) {
1194 bool SanitizeFunction
=
1195 F
.hasFnAttribute(Attribute::SanitizeMemory
) && !ClDisableChecks
;
1196 InsertChecks
= SanitizeFunction
;
1197 PropagateShadow
= SanitizeFunction
;
1198 PoisonStack
= SanitizeFunction
&& ClPoisonStack
;
1199 PoisonUndef
= SanitizeFunction
&& ClPoisonUndef
;
1201 // In the presence of unreachable blocks, we may see Phi nodes with
1202 // incoming nodes from such blocks. Since InstVisitor skips unreachable
1203 // blocks, such nodes will not have any shadow value associated with them.
1204 // It's easier to remove unreachable blocks than deal with missing shadow.
1205 removeUnreachableBlocks(F
);
1207 MS
.initializeCallbacks(*F
.getParent(), TLI
);
1209 IRBuilder
<>(&F
.getEntryBlock(), F
.getEntryBlock().getFirstNonPHIIt())
1210 .CreateIntrinsic(Intrinsic::donothing
, {}, {});
1212 if (MS
.CompileKernel
) {
1213 IRBuilder
<> IRB(FnPrologueEnd
);
1214 insertKmsanPrologue(IRB
);
1217 LLVM_DEBUG(if (!InsertChecks
) dbgs()
1218 << "MemorySanitizer is not inserting checks into '"
1219 << F
.getName() << "'\n");
1222 bool instrumentWithCalls(Value
*V
) {
1223 // Constants likely will be eliminated by follow-up passes.
1224 if (isa
<Constant
>(V
))
1227 ++SplittableBlocksCount
;
1228 return ClInstrumentationWithCallThreshold
>= 0 &&
1229 SplittableBlocksCount
> ClInstrumentationWithCallThreshold
;
1232 bool isInPrologue(Instruction
&I
) {
1233 return I
.getParent() == FnPrologueEnd
->getParent() &&
1234 (&I
== FnPrologueEnd
|| I
.comesBefore(FnPrologueEnd
));
1237 // Creates a new origin and records the stack trace. In general we can call
1238 // this function for any origin manipulation we like. However it will cost
1239 // runtime resources. So use this wisely only if it can provide additional
1240 // information helpful to a user.
1241 Value
*updateOrigin(Value
*V
, IRBuilder
<> &IRB
) {
1242 if (MS
.TrackOrigins
<= 1)
1244 return IRB
.CreateCall(MS
.MsanChainOriginFn
, V
);
1247 Value
*originToIntptr(IRBuilder
<> &IRB
, Value
*Origin
) {
1248 const DataLayout
&DL
= F
.getDataLayout();
1249 unsigned IntptrSize
= DL
.getTypeStoreSize(MS
.IntptrTy
);
1250 if (IntptrSize
== kOriginSize
)
1252 assert(IntptrSize
== kOriginSize
* 2);
1253 Origin
= IRB
.CreateIntCast(Origin
, MS
.IntptrTy
, /* isSigned */ false);
1254 return IRB
.CreateOr(Origin
, IRB
.CreateShl(Origin
, kOriginSize
* 8));
1257 /// Fill memory range with the given origin value.
1258 void paintOrigin(IRBuilder
<> &IRB
, Value
*Origin
, Value
*OriginPtr
,
1259 TypeSize TS
, Align Alignment
) {
1260 const DataLayout
&DL
= F
.getDataLayout();
1261 const Align IntptrAlignment
= DL
.getABITypeAlign(MS
.IntptrTy
);
1262 unsigned IntptrSize
= DL
.getTypeStoreSize(MS
.IntptrTy
);
1263 assert(IntptrAlignment
>= kMinOriginAlignment
);
1264 assert(IntptrSize
>= kOriginSize
);
1266 // Note: The loop based formation works for fixed length vectors too,
1267 // however we prefer to unroll and specialize alignment below.
1268 if (TS
.isScalable()) {
1269 Value
*Size
= IRB
.CreateTypeSize(MS
.IntptrTy
, TS
);
1271 IRB
.CreateAdd(Size
, ConstantInt::get(MS
.IntptrTy
, kOriginSize
- 1));
1273 IRB
.CreateUDiv(RoundUp
, ConstantInt::get(MS
.IntptrTy
, kOriginSize
));
1274 auto [InsertPt
, Index
] =
1275 SplitBlockAndInsertSimpleForLoop(End
, &*IRB
.GetInsertPoint());
1276 IRB
.SetInsertPoint(InsertPt
);
1278 Value
*GEP
= IRB
.CreateGEP(MS
.OriginTy
, OriginPtr
, Index
);
1279 IRB
.CreateAlignedStore(Origin
, GEP
, kMinOriginAlignment
);
1283 unsigned Size
= TS
.getFixedValue();
1286 Align CurrentAlignment
= Alignment
;
1287 if (Alignment
>= IntptrAlignment
&& IntptrSize
> kOriginSize
) {
1288 Value
*IntptrOrigin
= originToIntptr(IRB
, Origin
);
1289 Value
*IntptrOriginPtr
= IRB
.CreatePointerCast(OriginPtr
, MS
.PtrTy
);
1290 for (unsigned i
= 0; i
< Size
/ IntptrSize
; ++i
) {
1291 Value
*Ptr
= i
? IRB
.CreateConstGEP1_32(MS
.IntptrTy
, IntptrOriginPtr
, i
)
1293 IRB
.CreateAlignedStore(IntptrOrigin
, Ptr
, CurrentAlignment
);
1294 Ofs
+= IntptrSize
/ kOriginSize
;
1295 CurrentAlignment
= IntptrAlignment
;
1299 for (unsigned i
= Ofs
; i
< (Size
+ kOriginSize
- 1) / kOriginSize
; ++i
) {
1301 i
? IRB
.CreateConstGEP1_32(MS
.OriginTy
, OriginPtr
, i
) : OriginPtr
;
1302 IRB
.CreateAlignedStore(Origin
, GEP
, CurrentAlignment
);
1303 CurrentAlignment
= kMinOriginAlignment
;
1307 void storeOrigin(IRBuilder
<> &IRB
, Value
*Addr
, Value
*Shadow
, Value
*Origin
,
1308 Value
*OriginPtr
, Align Alignment
) {
1309 const DataLayout
&DL
= F
.getDataLayout();
1310 const Align OriginAlignment
= std::max(kMinOriginAlignment
, Alignment
);
1311 TypeSize StoreSize
= DL
.getTypeStoreSize(Shadow
->getType());
1312 // ZExt cannot convert between vector and scalar
1313 Value
*ConvertedShadow
= convertShadowToScalar(Shadow
, IRB
);
1314 if (auto *ConstantShadow
= dyn_cast
<Constant
>(ConvertedShadow
)) {
1315 if (!ClCheckConstantShadow
|| ConstantShadow
->isZeroValue()) {
1316 // Origin is not needed: value is initialized or const shadow is
1320 if (llvm::isKnownNonZero(ConvertedShadow
, DL
)) {
1321 // Copy origin as the value is definitely uninitialized.
1322 paintOrigin(IRB
, updateOrigin(Origin
, IRB
), OriginPtr
, StoreSize
,
1326 // Fallback to runtime check, which still can be optimized out later.
1329 TypeSize TypeSizeInBits
= DL
.getTypeSizeInBits(ConvertedShadow
->getType());
1330 unsigned SizeIndex
= TypeSizeToSizeIndex(TypeSizeInBits
);
1331 if (instrumentWithCalls(ConvertedShadow
) &&
1332 SizeIndex
< kNumberOfAccessSizes
&& !MS
.CompileKernel
) {
1333 FunctionCallee Fn
= MS
.MaybeStoreOriginFn
[SizeIndex
];
1334 Value
*ConvertedShadow2
=
1335 IRB
.CreateZExt(ConvertedShadow
, IRB
.getIntNTy(8 * (1 << SizeIndex
)));
1336 CallBase
*CB
= IRB
.CreateCall(Fn
, {ConvertedShadow2
, Addr
, Origin
});
1337 CB
->addParamAttr(0, Attribute::ZExt
);
1338 CB
->addParamAttr(2, Attribute::ZExt
);
1340 Value
*Cmp
= convertToBool(ConvertedShadow
, IRB
, "_mscmp");
1341 Instruction
*CheckTerm
= SplitBlockAndInsertIfThen(
1342 Cmp
, &*IRB
.GetInsertPoint(), false, MS
.OriginStoreWeights
);
1343 IRBuilder
<> IRBNew(CheckTerm
);
1344 paintOrigin(IRBNew
, updateOrigin(Origin
, IRBNew
), OriginPtr
, StoreSize
,
1349 void materializeStores() {
1350 for (StoreInst
*SI
: StoreList
) {
1351 IRBuilder
<> IRB(SI
);
1352 Value
*Val
= SI
->getValueOperand();
1353 Value
*Addr
= SI
->getPointerOperand();
1354 Value
*Shadow
= SI
->isAtomic() ? getCleanShadow(Val
) : getShadow(Val
);
1355 Value
*ShadowPtr
, *OriginPtr
;
1356 Type
*ShadowTy
= Shadow
->getType();
1357 const Align Alignment
= SI
->getAlign();
1358 const Align OriginAlignment
= std::max(kMinOriginAlignment
, Alignment
);
1359 std::tie(ShadowPtr
, OriginPtr
) =
1360 getShadowOriginPtr(Addr
, IRB
, ShadowTy
, Alignment
, /*isStore*/ true);
1362 StoreInst
*NewSI
= IRB
.CreateAlignedStore(Shadow
, ShadowPtr
, Alignment
);
1363 LLVM_DEBUG(dbgs() << " STORE: " << *NewSI
<< "\n");
1367 SI
->setOrdering(addReleaseOrdering(SI
->getOrdering()));
1369 if (MS
.TrackOrigins
&& !SI
->isAtomic())
1370 storeOrigin(IRB
, Addr
, Shadow
, getOrigin(Val
), OriginPtr
,
1375 // Returns true if Debug Location corresponds to multiple warnings.
1376 bool shouldDisambiguateWarningLocation(const DebugLoc
&DebugLoc
) {
1377 if (MS
.TrackOrigins
< 2)
1380 if (LazyWarningDebugLocationCount
.empty())
1381 for (const auto &I
: InstrumentationList
)
1382 ++LazyWarningDebugLocationCount
[I
.OrigIns
->getDebugLoc()];
1384 return LazyWarningDebugLocationCount
[DebugLoc
] >= ClDisambiguateWarning
;
1387 /// Helper function to insert a warning at IRB's current insert point.
1388 void insertWarningFn(IRBuilder
<> &IRB
, Value
*Origin
) {
1390 Origin
= (Value
*)IRB
.getInt32(0);
1391 assert(Origin
->getType()->isIntegerTy());
1393 if (shouldDisambiguateWarningLocation(IRB
.getCurrentDebugLocation())) {
1394 // Try to create additional origin with debug info of the last origin
1395 // instruction. It may provide additional information to the user.
1396 if (Instruction
*OI
= dyn_cast_or_null
<Instruction
>(Origin
)) {
1397 assert(MS
.TrackOrigins
);
1398 auto NewDebugLoc
= OI
->getDebugLoc();
1399 // Origin update with missing or the same debug location provides no
1400 // additional value.
1401 if (NewDebugLoc
&& NewDebugLoc
!= IRB
.getCurrentDebugLocation()) {
1402 // Insert update just before the check, so we call runtime only just
1403 // before the report.
1404 IRBuilder
<> IRBOrigin(&*IRB
.GetInsertPoint());
1405 IRBOrigin
.SetCurrentDebugLocation(NewDebugLoc
);
1406 Origin
= updateOrigin(Origin
, IRBOrigin
);
1411 if (MS
.CompileKernel
|| MS
.TrackOrigins
)
1412 IRB
.CreateCall(MS
.WarningFn
, Origin
)->setCannotMerge();
1414 IRB
.CreateCall(MS
.WarningFn
)->setCannotMerge();
1415 // FIXME: Insert UnreachableInst if !MS.Recover?
1416 // This may invalidate some of the following checks and needs to be done
1420 void materializeOneCheck(IRBuilder
<> &IRB
, Value
*ConvertedShadow
,
1422 const DataLayout
&DL
= F
.getDataLayout();
1423 TypeSize TypeSizeInBits
= DL
.getTypeSizeInBits(ConvertedShadow
->getType());
1424 unsigned SizeIndex
= TypeSizeToSizeIndex(TypeSizeInBits
);
1425 if (instrumentWithCalls(ConvertedShadow
) &&
1426 SizeIndex
< kNumberOfAccessSizes
&& !MS
.CompileKernel
) {
1427 FunctionCallee Fn
= MS
.MaybeWarningFn
[SizeIndex
];
1428 // ZExt cannot convert between vector and scalar
1429 ConvertedShadow
= convertShadowToScalar(ConvertedShadow
, IRB
);
1430 Value
*ConvertedShadow2
=
1431 IRB
.CreateZExt(ConvertedShadow
, IRB
.getIntNTy(8 * (1 << SizeIndex
)));
1432 CallBase
*CB
= IRB
.CreateCall(
1433 Fn
, {ConvertedShadow2
,
1434 MS
.TrackOrigins
&& Origin
? Origin
: (Value
*)IRB
.getInt32(0)});
1435 CB
->addParamAttr(0, Attribute::ZExt
);
1436 CB
->addParamAttr(1, Attribute::ZExt
);
1438 Value
*Cmp
= convertToBool(ConvertedShadow
, IRB
, "_mscmp");
1439 Instruction
*CheckTerm
= SplitBlockAndInsertIfThen(
1440 Cmp
, &*IRB
.GetInsertPoint(),
1441 /* Unreachable */ !MS
.Recover
, MS
.ColdCallWeights
);
1443 IRB
.SetInsertPoint(CheckTerm
);
1444 insertWarningFn(IRB
, Origin
);
1445 LLVM_DEBUG(dbgs() << " CHECK: " << *Cmp
<< "\n");
1449 void materializeInstructionChecks(
1450 ArrayRef
<ShadowOriginAndInsertPoint
> InstructionChecks
) {
1451 const DataLayout
&DL
= F
.getDataLayout();
1452 // Disable combining in some cases. TrackOrigins checks each shadow to pick
1454 bool Combine
= !MS
.TrackOrigins
;
1455 Instruction
*Instruction
= InstructionChecks
.front().OrigIns
;
1456 Value
*Shadow
= nullptr;
1457 for (const auto &ShadowData
: InstructionChecks
) {
1458 assert(ShadowData
.OrigIns
== Instruction
);
1459 IRBuilder
<> IRB(Instruction
);
1461 Value
*ConvertedShadow
= ShadowData
.Shadow
;
1463 if (auto *ConstantShadow
= dyn_cast
<Constant
>(ConvertedShadow
)) {
1464 if (!ClCheckConstantShadow
|| ConstantShadow
->isZeroValue()) {
1465 // Skip, value is initialized or const shadow is ignored.
1468 if (llvm::isKnownNonZero(ConvertedShadow
, DL
)) {
1469 // Report as the value is definitely uninitialized.
1470 insertWarningFn(IRB
, ShadowData
.Origin
);
1472 return; // Always fail and stop here, not need to check the rest.
1473 // Skip entire instruction,
1476 // Fallback to runtime check, which still can be optimized out later.
1480 materializeOneCheck(IRB
, ConvertedShadow
, ShadowData
.Origin
);
1485 Shadow
= ConvertedShadow
;
1489 Shadow
= convertToBool(Shadow
, IRB
, "_mscmp");
1490 ConvertedShadow
= convertToBool(ConvertedShadow
, IRB
, "_mscmp");
1491 Shadow
= IRB
.CreateOr(Shadow
, ConvertedShadow
, "_msor");
1496 IRBuilder
<> IRB(Instruction
);
1497 materializeOneCheck(IRB
, Shadow
, nullptr);
1501 void materializeChecks() {
1503 // For assert below.
1504 SmallPtrSet
<Instruction
*, 16> Done
;
1507 for (auto I
= InstrumentationList
.begin();
1508 I
!= InstrumentationList
.end();) {
1509 auto OrigIns
= I
->OrigIns
;
1510 // Checks are grouped by the original instruction. We call all
1511 // `insertShadowCheck` for an instruction at once.
1512 assert(Done
.insert(OrigIns
).second
);
1513 auto J
= std::find_if(I
+ 1, InstrumentationList
.end(),
1514 [OrigIns
](const ShadowOriginAndInsertPoint
&R
) {
1515 return OrigIns
!= R
.OrigIns
;
1517 // Process all checks of instruction at once.
1518 materializeInstructionChecks(ArrayRef
<ShadowOriginAndInsertPoint
>(I
, J
));
1522 LLVM_DEBUG(dbgs() << "DONE:\n" << F
);
1525 // Returns the last instruction in the new prologue
1526 void insertKmsanPrologue(IRBuilder
<> &IRB
) {
1527 Value
*ContextState
= IRB
.CreateCall(MS
.MsanGetContextStateFn
, {});
1528 Constant
*Zero
= IRB
.getInt32(0);
1529 MS
.ParamTLS
= IRB
.CreateGEP(MS
.MsanContextStateTy
, ContextState
,
1530 {Zero
, IRB
.getInt32(0)}, "param_shadow");
1531 MS
.RetvalTLS
= IRB
.CreateGEP(MS
.MsanContextStateTy
, ContextState
,
1532 {Zero
, IRB
.getInt32(1)}, "retval_shadow");
1533 MS
.VAArgTLS
= IRB
.CreateGEP(MS
.MsanContextStateTy
, ContextState
,
1534 {Zero
, IRB
.getInt32(2)}, "va_arg_shadow");
1535 MS
.VAArgOriginTLS
= IRB
.CreateGEP(MS
.MsanContextStateTy
, ContextState
,
1536 {Zero
, IRB
.getInt32(3)}, "va_arg_origin");
1537 MS
.VAArgOverflowSizeTLS
=
1538 IRB
.CreateGEP(MS
.MsanContextStateTy
, ContextState
,
1539 {Zero
, IRB
.getInt32(4)}, "va_arg_overflow_size");
1540 MS
.ParamOriginTLS
= IRB
.CreateGEP(MS
.MsanContextStateTy
, ContextState
,
1541 {Zero
, IRB
.getInt32(5)}, "param_origin");
1542 MS
.RetvalOriginTLS
=
1543 IRB
.CreateGEP(MS
.MsanContextStateTy
, ContextState
,
1544 {Zero
, IRB
.getInt32(6)}, "retval_origin");
1545 if (MS
.TargetTriple
.getArch() == Triple::systemz
)
1546 MS
.MsanMetadataAlloca
= IRB
.CreateAlloca(MS
.MsanMetadata
, 0u);
1549 /// Add MemorySanitizer instrumentation to a function.
1550 bool runOnFunction() {
1551 // Iterate all BBs in depth-first order and create shadow instructions
1552 // for all instructions (where applicable).
1553 // For PHI nodes we create dummy shadow PHIs which will be finalized later.
1554 for (BasicBlock
*BB
: depth_first(FnPrologueEnd
->getParent()))
1557 // `visit` above only collects instructions. Process them after iterating
1558 // CFG to avoid requirement on CFG transformations.
1559 for (Instruction
*I
: Instructions
)
1560 InstVisitor
<MemorySanitizerVisitor
>::visit(*I
);
1562 // Finalize PHI nodes.
1563 for (PHINode
*PN
: ShadowPHINodes
) {
1564 PHINode
*PNS
= cast
<PHINode
>(getShadow(PN
));
1565 PHINode
*PNO
= MS
.TrackOrigins
? cast
<PHINode
>(getOrigin(PN
)) : nullptr;
1566 size_t NumValues
= PN
->getNumIncomingValues();
1567 for (size_t v
= 0; v
< NumValues
; v
++) {
1568 PNS
->addIncoming(getShadow(PN
, v
), PN
->getIncomingBlock(v
));
1570 PNO
->addIncoming(getOrigin(PN
, v
), PN
->getIncomingBlock(v
));
1574 VAHelper
->finalizeInstrumentation();
1576 // Poison llvm.lifetime.start intrinsics, if we haven't fallen back to
1577 // instrumenting only allocas.
1578 if (InstrumentLifetimeStart
) {
1579 for (auto Item
: LifetimeStartList
) {
1580 instrumentAlloca(*Item
.second
, Item
.first
);
1581 AllocaSet
.remove(Item
.second
);
1584 // Poison the allocas for which we didn't instrument the corresponding
1585 // lifetime intrinsics.
1586 for (AllocaInst
*AI
: AllocaSet
)
1587 instrumentAlloca(*AI
);
1589 // Insert shadow value checks.
1590 materializeChecks();
1592 // Delayed instrumentation of StoreInst.
1593 // This may not add new address checks.
1594 materializeStores();
1599 /// Compute the shadow type that corresponds to a given Value.
1600 Type
*getShadowTy(Value
*V
) { return getShadowTy(V
->getType()); }
1602 /// Compute the shadow type that corresponds to a given Type.
1603 Type
*getShadowTy(Type
*OrigTy
) {
1604 if (!OrigTy
->isSized()) {
1607 // For integer type, shadow is the same as the original type.
1608 // This may return weird-sized types like i1.
1609 if (IntegerType
*IT
= dyn_cast
<IntegerType
>(OrigTy
))
1611 const DataLayout
&DL
= F
.getDataLayout();
1612 if (VectorType
*VT
= dyn_cast
<VectorType
>(OrigTy
)) {
1613 uint32_t EltSize
= DL
.getTypeSizeInBits(VT
->getElementType());
1614 return VectorType::get(IntegerType::get(*MS
.C
, EltSize
),
1615 VT
->getElementCount());
1617 if (ArrayType
*AT
= dyn_cast
<ArrayType
>(OrigTy
)) {
1618 return ArrayType::get(getShadowTy(AT
->getElementType()),
1619 AT
->getNumElements());
1621 if (StructType
*ST
= dyn_cast
<StructType
>(OrigTy
)) {
1622 SmallVector
<Type
*, 4> Elements
;
1623 for (unsigned i
= 0, n
= ST
->getNumElements(); i
< n
; i
++)
1624 Elements
.push_back(getShadowTy(ST
->getElementType(i
)));
1625 StructType
*Res
= StructType::get(*MS
.C
, Elements
, ST
->isPacked());
1626 LLVM_DEBUG(dbgs() << "getShadowTy: " << *ST
<< " ===> " << *Res
<< "\n");
1629 uint32_t TypeSize
= DL
.getTypeSizeInBits(OrigTy
);
1630 return IntegerType::get(*MS
.C
, TypeSize
);
1633 /// Extract combined shadow of struct elements as a bool
1634 Value
*collapseStructShadow(StructType
*Struct
, Value
*Shadow
,
1636 Value
*FalseVal
= IRB
.getIntN(/* width */ 1, /* value */ 0);
1637 Value
*Aggregator
= FalseVal
;
1639 for (unsigned Idx
= 0; Idx
< Struct
->getNumElements(); Idx
++) {
1640 // Combine by ORing together each element's bool shadow
1641 Value
*ShadowItem
= IRB
.CreateExtractValue(Shadow
, Idx
);
1642 Value
*ShadowBool
= convertToBool(ShadowItem
, IRB
);
1644 if (Aggregator
!= FalseVal
)
1645 Aggregator
= IRB
.CreateOr(Aggregator
, ShadowBool
);
1647 Aggregator
= ShadowBool
;
1653 // Extract combined shadow of array elements
1654 Value
*collapseArrayShadow(ArrayType
*Array
, Value
*Shadow
,
1656 if (!Array
->getNumElements())
1657 return IRB
.getIntN(/* width */ 1, /* value */ 0);
1659 Value
*FirstItem
= IRB
.CreateExtractValue(Shadow
, 0);
1660 Value
*Aggregator
= convertShadowToScalar(FirstItem
, IRB
);
1662 for (unsigned Idx
= 1; Idx
< Array
->getNumElements(); Idx
++) {
1663 Value
*ShadowItem
= IRB
.CreateExtractValue(Shadow
, Idx
);
1664 Value
*ShadowInner
= convertShadowToScalar(ShadowItem
, IRB
);
1665 Aggregator
= IRB
.CreateOr(Aggregator
, ShadowInner
);
1670 /// Convert a shadow value to it's flattened variant. The resulting
1671 /// shadow may not necessarily have the same bit width as the input
1672 /// value, but it will always be comparable to zero.
1673 Value
*convertShadowToScalar(Value
*V
, IRBuilder
<> &IRB
) {
1674 if (StructType
*Struct
= dyn_cast
<StructType
>(V
->getType()))
1675 return collapseStructShadow(Struct
, V
, IRB
);
1676 if (ArrayType
*Array
= dyn_cast
<ArrayType
>(V
->getType()))
1677 return collapseArrayShadow(Array
, V
, IRB
);
1678 if (isa
<VectorType
>(V
->getType())) {
1679 if (isa
<ScalableVectorType
>(V
->getType()))
1680 return convertShadowToScalar(IRB
.CreateOrReduce(V
), IRB
);
1682 V
->getType()->getPrimitiveSizeInBits().getFixedValue();
1683 return IRB
.CreateBitCast(V
, IntegerType::get(*MS
.C
, BitWidth
));
1688 // Convert a scalar value to an i1 by comparing with 0
1689 Value
*convertToBool(Value
*V
, IRBuilder
<> &IRB
, const Twine
&name
= "") {
1690 Type
*VTy
= V
->getType();
1691 if (!VTy
->isIntegerTy())
1692 return convertToBool(convertShadowToScalar(V
, IRB
), IRB
, name
);
1693 if (VTy
->getIntegerBitWidth() == 1)
1694 // Just converting a bool to a bool, so do nothing.
1696 return IRB
.CreateICmpNE(V
, ConstantInt::get(VTy
, 0), name
);
1699 Type
*ptrToIntPtrType(Type
*PtrTy
) const {
1700 if (VectorType
*VectTy
= dyn_cast
<VectorType
>(PtrTy
)) {
1701 return VectorType::get(ptrToIntPtrType(VectTy
->getElementType()),
1702 VectTy
->getElementCount());
1704 assert(PtrTy
->isIntOrPtrTy());
1708 Type
*getPtrToShadowPtrType(Type
*IntPtrTy
, Type
*ShadowTy
) const {
1709 if (VectorType
*VectTy
= dyn_cast
<VectorType
>(IntPtrTy
)) {
1710 return VectorType::get(
1711 getPtrToShadowPtrType(VectTy
->getElementType(), ShadowTy
),
1712 VectTy
->getElementCount());
1714 assert(IntPtrTy
== MS
.IntptrTy
);
1718 Constant
*constToIntPtr(Type
*IntPtrTy
, uint64_t C
) const {
1719 if (VectorType
*VectTy
= dyn_cast
<VectorType
>(IntPtrTy
)) {
1720 return ConstantVector::getSplat(
1721 VectTy
->getElementCount(),
1722 constToIntPtr(VectTy
->getElementType(), C
));
1724 assert(IntPtrTy
== MS
.IntptrTy
);
1725 return ConstantInt::get(MS
.IntptrTy
, C
);
1728 /// Returns the integer shadow offset that corresponds to a given
1729 /// application address, whereby:
1731 /// Offset = (Addr & ~AndMask) ^ XorMask
1732 /// Shadow = ShadowBase + Offset
1733 /// Origin = (OriginBase + Offset) & ~Alignment
1735 /// Note: for efficiency, many shadow mappings only require use the XorMask
1736 /// and OriginBase; the AndMask and ShadowBase are often zero.
1737 Value
*getShadowPtrOffset(Value
*Addr
, IRBuilder
<> &IRB
) {
1738 Type
*IntptrTy
= ptrToIntPtrType(Addr
->getType());
1739 Value
*OffsetLong
= IRB
.CreatePointerCast(Addr
, IntptrTy
);
1741 if (uint64_t AndMask
= MS
.MapParams
->AndMask
)
1742 OffsetLong
= IRB
.CreateAnd(OffsetLong
, constToIntPtr(IntptrTy
, ~AndMask
));
1744 if (uint64_t XorMask
= MS
.MapParams
->XorMask
)
1745 OffsetLong
= IRB
.CreateXor(OffsetLong
, constToIntPtr(IntptrTy
, XorMask
));
1749 /// Compute the shadow and origin addresses corresponding to a given
1750 /// application address.
1752 /// Shadow = ShadowBase + Offset
1753 /// Origin = (OriginBase + Offset) & ~3ULL
1754 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1755 /// a single pointee.
1756 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1757 std::pair
<Value
*, Value
*>
1758 getShadowOriginPtrUserspace(Value
*Addr
, IRBuilder
<> &IRB
, Type
*ShadowTy
,
1759 MaybeAlign Alignment
) {
1760 VectorType
*VectTy
= dyn_cast
<VectorType
>(Addr
->getType());
1762 assert(Addr
->getType()->isPointerTy());
1764 assert(VectTy
->getElementType()->isPointerTy());
1766 Type
*IntptrTy
= ptrToIntPtrType(Addr
->getType());
1767 Value
*ShadowOffset
= getShadowPtrOffset(Addr
, IRB
);
1768 Value
*ShadowLong
= ShadowOffset
;
1769 if (uint64_t ShadowBase
= MS
.MapParams
->ShadowBase
) {
1771 IRB
.CreateAdd(ShadowLong
, constToIntPtr(IntptrTy
, ShadowBase
));
1773 Value
*ShadowPtr
= IRB
.CreateIntToPtr(
1774 ShadowLong
, getPtrToShadowPtrType(IntptrTy
, ShadowTy
));
1776 Value
*OriginPtr
= nullptr;
1777 if (MS
.TrackOrigins
) {
1778 Value
*OriginLong
= ShadowOffset
;
1779 uint64_t OriginBase
= MS
.MapParams
->OriginBase
;
1780 if (OriginBase
!= 0)
1782 IRB
.CreateAdd(OriginLong
, constToIntPtr(IntptrTy
, OriginBase
));
1783 if (!Alignment
|| *Alignment
< kMinOriginAlignment
) {
1784 uint64_t Mask
= kMinOriginAlignment
.value() - 1;
1785 OriginLong
= IRB
.CreateAnd(OriginLong
, constToIntPtr(IntptrTy
, ~Mask
));
1787 OriginPtr
= IRB
.CreateIntToPtr(
1788 OriginLong
, getPtrToShadowPtrType(IntptrTy
, MS
.OriginTy
));
1790 return std::make_pair(ShadowPtr
, OriginPtr
);
1793 template <typename
... ArgsTy
>
1794 Value
*createMetadataCall(IRBuilder
<> &IRB
, FunctionCallee Callee
,
1796 if (MS
.TargetTriple
.getArch() == Triple::systemz
) {
1797 IRB
.CreateCall(Callee
,
1798 {MS
.MsanMetadataAlloca
, std::forward
<ArgsTy
>(Args
)...});
1799 return IRB
.CreateLoad(MS
.MsanMetadata
, MS
.MsanMetadataAlloca
);
1802 return IRB
.CreateCall(Callee
, {std::forward
<ArgsTy
>(Args
)...});
1805 std::pair
<Value
*, Value
*> getShadowOriginPtrKernelNoVec(Value
*Addr
,
1809 Value
*ShadowOriginPtrs
;
1810 const DataLayout
&DL
= F
.getDataLayout();
1811 TypeSize Size
= DL
.getTypeStoreSize(ShadowTy
);
1813 FunctionCallee Getter
= MS
.getKmsanShadowOriginAccessFn(isStore
, Size
);
1814 Value
*AddrCast
= IRB
.CreatePointerCast(Addr
, MS
.PtrTy
);
1816 ShadowOriginPtrs
= createMetadataCall(IRB
, Getter
, AddrCast
);
1818 Value
*SizeVal
= ConstantInt::get(MS
.IntptrTy
, Size
);
1819 ShadowOriginPtrs
= createMetadataCall(
1821 isStore
? MS
.MsanMetadataPtrForStoreN
: MS
.MsanMetadataPtrForLoadN
,
1824 Value
*ShadowPtr
= IRB
.CreateExtractValue(ShadowOriginPtrs
, 0);
1825 ShadowPtr
= IRB
.CreatePointerCast(ShadowPtr
, MS
.PtrTy
);
1826 Value
*OriginPtr
= IRB
.CreateExtractValue(ShadowOriginPtrs
, 1);
1828 return std::make_pair(ShadowPtr
, OriginPtr
);
1831 /// Addr can be a ptr or <N x ptr>. In both cases ShadowTy the shadow type of
1832 /// a single pointee.
1833 /// Returns <shadow_ptr, origin_ptr> or <<N x shadow_ptr>, <N x origin_ptr>>.
1834 std::pair
<Value
*, Value
*> getShadowOriginPtrKernel(Value
*Addr
,
1838 VectorType
*VectTy
= dyn_cast
<VectorType
>(Addr
->getType());
1840 assert(Addr
->getType()->isPointerTy());
1841 return getShadowOriginPtrKernelNoVec(Addr
, IRB
, ShadowTy
, isStore
);
1844 // TODO: Support callbacs with vectors of addresses.
1845 unsigned NumElements
= cast
<FixedVectorType
>(VectTy
)->getNumElements();
1846 Value
*ShadowPtrs
= ConstantInt::getNullValue(
1847 FixedVectorType::get(IRB
.getPtrTy(), NumElements
));
1848 Value
*OriginPtrs
= nullptr;
1849 if (MS
.TrackOrigins
)
1850 OriginPtrs
= ConstantInt::getNullValue(
1851 FixedVectorType::get(IRB
.getPtrTy(), NumElements
));
1852 for (unsigned i
= 0; i
< NumElements
; ++i
) {
1854 IRB
.CreateExtractElement(Addr
, ConstantInt::get(IRB
.getInt32Ty(), i
));
1855 auto [ShadowPtr
, OriginPtr
] =
1856 getShadowOriginPtrKernelNoVec(OneAddr
, IRB
, ShadowTy
, isStore
);
1858 ShadowPtrs
= IRB
.CreateInsertElement(
1859 ShadowPtrs
, ShadowPtr
, ConstantInt::get(IRB
.getInt32Ty(), i
));
1860 if (MS
.TrackOrigins
)
1861 OriginPtrs
= IRB
.CreateInsertElement(
1862 OriginPtrs
, OriginPtr
, ConstantInt::get(IRB
.getInt32Ty(), i
));
1864 return {ShadowPtrs
, OriginPtrs
};
1867 std::pair
<Value
*, Value
*> getShadowOriginPtr(Value
*Addr
, IRBuilder
<> &IRB
,
1869 MaybeAlign Alignment
,
1871 if (MS
.CompileKernel
)
1872 return getShadowOriginPtrKernel(Addr
, IRB
, ShadowTy
, isStore
);
1873 return getShadowOriginPtrUserspace(Addr
, IRB
, ShadowTy
, Alignment
);
1876 /// Compute the shadow address for a given function argument.
1878 /// Shadow = ParamTLS+ArgOffset.
1879 Value
*getShadowPtrForArgument(IRBuilder
<> &IRB
, int ArgOffset
) {
1880 Value
*Base
= IRB
.CreatePointerCast(MS
.ParamTLS
, MS
.IntptrTy
);
1882 Base
= IRB
.CreateAdd(Base
, ConstantInt::get(MS
.IntptrTy
, ArgOffset
));
1883 return IRB
.CreateIntToPtr(Base
, IRB
.getPtrTy(0), "_msarg");
1886 /// Compute the origin address for a given function argument.
1887 Value
*getOriginPtrForArgument(IRBuilder
<> &IRB
, int ArgOffset
) {
1888 if (!MS
.TrackOrigins
)
1890 Value
*Base
= IRB
.CreatePointerCast(MS
.ParamOriginTLS
, MS
.IntptrTy
);
1892 Base
= IRB
.CreateAdd(Base
, ConstantInt::get(MS
.IntptrTy
, ArgOffset
));
1893 return IRB
.CreateIntToPtr(Base
, IRB
.getPtrTy(0), "_msarg_o");
1896 /// Compute the shadow address for a retval.
1897 Value
*getShadowPtrForRetval(IRBuilder
<> &IRB
) {
1898 return IRB
.CreatePointerCast(MS
.RetvalTLS
, IRB
.getPtrTy(0), "_msret");
1901 /// Compute the origin address for a retval.
1902 Value
*getOriginPtrForRetval() {
1903 // We keep a single origin for the entire retval. Might be too optimistic.
1904 return MS
.RetvalOriginTLS
;
1907 /// Set SV to be the shadow value for V.
1908 void setShadow(Value
*V
, Value
*SV
) {
1909 assert(!ShadowMap
.count(V
) && "Values may only have one shadow");
1910 ShadowMap
[V
] = PropagateShadow
? SV
: getCleanShadow(V
);
1913 /// Set Origin to be the origin value for V.
1914 void setOrigin(Value
*V
, Value
*Origin
) {
1915 if (!MS
.TrackOrigins
)
1917 assert(!OriginMap
.count(V
) && "Values may only have one origin");
1918 LLVM_DEBUG(dbgs() << "ORIGIN: " << *V
<< " ==> " << *Origin
<< "\n");
1919 OriginMap
[V
] = Origin
;
1922 Constant
*getCleanShadow(Type
*OrigTy
) {
1923 Type
*ShadowTy
= getShadowTy(OrigTy
);
1926 return Constant::getNullValue(ShadowTy
);
1929 /// Create a clean shadow value for a given value.
1931 /// Clean shadow (all zeroes) means all bits of the value are defined
1933 Constant
*getCleanShadow(Value
*V
) { return getCleanShadow(V
->getType()); }
1935 /// Create a dirty shadow of a given shadow type.
1936 Constant
*getPoisonedShadow(Type
*ShadowTy
) {
1938 if (isa
<IntegerType
>(ShadowTy
) || isa
<VectorType
>(ShadowTy
))
1939 return Constant::getAllOnesValue(ShadowTy
);
1940 if (ArrayType
*AT
= dyn_cast
<ArrayType
>(ShadowTy
)) {
1941 SmallVector
<Constant
*, 4> Vals(AT
->getNumElements(),
1942 getPoisonedShadow(AT
->getElementType()));
1943 return ConstantArray::get(AT
, Vals
);
1945 if (StructType
*ST
= dyn_cast
<StructType
>(ShadowTy
)) {
1946 SmallVector
<Constant
*, 4> Vals
;
1947 for (unsigned i
= 0, n
= ST
->getNumElements(); i
< n
; i
++)
1948 Vals
.push_back(getPoisonedShadow(ST
->getElementType(i
)));
1949 return ConstantStruct::get(ST
, Vals
);
1951 llvm_unreachable("Unexpected shadow type");
1954 /// Create a dirty shadow for a given value.
1955 Constant
*getPoisonedShadow(Value
*V
) {
1956 Type
*ShadowTy
= getShadowTy(V
);
1959 return getPoisonedShadow(ShadowTy
);
1962 /// Create a clean (zero) origin.
1963 Value
*getCleanOrigin() { return Constant::getNullValue(MS
.OriginTy
); }
1965 /// Get the shadow value for a given Value.
1967 /// This function either returns the value set earlier with setShadow,
1968 /// or extracts if from ParamTLS (for function arguments).
1969 Value
*getShadow(Value
*V
) {
1970 if (Instruction
*I
= dyn_cast
<Instruction
>(V
)) {
1971 if (!PropagateShadow
|| I
->getMetadata(LLVMContext::MD_nosanitize
))
1972 return getCleanShadow(V
);
1973 // For instructions the shadow is already stored in the map.
1974 Value
*Shadow
= ShadowMap
[V
];
1976 LLVM_DEBUG(dbgs() << "No shadow: " << *V
<< "\n" << *(I
->getParent()));
1978 assert(Shadow
&& "No shadow for a value");
1982 if (UndefValue
*U
= dyn_cast
<UndefValue
>(V
)) {
1983 Value
*AllOnes
= (PropagateShadow
&& PoisonUndef
) ? getPoisonedShadow(V
)
1984 : getCleanShadow(V
);
1985 LLVM_DEBUG(dbgs() << "Undef: " << *U
<< " ==> " << *AllOnes
<< "\n");
1989 if (Argument
*A
= dyn_cast
<Argument
>(V
)) {
1990 // For arguments we compute the shadow on demand and store it in the map.
1991 Value
*&ShadowPtr
= ShadowMap
[V
];
1994 Function
*F
= A
->getParent();
1995 IRBuilder
<> EntryIRB(FnPrologueEnd
);
1996 unsigned ArgOffset
= 0;
1997 const DataLayout
&DL
= F
->getDataLayout();
1998 for (auto &FArg
: F
->args()) {
1999 if (!FArg
.getType()->isSized() || FArg
.getType()->isScalableTy()) {
2000 LLVM_DEBUG(dbgs() << (FArg
.getType()->isScalableTy()
2001 ? "vscale not fully supported\n"
2002 : "Arg is not sized\n"));
2004 ShadowPtr
= getCleanShadow(V
);
2005 setOrigin(A
, getCleanOrigin());
2011 unsigned Size
= FArg
.hasByValAttr()
2012 ? DL
.getTypeAllocSize(FArg
.getParamByValType())
2013 : DL
.getTypeAllocSize(FArg
.getType());
2016 bool Overflow
= ArgOffset
+ Size
> kParamTLSSize
;
2017 if (FArg
.hasByValAttr()) {
2018 // ByVal pointer itself has clean shadow. We copy the actual
2019 // argument shadow to the underlying memory.
2020 // Figure out maximal valid memcpy alignment.
2021 const Align ArgAlign
= DL
.getValueOrABITypeAlignment(
2022 FArg
.getParamAlign(), FArg
.getParamByValType());
2023 Value
*CpShadowPtr
, *CpOriginPtr
;
2024 std::tie(CpShadowPtr
, CpOriginPtr
) =
2025 getShadowOriginPtr(V
, EntryIRB
, EntryIRB
.getInt8Ty(), ArgAlign
,
2027 if (!PropagateShadow
|| Overflow
) {
2028 // ParamTLS overflow.
2029 EntryIRB
.CreateMemSet(
2030 CpShadowPtr
, Constant::getNullValue(EntryIRB
.getInt8Ty()),
2033 Value
*Base
= getShadowPtrForArgument(EntryIRB
, ArgOffset
);
2034 const Align CopyAlign
= std::min(ArgAlign
, kShadowTLSAlignment
);
2035 Value
*Cpy
= EntryIRB
.CreateMemCpy(CpShadowPtr
, CopyAlign
, Base
,
2037 LLVM_DEBUG(dbgs() << " ByValCpy: " << *Cpy
<< "\n");
2040 if (MS
.TrackOrigins
) {
2041 Value
*OriginPtr
= getOriginPtrForArgument(EntryIRB
, ArgOffset
);
2042 // FIXME: OriginSize should be:
2043 // alignTo(V % kMinOriginAlignment + Size, kMinOriginAlignment)
2044 unsigned OriginSize
= alignTo(Size
, kMinOriginAlignment
);
2045 EntryIRB
.CreateMemCpy(
2047 /* by getShadowOriginPtr */ kMinOriginAlignment
, OriginPtr
,
2048 /* by origin_tls[ArgOffset] */ kMinOriginAlignment
,
2054 if (!PropagateShadow
|| Overflow
|| FArg
.hasByValAttr() ||
2055 (MS
.EagerChecks
&& FArg
.hasAttribute(Attribute::NoUndef
))) {
2056 ShadowPtr
= getCleanShadow(V
);
2057 setOrigin(A
, getCleanOrigin());
2060 Value
*Base
= getShadowPtrForArgument(EntryIRB
, ArgOffset
);
2061 ShadowPtr
= EntryIRB
.CreateAlignedLoad(getShadowTy(&FArg
), Base
,
2062 kShadowTLSAlignment
);
2063 if (MS
.TrackOrigins
) {
2064 Value
*OriginPtr
= getOriginPtrForArgument(EntryIRB
, ArgOffset
);
2065 setOrigin(A
, EntryIRB
.CreateLoad(MS
.OriginTy
, OriginPtr
));
2069 << " ARG: " << FArg
<< " ==> " << *ShadowPtr
<< "\n");
2073 ArgOffset
+= alignTo(Size
, kShadowTLSAlignment
);
2075 assert(ShadowPtr
&& "Could not find shadow for an argument");
2078 // For everything else the shadow is zero.
2079 return getCleanShadow(V
);
2082 /// Get the shadow for i-th argument of the instruction I.
2083 Value
*getShadow(Instruction
*I
, int i
) {
2084 return getShadow(I
->getOperand(i
));
2087 /// Get the origin for a value.
2088 Value
*getOrigin(Value
*V
) {
2089 if (!MS
.TrackOrigins
)
2091 if (!PropagateShadow
|| isa
<Constant
>(V
) || isa
<InlineAsm
>(V
))
2092 return getCleanOrigin();
2093 assert((isa
<Instruction
>(V
) || isa
<Argument
>(V
)) &&
2094 "Unexpected value type in getOrigin()");
2095 if (Instruction
*I
= dyn_cast
<Instruction
>(V
)) {
2096 if (I
->getMetadata(LLVMContext::MD_nosanitize
))
2097 return getCleanOrigin();
2099 Value
*Origin
= OriginMap
[V
];
2100 assert(Origin
&& "Missing origin");
2104 /// Get the origin for i-th argument of the instruction I.
2105 Value
*getOrigin(Instruction
*I
, int i
) {
2106 return getOrigin(I
->getOperand(i
));
2109 /// Remember the place where a shadow check should be inserted.
2111 /// This location will be later instrumented with a check that will print a
2112 /// UMR warning in runtime if the shadow value is not 0.
2113 void insertShadowCheck(Value
*Shadow
, Value
*Origin
, Instruction
*OrigIns
) {
2118 if (!DebugCounter::shouldExecute(DebugInsertCheck
)) {
2119 LLVM_DEBUG(dbgs() << "Skipping check of " << *Shadow
<< " before "
2120 << *OrigIns
<< "\n");
2124 Type
*ShadowTy
= Shadow
->getType();
2125 assert((isa
<IntegerType
>(ShadowTy
) || isa
<VectorType
>(ShadowTy
) ||
2126 isa
<StructType
>(ShadowTy
) || isa
<ArrayType
>(ShadowTy
)) &&
2127 "Can only insert checks for integer, vector, and aggregate shadow "
2130 InstrumentationList
.push_back(
2131 ShadowOriginAndInsertPoint(Shadow
, Origin
, OrigIns
));
2134 /// Remember the place where a shadow check should be inserted.
2136 /// This location will be later instrumented with a check that will print a
2137 /// UMR warning in runtime if the value is not fully defined.
2138 void insertShadowCheck(Value
*Val
, Instruction
*OrigIns
) {
2140 Value
*Shadow
, *Origin
;
2141 if (ClCheckConstantShadow
) {
2142 Shadow
= getShadow(Val
);
2145 Origin
= getOrigin(Val
);
2147 Shadow
= dyn_cast_or_null
<Instruction
>(getShadow(Val
));
2150 Origin
= dyn_cast_or_null
<Instruction
>(getOrigin(Val
));
2152 insertShadowCheck(Shadow
, Origin
, OrigIns
);
2155 AtomicOrdering
addReleaseOrdering(AtomicOrdering a
) {
2157 case AtomicOrdering::NotAtomic
:
2158 return AtomicOrdering::NotAtomic
;
2159 case AtomicOrdering::Unordered
:
2160 case AtomicOrdering::Monotonic
:
2161 case AtomicOrdering::Release
:
2162 return AtomicOrdering::Release
;
2163 case AtomicOrdering::Acquire
:
2164 case AtomicOrdering::AcquireRelease
:
2165 return AtomicOrdering::AcquireRelease
;
2166 case AtomicOrdering::SequentiallyConsistent
:
2167 return AtomicOrdering::SequentiallyConsistent
;
2169 llvm_unreachable("Unknown ordering");
2172 Value
*makeAddReleaseOrderingTable(IRBuilder
<> &IRB
) {
2173 constexpr int NumOrderings
= (int)AtomicOrderingCABI::seq_cst
+ 1;
2174 uint32_t OrderingTable
[NumOrderings
] = {};
2176 OrderingTable
[(int)AtomicOrderingCABI::relaxed
] =
2177 OrderingTable
[(int)AtomicOrderingCABI::release
] =
2178 (int)AtomicOrderingCABI::release
;
2179 OrderingTable
[(int)AtomicOrderingCABI::consume
] =
2180 OrderingTable
[(int)AtomicOrderingCABI::acquire
] =
2181 OrderingTable
[(int)AtomicOrderingCABI::acq_rel
] =
2182 (int)AtomicOrderingCABI::acq_rel
;
2183 OrderingTable
[(int)AtomicOrderingCABI::seq_cst
] =
2184 (int)AtomicOrderingCABI::seq_cst
;
2186 return ConstantDataVector::get(IRB
.getContext(), OrderingTable
);
2189 AtomicOrdering
addAcquireOrdering(AtomicOrdering a
) {
2191 case AtomicOrdering::NotAtomic
:
2192 return AtomicOrdering::NotAtomic
;
2193 case AtomicOrdering::Unordered
:
2194 case AtomicOrdering::Monotonic
:
2195 case AtomicOrdering::Acquire
:
2196 return AtomicOrdering::Acquire
;
2197 case AtomicOrdering::Release
:
2198 case AtomicOrdering::AcquireRelease
:
2199 return AtomicOrdering::AcquireRelease
;
2200 case AtomicOrdering::SequentiallyConsistent
:
2201 return AtomicOrdering::SequentiallyConsistent
;
2203 llvm_unreachable("Unknown ordering");
2206 Value
*makeAddAcquireOrderingTable(IRBuilder
<> &IRB
) {
2207 constexpr int NumOrderings
= (int)AtomicOrderingCABI::seq_cst
+ 1;
2208 uint32_t OrderingTable
[NumOrderings
] = {};
2210 OrderingTable
[(int)AtomicOrderingCABI::relaxed
] =
2211 OrderingTable
[(int)AtomicOrderingCABI::acquire
] =
2212 OrderingTable
[(int)AtomicOrderingCABI::consume
] =
2213 (int)AtomicOrderingCABI::acquire
;
2214 OrderingTable
[(int)AtomicOrderingCABI::release
] =
2215 OrderingTable
[(int)AtomicOrderingCABI::acq_rel
] =
2216 (int)AtomicOrderingCABI::acq_rel
;
2217 OrderingTable
[(int)AtomicOrderingCABI::seq_cst
] =
2218 (int)AtomicOrderingCABI::seq_cst
;
2220 return ConstantDataVector::get(IRB
.getContext(), OrderingTable
);
2223 // ------------------- Visitors.
2224 using InstVisitor
<MemorySanitizerVisitor
>::visit
;
2225 void visit(Instruction
&I
) {
2226 if (I
.getMetadata(LLVMContext::MD_nosanitize
))
2228 // Don't want to visit if we're in the prologue
2229 if (isInPrologue(I
))
2231 if (!DebugCounter::shouldExecute(DebugInstrumentInstruction
)) {
2232 LLVM_DEBUG(dbgs() << "Skipping instruction: " << I
<< "\n");
2233 // We still need to set the shadow and origin to clean values.
2234 setShadow(&I
, getCleanShadow(&I
));
2235 setOrigin(&I
, getCleanOrigin());
2239 Instructions
.push_back(&I
);
2242 /// Instrument LoadInst
2244 /// Loads the corresponding shadow and (optionally) origin.
2245 /// Optionally, checks that the load address is fully defined.
2246 void visitLoadInst(LoadInst
&I
) {
2247 assert(I
.getType()->isSized() && "Load type must have size");
2248 assert(!I
.getMetadata(LLVMContext::MD_nosanitize
));
2249 NextNodeIRBuilder
IRB(&I
);
2250 Type
*ShadowTy
= getShadowTy(&I
);
2251 Value
*Addr
= I
.getPointerOperand();
2252 Value
*ShadowPtr
= nullptr, *OriginPtr
= nullptr;
2253 const Align Alignment
= I
.getAlign();
2254 if (PropagateShadow
) {
2255 std::tie(ShadowPtr
, OriginPtr
) =
2256 getShadowOriginPtr(Addr
, IRB
, ShadowTy
, Alignment
, /*isStore*/ false);
2258 IRB
.CreateAlignedLoad(ShadowTy
, ShadowPtr
, Alignment
, "_msld"));
2260 setShadow(&I
, getCleanShadow(&I
));
2263 if (ClCheckAccessAddress
)
2264 insertShadowCheck(I
.getPointerOperand(), &I
);
2267 I
.setOrdering(addAcquireOrdering(I
.getOrdering()));
2269 if (MS
.TrackOrigins
) {
2270 if (PropagateShadow
) {
2271 const Align OriginAlignment
= std::max(kMinOriginAlignment
, Alignment
);
2273 &I
, IRB
.CreateAlignedLoad(MS
.OriginTy
, OriginPtr
, OriginAlignment
));
2275 setOrigin(&I
, getCleanOrigin());
2280 /// Instrument StoreInst
2282 /// Stores the corresponding shadow and (optionally) origin.
2283 /// Optionally, checks that the store address is fully defined.
2284 void visitStoreInst(StoreInst
&I
) {
2285 StoreList
.push_back(&I
);
2286 if (ClCheckAccessAddress
)
2287 insertShadowCheck(I
.getPointerOperand(), &I
);
2290 void handleCASOrRMW(Instruction
&I
) {
2291 assert(isa
<AtomicRMWInst
>(I
) || isa
<AtomicCmpXchgInst
>(I
));
2293 IRBuilder
<> IRB(&I
);
2294 Value
*Addr
= I
.getOperand(0);
2295 Value
*Val
= I
.getOperand(1);
2296 Value
*ShadowPtr
= getShadowOriginPtr(Addr
, IRB
, getShadowTy(Val
), Align(1),
2300 if (ClCheckAccessAddress
)
2301 insertShadowCheck(Addr
, &I
);
2303 // Only test the conditional argument of cmpxchg instruction.
2304 // The other argument can potentially be uninitialized, but we can not
2305 // detect this situation reliably without possible false positives.
2306 if (isa
<AtomicCmpXchgInst
>(I
))
2307 insertShadowCheck(Val
, &I
);
2309 IRB
.CreateStore(getCleanShadow(Val
), ShadowPtr
);
2311 setShadow(&I
, getCleanShadow(&I
));
2312 setOrigin(&I
, getCleanOrigin());
2315 void visitAtomicRMWInst(AtomicRMWInst
&I
) {
2317 I
.setOrdering(addReleaseOrdering(I
.getOrdering()));
2320 void visitAtomicCmpXchgInst(AtomicCmpXchgInst
&I
) {
2322 I
.setSuccessOrdering(addReleaseOrdering(I
.getSuccessOrdering()));
2325 // Vector manipulation.
2326 void visitExtractElementInst(ExtractElementInst
&I
) {
2327 insertShadowCheck(I
.getOperand(1), &I
);
2328 IRBuilder
<> IRB(&I
);
2329 setShadow(&I
, IRB
.CreateExtractElement(getShadow(&I
, 0), I
.getOperand(1),
2331 setOrigin(&I
, getOrigin(&I
, 0));
2334 void visitInsertElementInst(InsertElementInst
&I
) {
2335 insertShadowCheck(I
.getOperand(2), &I
);
2336 IRBuilder
<> IRB(&I
);
2337 auto *Shadow0
= getShadow(&I
, 0);
2338 auto *Shadow1
= getShadow(&I
, 1);
2339 setShadow(&I
, IRB
.CreateInsertElement(Shadow0
, Shadow1
, I
.getOperand(2),
2341 setOriginForNaryOp(I
);
2344 void visitShuffleVectorInst(ShuffleVectorInst
&I
) {
2345 IRBuilder
<> IRB(&I
);
2346 auto *Shadow0
= getShadow(&I
, 0);
2347 auto *Shadow1
= getShadow(&I
, 1);
2348 setShadow(&I
, IRB
.CreateShuffleVector(Shadow0
, Shadow1
, I
.getShuffleMask(),
2350 setOriginForNaryOp(I
);
2354 void visitSExtInst(SExtInst
&I
) {
2355 IRBuilder
<> IRB(&I
);
2356 setShadow(&I
, IRB
.CreateSExt(getShadow(&I
, 0), I
.getType(), "_msprop"));
2357 setOrigin(&I
, getOrigin(&I
, 0));
2360 void visitZExtInst(ZExtInst
&I
) {
2361 IRBuilder
<> IRB(&I
);
2362 setShadow(&I
, IRB
.CreateZExt(getShadow(&I
, 0), I
.getType(), "_msprop"));
2363 setOrigin(&I
, getOrigin(&I
, 0));
2366 void visitTruncInst(TruncInst
&I
) {
2367 IRBuilder
<> IRB(&I
);
2368 setShadow(&I
, IRB
.CreateTrunc(getShadow(&I
, 0), I
.getType(), "_msprop"));
2369 setOrigin(&I
, getOrigin(&I
, 0));
2372 void visitBitCastInst(BitCastInst
&I
) {
2373 // Special case: if this is the bitcast (there is exactly 1 allowed) between
2374 // a musttail call and a ret, don't instrument. New instructions are not
2375 // allowed after a musttail call.
2376 if (auto *CI
= dyn_cast
<CallInst
>(I
.getOperand(0)))
2377 if (CI
->isMustTailCall())
2379 IRBuilder
<> IRB(&I
);
2380 setShadow(&I
, IRB
.CreateBitCast(getShadow(&I
, 0), getShadowTy(&I
)));
2381 setOrigin(&I
, getOrigin(&I
, 0));
2384 void visitPtrToIntInst(PtrToIntInst
&I
) {
2385 IRBuilder
<> IRB(&I
);
2386 setShadow(&I
, IRB
.CreateIntCast(getShadow(&I
, 0), getShadowTy(&I
), false,
2387 "_msprop_ptrtoint"));
2388 setOrigin(&I
, getOrigin(&I
, 0));
2391 void visitIntToPtrInst(IntToPtrInst
&I
) {
2392 IRBuilder
<> IRB(&I
);
2393 setShadow(&I
, IRB
.CreateIntCast(getShadow(&I
, 0), getShadowTy(&I
), false,
2394 "_msprop_inttoptr"));
2395 setOrigin(&I
, getOrigin(&I
, 0));
2398 void visitFPToSIInst(CastInst
&I
) { handleShadowOr(I
); }
2399 void visitFPToUIInst(CastInst
&I
) { handleShadowOr(I
); }
2400 void visitSIToFPInst(CastInst
&I
) { handleShadowOr(I
); }
2401 void visitUIToFPInst(CastInst
&I
) { handleShadowOr(I
); }
2402 void visitFPExtInst(CastInst
&I
) { handleShadowOr(I
); }
2403 void visitFPTruncInst(CastInst
&I
) { handleShadowOr(I
); }
2405 /// Propagate shadow for bitwise AND.
2407 /// This code is exact, i.e. if, for example, a bit in the left argument
2408 /// is defined and 0, then neither the value not definedness of the
2409 /// corresponding bit in B don't affect the resulting shadow.
2410 void visitAnd(BinaryOperator
&I
) {
2411 IRBuilder
<> IRB(&I
);
2412 // "And" of 0 and a poisoned value results in unpoisoned value.
2413 // 1&1 => 1; 0&1 => 0; p&1 => p;
2414 // 1&0 => 0; 0&0 => 0; p&0 => 0;
2415 // 1&p => p; 0&p => 0; p&p => p;
2416 // S = (S1 & S2) | (V1 & S2) | (S1 & V2)
2417 Value
*S1
= getShadow(&I
, 0);
2418 Value
*S2
= getShadow(&I
, 1);
2419 Value
*V1
= I
.getOperand(0);
2420 Value
*V2
= I
.getOperand(1);
2421 if (V1
->getType() != S1
->getType()) {
2422 V1
= IRB
.CreateIntCast(V1
, S1
->getType(), false);
2423 V2
= IRB
.CreateIntCast(V2
, S2
->getType(), false);
2425 Value
*S1S2
= IRB
.CreateAnd(S1
, S2
);
2426 Value
*V1S2
= IRB
.CreateAnd(V1
, S2
);
2427 Value
*S1V2
= IRB
.CreateAnd(S1
, V2
);
2428 setShadow(&I
, IRB
.CreateOr({S1S2
, V1S2
, S1V2
}));
2429 setOriginForNaryOp(I
);
2432 void visitOr(BinaryOperator
&I
) {
2433 IRBuilder
<> IRB(&I
);
2434 // "Or" of 1 and a poisoned value results in unpoisoned value.
2435 // 1|1 => 1; 0|1 => 1; p|1 => 1;
2436 // 1|0 => 1; 0|0 => 0; p|0 => p;
2437 // 1|p => 1; 0|p => p; p|p => p;
2438 // S = (S1 & S2) | (~V1 & S2) | (S1 & ~V2)
2439 Value
*S1
= getShadow(&I
, 0);
2440 Value
*S2
= getShadow(&I
, 1);
2441 Value
*V1
= IRB
.CreateNot(I
.getOperand(0));
2442 Value
*V2
= IRB
.CreateNot(I
.getOperand(1));
2443 if (V1
->getType() != S1
->getType()) {
2444 V1
= IRB
.CreateIntCast(V1
, S1
->getType(), false);
2445 V2
= IRB
.CreateIntCast(V2
, S2
->getType(), false);
2447 Value
*S1S2
= IRB
.CreateAnd(S1
, S2
);
2448 Value
*V1S2
= IRB
.CreateAnd(V1
, S2
);
2449 Value
*S1V2
= IRB
.CreateAnd(S1
, V2
);
2450 setShadow(&I
, IRB
.CreateOr({S1S2
, V1S2
, S1V2
}));
2451 setOriginForNaryOp(I
);
2454 /// Default propagation of shadow and/or origin.
2456 /// This class implements the general case of shadow propagation, used in all
2457 /// cases where we don't know and/or don't care about what the operation
2458 /// actually does. It converts all input shadow values to a common type
2459 /// (extending or truncating as necessary), and bitwise OR's them.
2461 /// This is much cheaper than inserting checks (i.e. requiring inputs to be
2462 /// fully initialized), and less prone to false positives.
2464 /// This class also implements the general case of origin propagation. For a
2465 /// Nary operation, result origin is set to the origin of an argument that is
2466 /// not entirely initialized. If there is more than one such arguments, the
2467 /// rightmost of them is picked. It does not matter which one is picked if all
2468 /// arguments are initialized.
2469 template <bool CombineShadow
> class Combiner
{
2470 Value
*Shadow
= nullptr;
2471 Value
*Origin
= nullptr;
2473 MemorySanitizerVisitor
*MSV
;
2476 Combiner(MemorySanitizerVisitor
*MSV
, IRBuilder
<> &IRB
)
2477 : IRB(IRB
), MSV(MSV
) {}
2479 /// Add a pair of shadow and origin values to the mix.
2480 Combiner
&Add(Value
*OpShadow
, Value
*OpOrigin
) {
2481 if (CombineShadow
) {
2486 OpShadow
= MSV
->CreateShadowCast(IRB
, OpShadow
, Shadow
->getType());
2487 Shadow
= IRB
.CreateOr(Shadow
, OpShadow
, "_msprop");
2491 if (MSV
->MS
.TrackOrigins
) {
2496 Constant
*ConstOrigin
= dyn_cast
<Constant
>(OpOrigin
);
2497 // No point in adding something that might result in 0 origin value.
2498 if (!ConstOrigin
|| !ConstOrigin
->isNullValue()) {
2499 Value
*Cond
= MSV
->convertToBool(OpShadow
, IRB
);
2500 Origin
= IRB
.CreateSelect(Cond
, OpOrigin
, Origin
);
2507 /// Add an application value to the mix.
2508 Combiner
&Add(Value
*V
) {
2509 Value
*OpShadow
= MSV
->getShadow(V
);
2510 Value
*OpOrigin
= MSV
->MS
.TrackOrigins
? MSV
->getOrigin(V
) : nullptr;
2511 return Add(OpShadow
, OpOrigin
);
2514 /// Set the current combined values as the given instruction's shadow
2516 void Done(Instruction
*I
) {
2517 if (CombineShadow
) {
2519 Shadow
= MSV
->CreateShadowCast(IRB
, Shadow
, MSV
->getShadowTy(I
));
2520 MSV
->setShadow(I
, Shadow
);
2522 if (MSV
->MS
.TrackOrigins
) {
2524 MSV
->setOrigin(I
, Origin
);
2528 /// Store the current combined value at the specified origin
2530 void DoneAndStoreOrigin(TypeSize TS
, Value
*OriginPtr
) {
2531 if (MSV
->MS
.TrackOrigins
) {
2533 MSV
->paintOrigin(IRB
, Origin
, OriginPtr
, TS
, kMinOriginAlignment
);
2538 using ShadowAndOriginCombiner
= Combiner
<true>;
2539 using OriginCombiner
= Combiner
<false>;
2541 /// Propagate origin for arbitrary operation.
2542 void setOriginForNaryOp(Instruction
&I
) {
2543 if (!MS
.TrackOrigins
)
2545 IRBuilder
<> IRB(&I
);
2546 OriginCombiner
OC(this, IRB
);
2547 for (Use
&Op
: I
.operands())
2552 size_t VectorOrPrimitiveTypeSizeInBits(Type
*Ty
) {
2553 assert(!(Ty
->isVectorTy() && Ty
->getScalarType()->isPointerTy()) &&
2554 "Vector of pointers is not a valid shadow type");
2555 return Ty
->isVectorTy() ? cast
<FixedVectorType
>(Ty
)->getNumElements() *
2556 Ty
->getScalarSizeInBits()
2557 : Ty
->getPrimitiveSizeInBits();
2560 /// Cast between two shadow types, extending or truncating as
2562 Value
*CreateShadowCast(IRBuilder
<> &IRB
, Value
*V
, Type
*dstTy
,
2563 bool Signed
= false) {
2564 Type
*srcTy
= V
->getType();
2567 size_t srcSizeInBits
= VectorOrPrimitiveTypeSizeInBits(srcTy
);
2568 size_t dstSizeInBits
= VectorOrPrimitiveTypeSizeInBits(dstTy
);
2569 if (srcSizeInBits
> 1 && dstSizeInBits
== 1)
2570 return IRB
.CreateICmpNE(V
, getCleanShadow(V
));
2572 if (dstTy
->isIntegerTy() && srcTy
->isIntegerTy())
2573 return IRB
.CreateIntCast(V
, dstTy
, Signed
);
2574 if (dstTy
->isVectorTy() && srcTy
->isVectorTy() &&
2575 cast
<VectorType
>(dstTy
)->getElementCount() ==
2576 cast
<VectorType
>(srcTy
)->getElementCount())
2577 return IRB
.CreateIntCast(V
, dstTy
, Signed
);
2578 Value
*V1
= IRB
.CreateBitCast(V
, Type::getIntNTy(*MS
.C
, srcSizeInBits
));
2580 IRB
.CreateIntCast(V1
, Type::getIntNTy(*MS
.C
, dstSizeInBits
), Signed
);
2581 return IRB
.CreateBitCast(V2
, dstTy
);
2582 // TODO: handle struct types.
2585 /// Cast an application value to the type of its own shadow.
2586 Value
*CreateAppToShadowCast(IRBuilder
<> &IRB
, Value
*V
) {
2587 Type
*ShadowTy
= getShadowTy(V
);
2588 if (V
->getType() == ShadowTy
)
2590 if (V
->getType()->isPtrOrPtrVectorTy())
2591 return IRB
.CreatePtrToInt(V
, ShadowTy
);
2593 return IRB
.CreateBitCast(V
, ShadowTy
);
2596 /// Propagate shadow for arbitrary operation.
2597 void handleShadowOr(Instruction
&I
) {
2598 IRBuilder
<> IRB(&I
);
2599 ShadowAndOriginCombiner
SC(this, IRB
);
2600 for (Use
&Op
: I
.operands())
2605 void visitFNeg(UnaryOperator
&I
) { handleShadowOr(I
); }
2607 // Handle multiplication by constant.
2609 // Handle a special case of multiplication by constant that may have one or
2610 // more zeros in the lower bits. This makes corresponding number of lower bits
2611 // of the result zero as well. We model it by shifting the other operand
2612 // shadow left by the required number of bits. Effectively, we transform
2613 // (X * (A * 2**B)) to ((X << B) * A) and instrument (X << B) as (Sx << B).
2614 // We use multiplication by 2**N instead of shift to cover the case of
2615 // multiplication by 0, which may occur in some elements of a vector operand.
2616 void handleMulByConstant(BinaryOperator
&I
, Constant
*ConstArg
,
2618 Constant
*ShadowMul
;
2619 Type
*Ty
= ConstArg
->getType();
2620 if (auto *VTy
= dyn_cast
<VectorType
>(Ty
)) {
2621 unsigned NumElements
= cast
<FixedVectorType
>(VTy
)->getNumElements();
2622 Type
*EltTy
= VTy
->getElementType();
2623 SmallVector
<Constant
*, 16> Elements
;
2624 for (unsigned Idx
= 0; Idx
< NumElements
; ++Idx
) {
2625 if (ConstantInt
*Elt
=
2626 dyn_cast
<ConstantInt
>(ConstArg
->getAggregateElement(Idx
))) {
2627 const APInt
&V
= Elt
->getValue();
2628 APInt V2
= APInt(V
.getBitWidth(), 1) << V
.countr_zero();
2629 Elements
.push_back(ConstantInt::get(EltTy
, V2
));
2631 Elements
.push_back(ConstantInt::get(EltTy
, 1));
2634 ShadowMul
= ConstantVector::get(Elements
);
2636 if (ConstantInt
*Elt
= dyn_cast
<ConstantInt
>(ConstArg
)) {
2637 const APInt
&V
= Elt
->getValue();
2638 APInt V2
= APInt(V
.getBitWidth(), 1) << V
.countr_zero();
2639 ShadowMul
= ConstantInt::get(Ty
, V2
);
2641 ShadowMul
= ConstantInt::get(Ty
, 1);
2645 IRBuilder
<> IRB(&I
);
2647 IRB
.CreateMul(getShadow(OtherArg
), ShadowMul
, "msprop_mul_cst"));
2648 setOrigin(&I
, getOrigin(OtherArg
));
2651 void visitMul(BinaryOperator
&I
) {
2652 Constant
*constOp0
= dyn_cast
<Constant
>(I
.getOperand(0));
2653 Constant
*constOp1
= dyn_cast
<Constant
>(I
.getOperand(1));
2654 if (constOp0
&& !constOp1
)
2655 handleMulByConstant(I
, constOp0
, I
.getOperand(1));
2656 else if (constOp1
&& !constOp0
)
2657 handleMulByConstant(I
, constOp1
, I
.getOperand(0));
2662 void visitFAdd(BinaryOperator
&I
) { handleShadowOr(I
); }
2663 void visitFSub(BinaryOperator
&I
) { handleShadowOr(I
); }
2664 void visitFMul(BinaryOperator
&I
) { handleShadowOr(I
); }
2665 void visitAdd(BinaryOperator
&I
) { handleShadowOr(I
); }
2666 void visitSub(BinaryOperator
&I
) { handleShadowOr(I
); }
2667 void visitXor(BinaryOperator
&I
) { handleShadowOr(I
); }
2669 void handleIntegerDiv(Instruction
&I
) {
2670 IRBuilder
<> IRB(&I
);
2671 // Strict on the second argument.
2672 insertShadowCheck(I
.getOperand(1), &I
);
2673 setShadow(&I
, getShadow(&I
, 0));
2674 setOrigin(&I
, getOrigin(&I
, 0));
2677 void visitUDiv(BinaryOperator
&I
) { handleIntegerDiv(I
); }
2678 void visitSDiv(BinaryOperator
&I
) { handleIntegerDiv(I
); }
2679 void visitURem(BinaryOperator
&I
) { handleIntegerDiv(I
); }
2680 void visitSRem(BinaryOperator
&I
) { handleIntegerDiv(I
); }
2682 // Floating point division is side-effect free. We can not require that the
2683 // divisor is fully initialized and must propagate shadow. See PR37523.
2684 void visitFDiv(BinaryOperator
&I
) { handleShadowOr(I
); }
2685 void visitFRem(BinaryOperator
&I
) { handleShadowOr(I
); }
2687 /// Instrument == and != comparisons.
2689 /// Sometimes the comparison result is known even if some of the bits of the
2690 /// arguments are not.
2691 void handleEqualityComparison(ICmpInst
&I
) {
2692 IRBuilder
<> IRB(&I
);
2693 Value
*A
= I
.getOperand(0);
2694 Value
*B
= I
.getOperand(1);
2695 Value
*Sa
= getShadow(A
);
2696 Value
*Sb
= getShadow(B
);
2698 // Get rid of pointers and vectors of pointers.
2699 // For ints (and vectors of ints), types of A and Sa match,
2700 // and this is a no-op.
2701 A
= IRB
.CreatePointerCast(A
, Sa
->getType());
2702 B
= IRB
.CreatePointerCast(B
, Sb
->getType());
2704 // A == B <==> (C = A^B) == 0
2705 // A != B <==> (C = A^B) != 0
2707 Value
*C
= IRB
.CreateXor(A
, B
);
2708 Value
*Sc
= IRB
.CreateOr(Sa
, Sb
);
2709 // Now dealing with i = (C == 0) comparison (or C != 0, does not matter now)
2710 // Result is defined if one of the following is true
2711 // * there is a defined 1 bit in C
2712 // * C is fully defined
2713 // Si = !(C & ~Sc) && Sc
2714 Value
*Zero
= Constant::getNullValue(Sc
->getType());
2715 Value
*MinusOne
= Constant::getAllOnesValue(Sc
->getType());
2716 Value
*LHS
= IRB
.CreateICmpNE(Sc
, Zero
);
2718 IRB
.CreateICmpEQ(IRB
.CreateAnd(IRB
.CreateXor(Sc
, MinusOne
), C
), Zero
);
2719 Value
*Si
= IRB
.CreateAnd(LHS
, RHS
);
2720 Si
->setName("_msprop_icmp");
2722 setOriginForNaryOp(I
);
2725 /// Instrument relational comparisons.
2727 /// This function does exact shadow propagation for all relational
2728 /// comparisons of integers, pointers and vectors of those.
2729 /// FIXME: output seems suboptimal when one of the operands is a constant
2730 void handleRelationalComparisonExact(ICmpInst
&I
) {
2731 IRBuilder
<> IRB(&I
);
2732 Value
*A
= I
.getOperand(0);
2733 Value
*B
= I
.getOperand(1);
2734 Value
*Sa
= getShadow(A
);
2735 Value
*Sb
= getShadow(B
);
2737 // Get rid of pointers and vectors of pointers.
2738 // For ints (and vectors of ints), types of A and Sa match,
2739 // and this is a no-op.
2740 A
= IRB
.CreatePointerCast(A
, Sa
->getType());
2741 B
= IRB
.CreatePointerCast(B
, Sb
->getType());
2743 // Let [a0, a1] be the interval of possible values of A, taking into account
2744 // its undefined bits. Let [b0, b1] be the interval of possible values of B.
2745 // Then (A cmp B) is defined iff (a0 cmp b1) == (a1 cmp b0).
2746 bool IsSigned
= I
.isSigned();
2748 auto GetMinMaxUnsigned
= [&](Value
*V
, Value
*S
) {
2750 // Sign-flip to map from signed range to unsigned range. Relation A vs B
2751 // should be preserved, if checked with `getUnsignedPredicate()`.
2752 // Relationship between Amin, Amax, Bmin, Bmax also will not be
2753 // affected, as they are created by effectively adding/substructing from
2754 // A (or B) a value, derived from shadow, with no overflow, either
2755 // before or after sign flip.
2757 APInt::getSignedMinValue(V
->getType()->getScalarSizeInBits());
2758 V
= IRB
.CreateXor(V
, ConstantInt::get(V
->getType(), MinVal
));
2760 // Minimize undefined bits.
2761 Value
*Min
= IRB
.CreateAnd(V
, IRB
.CreateNot(S
));
2762 Value
*Max
= IRB
.CreateOr(V
, S
);
2763 return std::make_pair(Min
, Max
);
2766 auto [Amin
, Amax
] = GetMinMaxUnsigned(A
, Sa
);
2767 auto [Bmin
, Bmax
] = GetMinMaxUnsigned(B
, Sb
);
2768 Value
*S1
= IRB
.CreateICmp(I
.getUnsignedPredicate(), Amin
, Bmax
);
2769 Value
*S2
= IRB
.CreateICmp(I
.getUnsignedPredicate(), Amax
, Bmin
);
2771 Value
*Si
= IRB
.CreateXor(S1
, S2
);
2773 setOriginForNaryOp(I
);
2776 /// Instrument signed relational comparisons.
2778 /// Handle sign bit tests: x<0, x>=0, x<=-1, x>-1 by propagating the highest
2779 /// bit of the shadow. Everything else is delegated to handleShadowOr().
2780 void handleSignedRelationalComparison(ICmpInst
&I
) {
2782 Value
*op
= nullptr;
2783 CmpInst::Predicate pre
;
2784 if ((constOp
= dyn_cast
<Constant
>(I
.getOperand(1)))) {
2785 op
= I
.getOperand(0);
2786 pre
= I
.getPredicate();
2787 } else if ((constOp
= dyn_cast
<Constant
>(I
.getOperand(0)))) {
2788 op
= I
.getOperand(1);
2789 pre
= I
.getSwappedPredicate();
2795 if ((constOp
->isNullValue() &&
2796 (pre
== CmpInst::ICMP_SLT
|| pre
== CmpInst::ICMP_SGE
)) ||
2797 (constOp
->isAllOnesValue() &&
2798 (pre
== CmpInst::ICMP_SGT
|| pre
== CmpInst::ICMP_SLE
))) {
2799 IRBuilder
<> IRB(&I
);
2800 Value
*Shadow
= IRB
.CreateICmpSLT(getShadow(op
), getCleanShadow(op
),
2802 setShadow(&I
, Shadow
);
2803 setOrigin(&I
, getOrigin(op
));
2809 void visitICmpInst(ICmpInst
&I
) {
2810 if (!ClHandleICmp
) {
2814 if (I
.isEquality()) {
2815 handleEqualityComparison(I
);
2819 assert(I
.isRelational());
2820 if (ClHandleICmpExact
) {
2821 handleRelationalComparisonExact(I
);
2825 handleSignedRelationalComparison(I
);
2829 assert(I
.isUnsigned());
2830 if ((isa
<Constant
>(I
.getOperand(0)) || isa
<Constant
>(I
.getOperand(1)))) {
2831 handleRelationalComparisonExact(I
);
2838 void visitFCmpInst(FCmpInst
&I
) { handleShadowOr(I
); }
2840 void handleShift(BinaryOperator
&I
) {
2841 IRBuilder
<> IRB(&I
);
2842 // If any of the S2 bits are poisoned, the whole thing is poisoned.
2843 // Otherwise perform the same shift on S1.
2844 Value
*S1
= getShadow(&I
, 0);
2845 Value
*S2
= getShadow(&I
, 1);
2847 IRB
.CreateSExt(IRB
.CreateICmpNE(S2
, getCleanShadow(S2
)), S2
->getType());
2848 Value
*V2
= I
.getOperand(1);
2849 Value
*Shift
= IRB
.CreateBinOp(I
.getOpcode(), S1
, V2
);
2850 setShadow(&I
, IRB
.CreateOr(Shift
, S2Conv
));
2851 setOriginForNaryOp(I
);
2854 void visitShl(BinaryOperator
&I
) { handleShift(I
); }
2855 void visitAShr(BinaryOperator
&I
) { handleShift(I
); }
2856 void visitLShr(BinaryOperator
&I
) { handleShift(I
); }
2858 void handleFunnelShift(IntrinsicInst
&I
) {
2859 IRBuilder
<> IRB(&I
);
2860 // If any of the S2 bits are poisoned, the whole thing is poisoned.
2861 // Otherwise perform the same shift on S0 and S1.
2862 Value
*S0
= getShadow(&I
, 0);
2863 Value
*S1
= getShadow(&I
, 1);
2864 Value
*S2
= getShadow(&I
, 2);
2866 IRB
.CreateSExt(IRB
.CreateICmpNE(S2
, getCleanShadow(S2
)), S2
->getType());
2867 Value
*V2
= I
.getOperand(2);
2868 Value
*Shift
= IRB
.CreateIntrinsic(I
.getIntrinsicID(), S2Conv
->getType(),
2870 setShadow(&I
, IRB
.CreateOr(Shift
, S2Conv
));
2871 setOriginForNaryOp(I
);
2874 /// Instrument llvm.memmove
2876 /// At this point we don't know if llvm.memmove will be inlined or not.
2877 /// If we don't instrument it and it gets inlined,
2878 /// our interceptor will not kick in and we will lose the memmove.
2879 /// If we instrument the call here, but it does not get inlined,
2880 /// we will memove the shadow twice: which is bad in case
2881 /// of overlapping regions. So, we simply lower the intrinsic to a call.
2883 /// Similar situation exists for memcpy and memset.
2884 void visitMemMoveInst(MemMoveInst
&I
) {
2885 getShadow(I
.getArgOperand(1)); // Ensure shadow initialized
2886 IRBuilder
<> IRB(&I
);
2887 IRB
.CreateCall(MS
.MemmoveFn
,
2888 {I
.getArgOperand(0), I
.getArgOperand(1),
2889 IRB
.CreateIntCast(I
.getArgOperand(2), MS
.IntptrTy
, false)});
2890 I
.eraseFromParent();
2893 /// Instrument memcpy
2895 /// Similar to memmove: avoid copying shadow twice. This is somewhat
2896 /// unfortunate as it may slowdown small constant memcpys.
2897 /// FIXME: consider doing manual inline for small constant sizes and proper
2900 /// Note: This also handles memcpy.inline, which promises no calls to external
2901 /// functions as an optimization. However, with instrumentation enabled this
2902 /// is difficult to promise; additionally, we know that the MSan runtime
2903 /// exists and provides __msan_memcpy(). Therefore, we assume that with
2904 /// instrumentation it's safe to turn memcpy.inline into a call to
2905 /// __msan_memcpy(). Should this be wrong, such as when implementing memcpy()
2906 /// itself, instrumentation should be disabled with the no_sanitize attribute.
2907 void visitMemCpyInst(MemCpyInst
&I
) {
2908 getShadow(I
.getArgOperand(1)); // Ensure shadow initialized
2909 IRBuilder
<> IRB(&I
);
2910 IRB
.CreateCall(MS
.MemcpyFn
,
2911 {I
.getArgOperand(0), I
.getArgOperand(1),
2912 IRB
.CreateIntCast(I
.getArgOperand(2), MS
.IntptrTy
, false)});
2913 I
.eraseFromParent();
2917 void visitMemSetInst(MemSetInst
&I
) {
2918 IRBuilder
<> IRB(&I
);
2921 {I
.getArgOperand(0),
2922 IRB
.CreateIntCast(I
.getArgOperand(1), IRB
.getInt32Ty(), false),
2923 IRB
.CreateIntCast(I
.getArgOperand(2), MS
.IntptrTy
, false)});
2924 I
.eraseFromParent();
2927 void visitVAStartInst(VAStartInst
&I
) { VAHelper
->visitVAStartInst(I
); }
2929 void visitVACopyInst(VACopyInst
&I
) { VAHelper
->visitVACopyInst(I
); }
2931 /// Handle vector store-like intrinsics.
2933 /// Instrument intrinsics that look like a simple SIMD store: writes memory,
2934 /// has 1 pointer argument and 1 vector argument, returns void.
2935 bool handleVectorStoreIntrinsic(IntrinsicInst
&I
) {
2936 IRBuilder
<> IRB(&I
);
2937 Value
*Addr
= I
.getArgOperand(0);
2938 Value
*Shadow
= getShadow(&I
, 1);
2939 Value
*ShadowPtr
, *OriginPtr
;
2941 // We don't know the pointer alignment (could be unaligned SSE store!).
2942 // Have to assume to worst case.
2943 std::tie(ShadowPtr
, OriginPtr
) = getShadowOriginPtr(
2944 Addr
, IRB
, Shadow
->getType(), Align(1), /*isStore*/ true);
2945 IRB
.CreateAlignedStore(Shadow
, ShadowPtr
, Align(1));
2947 if (ClCheckAccessAddress
)
2948 insertShadowCheck(Addr
, &I
);
2950 // FIXME: factor out common code from materializeStores
2951 if (MS
.TrackOrigins
)
2952 IRB
.CreateStore(getOrigin(&I
, 1), OriginPtr
);
2956 /// Handle vector load-like intrinsics.
2958 /// Instrument intrinsics that look like a simple SIMD load: reads memory,
2959 /// has 1 pointer argument, returns a vector.
2960 bool handleVectorLoadIntrinsic(IntrinsicInst
&I
) {
2961 IRBuilder
<> IRB(&I
);
2962 Value
*Addr
= I
.getArgOperand(0);
2964 Type
*ShadowTy
= getShadowTy(&I
);
2965 Value
*ShadowPtr
= nullptr, *OriginPtr
= nullptr;
2966 if (PropagateShadow
) {
2967 // We don't know the pointer alignment (could be unaligned SSE load!).
2968 // Have to assume to worst case.
2969 const Align Alignment
= Align(1);
2970 std::tie(ShadowPtr
, OriginPtr
) =
2971 getShadowOriginPtr(Addr
, IRB
, ShadowTy
, Alignment
, /*isStore*/ false);
2973 IRB
.CreateAlignedLoad(ShadowTy
, ShadowPtr
, Alignment
, "_msld"));
2975 setShadow(&I
, getCleanShadow(&I
));
2978 if (ClCheckAccessAddress
)
2979 insertShadowCheck(Addr
, &I
);
2981 if (MS
.TrackOrigins
) {
2982 if (PropagateShadow
)
2983 setOrigin(&I
, IRB
.CreateLoad(MS
.OriginTy
, OriginPtr
));
2985 setOrigin(&I
, getCleanOrigin());
2990 /// Handle (SIMD arithmetic)-like intrinsics.
2992 /// Instrument intrinsics with any number of arguments of the same type,
2993 /// equal to the return type. The type should be simple (no aggregates or
2994 /// pointers; vectors are fine).
2995 /// Caller guarantees that this intrinsic does not access memory.
2996 bool maybeHandleSimpleNomemIntrinsic(IntrinsicInst
&I
) {
2997 Type
*RetTy
= I
.getType();
2998 if (!(RetTy
->isIntOrIntVectorTy() || RetTy
->isFPOrFPVectorTy()))
3001 unsigned NumArgOperands
= I
.arg_size();
3002 for (unsigned i
= 0; i
< NumArgOperands
; ++i
) {
3003 Type
*Ty
= I
.getArgOperand(i
)->getType();
3008 IRBuilder
<> IRB(&I
);
3009 ShadowAndOriginCombiner
SC(this, IRB
);
3010 for (unsigned i
= 0; i
< NumArgOperands
; ++i
)
3011 SC
.Add(I
.getArgOperand(i
));
3017 /// Heuristically instrument unknown intrinsics.
3019 /// The main purpose of this code is to do something reasonable with all
3020 /// random intrinsics we might encounter, most importantly - SIMD intrinsics.
3021 /// We recognize several classes of intrinsics by their argument types and
3022 /// ModRefBehaviour and apply special instrumentation when we are reasonably
3023 /// sure that we know what the intrinsic does.
3025 /// We special-case intrinsics where this approach fails. See llvm.bswap
3026 /// handling as an example of that.
3027 bool handleUnknownIntrinsicUnlogged(IntrinsicInst
&I
) {
3028 unsigned NumArgOperands
= I
.arg_size();
3029 if (NumArgOperands
== 0)
3032 if (NumArgOperands
== 2 && I
.getArgOperand(0)->getType()->isPointerTy() &&
3033 I
.getArgOperand(1)->getType()->isVectorTy() &&
3034 I
.getType()->isVoidTy() && !I
.onlyReadsMemory()) {
3035 // This looks like a vector store.
3036 return handleVectorStoreIntrinsic(I
);
3039 if (NumArgOperands
== 1 && I
.getArgOperand(0)->getType()->isPointerTy() &&
3040 I
.getType()->isVectorTy() && I
.onlyReadsMemory()) {
3041 // This looks like a vector load.
3042 return handleVectorLoadIntrinsic(I
);
3045 if (I
.doesNotAccessMemory())
3046 if (maybeHandleSimpleNomemIntrinsic(I
))
3049 // FIXME: detect and handle SSE maskstore/maskload
3053 bool handleUnknownIntrinsic(IntrinsicInst
&I
) {
3054 if (handleUnknownIntrinsicUnlogged(I
)) {
3055 if (ClDumpStrictIntrinsics
)
3058 LLVM_DEBUG(dbgs() << "UNKNOWN INTRINSIC HANDLED HEURISTICALLY: " << I
3065 void handleInvariantGroup(IntrinsicInst
&I
) {
3066 setShadow(&I
, getShadow(&I
, 0));
3067 setOrigin(&I
, getOrigin(&I
, 0));
3070 void handleLifetimeStart(IntrinsicInst
&I
) {
3073 AllocaInst
*AI
= llvm::findAllocaForValue(I
.getArgOperand(1));
3075 InstrumentLifetimeStart
= false;
3076 LifetimeStartList
.push_back(std::make_pair(&I
, AI
));
3079 void handleBswap(IntrinsicInst
&I
) {
3080 IRBuilder
<> IRB(&I
);
3081 Value
*Op
= I
.getArgOperand(0);
3082 Type
*OpType
= Op
->getType();
3083 setShadow(&I
, IRB
.CreateIntrinsic(Intrinsic::bswap
, ArrayRef(&OpType
, 1),
3085 setOrigin(&I
, getOrigin(Op
));
3088 void handleCountZeroes(IntrinsicInst
&I
) {
3089 IRBuilder
<> IRB(&I
);
3090 Value
*Src
= I
.getArgOperand(0);
3092 // Set the Output shadow based on input Shadow
3093 Value
*BoolShadow
= IRB
.CreateIsNotNull(getShadow(Src
), "_mscz_bs");
3095 // If zero poison is requested, mix in with the shadow
3096 Constant
*IsZeroPoison
= cast
<Constant
>(I
.getOperand(1));
3097 if (!IsZeroPoison
->isZeroValue()) {
3098 Value
*BoolZeroPoison
= IRB
.CreateIsNull(Src
, "_mscz_bzp");
3099 BoolShadow
= IRB
.CreateOr(BoolShadow
, BoolZeroPoison
, "_mscz_bs");
3102 Value
*OutputShadow
=
3103 IRB
.CreateSExt(BoolShadow
, getShadowTy(Src
), "_mscz_os");
3105 setShadow(&I
, OutputShadow
);
3106 setOriginForNaryOp(I
);
3109 // Instrument vector convert intrinsic.
3111 // This function instruments intrinsics like cvtsi2ss:
3112 // %Out = int_xxx_cvtyyy(%ConvertOp)
3114 // %Out = int_xxx_cvtyyy(%CopyOp, %ConvertOp)
3115 // Intrinsic converts \p NumUsedElements elements of \p ConvertOp to the same
3116 // number \p Out elements, and (if has 2 arguments) copies the rest of the
3117 // elements from \p CopyOp.
3118 // In most cases conversion involves floating-point value which may trigger a
3119 // hardware exception when not fully initialized. For this reason we require
3120 // \p ConvertOp[0:NumUsedElements] to be fully initialized and trap otherwise.
3121 // We copy the shadow of \p CopyOp[NumUsedElements:] to \p
3122 // Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always
3123 // return a fully initialized value.
3124 void handleVectorConvertIntrinsic(IntrinsicInst
&I
, int NumUsedElements
,
3125 bool HasRoundingMode
= false) {
3126 IRBuilder
<> IRB(&I
);
3127 Value
*CopyOp
, *ConvertOp
;
3129 assert((!HasRoundingMode
||
3130 isa
<ConstantInt
>(I
.getArgOperand(I
.arg_size() - 1))) &&
3131 "Invalid rounding mode");
3133 switch (I
.arg_size() - HasRoundingMode
) {
3135 CopyOp
= I
.getArgOperand(0);
3136 ConvertOp
= I
.getArgOperand(1);
3139 ConvertOp
= I
.getArgOperand(0);
3143 llvm_unreachable("Cvt intrinsic with unsupported number of arguments.");
3146 // The first *NumUsedElements* elements of ConvertOp are converted to the
3147 // same number of output elements. The rest of the output is copied from
3148 // CopyOp, or (if not available) filled with zeroes.
3149 // Combine shadow for elements of ConvertOp that are used in this operation,
3150 // and insert a check.
3151 // FIXME: consider propagating shadow of ConvertOp, at least in the case of
3152 // int->any conversion.
3153 Value
*ConvertShadow
= getShadow(ConvertOp
);
3154 Value
*AggShadow
= nullptr;
3155 if (ConvertOp
->getType()->isVectorTy()) {
3156 AggShadow
= IRB
.CreateExtractElement(
3157 ConvertShadow
, ConstantInt::get(IRB
.getInt32Ty(), 0));
3158 for (int i
= 1; i
< NumUsedElements
; ++i
) {
3159 Value
*MoreShadow
= IRB
.CreateExtractElement(
3160 ConvertShadow
, ConstantInt::get(IRB
.getInt32Ty(), i
));
3161 AggShadow
= IRB
.CreateOr(AggShadow
, MoreShadow
);
3164 AggShadow
= ConvertShadow
;
3166 assert(AggShadow
->getType()->isIntegerTy());
3167 insertShadowCheck(AggShadow
, getOrigin(ConvertOp
), &I
);
3169 // Build result shadow by zero-filling parts of CopyOp shadow that come from
3172 assert(CopyOp
->getType() == I
.getType());
3173 assert(CopyOp
->getType()->isVectorTy());
3174 Value
*ResultShadow
= getShadow(CopyOp
);
3175 Type
*EltTy
= cast
<VectorType
>(ResultShadow
->getType())->getElementType();
3176 for (int i
= 0; i
< NumUsedElements
; ++i
) {
3177 ResultShadow
= IRB
.CreateInsertElement(
3178 ResultShadow
, ConstantInt::getNullValue(EltTy
),
3179 ConstantInt::get(IRB
.getInt32Ty(), i
));
3181 setShadow(&I
, ResultShadow
);
3182 setOrigin(&I
, getOrigin(CopyOp
));
3184 setShadow(&I
, getCleanShadow(&I
));
3185 setOrigin(&I
, getCleanOrigin());
3189 // Given a scalar or vector, extract lower 64 bits (or less), and return all
3190 // zeroes if it is zero, and all ones otherwise.
3191 Value
*Lower64ShadowExtend(IRBuilder
<> &IRB
, Value
*S
, Type
*T
) {
3192 if (S
->getType()->isVectorTy())
3193 S
= CreateShadowCast(IRB
, S
, IRB
.getInt64Ty(), /* Signed */ true);
3194 assert(S
->getType()->getPrimitiveSizeInBits() <= 64);
3195 Value
*S2
= IRB
.CreateICmpNE(S
, getCleanShadow(S
));
3196 return CreateShadowCast(IRB
, S2
, T
, /* Signed */ true);
3199 // Given a vector, extract its first element, and return all
3200 // zeroes if it is zero, and all ones otherwise.
3201 Value
*LowerElementShadowExtend(IRBuilder
<> &IRB
, Value
*S
, Type
*T
) {
3202 Value
*S1
= IRB
.CreateExtractElement(S
, (uint64_t)0);
3203 Value
*S2
= IRB
.CreateICmpNE(S1
, getCleanShadow(S1
));
3204 return CreateShadowCast(IRB
, S2
, T
, /* Signed */ true);
3207 Value
*VariableShadowExtend(IRBuilder
<> &IRB
, Value
*S
) {
3208 Type
*T
= S
->getType();
3209 assert(T
->isVectorTy());
3210 Value
*S2
= IRB
.CreateICmpNE(S
, getCleanShadow(S
));
3211 return IRB
.CreateSExt(S2
, T
);
3214 // Instrument vector shift intrinsic.
3216 // This function instruments intrinsics like int_x86_avx2_psll_w.
3217 // Intrinsic shifts %In by %ShiftSize bits.
3218 // %ShiftSize may be a vector. In that case the lower 64 bits determine shift
3219 // size, and the rest is ignored. Behavior is defined even if shift size is
3220 // greater than register (or field) width.
3221 void handleVectorShiftIntrinsic(IntrinsicInst
&I
, bool Variable
) {
3222 assert(I
.arg_size() == 2);
3223 IRBuilder
<> IRB(&I
);
3224 // If any of the S2 bits are poisoned, the whole thing is poisoned.
3225 // Otherwise perform the same shift on S1.
3226 Value
*S1
= getShadow(&I
, 0);
3227 Value
*S2
= getShadow(&I
, 1);
3228 Value
*S2Conv
= Variable
? VariableShadowExtend(IRB
, S2
)
3229 : Lower64ShadowExtend(IRB
, S2
, getShadowTy(&I
));
3230 Value
*V1
= I
.getOperand(0);
3231 Value
*V2
= I
.getOperand(1);
3232 Value
*Shift
= IRB
.CreateCall(I
.getFunctionType(), I
.getCalledOperand(),
3233 {IRB
.CreateBitCast(S1
, V1
->getType()), V2
});
3234 Shift
= IRB
.CreateBitCast(Shift
, getShadowTy(&I
));
3235 setShadow(&I
, IRB
.CreateOr(Shift
, S2Conv
));
3236 setOriginForNaryOp(I
);
3239 // Get an MMX-sized vector type.
3240 Type
*getMMXVectorTy(unsigned EltSizeInBits
) {
3241 const unsigned X86_MMXSizeInBits
= 64;
3242 assert(EltSizeInBits
!= 0 && (X86_MMXSizeInBits
% EltSizeInBits
) == 0 &&
3243 "Illegal MMX vector element size");
3244 return FixedVectorType::get(IntegerType::get(*MS
.C
, EltSizeInBits
),
3245 X86_MMXSizeInBits
/ EltSizeInBits
);
3248 // Returns a signed counterpart for an (un)signed-saturate-and-pack
3250 Intrinsic::ID
getSignedPackIntrinsic(Intrinsic::ID id
) {
3252 case Intrinsic::x86_sse2_packsswb_128
:
3253 case Intrinsic::x86_sse2_packuswb_128
:
3254 return Intrinsic::x86_sse2_packsswb_128
;
3256 case Intrinsic::x86_sse2_packssdw_128
:
3257 case Intrinsic::x86_sse41_packusdw
:
3258 return Intrinsic::x86_sse2_packssdw_128
;
3260 case Intrinsic::x86_avx2_packsswb
:
3261 case Intrinsic::x86_avx2_packuswb
:
3262 return Intrinsic::x86_avx2_packsswb
;
3264 case Intrinsic::x86_avx2_packssdw
:
3265 case Intrinsic::x86_avx2_packusdw
:
3266 return Intrinsic::x86_avx2_packssdw
;
3268 case Intrinsic::x86_mmx_packsswb
:
3269 case Intrinsic::x86_mmx_packuswb
:
3270 return Intrinsic::x86_mmx_packsswb
;
3272 case Intrinsic::x86_mmx_packssdw
:
3273 return Intrinsic::x86_mmx_packssdw
;
3275 llvm_unreachable("unexpected intrinsic id");
3279 // Instrument vector pack intrinsic.
3281 // This function instruments intrinsics like x86_mmx_packsswb, that
3282 // packs elements of 2 input vectors into half as many bits with saturation.
3283 // Shadow is propagated with the signed variant of the same intrinsic applied
3284 // to sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
3285 // MMXEltSizeInBits is used only for x86mmx arguments.
3286 void handleVectorPackIntrinsic(IntrinsicInst
&I
,
3287 unsigned MMXEltSizeInBits
= 0) {
3288 assert(I
.arg_size() == 2);
3289 IRBuilder
<> IRB(&I
);
3290 Value
*S1
= getShadow(&I
, 0);
3291 Value
*S2
= getShadow(&I
, 1);
3292 assert(S1
->getType()->isVectorTy());
3294 // SExt and ICmpNE below must apply to individual elements of input vectors.
3295 // In case of x86mmx arguments, cast them to appropriate vector types and
3298 MMXEltSizeInBits
? getMMXVectorTy(MMXEltSizeInBits
) : S1
->getType();
3299 if (MMXEltSizeInBits
) {
3300 S1
= IRB
.CreateBitCast(S1
, T
);
3301 S2
= IRB
.CreateBitCast(S2
, T
);
3304 IRB
.CreateSExt(IRB
.CreateICmpNE(S1
, Constant::getNullValue(T
)), T
);
3306 IRB
.CreateSExt(IRB
.CreateICmpNE(S2
, Constant::getNullValue(T
)), T
);
3307 if (MMXEltSizeInBits
) {
3308 S1_ext
= IRB
.CreateBitCast(S1_ext
, getMMXVectorTy(64));
3309 S2_ext
= IRB
.CreateBitCast(S2_ext
, getMMXVectorTy(64));
3312 Value
*S
= IRB
.CreateIntrinsic(getSignedPackIntrinsic(I
.getIntrinsicID()),
3313 {}, {S1_ext
, S2_ext
}, /*FMFSource=*/nullptr,
3314 "_msprop_vector_pack");
3315 if (MMXEltSizeInBits
)
3316 S
= IRB
.CreateBitCast(S
, getShadowTy(&I
));
3318 setOriginForNaryOp(I
);
3321 // Convert `Mask` into `<n x i1>`.
3322 Constant
*createDppMask(unsigned Width
, unsigned Mask
) {
3323 SmallVector
<Constant
*, 4> R(Width
);
3325 M
= ConstantInt::getBool(F
.getContext(), Mask
& 1);
3328 return ConstantVector::get(R
);
3331 // Calculate output shadow as array of booleans `<n x i1>`, assuming if any
3332 // arg is poisoned, entire dot product is poisoned.
3333 Value
*findDppPoisonedOutput(IRBuilder
<> &IRB
, Value
*S
, unsigned SrcMask
,
3335 const unsigned Width
=
3336 cast
<FixedVectorType
>(S
->getType())->getNumElements();
3338 S
= IRB
.CreateSelect(createDppMask(Width
, SrcMask
), S
,
3339 Constant::getNullValue(S
->getType()));
3340 Value
*SElem
= IRB
.CreateOrReduce(S
);
3341 Value
*IsClean
= IRB
.CreateIsNull(SElem
, "_msdpp");
3342 Value
*DstMaskV
= createDppMask(Width
, DstMask
);
3344 return IRB
.CreateSelect(
3345 IsClean
, Constant::getNullValue(DstMaskV
->getType()), DstMaskV
);
3348 // See `Intel Intrinsics Guide` for `_dp_p*` instructions.
3350 // 2 and 4 element versions produce single scalar of dot product, and then
3351 // puts it into elements of output vector, selected by 4 lowest bits of the
3352 // mask. Top 4 bits of the mask control which elements of input to use for dot
3355 // 8 element version mask still has only 4 bit for input, and 4 bit for output
3356 // mask. According to the spec it just operates as 4 element version on first
3357 // 4 elements of inputs and output, and then on last 4 elements of inputs and
3359 void handleDppIntrinsic(IntrinsicInst
&I
) {
3360 IRBuilder
<> IRB(&I
);
3362 Value
*S0
= getShadow(&I
, 0);
3363 Value
*S1
= getShadow(&I
, 1);
3364 Value
*S
= IRB
.CreateOr(S0
, S1
);
3366 const unsigned Width
=
3367 cast
<FixedVectorType
>(S
->getType())->getNumElements();
3368 assert(Width
== 2 || Width
== 4 || Width
== 8);
3370 const unsigned Mask
= cast
<ConstantInt
>(I
.getArgOperand(2))->getZExtValue();
3371 const unsigned SrcMask
= Mask
>> 4;
3372 const unsigned DstMask
= Mask
& 0xf;
3374 // Calculate shadow as `<n x i1>`.
3375 Value
*SI1
= findDppPoisonedOutput(IRB
, S
, SrcMask
, DstMask
);
3377 // First 4 elements of shadow are already calculated. `makeDppShadow`
3378 // operats on 32 bit masks, so we can just shift masks, and repeat.
3380 SI1
, findDppPoisonedOutput(IRB
, S
, SrcMask
<< 4, DstMask
<< 4));
3382 // Extend to real size of shadow, poisoning either all or none bits of an
3384 S
= IRB
.CreateSExt(SI1
, S
->getType(), "_msdpp");
3387 setOriginForNaryOp(I
);
3390 Value
*convertBlendvToSelectMask(IRBuilder
<> &IRB
, Value
*C
) {
3391 C
= CreateAppToShadowCast(IRB
, C
);
3392 FixedVectorType
*FVT
= cast
<FixedVectorType
>(C
->getType());
3393 unsigned ElSize
= FVT
->getElementType()->getPrimitiveSizeInBits();
3394 C
= IRB
.CreateAShr(C
, ElSize
- 1);
3395 FVT
= FixedVectorType::get(IRB
.getInt1Ty(), FVT
->getNumElements());
3396 return IRB
.CreateTrunc(C
, FVT
);
3399 // `blendv(f, t, c)` is effectively `select(c[top_bit], t, f)`.
3400 void handleBlendvIntrinsic(IntrinsicInst
&I
) {
3401 Value
*C
= I
.getOperand(2);
3402 Value
*T
= I
.getOperand(1);
3403 Value
*F
= I
.getOperand(0);
3405 Value
*Sc
= getShadow(&I
, 2);
3406 Value
*Oc
= MS
.TrackOrigins
? getOrigin(C
) : nullptr;
3409 IRBuilder
<> IRB(&I
);
3410 // Extract top bit from condition and its shadow.
3411 C
= convertBlendvToSelectMask(IRB
, C
);
3412 Sc
= convertBlendvToSelectMask(IRB
, Sc
);
3418 handleSelectLikeInst(I
, C
, T
, F
);
3421 // Instrument sum-of-absolute-differences intrinsic.
3422 void handleVectorSadIntrinsic(IntrinsicInst
&I
, bool IsMMX
= false) {
3423 const unsigned SignificantBitsPerResultElement
= 16;
3424 Type
*ResTy
= IsMMX
? IntegerType::get(*MS
.C
, 64) : I
.getType();
3425 unsigned ZeroBitsPerResultElement
=
3426 ResTy
->getScalarSizeInBits() - SignificantBitsPerResultElement
;
3428 IRBuilder
<> IRB(&I
);
3429 auto *Shadow0
= getShadow(&I
, 0);
3430 auto *Shadow1
= getShadow(&I
, 1);
3431 Value
*S
= IRB
.CreateOr(Shadow0
, Shadow1
);
3432 S
= IRB
.CreateBitCast(S
, ResTy
);
3433 S
= IRB
.CreateSExt(IRB
.CreateICmpNE(S
, Constant::getNullValue(ResTy
)),
3435 S
= IRB
.CreateLShr(S
, ZeroBitsPerResultElement
);
3436 S
= IRB
.CreateBitCast(S
, getShadowTy(&I
));
3438 setOriginForNaryOp(I
);
3441 // Instrument multiply-add intrinsic.
3442 void handleVectorPmaddIntrinsic(IntrinsicInst
&I
,
3443 unsigned MMXEltSizeInBits
= 0) {
3445 MMXEltSizeInBits
? getMMXVectorTy(MMXEltSizeInBits
* 2) : I
.getType();
3446 IRBuilder
<> IRB(&I
);
3447 auto *Shadow0
= getShadow(&I
, 0);
3448 auto *Shadow1
= getShadow(&I
, 1);
3449 Value
*S
= IRB
.CreateOr(Shadow0
, Shadow1
);
3450 S
= IRB
.CreateBitCast(S
, ResTy
);
3451 S
= IRB
.CreateSExt(IRB
.CreateICmpNE(S
, Constant::getNullValue(ResTy
)),
3453 S
= IRB
.CreateBitCast(S
, getShadowTy(&I
));
3455 setOriginForNaryOp(I
);
3458 // Instrument compare-packed intrinsic.
3459 // Basically, an or followed by sext(icmp ne 0) to end up with all-zeros or
3461 void handleVectorComparePackedIntrinsic(IntrinsicInst
&I
) {
3462 IRBuilder
<> IRB(&I
);
3463 Type
*ResTy
= getShadowTy(&I
);
3464 auto *Shadow0
= getShadow(&I
, 0);
3465 auto *Shadow1
= getShadow(&I
, 1);
3466 Value
*S0
= IRB
.CreateOr(Shadow0
, Shadow1
);
3467 Value
*S
= IRB
.CreateSExt(
3468 IRB
.CreateICmpNE(S0
, Constant::getNullValue(ResTy
)), ResTy
);
3470 setOriginForNaryOp(I
);
3473 // Instrument compare-scalar intrinsic.
3474 // This handles both cmp* intrinsics which return the result in the first
3475 // element of a vector, and comi* which return the result as i32.
3476 void handleVectorCompareScalarIntrinsic(IntrinsicInst
&I
) {
3477 IRBuilder
<> IRB(&I
);
3478 auto *Shadow0
= getShadow(&I
, 0);
3479 auto *Shadow1
= getShadow(&I
, 1);
3480 Value
*S0
= IRB
.CreateOr(Shadow0
, Shadow1
);
3481 Value
*S
= LowerElementShadowExtend(IRB
, S0
, getShadowTy(&I
));
3483 setOriginForNaryOp(I
);
3486 // Instrument generic vector reduction intrinsics
3487 // by ORing together all their fields.
3488 void handleVectorReduceIntrinsic(IntrinsicInst
&I
) {
3489 IRBuilder
<> IRB(&I
);
3490 Value
*S
= IRB
.CreateOrReduce(getShadow(&I
, 0));
3492 setOrigin(&I
, getOrigin(&I
, 0));
3495 // Instrument vector.reduce.or intrinsic.
3496 // Valid (non-poisoned) set bits in the operand pull low the
3497 // corresponding shadow bits.
3498 void handleVectorReduceOrIntrinsic(IntrinsicInst
&I
) {
3499 IRBuilder
<> IRB(&I
);
3500 Value
*OperandShadow
= getShadow(&I
, 0);
3501 Value
*OperandUnsetBits
= IRB
.CreateNot(I
.getOperand(0));
3502 Value
*OperandUnsetOrPoison
= IRB
.CreateOr(OperandUnsetBits
, OperandShadow
);
3503 // Bit N is clean if any field's bit N is 1 and unpoison
3504 Value
*OutShadowMask
= IRB
.CreateAndReduce(OperandUnsetOrPoison
);
3505 // Otherwise, it is clean if every field's bit N is unpoison
3506 Value
*OrShadow
= IRB
.CreateOrReduce(OperandShadow
);
3507 Value
*S
= IRB
.CreateAnd(OutShadowMask
, OrShadow
);
3510 setOrigin(&I
, getOrigin(&I
, 0));
3513 // Instrument vector.reduce.and intrinsic.
3514 // Valid (non-poisoned) unset bits in the operand pull down the
3515 // corresponding shadow bits.
3516 void handleVectorReduceAndIntrinsic(IntrinsicInst
&I
) {
3517 IRBuilder
<> IRB(&I
);
3518 Value
*OperandShadow
= getShadow(&I
, 0);
3519 Value
*OperandSetOrPoison
= IRB
.CreateOr(I
.getOperand(0), OperandShadow
);
3520 // Bit N is clean if any field's bit N is 0 and unpoison
3521 Value
*OutShadowMask
= IRB
.CreateAndReduce(OperandSetOrPoison
);
3522 // Otherwise, it is clean if every field's bit N is unpoison
3523 Value
*OrShadow
= IRB
.CreateOrReduce(OperandShadow
);
3524 Value
*S
= IRB
.CreateAnd(OutShadowMask
, OrShadow
);
3527 setOrigin(&I
, getOrigin(&I
, 0));
3530 void handleStmxcsr(IntrinsicInst
&I
) {
3531 IRBuilder
<> IRB(&I
);
3532 Value
*Addr
= I
.getArgOperand(0);
3533 Type
*Ty
= IRB
.getInt32Ty();
3535 getShadowOriginPtr(Addr
, IRB
, Ty
, Align(1), /*isStore*/ true).first
;
3537 IRB
.CreateStore(getCleanShadow(Ty
), ShadowPtr
);
3539 if (ClCheckAccessAddress
)
3540 insertShadowCheck(Addr
, &I
);
3543 void handleLdmxcsr(IntrinsicInst
&I
) {
3547 IRBuilder
<> IRB(&I
);
3548 Value
*Addr
= I
.getArgOperand(0);
3549 Type
*Ty
= IRB
.getInt32Ty();
3550 const Align Alignment
= Align(1);
3551 Value
*ShadowPtr
, *OriginPtr
;
3552 std::tie(ShadowPtr
, OriginPtr
) =
3553 getShadowOriginPtr(Addr
, IRB
, Ty
, Alignment
, /*isStore*/ false);
3555 if (ClCheckAccessAddress
)
3556 insertShadowCheck(Addr
, &I
);
3558 Value
*Shadow
= IRB
.CreateAlignedLoad(Ty
, ShadowPtr
, Alignment
, "_ldmxcsr");
3559 Value
*Origin
= MS
.TrackOrigins
? IRB
.CreateLoad(MS
.OriginTy
, OriginPtr
)
3561 insertShadowCheck(Shadow
, Origin
, &I
);
3564 void handleMaskedExpandLoad(IntrinsicInst
&I
) {
3565 IRBuilder
<> IRB(&I
);
3566 Value
*Ptr
= I
.getArgOperand(0);
3567 MaybeAlign Align
= I
.getParamAlign(0);
3568 Value
*Mask
= I
.getArgOperand(1);
3569 Value
*PassThru
= I
.getArgOperand(2);
3571 if (ClCheckAccessAddress
) {
3572 insertShadowCheck(Ptr
, &I
);
3573 insertShadowCheck(Mask
, &I
);
3576 if (!PropagateShadow
) {
3577 setShadow(&I
, getCleanShadow(&I
));
3578 setOrigin(&I
, getCleanOrigin());
3582 Type
*ShadowTy
= getShadowTy(&I
);
3583 Type
*ElementShadowTy
= cast
<VectorType
>(ShadowTy
)->getElementType();
3584 auto [ShadowPtr
, OriginPtr
] =
3585 getShadowOriginPtr(Ptr
, IRB
, ElementShadowTy
, Align
, /*isStore*/ false);
3588 IRB
.CreateMaskedExpandLoad(ShadowTy
, ShadowPtr
, Align
, Mask
,
3589 getShadow(PassThru
), "_msmaskedexpload");
3591 setShadow(&I
, Shadow
);
3593 // TODO: Store origins.
3594 setOrigin(&I
, getCleanOrigin());
3597 void handleMaskedCompressStore(IntrinsicInst
&I
) {
3598 IRBuilder
<> IRB(&I
);
3599 Value
*Values
= I
.getArgOperand(0);
3600 Value
*Ptr
= I
.getArgOperand(1);
3601 MaybeAlign Align
= I
.getParamAlign(1);
3602 Value
*Mask
= I
.getArgOperand(2);
3604 if (ClCheckAccessAddress
) {
3605 insertShadowCheck(Ptr
, &I
);
3606 insertShadowCheck(Mask
, &I
);
3609 Value
*Shadow
= getShadow(Values
);
3610 Type
*ElementShadowTy
=
3611 getShadowTy(cast
<VectorType
>(Values
->getType())->getElementType());
3612 auto [ShadowPtr
, OriginPtrs
] =
3613 getShadowOriginPtr(Ptr
, IRB
, ElementShadowTy
, Align
, /*isStore*/ true);
3615 IRB
.CreateMaskedCompressStore(Shadow
, ShadowPtr
, Align
, Mask
);
3617 // TODO: Store origins.
3620 void handleMaskedGather(IntrinsicInst
&I
) {
3621 IRBuilder
<> IRB(&I
);
3622 Value
*Ptrs
= I
.getArgOperand(0);
3623 const Align
Alignment(
3624 cast
<ConstantInt
>(I
.getArgOperand(1))->getZExtValue());
3625 Value
*Mask
= I
.getArgOperand(2);
3626 Value
*PassThru
= I
.getArgOperand(3);
3628 Type
*PtrsShadowTy
= getShadowTy(Ptrs
);
3629 if (ClCheckAccessAddress
) {
3630 insertShadowCheck(Mask
, &I
);
3631 Value
*MaskedPtrShadow
= IRB
.CreateSelect(
3632 Mask
, getShadow(Ptrs
), Constant::getNullValue((PtrsShadowTy
)),
3634 insertShadowCheck(MaskedPtrShadow
, getOrigin(Ptrs
), &I
);
3637 if (!PropagateShadow
) {
3638 setShadow(&I
, getCleanShadow(&I
));
3639 setOrigin(&I
, getCleanOrigin());
3643 Type
*ShadowTy
= getShadowTy(&I
);
3644 Type
*ElementShadowTy
= cast
<VectorType
>(ShadowTy
)->getElementType();
3645 auto [ShadowPtrs
, OriginPtrs
] = getShadowOriginPtr(
3646 Ptrs
, IRB
, ElementShadowTy
, Alignment
, /*isStore*/ false);
3649 IRB
.CreateMaskedGather(ShadowTy
, ShadowPtrs
, Alignment
, Mask
,
3650 getShadow(PassThru
), "_msmaskedgather");
3652 setShadow(&I
, Shadow
);
3654 // TODO: Store origins.
3655 setOrigin(&I
, getCleanOrigin());
3658 void handleMaskedScatter(IntrinsicInst
&I
) {
3659 IRBuilder
<> IRB(&I
);
3660 Value
*Values
= I
.getArgOperand(0);
3661 Value
*Ptrs
= I
.getArgOperand(1);
3662 const Align
Alignment(
3663 cast
<ConstantInt
>(I
.getArgOperand(2))->getZExtValue());
3664 Value
*Mask
= I
.getArgOperand(3);
3666 Type
*PtrsShadowTy
= getShadowTy(Ptrs
);
3667 if (ClCheckAccessAddress
) {
3668 insertShadowCheck(Mask
, &I
);
3669 Value
*MaskedPtrShadow
= IRB
.CreateSelect(
3670 Mask
, getShadow(Ptrs
), Constant::getNullValue((PtrsShadowTy
)),
3672 insertShadowCheck(MaskedPtrShadow
, getOrigin(Ptrs
), &I
);
3675 Value
*Shadow
= getShadow(Values
);
3676 Type
*ElementShadowTy
=
3677 getShadowTy(cast
<VectorType
>(Values
->getType())->getElementType());
3678 auto [ShadowPtrs
, OriginPtrs
] = getShadowOriginPtr(
3679 Ptrs
, IRB
, ElementShadowTy
, Alignment
, /*isStore*/ true);
3681 IRB
.CreateMaskedScatter(Shadow
, ShadowPtrs
, Alignment
, Mask
);
3683 // TODO: Store origin.
3686 void handleMaskedStore(IntrinsicInst
&I
) {
3687 IRBuilder
<> IRB(&I
);
3688 Value
*V
= I
.getArgOperand(0);
3689 Value
*Ptr
= I
.getArgOperand(1);
3690 const Align
Alignment(
3691 cast
<ConstantInt
>(I
.getArgOperand(2))->getZExtValue());
3692 Value
*Mask
= I
.getArgOperand(3);
3693 Value
*Shadow
= getShadow(V
);
3695 if (ClCheckAccessAddress
) {
3696 insertShadowCheck(Ptr
, &I
);
3697 insertShadowCheck(Mask
, &I
);
3702 std::tie(ShadowPtr
, OriginPtr
) = getShadowOriginPtr(
3703 Ptr
, IRB
, Shadow
->getType(), Alignment
, /*isStore*/ true);
3705 IRB
.CreateMaskedStore(Shadow
, ShadowPtr
, Alignment
, Mask
);
3707 if (!MS
.TrackOrigins
)
3710 auto &DL
= F
.getDataLayout();
3711 paintOrigin(IRB
, getOrigin(V
), OriginPtr
,
3712 DL
.getTypeStoreSize(Shadow
->getType()),
3713 std::max(Alignment
, kMinOriginAlignment
));
3716 void handleMaskedLoad(IntrinsicInst
&I
) {
3717 IRBuilder
<> IRB(&I
);
3718 Value
*Ptr
= I
.getArgOperand(0);
3719 const Align
Alignment(
3720 cast
<ConstantInt
>(I
.getArgOperand(1))->getZExtValue());
3721 Value
*Mask
= I
.getArgOperand(2);
3722 Value
*PassThru
= I
.getArgOperand(3);
3724 if (ClCheckAccessAddress
) {
3725 insertShadowCheck(Ptr
, &I
);
3726 insertShadowCheck(Mask
, &I
);
3729 if (!PropagateShadow
) {
3730 setShadow(&I
, getCleanShadow(&I
));
3731 setOrigin(&I
, getCleanOrigin());
3735 Type
*ShadowTy
= getShadowTy(&I
);
3736 Value
*ShadowPtr
, *OriginPtr
;
3737 std::tie(ShadowPtr
, OriginPtr
) =
3738 getShadowOriginPtr(Ptr
, IRB
, ShadowTy
, Alignment
, /*isStore*/ false);
3739 setShadow(&I
, IRB
.CreateMaskedLoad(ShadowTy
, ShadowPtr
, Alignment
, Mask
,
3740 getShadow(PassThru
), "_msmaskedld"));
3742 if (!MS
.TrackOrigins
)
3745 // Choose between PassThru's and the loaded value's origins.
3746 Value
*MaskedPassThruShadow
= IRB
.CreateAnd(
3747 getShadow(PassThru
), IRB
.CreateSExt(IRB
.CreateNeg(Mask
), ShadowTy
));
3749 Value
*NotNull
= convertToBool(MaskedPassThruShadow
, IRB
, "_mscmp");
3751 Value
*PtrOrigin
= IRB
.CreateLoad(MS
.OriginTy
, OriginPtr
);
3752 Value
*Origin
= IRB
.CreateSelect(NotNull
, getOrigin(PassThru
), PtrOrigin
);
3754 setOrigin(&I
, Origin
);
3757 // Instrument BMI / BMI2 intrinsics.
3758 // All of these intrinsics are Z = I(X, Y)
3759 // where the types of all operands and the result match, and are either i32 or
3760 // i64. The following instrumentation happens to work for all of them:
3761 // Sz = I(Sx, Y) | (sext (Sy != 0))
3762 void handleBmiIntrinsic(IntrinsicInst
&I
) {
3763 IRBuilder
<> IRB(&I
);
3764 Type
*ShadowTy
= getShadowTy(&I
);
3766 // If any bit of the mask operand is poisoned, then the whole thing is.
3767 Value
*SMask
= getShadow(&I
, 1);
3768 SMask
= IRB
.CreateSExt(IRB
.CreateICmpNE(SMask
, getCleanShadow(ShadowTy
)),
3770 // Apply the same intrinsic to the shadow of the first operand.
3771 Value
*S
= IRB
.CreateCall(I
.getCalledFunction(),
3772 {getShadow(&I
, 0), I
.getOperand(1)});
3773 S
= IRB
.CreateOr(SMask
, S
);
3775 setOriginForNaryOp(I
);
3778 static SmallVector
<int, 8> getPclmulMask(unsigned Width
, bool OddElements
) {
3779 SmallVector
<int, 8> Mask
;
3780 for (unsigned X
= OddElements
? 1 : 0; X
< Width
; X
+= 2) {
3786 // Instrument pclmul intrinsics.
3787 // These intrinsics operate either on odd or on even elements of the input
3788 // vectors, depending on the constant in the 3rd argument, ignoring the rest.
3789 // Replace the unused elements with copies of the used ones, ex:
3790 // (0, 1, 2, 3) -> (0, 0, 2, 2) (even case)
3792 // (0, 1, 2, 3) -> (1, 1, 3, 3) (odd case)
3793 // and then apply the usual shadow combining logic.
3794 void handlePclmulIntrinsic(IntrinsicInst
&I
) {
3795 IRBuilder
<> IRB(&I
);
3797 cast
<FixedVectorType
>(I
.getArgOperand(0)->getType())->getNumElements();
3798 assert(isa
<ConstantInt
>(I
.getArgOperand(2)) &&
3799 "pclmul 3rd operand must be a constant");
3800 unsigned Imm
= cast
<ConstantInt
>(I
.getArgOperand(2))->getZExtValue();
3801 Value
*Shuf0
= IRB
.CreateShuffleVector(getShadow(&I
, 0),
3802 getPclmulMask(Width
, Imm
& 0x01));
3803 Value
*Shuf1
= IRB
.CreateShuffleVector(getShadow(&I
, 1),
3804 getPclmulMask(Width
, Imm
& 0x10));
3805 ShadowAndOriginCombiner
SOC(this, IRB
);
3806 SOC
.Add(Shuf0
, getOrigin(&I
, 0));
3807 SOC
.Add(Shuf1
, getOrigin(&I
, 1));
3811 // Instrument _mm_*_sd|ss intrinsics
3812 void handleUnarySdSsIntrinsic(IntrinsicInst
&I
) {
3813 IRBuilder
<> IRB(&I
);
3815 cast
<FixedVectorType
>(I
.getArgOperand(0)->getType())->getNumElements();
3816 Value
*First
= getShadow(&I
, 0);
3817 Value
*Second
= getShadow(&I
, 1);
3818 // First element of second operand, remaining elements of first operand
3819 SmallVector
<int, 16> Mask
;
3820 Mask
.push_back(Width
);
3821 for (unsigned i
= 1; i
< Width
; i
++)
3823 Value
*Shadow
= IRB
.CreateShuffleVector(First
, Second
, Mask
);
3825 setShadow(&I
, Shadow
);
3826 setOriginForNaryOp(I
);
3829 void handleVtestIntrinsic(IntrinsicInst
&I
) {
3830 IRBuilder
<> IRB(&I
);
3831 Value
*Shadow0
= getShadow(&I
, 0);
3832 Value
*Shadow1
= getShadow(&I
, 1);
3833 Value
*Or
= IRB
.CreateOr(Shadow0
, Shadow1
);
3834 Value
*NZ
= IRB
.CreateICmpNE(Or
, Constant::getNullValue(Or
->getType()));
3835 Value
*Scalar
= convertShadowToScalar(NZ
, IRB
);
3836 Value
*Shadow
= IRB
.CreateZExt(Scalar
, getShadowTy(&I
));
3838 setShadow(&I
, Shadow
);
3839 setOriginForNaryOp(I
);
3842 void handleBinarySdSsIntrinsic(IntrinsicInst
&I
) {
3843 IRBuilder
<> IRB(&I
);
3845 cast
<FixedVectorType
>(I
.getArgOperand(0)->getType())->getNumElements();
3846 Value
*First
= getShadow(&I
, 0);
3847 Value
*Second
= getShadow(&I
, 1);
3848 Value
*OrShadow
= IRB
.CreateOr(First
, Second
);
3849 // First element of both OR'd together, remaining elements of first operand
3850 SmallVector
<int, 16> Mask
;
3851 Mask
.push_back(Width
);
3852 for (unsigned i
= 1; i
< Width
; i
++)
3854 Value
*Shadow
= IRB
.CreateShuffleVector(First
, OrShadow
, Mask
);
3856 setShadow(&I
, Shadow
);
3857 setOriginForNaryOp(I
);
3860 // _mm_round_ps / _mm_round_ps.
3861 // Similar to maybeHandleSimpleNomemIntrinsic except
3862 // the second argument is guranteed to be a constant integer.
3863 void handleRoundPdPsIntrinsic(IntrinsicInst
&I
) {
3864 assert(I
.getArgOperand(0)->getType() == I
.getType());
3865 assert(I
.arg_size() == 2);
3866 assert(isa
<ConstantInt
>(I
.getArgOperand(1)));
3868 IRBuilder
<> IRB(&I
);
3869 ShadowAndOriginCombiner
SC(this, IRB
);
3870 SC
.Add(I
.getArgOperand(0));
3874 // Instrument abs intrinsic.
3875 // handleUnknownIntrinsic can't handle it because of the last
3876 // is_int_min_poison argument which does not match the result type.
3877 void handleAbsIntrinsic(IntrinsicInst
&I
) {
3878 assert(I
.getType()->isIntOrIntVectorTy());
3879 assert(I
.getArgOperand(0)->getType() == I
.getType());
3881 // FIXME: Handle is_int_min_poison.
3882 IRBuilder
<> IRB(&I
);
3883 setShadow(&I
, getShadow(&I
, 0));
3884 setOrigin(&I
, getOrigin(&I
, 0));
3887 void handleIsFpClass(IntrinsicInst
&I
) {
3888 IRBuilder
<> IRB(&I
);
3889 Value
*Shadow
= getShadow(&I
, 0);
3890 setShadow(&I
, IRB
.CreateICmpNE(Shadow
, getCleanShadow(Shadow
)));
3891 setOrigin(&I
, getOrigin(&I
, 0));
3894 void handleArithmeticWithOverflow(IntrinsicInst
&I
) {
3895 IRBuilder
<> IRB(&I
);
3896 Value
*Shadow0
= getShadow(&I
, 0);
3897 Value
*Shadow1
= getShadow(&I
, 1);
3898 Value
*ShadowElt0
= IRB
.CreateOr(Shadow0
, Shadow1
);
3900 IRB
.CreateICmpNE(ShadowElt0
, getCleanShadow(ShadowElt0
));
3902 Value
*Shadow
= PoisonValue::get(getShadowTy(&I
));
3903 Shadow
= IRB
.CreateInsertValue(Shadow
, ShadowElt0
, 0);
3904 Shadow
= IRB
.CreateInsertValue(Shadow
, ShadowElt1
, 1);
3906 setShadow(&I
, Shadow
);
3907 setOriginForNaryOp(I
);
3910 void handleAVXHorizontalAddSubIntrinsic(IntrinsicInst
&I
) {
3911 // Approximation only:
3912 // output = horizontal_add(A, B)
3913 // => shadow[output] = horizontal_add(shadow[A], shadow[B])
3915 // - If we add/subtract two adjacent zero (initialized) shadow values, the
3916 // result always be zero i.e., no false positives.
3917 // - If we add/subtract two shadows, one of which is uninitialized, the
3918 // result will always be non-zero i.e., no false negative.
3919 // - However, we can have false negatives if we subtract two non-zero
3920 // shadows of the same value (or do an addition that wraps to zero); we
3921 // consider this an acceptable tradeoff for performance.
3922 // To make shadow propagation precise, we want the equivalent of
3923 // "horizontal OR", but this is not available.
3924 return handleIntrinsicByApplyingToShadow(I
, /* trailingVerbatimArgs */ 0);
3927 /// Handle Arm NEON vector store intrinsics (vst{2,3,4}, vst1x_{2,3,4},
3928 /// and vst{2,3,4}lane).
3930 /// Arm NEON vector store intrinsics have the output address (pointer) as the
3931 /// last argument, with the initial arguments being the inputs (and lane
3932 /// number for vst{2,3,4}lane). They return void.
3934 /// - st4 interleaves the output e.g., st4 (inA, inB, inC, inD, outP) writes
3935 /// abcdabcdabcdabcd... into *outP
3936 /// - st1_x4 is non-interleaved e.g., st1_x4 (inA, inB, inC, inD, outP)
3937 /// writes aaaa...bbbb...cccc...dddd... into *outP
3938 /// - st4lane has arguments of (inA, inB, inC, inD, lane, outP)
3939 /// These instructions can all be instrumented with essentially the same
3940 /// MSan logic, simply by applying the corresponding intrinsic to the shadow.
3941 void handleNEONVectorStoreIntrinsic(IntrinsicInst
&I
, bool useLane
) {
3942 IRBuilder
<> IRB(&I
);
3944 // Don't use getNumOperands() because it includes the callee
3945 int numArgOperands
= I
.arg_size();
3947 // The last arg operand is the output (pointer)
3948 assert(numArgOperands
>= 1);
3949 Value
*Addr
= I
.getArgOperand(numArgOperands
- 1);
3950 assert(Addr
->getType()->isPointerTy());
3951 int skipTrailingOperands
= 1;
3953 if (ClCheckAccessAddress
)
3954 insertShadowCheck(Addr
, &I
);
3956 // Second-last operand is the lane number (for vst{2,3,4}lane)
3958 skipTrailingOperands
++;
3959 assert(numArgOperands
>= static_cast<int>(skipTrailingOperands
));
3960 assert(isa
<IntegerType
>(
3961 I
.getArgOperand(numArgOperands
- skipTrailingOperands
)->getType()));
3964 SmallVector
<Value
*, 8> ShadowArgs
;
3965 // All the initial operands are the inputs
3966 for (int i
= 0; i
< numArgOperands
- skipTrailingOperands
; i
++) {
3967 assert(isa
<FixedVectorType
>(I
.getArgOperand(i
)->getType()));
3968 Value
*Shadow
= getShadow(&I
, i
);
3969 ShadowArgs
.append(1, Shadow
);
3972 // MSan's GetShadowTy assumes the LHS is the type we want the shadow for
3974 // [[TMP5:%.*]] = bitcast <16 x i8> [[TMP2]] to i128
3975 // we know the type of the output (and its shadow) is <16 x i8>.
3977 // Arm NEON VST is unusual because the last argument is the output address:
3978 // define void @st2_16b(<16 x i8> %A, <16 x i8> %B, ptr %P) {
3979 // call void @llvm.aarch64.neon.st2.v16i8.p0
3980 // (<16 x i8> [[A]], <16 x i8> [[B]], ptr [[P]])
3981 // and we have no type information about P's operand. We must manually
3982 // compute the type (<16 x i8> x 2).
3983 FixedVectorType
*OutputVectorTy
= FixedVectorType::get(
3984 cast
<FixedVectorType
>(I
.getArgOperand(0)->getType())->getElementType(),
3985 cast
<FixedVectorType
>(I
.getArgOperand(0)->getType())->getNumElements() *
3986 (numArgOperands
- skipTrailingOperands
));
3987 Type
*OutputShadowTy
= getShadowTy(OutputVectorTy
);
3990 ShadowArgs
.append(1,
3991 I
.getArgOperand(numArgOperands
- skipTrailingOperands
));
3993 Value
*OutputShadowPtr
, *OutputOriginPtr
;
3994 // AArch64 NEON does not need alignment (unless OS requires it)
3995 std::tie(OutputShadowPtr
, OutputOriginPtr
) = getShadowOriginPtr(
3996 Addr
, IRB
, OutputShadowTy
, Align(1), /*isStore*/ true);
3997 ShadowArgs
.append(1, OutputShadowPtr
);
4000 IRB
.CreateIntrinsic(IRB
.getVoidTy(), I
.getIntrinsicID(), ShadowArgs
);
4003 if (MS
.TrackOrigins
) {
4004 // TODO: if we modelled the vst* instruction more precisely, we could
4005 // more accurately track the origins (e.g., if both inputs are
4006 // uninitialized for vst2, we currently blame the second input, even
4007 // though part of the output depends only on the first input).
4009 // This is particularly imprecise for vst{2,3,4}lane, since only one
4010 // lane of each input is actually copied to the output.
4011 OriginCombiner
OC(this, IRB
);
4012 for (int i
= 0; i
< numArgOperands
- skipTrailingOperands
; i
++)
4013 OC
.Add(I
.getArgOperand(i
));
4015 const DataLayout
&DL
= F
.getDataLayout();
4016 OC
.DoneAndStoreOrigin(DL
.getTypeStoreSize(OutputVectorTy
),
4021 /// Handle intrinsics by applying the intrinsic to the shadows.
4023 /// The trailing arguments are passed verbatim to the intrinsic, though any
4024 /// uninitialized trailing arguments can also taint the shadow e.g., for an
4025 /// intrinsic with one trailing verbatim argument:
4026 /// out = intrinsic(var1, var2, opType)
4029 /// intrinsic(shadow[var1], shadow[var2], opType) | shadow[opType]
4031 /// CAUTION: this assumes that the intrinsic will handle arbitrary
4032 /// bit-patterns (for example, if the intrinsic accepts floats for
4033 /// var1, we require that it doesn't care if inputs are NaNs).
4035 /// For example, this can be applied to the Arm NEON vector table intrinsics
4038 /// The origin is approximated using setOriginForNaryOp.
4039 void handleIntrinsicByApplyingToShadow(IntrinsicInst
&I
,
4040 unsigned int trailingVerbatimArgs
) {
4041 IRBuilder
<> IRB(&I
);
4043 assert(trailingVerbatimArgs
< I
.arg_size());
4045 SmallVector
<Value
*, 8> ShadowArgs
;
4046 // Don't use getNumOperands() because it includes the callee
4047 for (unsigned int i
= 0; i
< I
.arg_size() - trailingVerbatimArgs
; i
++) {
4048 Value
*Shadow
= getShadow(&I
, i
);
4050 // Shadows are integer-ish types but some intrinsics require a
4051 // different (e.g., floating-point) type.
4052 ShadowArgs
.push_back(
4053 IRB
.CreateBitCast(Shadow
, I
.getArgOperand(i
)->getType()));
4056 for (unsigned int i
= I
.arg_size() - trailingVerbatimArgs
; i
< I
.arg_size();
4058 Value
*Arg
= I
.getArgOperand(i
);
4059 ShadowArgs
.push_back(Arg
);
4063 IRB
.CreateIntrinsic(I
.getType(), I
.getIntrinsicID(), ShadowArgs
);
4064 Value
*CombinedShadow
= CI
;
4066 // Combine the computed shadow with the shadow of trailing args
4067 for (unsigned int i
= I
.arg_size() - trailingVerbatimArgs
; i
< I
.arg_size();
4070 CreateShadowCast(IRB
, getShadow(&I
, i
), CombinedShadow
->getType());
4071 CombinedShadow
= IRB
.CreateOr(Shadow
, CombinedShadow
, "_msprop");
4074 setShadow(&I
, IRB
.CreateBitCast(CombinedShadow
, getShadowTy(&I
)));
4076 setOriginForNaryOp(I
);
4079 // Approximation only
4080 void handleNEONVectorMultiplyIntrinsic(IntrinsicInst
&I
) {
4084 void visitIntrinsicInst(IntrinsicInst
&I
) {
4085 switch (I
.getIntrinsicID()) {
4086 case Intrinsic::uadd_with_overflow
:
4087 case Intrinsic::sadd_with_overflow
:
4088 case Intrinsic::usub_with_overflow
:
4089 case Intrinsic::ssub_with_overflow
:
4090 case Intrinsic::umul_with_overflow
:
4091 case Intrinsic::smul_with_overflow
:
4092 handleArithmeticWithOverflow(I
);
4094 case Intrinsic::abs
:
4095 handleAbsIntrinsic(I
);
4097 case Intrinsic::is_fpclass
:
4100 case Intrinsic::lifetime_start
:
4101 handleLifetimeStart(I
);
4103 case Intrinsic::launder_invariant_group
:
4104 case Intrinsic::strip_invariant_group
:
4105 handleInvariantGroup(I
);
4107 case Intrinsic::bswap
:
4110 case Intrinsic::ctlz
:
4111 case Intrinsic::cttz
:
4112 handleCountZeroes(I
);
4114 case Intrinsic::masked_compressstore
:
4115 handleMaskedCompressStore(I
);
4117 case Intrinsic::masked_expandload
:
4118 handleMaskedExpandLoad(I
);
4120 case Intrinsic::masked_gather
:
4121 handleMaskedGather(I
);
4123 case Intrinsic::masked_scatter
:
4124 handleMaskedScatter(I
);
4126 case Intrinsic::masked_store
:
4127 handleMaskedStore(I
);
4129 case Intrinsic::masked_load
:
4130 handleMaskedLoad(I
);
4132 case Intrinsic::vector_reduce_and
:
4133 handleVectorReduceAndIntrinsic(I
);
4135 case Intrinsic::vector_reduce_or
:
4136 handleVectorReduceOrIntrinsic(I
);
4138 case Intrinsic::vector_reduce_add
:
4139 case Intrinsic::vector_reduce_xor
:
4140 case Intrinsic::vector_reduce_mul
:
4141 handleVectorReduceIntrinsic(I
);
4143 case Intrinsic::x86_sse_stmxcsr
:
4146 case Intrinsic::x86_sse_ldmxcsr
:
4149 case Intrinsic::x86_avx512_vcvtsd2usi64
:
4150 case Intrinsic::x86_avx512_vcvtsd2usi32
:
4151 case Intrinsic::x86_avx512_vcvtss2usi64
:
4152 case Intrinsic::x86_avx512_vcvtss2usi32
:
4153 case Intrinsic::x86_avx512_cvttss2usi64
:
4154 case Intrinsic::x86_avx512_cvttss2usi
:
4155 case Intrinsic::x86_avx512_cvttsd2usi64
:
4156 case Intrinsic::x86_avx512_cvttsd2usi
:
4157 case Intrinsic::x86_avx512_cvtusi2ss
:
4158 case Intrinsic::x86_avx512_cvtusi642sd
:
4159 case Intrinsic::x86_avx512_cvtusi642ss
:
4160 handleVectorConvertIntrinsic(I
, 1, true);
4162 case Intrinsic::x86_sse2_cvtsd2si64
:
4163 case Intrinsic::x86_sse2_cvtsd2si
:
4164 case Intrinsic::x86_sse2_cvtsd2ss
:
4165 case Intrinsic::x86_sse2_cvttsd2si64
:
4166 case Intrinsic::x86_sse2_cvttsd2si
:
4167 case Intrinsic::x86_sse_cvtss2si64
:
4168 case Intrinsic::x86_sse_cvtss2si
:
4169 case Intrinsic::x86_sse_cvttss2si64
:
4170 case Intrinsic::x86_sse_cvttss2si
:
4171 handleVectorConvertIntrinsic(I
, 1);
4173 case Intrinsic::x86_sse_cvtps2pi
:
4174 case Intrinsic::x86_sse_cvttps2pi
:
4175 handleVectorConvertIntrinsic(I
, 2);
4178 case Intrinsic::x86_avx512_psll_w_512
:
4179 case Intrinsic::x86_avx512_psll_d_512
:
4180 case Intrinsic::x86_avx512_psll_q_512
:
4181 case Intrinsic::x86_avx512_pslli_w_512
:
4182 case Intrinsic::x86_avx512_pslli_d_512
:
4183 case Intrinsic::x86_avx512_pslli_q_512
:
4184 case Intrinsic::x86_avx512_psrl_w_512
:
4185 case Intrinsic::x86_avx512_psrl_d_512
:
4186 case Intrinsic::x86_avx512_psrl_q_512
:
4187 case Intrinsic::x86_avx512_psra_w_512
:
4188 case Intrinsic::x86_avx512_psra_d_512
:
4189 case Intrinsic::x86_avx512_psra_q_512
:
4190 case Intrinsic::x86_avx512_psrli_w_512
:
4191 case Intrinsic::x86_avx512_psrli_d_512
:
4192 case Intrinsic::x86_avx512_psrli_q_512
:
4193 case Intrinsic::x86_avx512_psrai_w_512
:
4194 case Intrinsic::x86_avx512_psrai_d_512
:
4195 case Intrinsic::x86_avx512_psrai_q_512
:
4196 case Intrinsic::x86_avx512_psra_q_256
:
4197 case Intrinsic::x86_avx512_psra_q_128
:
4198 case Intrinsic::x86_avx512_psrai_q_256
:
4199 case Intrinsic::x86_avx512_psrai_q_128
:
4200 case Intrinsic::x86_avx2_psll_w
:
4201 case Intrinsic::x86_avx2_psll_d
:
4202 case Intrinsic::x86_avx2_psll_q
:
4203 case Intrinsic::x86_avx2_pslli_w
:
4204 case Intrinsic::x86_avx2_pslli_d
:
4205 case Intrinsic::x86_avx2_pslli_q
:
4206 case Intrinsic::x86_avx2_psrl_w
:
4207 case Intrinsic::x86_avx2_psrl_d
:
4208 case Intrinsic::x86_avx2_psrl_q
:
4209 case Intrinsic::x86_avx2_psra_w
:
4210 case Intrinsic::x86_avx2_psra_d
:
4211 case Intrinsic::x86_avx2_psrli_w
:
4212 case Intrinsic::x86_avx2_psrli_d
:
4213 case Intrinsic::x86_avx2_psrli_q
:
4214 case Intrinsic::x86_avx2_psrai_w
:
4215 case Intrinsic::x86_avx2_psrai_d
:
4216 case Intrinsic::x86_sse2_psll_w
:
4217 case Intrinsic::x86_sse2_psll_d
:
4218 case Intrinsic::x86_sse2_psll_q
:
4219 case Intrinsic::x86_sse2_pslli_w
:
4220 case Intrinsic::x86_sse2_pslli_d
:
4221 case Intrinsic::x86_sse2_pslli_q
:
4222 case Intrinsic::x86_sse2_psrl_w
:
4223 case Intrinsic::x86_sse2_psrl_d
:
4224 case Intrinsic::x86_sse2_psrl_q
:
4225 case Intrinsic::x86_sse2_psra_w
:
4226 case Intrinsic::x86_sse2_psra_d
:
4227 case Intrinsic::x86_sse2_psrli_w
:
4228 case Intrinsic::x86_sse2_psrli_d
:
4229 case Intrinsic::x86_sse2_psrli_q
:
4230 case Intrinsic::x86_sse2_psrai_w
:
4231 case Intrinsic::x86_sse2_psrai_d
:
4232 case Intrinsic::x86_mmx_psll_w
:
4233 case Intrinsic::x86_mmx_psll_d
:
4234 case Intrinsic::x86_mmx_psll_q
:
4235 case Intrinsic::x86_mmx_pslli_w
:
4236 case Intrinsic::x86_mmx_pslli_d
:
4237 case Intrinsic::x86_mmx_pslli_q
:
4238 case Intrinsic::x86_mmx_psrl_w
:
4239 case Intrinsic::x86_mmx_psrl_d
:
4240 case Intrinsic::x86_mmx_psrl_q
:
4241 case Intrinsic::x86_mmx_psra_w
:
4242 case Intrinsic::x86_mmx_psra_d
:
4243 case Intrinsic::x86_mmx_psrli_w
:
4244 case Intrinsic::x86_mmx_psrli_d
:
4245 case Intrinsic::x86_mmx_psrli_q
:
4246 case Intrinsic::x86_mmx_psrai_w
:
4247 case Intrinsic::x86_mmx_psrai_d
:
4248 case Intrinsic::aarch64_neon_rshrn
:
4249 case Intrinsic::aarch64_neon_sqrshl
:
4250 case Intrinsic::aarch64_neon_sqrshrn
:
4251 case Intrinsic::aarch64_neon_sqrshrun
:
4252 case Intrinsic::aarch64_neon_sqshl
:
4253 case Intrinsic::aarch64_neon_sqshlu
:
4254 case Intrinsic::aarch64_neon_sqshrn
:
4255 case Intrinsic::aarch64_neon_sqshrun
:
4256 case Intrinsic::aarch64_neon_srshl
:
4257 case Intrinsic::aarch64_neon_sshl
:
4258 case Intrinsic::aarch64_neon_uqrshl
:
4259 case Intrinsic::aarch64_neon_uqrshrn
:
4260 case Intrinsic::aarch64_neon_uqshl
:
4261 case Intrinsic::aarch64_neon_uqshrn
:
4262 case Intrinsic::aarch64_neon_urshl
:
4263 case Intrinsic::aarch64_neon_ushl
:
4264 // Not handled here: aarch64_neon_vsli (vector shift left and insert)
4265 handleVectorShiftIntrinsic(I
, /* Variable */ false);
4267 case Intrinsic::x86_avx2_psllv_d
:
4268 case Intrinsic::x86_avx2_psllv_d_256
:
4269 case Intrinsic::x86_avx512_psllv_d_512
:
4270 case Intrinsic::x86_avx2_psllv_q
:
4271 case Intrinsic::x86_avx2_psllv_q_256
:
4272 case Intrinsic::x86_avx512_psllv_q_512
:
4273 case Intrinsic::x86_avx2_psrlv_d
:
4274 case Intrinsic::x86_avx2_psrlv_d_256
:
4275 case Intrinsic::x86_avx512_psrlv_d_512
:
4276 case Intrinsic::x86_avx2_psrlv_q
:
4277 case Intrinsic::x86_avx2_psrlv_q_256
:
4278 case Intrinsic::x86_avx512_psrlv_q_512
:
4279 case Intrinsic::x86_avx2_psrav_d
:
4280 case Intrinsic::x86_avx2_psrav_d_256
:
4281 case Intrinsic::x86_avx512_psrav_d_512
:
4282 case Intrinsic::x86_avx512_psrav_q_128
:
4283 case Intrinsic::x86_avx512_psrav_q_256
:
4284 case Intrinsic::x86_avx512_psrav_q_512
:
4285 handleVectorShiftIntrinsic(I
, /* Variable */ true);
4288 case Intrinsic::x86_sse2_packsswb_128
:
4289 case Intrinsic::x86_sse2_packssdw_128
:
4290 case Intrinsic::x86_sse2_packuswb_128
:
4291 case Intrinsic::x86_sse41_packusdw
:
4292 case Intrinsic::x86_avx2_packsswb
:
4293 case Intrinsic::x86_avx2_packssdw
:
4294 case Intrinsic::x86_avx2_packuswb
:
4295 case Intrinsic::x86_avx2_packusdw
:
4296 handleVectorPackIntrinsic(I
);
4299 case Intrinsic::x86_sse41_pblendvb
:
4300 case Intrinsic::x86_sse41_blendvpd
:
4301 case Intrinsic::x86_sse41_blendvps
:
4302 case Intrinsic::x86_avx_blendv_pd_256
:
4303 case Intrinsic::x86_avx_blendv_ps_256
:
4304 case Intrinsic::x86_avx2_pblendvb
:
4305 handleBlendvIntrinsic(I
);
4308 case Intrinsic::x86_avx_dp_ps_256
:
4309 case Intrinsic::x86_sse41_dppd
:
4310 case Intrinsic::x86_sse41_dpps
:
4311 handleDppIntrinsic(I
);
4314 case Intrinsic::x86_mmx_packsswb
:
4315 case Intrinsic::x86_mmx_packuswb
:
4316 handleVectorPackIntrinsic(I
, 16);
4319 case Intrinsic::x86_mmx_packssdw
:
4320 handleVectorPackIntrinsic(I
, 32);
4323 case Intrinsic::x86_mmx_psad_bw
:
4324 handleVectorSadIntrinsic(I
, true);
4326 case Intrinsic::x86_sse2_psad_bw
:
4327 case Intrinsic::x86_avx2_psad_bw
:
4328 handleVectorSadIntrinsic(I
);
4331 case Intrinsic::x86_sse2_pmadd_wd
:
4332 case Intrinsic::x86_avx2_pmadd_wd
:
4333 case Intrinsic::x86_ssse3_pmadd_ub_sw_128
:
4334 case Intrinsic::x86_avx2_pmadd_ub_sw
:
4335 handleVectorPmaddIntrinsic(I
);
4338 case Intrinsic::x86_ssse3_pmadd_ub_sw
:
4339 handleVectorPmaddIntrinsic(I
, 8);
4342 case Intrinsic::x86_mmx_pmadd_wd
:
4343 handleVectorPmaddIntrinsic(I
, 16);
4346 case Intrinsic::x86_sse_cmp_ss
:
4347 case Intrinsic::x86_sse2_cmp_sd
:
4348 case Intrinsic::x86_sse_comieq_ss
:
4349 case Intrinsic::x86_sse_comilt_ss
:
4350 case Intrinsic::x86_sse_comile_ss
:
4351 case Intrinsic::x86_sse_comigt_ss
:
4352 case Intrinsic::x86_sse_comige_ss
:
4353 case Intrinsic::x86_sse_comineq_ss
:
4354 case Intrinsic::x86_sse_ucomieq_ss
:
4355 case Intrinsic::x86_sse_ucomilt_ss
:
4356 case Intrinsic::x86_sse_ucomile_ss
:
4357 case Intrinsic::x86_sse_ucomigt_ss
:
4358 case Intrinsic::x86_sse_ucomige_ss
:
4359 case Intrinsic::x86_sse_ucomineq_ss
:
4360 case Intrinsic::x86_sse2_comieq_sd
:
4361 case Intrinsic::x86_sse2_comilt_sd
:
4362 case Intrinsic::x86_sse2_comile_sd
:
4363 case Intrinsic::x86_sse2_comigt_sd
:
4364 case Intrinsic::x86_sse2_comige_sd
:
4365 case Intrinsic::x86_sse2_comineq_sd
:
4366 case Intrinsic::x86_sse2_ucomieq_sd
:
4367 case Intrinsic::x86_sse2_ucomilt_sd
:
4368 case Intrinsic::x86_sse2_ucomile_sd
:
4369 case Intrinsic::x86_sse2_ucomigt_sd
:
4370 case Intrinsic::x86_sse2_ucomige_sd
:
4371 case Intrinsic::x86_sse2_ucomineq_sd
:
4372 handleVectorCompareScalarIntrinsic(I
);
4375 case Intrinsic::x86_avx_cmp_pd_256
:
4376 case Intrinsic::x86_avx_cmp_ps_256
:
4377 case Intrinsic::x86_sse2_cmp_pd
:
4378 case Intrinsic::x86_sse_cmp_ps
:
4379 handleVectorComparePackedIntrinsic(I
);
4382 case Intrinsic::x86_bmi_bextr_32
:
4383 case Intrinsic::x86_bmi_bextr_64
:
4384 case Intrinsic::x86_bmi_bzhi_32
:
4385 case Intrinsic::x86_bmi_bzhi_64
:
4386 case Intrinsic::x86_bmi_pdep_32
:
4387 case Intrinsic::x86_bmi_pdep_64
:
4388 case Intrinsic::x86_bmi_pext_32
:
4389 case Intrinsic::x86_bmi_pext_64
:
4390 handleBmiIntrinsic(I
);
4393 case Intrinsic::x86_pclmulqdq
:
4394 case Intrinsic::x86_pclmulqdq_256
:
4395 case Intrinsic::x86_pclmulqdq_512
:
4396 handlePclmulIntrinsic(I
);
4399 case Intrinsic::x86_avx_round_pd_256
:
4400 case Intrinsic::x86_avx_round_ps_256
:
4401 case Intrinsic::x86_sse41_round_pd
:
4402 case Intrinsic::x86_sse41_round_ps
:
4403 handleRoundPdPsIntrinsic(I
);
4406 case Intrinsic::x86_sse41_round_sd
:
4407 case Intrinsic::x86_sse41_round_ss
:
4408 handleUnarySdSsIntrinsic(I
);
4411 case Intrinsic::x86_sse2_max_sd
:
4412 case Intrinsic::x86_sse_max_ss
:
4413 case Intrinsic::x86_sse2_min_sd
:
4414 case Intrinsic::x86_sse_min_ss
:
4415 handleBinarySdSsIntrinsic(I
);
4418 case Intrinsic::x86_avx_vtestc_pd
:
4419 case Intrinsic::x86_avx_vtestc_pd_256
:
4420 case Intrinsic::x86_avx_vtestc_ps
:
4421 case Intrinsic::x86_avx_vtestc_ps_256
:
4422 case Intrinsic::x86_avx_vtestnzc_pd
:
4423 case Intrinsic::x86_avx_vtestnzc_pd_256
:
4424 case Intrinsic::x86_avx_vtestnzc_ps
:
4425 case Intrinsic::x86_avx_vtestnzc_ps_256
:
4426 case Intrinsic::x86_avx_vtestz_pd
:
4427 case Intrinsic::x86_avx_vtestz_pd_256
:
4428 case Intrinsic::x86_avx_vtestz_ps
:
4429 case Intrinsic::x86_avx_vtestz_ps_256
:
4430 case Intrinsic::x86_avx_ptestc_256
:
4431 case Intrinsic::x86_avx_ptestnzc_256
:
4432 case Intrinsic::x86_avx_ptestz_256
:
4433 case Intrinsic::x86_sse41_ptestc
:
4434 case Intrinsic::x86_sse41_ptestnzc
:
4435 case Intrinsic::x86_sse41_ptestz
:
4436 handleVtestIntrinsic(I
);
4439 case Intrinsic::x86_sse3_hadd_ps
:
4440 case Intrinsic::x86_sse3_hadd_pd
:
4441 case Intrinsic::x86_ssse3_phadd_d
:
4442 case Intrinsic::x86_ssse3_phadd_d_128
:
4443 case Intrinsic::x86_ssse3_phadd_w
:
4444 case Intrinsic::x86_ssse3_phadd_w_128
:
4445 case Intrinsic::x86_ssse3_phadd_sw
:
4446 case Intrinsic::x86_ssse3_phadd_sw_128
:
4447 case Intrinsic::x86_avx_hadd_pd_256
:
4448 case Intrinsic::x86_avx_hadd_ps_256
:
4449 case Intrinsic::x86_avx2_phadd_d
:
4450 case Intrinsic::x86_avx2_phadd_w
:
4451 case Intrinsic::x86_avx2_phadd_sw
:
4452 case Intrinsic::x86_sse3_hsub_ps
:
4453 case Intrinsic::x86_sse3_hsub_pd
:
4454 case Intrinsic::x86_ssse3_phsub_d
:
4455 case Intrinsic::x86_ssse3_phsub_d_128
:
4456 case Intrinsic::x86_ssse3_phsub_w
:
4457 case Intrinsic::x86_ssse3_phsub_w_128
:
4458 case Intrinsic::x86_ssse3_phsub_sw
:
4459 case Intrinsic::x86_ssse3_phsub_sw_128
:
4460 case Intrinsic::x86_avx_hsub_pd_256
:
4461 case Intrinsic::x86_avx_hsub_ps_256
:
4462 case Intrinsic::x86_avx2_phsub_d
:
4463 case Intrinsic::x86_avx2_phsub_w
:
4464 case Intrinsic::x86_avx2_phsub_sw
: {
4465 handleAVXHorizontalAddSubIntrinsic(I
);
4469 case Intrinsic::fshl
:
4470 case Intrinsic::fshr
:
4471 handleFunnelShift(I
);
4474 case Intrinsic::is_constant
:
4475 // The result of llvm.is.constant() is always defined.
4476 setShadow(&I
, getCleanShadow(&I
));
4477 setOrigin(&I
, getCleanOrigin());
4480 case Intrinsic::aarch64_neon_st1x2
:
4481 case Intrinsic::aarch64_neon_st1x3
:
4482 case Intrinsic::aarch64_neon_st1x4
:
4483 case Intrinsic::aarch64_neon_st2
:
4484 case Intrinsic::aarch64_neon_st3
:
4485 case Intrinsic::aarch64_neon_st4
: {
4486 handleNEONVectorStoreIntrinsic(I
, false);
4490 case Intrinsic::aarch64_neon_st2lane
:
4491 case Intrinsic::aarch64_neon_st3lane
:
4492 case Intrinsic::aarch64_neon_st4lane
: {
4493 handleNEONVectorStoreIntrinsic(I
, true);
4497 // Arm NEON vector table intrinsics have the source/table register(s) as
4498 // arguments, followed by the index register. They return the output.
4500 // 'TBL writes a zero if an index is out-of-range, while TBX leaves the
4501 // original value unchanged in the destination register.'
4502 // Conveniently, zero denotes a clean shadow, which means out-of-range
4503 // indices for TBL will initialize the user data with zero and also clean
4504 // the shadow. (For TBX, neither the user data nor the shadow will be
4505 // updated, which is also correct.)
4506 case Intrinsic::aarch64_neon_tbl1
:
4507 case Intrinsic::aarch64_neon_tbl2
:
4508 case Intrinsic::aarch64_neon_tbl3
:
4509 case Intrinsic::aarch64_neon_tbl4
:
4510 case Intrinsic::aarch64_neon_tbx1
:
4511 case Intrinsic::aarch64_neon_tbx2
:
4512 case Intrinsic::aarch64_neon_tbx3
:
4513 case Intrinsic::aarch64_neon_tbx4
: {
4514 // The last trailing argument (index register) should be handled verbatim
4515 handleIntrinsicByApplyingToShadow(I
, 1);
4519 case Intrinsic::aarch64_neon_fmulx
:
4520 case Intrinsic::aarch64_neon_pmul
:
4521 case Intrinsic::aarch64_neon_pmull
:
4522 case Intrinsic::aarch64_neon_smull
:
4523 case Intrinsic::aarch64_neon_pmull64
:
4524 case Intrinsic::aarch64_neon_umull
: {
4525 handleNEONVectorMultiplyIntrinsic(I
);
4530 if (!handleUnknownIntrinsic(I
))
4531 visitInstruction(I
);
4536 void visitLibAtomicLoad(CallBase
&CB
) {
4537 // Since we use getNextNode here, we can't have CB terminate the BB.
4538 assert(isa
<CallInst
>(CB
));
4540 IRBuilder
<> IRB(&CB
);
4541 Value
*Size
= CB
.getArgOperand(0);
4542 Value
*SrcPtr
= CB
.getArgOperand(1);
4543 Value
*DstPtr
= CB
.getArgOperand(2);
4544 Value
*Ordering
= CB
.getArgOperand(3);
4545 // Convert the call to have at least Acquire ordering to make sure
4546 // the shadow operations aren't reordered before it.
4547 Value
*NewOrdering
=
4548 IRB
.CreateExtractElement(makeAddAcquireOrderingTable(IRB
), Ordering
);
4549 CB
.setArgOperand(3, NewOrdering
);
4551 NextNodeIRBuilder
NextIRB(&CB
);
4552 Value
*SrcShadowPtr
, *SrcOriginPtr
;
4553 std::tie(SrcShadowPtr
, SrcOriginPtr
) =
4554 getShadowOriginPtr(SrcPtr
, NextIRB
, NextIRB
.getInt8Ty(), Align(1),
4556 Value
*DstShadowPtr
=
4557 getShadowOriginPtr(DstPtr
, NextIRB
, NextIRB
.getInt8Ty(), Align(1),
4561 NextIRB
.CreateMemCpy(DstShadowPtr
, Align(1), SrcShadowPtr
, Align(1), Size
);
4562 if (MS
.TrackOrigins
) {
4563 Value
*SrcOrigin
= NextIRB
.CreateAlignedLoad(MS
.OriginTy
, SrcOriginPtr
,
4564 kMinOriginAlignment
);
4565 Value
*NewOrigin
= updateOrigin(SrcOrigin
, NextIRB
);
4566 NextIRB
.CreateCall(MS
.MsanSetOriginFn
, {DstPtr
, Size
, NewOrigin
});
4570 void visitLibAtomicStore(CallBase
&CB
) {
4571 IRBuilder
<> IRB(&CB
);
4572 Value
*Size
= CB
.getArgOperand(0);
4573 Value
*DstPtr
= CB
.getArgOperand(2);
4574 Value
*Ordering
= CB
.getArgOperand(3);
4575 // Convert the call to have at least Release ordering to make sure
4576 // the shadow operations aren't reordered after it.
4577 Value
*NewOrdering
=
4578 IRB
.CreateExtractElement(makeAddReleaseOrderingTable(IRB
), Ordering
);
4579 CB
.setArgOperand(3, NewOrdering
);
4581 Value
*DstShadowPtr
=
4582 getShadowOriginPtr(DstPtr
, IRB
, IRB
.getInt8Ty(), Align(1),
4586 // Atomic store always paints clean shadow/origin. See file header.
4587 IRB
.CreateMemSet(DstShadowPtr
, getCleanShadow(IRB
.getInt8Ty()), Size
,
4591 void visitCallBase(CallBase
&CB
) {
4592 assert(!CB
.getMetadata(LLVMContext::MD_nosanitize
));
4593 if (CB
.isInlineAsm()) {
4594 // For inline asm (either a call to asm function, or callbr instruction),
4595 // do the usual thing: check argument shadow and mark all outputs as
4596 // clean. Note that any side effects of the inline asm that are not
4597 // immediately visible in its constraints are not handled.
4598 if (ClHandleAsmConservative
)
4599 visitAsmInstruction(CB
);
4601 visitInstruction(CB
);
4605 if (TLI
->getLibFunc(CB
, LF
)) {
4606 // libatomic.a functions need to have special handling because there isn't
4607 // a good way to intercept them or compile the library with
4610 case LibFunc_atomic_load
:
4611 if (!isa
<CallInst
>(CB
)) {
4612 llvm::errs() << "MSAN -- cannot instrument invoke of libatomic load."
4616 visitLibAtomicLoad(CB
);
4618 case LibFunc_atomic_store
:
4619 visitLibAtomicStore(CB
);
4626 if (auto *Call
= dyn_cast
<CallInst
>(&CB
)) {
4627 assert(!isa
<IntrinsicInst
>(Call
) && "intrinsics are handled elsewhere");
4629 // We are going to insert code that relies on the fact that the callee
4630 // will become a non-readonly function after it is instrumented by us. To
4631 // prevent this code from being optimized out, mark that function
4632 // non-readonly in advance.
4633 // TODO: We can likely do better than dropping memory() completely here.
4635 B
.addAttribute(Attribute::Memory
).addAttribute(Attribute::Speculatable
);
4637 Call
->removeFnAttrs(B
);
4638 if (Function
*Func
= Call
->getCalledFunction()) {
4639 Func
->removeFnAttrs(B
);
4642 maybeMarkSanitizerLibraryCallNoBuiltin(Call
, TLI
);
4644 IRBuilder
<> IRB(&CB
);
4645 bool MayCheckCall
= MS
.EagerChecks
;
4646 if (Function
*Func
= CB
.getCalledFunction()) {
4647 // __sanitizer_unaligned_{load,store} functions may be called by users
4648 // and always expects shadows in the TLS. So don't check them.
4649 MayCheckCall
&= !Func
->getName().starts_with("__sanitizer_unaligned_");
4652 unsigned ArgOffset
= 0;
4653 LLVM_DEBUG(dbgs() << " CallSite: " << CB
<< "\n");
4654 for (const auto &[i
, A
] : llvm::enumerate(CB
.args())) {
4655 if (!A
->getType()->isSized()) {
4656 LLVM_DEBUG(dbgs() << "Arg " << i
<< " is not sized: " << CB
<< "\n");
4660 if (A
->getType()->isScalableTy()) {
4661 LLVM_DEBUG(dbgs() << "Arg " << i
<< " is vscale: " << CB
<< "\n");
4662 // Handle as noundef, but don't reserve tls slots.
4663 insertShadowCheck(A
, &CB
);
4668 const DataLayout
&DL
= F
.getDataLayout();
4670 bool ByVal
= CB
.paramHasAttr(i
, Attribute::ByVal
);
4671 bool NoUndef
= CB
.paramHasAttr(i
, Attribute::NoUndef
);
4672 bool EagerCheck
= MayCheckCall
&& !ByVal
&& NoUndef
;
4675 insertShadowCheck(A
, &CB
);
4676 Size
= DL
.getTypeAllocSize(A
->getType());
4678 Value
*Store
= nullptr;
4679 // Compute the Shadow for arg even if it is ByVal, because
4680 // in that case getShadow() will copy the actual arg shadow to
4681 // __msan_param_tls.
4682 Value
*ArgShadow
= getShadow(A
);
4683 Value
*ArgShadowBase
= getShadowPtrForArgument(IRB
, ArgOffset
);
4684 LLVM_DEBUG(dbgs() << " Arg#" << i
<< ": " << *A
4685 << " Shadow: " << *ArgShadow
<< "\n");
4687 // ByVal requires some special handling as it's too big for a single
4689 assert(A
->getType()->isPointerTy() &&
4690 "ByVal argument is not a pointer!");
4691 Size
= DL
.getTypeAllocSize(CB
.getParamByValType(i
));
4692 if (ArgOffset
+ Size
> kParamTLSSize
)
4694 const MaybeAlign
ParamAlignment(CB
.getParamAlign(i
));
4695 MaybeAlign Alignment
= std::nullopt
;
4697 Alignment
= std::min(*ParamAlignment
, kShadowTLSAlignment
);
4698 Value
*AShadowPtr
, *AOriginPtr
;
4699 std::tie(AShadowPtr
, AOriginPtr
) =
4700 getShadowOriginPtr(A
, IRB
, IRB
.getInt8Ty(), Alignment
,
4702 if (!PropagateShadow
) {
4703 Store
= IRB
.CreateMemSet(ArgShadowBase
,
4704 Constant::getNullValue(IRB
.getInt8Ty()),
4707 Store
= IRB
.CreateMemCpy(ArgShadowBase
, Alignment
, AShadowPtr
,
4709 if (MS
.TrackOrigins
) {
4710 Value
*ArgOriginBase
= getOriginPtrForArgument(IRB
, ArgOffset
);
4711 // FIXME: OriginSize should be:
4712 // alignTo(A % kMinOriginAlignment + Size, kMinOriginAlignment)
4713 unsigned OriginSize
= alignTo(Size
, kMinOriginAlignment
);
4716 /* by origin_tls[ArgOffset] */ kMinOriginAlignment
,
4718 /* by getShadowOriginPtr */ kMinOriginAlignment
, OriginSize
);
4722 // Any other parameters mean we need bit-grained tracking of uninit
4724 Size
= DL
.getTypeAllocSize(A
->getType());
4725 if (ArgOffset
+ Size
> kParamTLSSize
)
4727 Store
= IRB
.CreateAlignedStore(ArgShadow
, ArgShadowBase
,
4728 kShadowTLSAlignment
);
4729 Constant
*Cst
= dyn_cast
<Constant
>(ArgShadow
);
4730 if (MS
.TrackOrigins
&& !(Cst
&& Cst
->isNullValue())) {
4731 IRB
.CreateStore(getOrigin(A
),
4732 getOriginPtrForArgument(IRB
, ArgOffset
));
4736 assert(Store
!= nullptr);
4737 LLVM_DEBUG(dbgs() << " Param:" << *Store
<< "\n");
4740 ArgOffset
+= alignTo(Size
, kShadowTLSAlignment
);
4742 LLVM_DEBUG(dbgs() << " done with call args\n");
4744 FunctionType
*FT
= CB
.getFunctionType();
4745 if (FT
->isVarArg()) {
4746 VAHelper
->visitCallBase(CB
, IRB
);
4749 // Now, get the shadow for the RetVal.
4750 if (!CB
.getType()->isSized())
4752 // Don't emit the epilogue for musttail call returns.
4753 if (isa
<CallInst
>(CB
) && cast
<CallInst
>(CB
).isMustTailCall())
4756 if (MayCheckCall
&& CB
.hasRetAttr(Attribute::NoUndef
)) {
4757 setShadow(&CB
, getCleanShadow(&CB
));
4758 setOrigin(&CB
, getCleanOrigin());
4762 IRBuilder
<> IRBBefore(&CB
);
4763 // Until we have full dynamic coverage, make sure the retval shadow is 0.
4764 Value
*Base
= getShadowPtrForRetval(IRBBefore
);
4765 IRBBefore
.CreateAlignedStore(getCleanShadow(&CB
), Base
,
4766 kShadowTLSAlignment
);
4767 BasicBlock::iterator NextInsn
;
4768 if (isa
<CallInst
>(CB
)) {
4769 NextInsn
= ++CB
.getIterator();
4770 assert(NextInsn
!= CB
.getParent()->end());
4772 BasicBlock
*NormalDest
= cast
<InvokeInst
>(CB
).getNormalDest();
4773 if (!NormalDest
->getSinglePredecessor()) {
4774 // FIXME: this case is tricky, so we are just conservative here.
4775 // Perhaps we need to split the edge between this BB and NormalDest,
4776 // but a naive attempt to use SplitEdge leads to a crash.
4777 setShadow(&CB
, getCleanShadow(&CB
));
4778 setOrigin(&CB
, getCleanOrigin());
4781 // FIXME: NextInsn is likely in a basic block that has not been visited
4782 // yet. Anything inserted there will be instrumented by MSan later!
4783 NextInsn
= NormalDest
->getFirstInsertionPt();
4784 assert(NextInsn
!= NormalDest
->end() &&
4785 "Could not find insertion point for retval shadow load");
4787 IRBuilder
<> IRBAfter(&*NextInsn
);
4788 Value
*RetvalShadow
= IRBAfter
.CreateAlignedLoad(
4789 getShadowTy(&CB
), getShadowPtrForRetval(IRBAfter
), kShadowTLSAlignment
,
4791 setShadow(&CB
, RetvalShadow
);
4792 if (MS
.TrackOrigins
)
4793 setOrigin(&CB
, IRBAfter
.CreateLoad(MS
.OriginTy
, getOriginPtrForRetval()));
4796 bool isAMustTailRetVal(Value
*RetVal
) {
4797 if (auto *I
= dyn_cast
<BitCastInst
>(RetVal
)) {
4798 RetVal
= I
->getOperand(0);
4800 if (auto *I
= dyn_cast
<CallInst
>(RetVal
)) {
4801 return I
->isMustTailCall();
4806 void visitReturnInst(ReturnInst
&I
) {
4807 IRBuilder
<> IRB(&I
);
4808 Value
*RetVal
= I
.getReturnValue();
4811 // Don't emit the epilogue for musttail call returns.
4812 if (isAMustTailRetVal(RetVal
))
4814 Value
*ShadowPtr
= getShadowPtrForRetval(IRB
);
4815 bool HasNoUndef
= F
.hasRetAttribute(Attribute::NoUndef
);
4816 bool StoreShadow
= !(MS
.EagerChecks
&& HasNoUndef
);
4817 // FIXME: Consider using SpecialCaseList to specify a list of functions that
4818 // must always return fully initialized values. For now, we hardcode "main".
4819 bool EagerCheck
= (MS
.EagerChecks
&& HasNoUndef
) || (F
.getName() == "main");
4821 Value
*Shadow
= getShadow(RetVal
);
4822 bool StoreOrigin
= true;
4824 insertShadowCheck(RetVal
, &I
);
4825 Shadow
= getCleanShadow(RetVal
);
4826 StoreOrigin
= false;
4829 // The caller may still expect information passed over TLS if we pass our
4832 IRB
.CreateAlignedStore(Shadow
, ShadowPtr
, kShadowTLSAlignment
);
4833 if (MS
.TrackOrigins
&& StoreOrigin
)
4834 IRB
.CreateStore(getOrigin(RetVal
), getOriginPtrForRetval());
4838 void visitPHINode(PHINode
&I
) {
4839 IRBuilder
<> IRB(&I
);
4840 if (!PropagateShadow
) {
4841 setShadow(&I
, getCleanShadow(&I
));
4842 setOrigin(&I
, getCleanOrigin());
4846 ShadowPHINodes
.push_back(&I
);
4847 setShadow(&I
, IRB
.CreatePHI(getShadowTy(&I
), I
.getNumIncomingValues(),
4849 if (MS
.TrackOrigins
)
4851 &I
, IRB
.CreatePHI(MS
.OriginTy
, I
.getNumIncomingValues(), "_msphi_o"));
4854 Value
*getLocalVarIdptr(AllocaInst
&I
) {
4855 ConstantInt
*IntConst
=
4856 ConstantInt::get(Type::getInt32Ty((*F
.getParent()).getContext()), 0);
4857 return new GlobalVariable(*F
.getParent(), IntConst
->getType(),
4858 /*isConstant=*/false, GlobalValue::PrivateLinkage
,
4862 Value
*getLocalVarDescription(AllocaInst
&I
) {
4863 return createPrivateConstGlobalForString(*F
.getParent(), I
.getName());
4866 void poisonAllocaUserspace(AllocaInst
&I
, IRBuilder
<> &IRB
, Value
*Len
) {
4867 if (PoisonStack
&& ClPoisonStackWithCall
) {
4868 IRB
.CreateCall(MS
.MsanPoisonStackFn
, {&I
, Len
});
4870 Value
*ShadowBase
, *OriginBase
;
4871 std::tie(ShadowBase
, OriginBase
) = getShadowOriginPtr(
4872 &I
, IRB
, IRB
.getInt8Ty(), Align(1), /*isStore*/ true);
4874 Value
*PoisonValue
= IRB
.getInt8(PoisonStack
? ClPoisonStackPattern
: 0);
4875 IRB
.CreateMemSet(ShadowBase
, PoisonValue
, Len
, I
.getAlign());
4878 if (PoisonStack
&& MS
.TrackOrigins
) {
4879 Value
*Idptr
= getLocalVarIdptr(I
);
4880 if (ClPrintStackNames
) {
4881 Value
*Descr
= getLocalVarDescription(I
);
4882 IRB
.CreateCall(MS
.MsanSetAllocaOriginWithDescriptionFn
,
4883 {&I
, Len
, Idptr
, Descr
});
4885 IRB
.CreateCall(MS
.MsanSetAllocaOriginNoDescriptionFn
, {&I
, Len
, Idptr
});
4890 void poisonAllocaKmsan(AllocaInst
&I
, IRBuilder
<> &IRB
, Value
*Len
) {
4891 Value
*Descr
= getLocalVarDescription(I
);
4893 IRB
.CreateCall(MS
.MsanPoisonAllocaFn
, {&I
, Len
, Descr
});
4895 IRB
.CreateCall(MS
.MsanUnpoisonAllocaFn
, {&I
, Len
});
4899 void instrumentAlloca(AllocaInst
&I
, Instruction
*InsPoint
= nullptr) {
4902 NextNodeIRBuilder
IRB(InsPoint
);
4903 const DataLayout
&DL
= F
.getDataLayout();
4904 TypeSize TS
= DL
.getTypeAllocSize(I
.getAllocatedType());
4905 Value
*Len
= IRB
.CreateTypeSize(MS
.IntptrTy
, TS
);
4906 if (I
.isArrayAllocation())
4907 Len
= IRB
.CreateMul(Len
,
4908 IRB
.CreateZExtOrTrunc(I
.getArraySize(), MS
.IntptrTy
));
4910 if (MS
.CompileKernel
)
4911 poisonAllocaKmsan(I
, IRB
, Len
);
4913 poisonAllocaUserspace(I
, IRB
, Len
);
4916 void visitAllocaInst(AllocaInst
&I
) {
4917 setShadow(&I
, getCleanShadow(&I
));
4918 setOrigin(&I
, getCleanOrigin());
4919 // We'll get to this alloca later unless it's poisoned at the corresponding
4920 // llvm.lifetime.start.
4921 AllocaSet
.insert(&I
);
4924 void visitSelectInst(SelectInst
&I
) {
4925 // a = select b, c, d
4926 Value
*B
= I
.getCondition();
4927 Value
*C
= I
.getTrueValue();
4928 Value
*D
= I
.getFalseValue();
4930 handleSelectLikeInst(I
, B
, C
, D
);
4933 void handleSelectLikeInst(Instruction
&I
, Value
*B
, Value
*C
, Value
*D
) {
4934 IRBuilder
<> IRB(&I
);
4936 Value
*Sb
= getShadow(B
);
4937 Value
*Sc
= getShadow(C
);
4938 Value
*Sd
= getShadow(D
);
4940 Value
*Ob
= MS
.TrackOrigins
? getOrigin(B
) : nullptr;
4941 Value
*Oc
= MS
.TrackOrigins
? getOrigin(C
) : nullptr;
4942 Value
*Od
= MS
.TrackOrigins
? getOrigin(D
) : nullptr;
4944 // Result shadow if condition shadow is 0.
4945 Value
*Sa0
= IRB
.CreateSelect(B
, Sc
, Sd
);
4947 if (I
.getType()->isAggregateType()) {
4948 // To avoid "sign extending" i1 to an arbitrary aggregate type, we just do
4949 // an extra "select". This results in much more compact IR.
4950 // Sa = select Sb, poisoned, (select b, Sc, Sd)
4951 Sa1
= getPoisonedShadow(getShadowTy(I
.getType()));
4953 // Sa = select Sb, [ (c^d) | Sc | Sd ], [ b ? Sc : Sd ]
4954 // If Sb (condition is poisoned), look for bits in c and d that are equal
4955 // and both unpoisoned.
4956 // If !Sb (condition is unpoisoned), simply pick one of Sc and Sd.
4958 // Cast arguments to shadow-compatible type.
4959 C
= CreateAppToShadowCast(IRB
, C
);
4960 D
= CreateAppToShadowCast(IRB
, D
);
4962 // Result shadow if condition shadow is 1.
4963 Sa1
= IRB
.CreateOr({IRB
.CreateXor(C
, D
), Sc
, Sd
});
4965 Value
*Sa
= IRB
.CreateSelect(Sb
, Sa1
, Sa0
, "_msprop_select");
4967 if (MS
.TrackOrigins
) {
4968 // Origins are always i32, so any vector conditions must be flattened.
4969 // FIXME: consider tracking vector origins for app vectors?
4970 if (B
->getType()->isVectorTy()) {
4971 B
= convertToBool(B
, IRB
);
4972 Sb
= convertToBool(Sb
, IRB
);
4974 // a = select b, c, d
4975 // Oa = Sb ? Ob : (b ? Oc : Od)
4976 setOrigin(&I
, IRB
.CreateSelect(Sb
, Ob
, IRB
.CreateSelect(B
, Oc
, Od
)));
4980 void visitLandingPadInst(LandingPadInst
&I
) {
4982 // See https://github.com/google/sanitizers/issues/504
4983 setShadow(&I
, getCleanShadow(&I
));
4984 setOrigin(&I
, getCleanOrigin());
4987 void visitCatchSwitchInst(CatchSwitchInst
&I
) {
4988 setShadow(&I
, getCleanShadow(&I
));
4989 setOrigin(&I
, getCleanOrigin());
4992 void visitFuncletPadInst(FuncletPadInst
&I
) {
4993 setShadow(&I
, getCleanShadow(&I
));
4994 setOrigin(&I
, getCleanOrigin());
4997 void visitGetElementPtrInst(GetElementPtrInst
&I
) { handleShadowOr(I
); }
4999 void visitExtractValueInst(ExtractValueInst
&I
) {
5000 IRBuilder
<> IRB(&I
);
5001 Value
*Agg
= I
.getAggregateOperand();
5002 LLVM_DEBUG(dbgs() << "ExtractValue: " << I
<< "\n");
5003 Value
*AggShadow
= getShadow(Agg
);
5004 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow
<< "\n");
5005 Value
*ResShadow
= IRB
.CreateExtractValue(AggShadow
, I
.getIndices());
5006 LLVM_DEBUG(dbgs() << " ResShadow: " << *ResShadow
<< "\n");
5007 setShadow(&I
, ResShadow
);
5008 setOriginForNaryOp(I
);
5011 void visitInsertValueInst(InsertValueInst
&I
) {
5012 IRBuilder
<> IRB(&I
);
5013 LLVM_DEBUG(dbgs() << "InsertValue: " << I
<< "\n");
5014 Value
*AggShadow
= getShadow(I
.getAggregateOperand());
5015 Value
*InsShadow
= getShadow(I
.getInsertedValueOperand());
5016 LLVM_DEBUG(dbgs() << " AggShadow: " << *AggShadow
<< "\n");
5017 LLVM_DEBUG(dbgs() << " InsShadow: " << *InsShadow
<< "\n");
5018 Value
*Res
= IRB
.CreateInsertValue(AggShadow
, InsShadow
, I
.getIndices());
5019 LLVM_DEBUG(dbgs() << " Res: " << *Res
<< "\n");
5021 setOriginForNaryOp(I
);
5024 void dumpInst(Instruction
&I
) {
5025 if (CallInst
*CI
= dyn_cast
<CallInst
>(&I
)) {
5026 errs() << "ZZZ call " << CI
->getCalledFunction()->getName() << "\n";
5028 errs() << "ZZZ " << I
.getOpcodeName() << "\n";
5030 errs() << "QQQ " << I
<< "\n";
5033 void visitResumeInst(ResumeInst
&I
) {
5034 LLVM_DEBUG(dbgs() << "Resume: " << I
<< "\n");
5035 // Nothing to do here.
5038 void visitCleanupReturnInst(CleanupReturnInst
&CRI
) {
5039 LLVM_DEBUG(dbgs() << "CleanupReturn: " << CRI
<< "\n");
5040 // Nothing to do here.
5043 void visitCatchReturnInst(CatchReturnInst
&CRI
) {
5044 LLVM_DEBUG(dbgs() << "CatchReturn: " << CRI
<< "\n");
5045 // Nothing to do here.
5048 void instrumentAsmArgument(Value
*Operand
, Type
*ElemTy
, Instruction
&I
,
5049 IRBuilder
<> &IRB
, const DataLayout
&DL
,
5051 // For each assembly argument, we check its value for being initialized.
5052 // If the argument is a pointer, we assume it points to a single element
5053 // of the corresponding type (or to a 8-byte word, if the type is unsized).
5054 // Each such pointer is instrumented with a call to the runtime library.
5055 Type
*OpType
= Operand
->getType();
5056 // Check the operand value itself.
5057 insertShadowCheck(Operand
, &I
);
5058 if (!OpType
->isPointerTy() || !isOutput
) {
5062 if (!ElemTy
->isSized())
5064 auto Size
= DL
.getTypeStoreSize(ElemTy
);
5065 Value
*SizeVal
= IRB
.CreateTypeSize(MS
.IntptrTy
, Size
);
5066 if (MS
.CompileKernel
) {
5067 IRB
.CreateCall(MS
.MsanInstrumentAsmStoreFn
, {Operand
, SizeVal
});
5069 // ElemTy, derived from elementtype(), does not encode the alignment of
5070 // the pointer. Conservatively assume that the shadow memory is unaligned.
5071 // When Size is large, avoid StoreInst as it would expand to many
5073 auto [ShadowPtr
, _
] =
5074 getShadowOriginPtrUserspace(Operand
, IRB
, IRB
.getInt8Ty(), Align(1));
5076 IRB
.CreateAlignedStore(getCleanShadow(ElemTy
), ShadowPtr
, Align(1));
5078 IRB
.CreateMemSet(ShadowPtr
, ConstantInt::getNullValue(IRB
.getInt8Ty()),
5083 /// Get the number of output arguments returned by pointers.
5084 int getNumOutputArgs(InlineAsm
*IA
, CallBase
*CB
) {
5085 int NumRetOutputs
= 0;
5087 Type
*RetTy
= cast
<Value
>(CB
)->getType();
5088 if (!RetTy
->isVoidTy()) {
5089 // Register outputs are returned via the CallInst return value.
5090 auto *ST
= dyn_cast
<StructType
>(RetTy
);
5092 NumRetOutputs
= ST
->getNumElements();
5096 InlineAsm::ConstraintInfoVector Constraints
= IA
->ParseConstraints();
5097 for (const InlineAsm::ConstraintInfo
&Info
: Constraints
) {
5098 switch (Info
.Type
) {
5099 case InlineAsm::isOutput
:
5106 return NumOutputs
- NumRetOutputs
;
5109 void visitAsmInstruction(Instruction
&I
) {
5110 // Conservative inline assembly handling: check for poisoned shadow of
5111 // asm() arguments, then unpoison the result and all the memory locations
5112 // pointed to by those arguments.
5113 // An inline asm() statement in C++ contains lists of input and output
5114 // arguments used by the assembly code. These are mapped to operands of the
5115 // CallInst as follows:
5116 // - nR register outputs ("=r) are returned by value in a single structure
5117 // (SSA value of the CallInst);
5118 // - nO other outputs ("=m" and others) are returned by pointer as first
5119 // nO operands of the CallInst;
5120 // - nI inputs ("r", "m" and others) are passed to CallInst as the
5121 // remaining nI operands.
5122 // The total number of asm() arguments in the source is nR+nO+nI, and the
5123 // corresponding CallInst has nO+nI+1 operands (the last operand is the
5124 // function to be called).
5125 const DataLayout
&DL
= F
.getDataLayout();
5126 CallBase
*CB
= cast
<CallBase
>(&I
);
5127 IRBuilder
<> IRB(&I
);
5128 InlineAsm
*IA
= cast
<InlineAsm
>(CB
->getCalledOperand());
5129 int OutputArgs
= getNumOutputArgs(IA
, CB
);
5130 // The last operand of a CallInst is the function itself.
5131 int NumOperands
= CB
->getNumOperands() - 1;
5133 // Check input arguments. Doing so before unpoisoning output arguments, so
5134 // that we won't overwrite uninit values before checking them.
5135 for (int i
= OutputArgs
; i
< NumOperands
; i
++) {
5136 Value
*Operand
= CB
->getOperand(i
);
5137 instrumentAsmArgument(Operand
, CB
->getParamElementType(i
), I
, IRB
, DL
,
5138 /*isOutput*/ false);
5140 // Unpoison output arguments. This must happen before the actual InlineAsm
5141 // call, so that the shadow for memory published in the asm() statement
5143 for (int i
= 0; i
< OutputArgs
; i
++) {
5144 Value
*Operand
= CB
->getOperand(i
);
5145 instrumentAsmArgument(Operand
, CB
->getParamElementType(i
), I
, IRB
, DL
,
5149 setShadow(&I
, getCleanShadow(&I
));
5150 setOrigin(&I
, getCleanOrigin());
5153 void visitFreezeInst(FreezeInst
&I
) {
5154 // Freeze always returns a fully defined value.
5155 setShadow(&I
, getCleanShadow(&I
));
5156 setOrigin(&I
, getCleanOrigin());
5159 void visitInstruction(Instruction
&I
) {
5160 // Everything else: stop propagating and check for poisoned shadow.
5161 if (ClDumpStrictInstructions
)
5163 LLVM_DEBUG(dbgs() << "DEFAULT: " << I
<< "\n");
5164 for (size_t i
= 0, n
= I
.getNumOperands(); i
< n
; i
++) {
5165 Value
*Operand
= I
.getOperand(i
);
5166 if (Operand
->getType()->isSized())
5167 insertShadowCheck(Operand
, &I
);
5169 setShadow(&I
, getCleanShadow(&I
));
5170 setOrigin(&I
, getCleanOrigin());
5174 struct VarArgHelperBase
: public VarArgHelper
{
5176 MemorySanitizer
&MS
;
5177 MemorySanitizerVisitor
&MSV
;
5178 SmallVector
<CallInst
*, 16> VAStartInstrumentationList
;
5179 const unsigned VAListTagSize
;
5181 VarArgHelperBase(Function
&F
, MemorySanitizer
&MS
,
5182 MemorySanitizerVisitor
&MSV
, unsigned VAListTagSize
)
5183 : F(F
), MS(MS
), MSV(MSV
), VAListTagSize(VAListTagSize
) {}
5185 Value
*getShadowAddrForVAArgument(IRBuilder
<> &IRB
, unsigned ArgOffset
) {
5186 Value
*Base
= IRB
.CreatePointerCast(MS
.VAArgTLS
, MS
.IntptrTy
);
5187 return IRB
.CreateAdd(Base
, ConstantInt::get(MS
.IntptrTy
, ArgOffset
));
5190 /// Compute the shadow address for a given va_arg.
5191 Value
*getShadowPtrForVAArgument(IRBuilder
<> &IRB
, unsigned ArgOffset
) {
5192 Value
*Base
= IRB
.CreatePointerCast(MS
.VAArgTLS
, MS
.IntptrTy
);
5193 Base
= IRB
.CreateAdd(Base
, ConstantInt::get(MS
.IntptrTy
, ArgOffset
));
5194 return IRB
.CreateIntToPtr(Base
, MS
.PtrTy
, "_msarg_va_s");
5197 /// Compute the shadow address for a given va_arg.
5198 Value
*getShadowPtrForVAArgument(IRBuilder
<> &IRB
, unsigned ArgOffset
,
5200 // Make sure we don't overflow __msan_va_arg_tls.
5201 if (ArgOffset
+ ArgSize
> kParamTLSSize
)
5203 return getShadowPtrForVAArgument(IRB
, ArgOffset
);
5206 /// Compute the origin address for a given va_arg.
5207 Value
*getOriginPtrForVAArgument(IRBuilder
<> &IRB
, int ArgOffset
) {
5208 Value
*Base
= IRB
.CreatePointerCast(MS
.VAArgOriginTLS
, MS
.IntptrTy
);
5209 // getOriginPtrForVAArgument() is always called after
5210 // getShadowPtrForVAArgument(), so __msan_va_arg_origin_tls can never
5212 Base
= IRB
.CreateAdd(Base
, ConstantInt::get(MS
.IntptrTy
, ArgOffset
));
5213 return IRB
.CreateIntToPtr(Base
, MS
.PtrTy
, "_msarg_va_o");
5216 void CleanUnusedTLS(IRBuilder
<> &IRB
, Value
*ShadowBase
,
5217 unsigned BaseOffset
) {
5218 // The tails of __msan_va_arg_tls is not large enough to fit full
5219 // value shadow, but it will be copied to backup anyway. Make it
5221 if (BaseOffset
>= kParamTLSSize
)
5224 ConstantInt::getSigned(IRB
.getInt32Ty(), kParamTLSSize
- BaseOffset
);
5225 IRB
.CreateMemSet(ShadowBase
, ConstantInt::getNullValue(IRB
.getInt8Ty()),
5226 TailSize
, Align(8));
5229 void unpoisonVAListTagForInst(IntrinsicInst
&I
) {
5230 IRBuilder
<> IRB(&I
);
5231 Value
*VAListTag
= I
.getArgOperand(0);
5232 const Align Alignment
= Align(8);
5233 auto [ShadowPtr
, OriginPtr
] = MSV
.getShadowOriginPtr(
5234 VAListTag
, IRB
, IRB
.getInt8Ty(), Alignment
, /*isStore*/ true);
5235 // Unpoison the whole __va_list_tag.
5236 IRB
.CreateMemSet(ShadowPtr
, Constant::getNullValue(IRB
.getInt8Ty()),
5237 VAListTagSize
, Alignment
, false);
5240 void visitVAStartInst(VAStartInst
&I
) override
{
5241 if (F
.getCallingConv() == CallingConv::Win64
)
5243 VAStartInstrumentationList
.push_back(&I
);
5244 unpoisonVAListTagForInst(I
);
5247 void visitVACopyInst(VACopyInst
&I
) override
{
5248 if (F
.getCallingConv() == CallingConv::Win64
)
5250 unpoisonVAListTagForInst(I
);
5254 /// AMD64-specific implementation of VarArgHelper.
5255 struct VarArgAMD64Helper
: public VarArgHelperBase
{
5256 // An unfortunate workaround for asymmetric lowering of va_arg stuff.
5257 // See a comment in visitCallBase for more details.
5258 static const unsigned AMD64GpEndOffset
= 48; // AMD64 ABI Draft 0.99.6 p3.5.7
5259 static const unsigned AMD64FpEndOffsetSSE
= 176;
5260 // If SSE is disabled, fp_offset in va_list is zero.
5261 static const unsigned AMD64FpEndOffsetNoSSE
= AMD64GpEndOffset
;
5263 unsigned AMD64FpEndOffset
;
5264 AllocaInst
*VAArgTLSCopy
= nullptr;
5265 AllocaInst
*VAArgTLSOriginCopy
= nullptr;
5266 Value
*VAArgOverflowSize
= nullptr;
5268 enum ArgKind
{ AK_GeneralPurpose
, AK_FloatingPoint
, AK_Memory
};
5270 VarArgAMD64Helper(Function
&F
, MemorySanitizer
&MS
,
5271 MemorySanitizerVisitor
&MSV
)
5272 : VarArgHelperBase(F
, MS
, MSV
, /*VAListTagSize=*/24) {
5273 AMD64FpEndOffset
= AMD64FpEndOffsetSSE
;
5274 for (const auto &Attr
: F
.getAttributes().getFnAttrs()) {
5275 if (Attr
.isStringAttribute() &&
5276 (Attr
.getKindAsString() == "target-features")) {
5277 if (Attr
.getValueAsString().contains("-sse"))
5278 AMD64FpEndOffset
= AMD64FpEndOffsetNoSSE
;
5284 ArgKind
classifyArgument(Value
*arg
) {
5285 // A very rough approximation of X86_64 argument classification rules.
5286 Type
*T
= arg
->getType();
5287 if (T
->isX86_FP80Ty())
5289 if (T
->isFPOrFPVectorTy())
5290 return AK_FloatingPoint
;
5291 if (T
->isIntegerTy() && T
->getPrimitiveSizeInBits() <= 64)
5292 return AK_GeneralPurpose
;
5293 if (T
->isPointerTy())
5294 return AK_GeneralPurpose
;
5298 // For VarArg functions, store the argument shadow in an ABI-specific format
5299 // that corresponds to va_list layout.
5300 // We do this because Clang lowers va_arg in the frontend, and this pass
5301 // only sees the low level code that deals with va_list internals.
5302 // A much easier alternative (provided that Clang emits va_arg instructions)
5303 // would have been to associate each live instance of va_list with a copy of
5304 // MSanParamTLS, and extract shadow on va_arg() call in the argument list
5306 void visitCallBase(CallBase
&CB
, IRBuilder
<> &IRB
) override
{
5307 unsigned GpOffset
= 0;
5308 unsigned FpOffset
= AMD64GpEndOffset
;
5309 unsigned OverflowOffset
= AMD64FpEndOffset
;
5310 const DataLayout
&DL
= F
.getDataLayout();
5312 for (const auto &[ArgNo
, A
] : llvm::enumerate(CB
.args())) {
5313 bool IsFixed
= ArgNo
< CB
.getFunctionType()->getNumParams();
5314 bool IsByVal
= CB
.paramHasAttr(ArgNo
, Attribute::ByVal
);
5316 // ByVal arguments always go to the overflow area.
5317 // Fixed arguments passed through the overflow area will be stepped
5318 // over by va_start, so don't count them towards the offset.
5321 assert(A
->getType()->isPointerTy());
5322 Type
*RealTy
= CB
.getParamByValType(ArgNo
);
5323 uint64_t ArgSize
= DL
.getTypeAllocSize(RealTy
);
5324 uint64_t AlignedSize
= alignTo(ArgSize
, 8);
5325 unsigned BaseOffset
= OverflowOffset
;
5326 Value
*ShadowBase
= getShadowPtrForVAArgument(IRB
, OverflowOffset
);
5327 Value
*OriginBase
= nullptr;
5328 if (MS
.TrackOrigins
)
5329 OriginBase
= getOriginPtrForVAArgument(IRB
, OverflowOffset
);
5330 OverflowOffset
+= AlignedSize
;
5332 if (OverflowOffset
> kParamTLSSize
) {
5333 CleanUnusedTLS(IRB
, ShadowBase
, BaseOffset
);
5334 continue; // We have no space to copy shadow there.
5337 Value
*ShadowPtr
, *OriginPtr
;
5338 std::tie(ShadowPtr
, OriginPtr
) =
5339 MSV
.getShadowOriginPtr(A
, IRB
, IRB
.getInt8Ty(), kShadowTLSAlignment
,
5341 IRB
.CreateMemCpy(ShadowBase
, kShadowTLSAlignment
, ShadowPtr
,
5342 kShadowTLSAlignment
, ArgSize
);
5343 if (MS
.TrackOrigins
)
5344 IRB
.CreateMemCpy(OriginBase
, kShadowTLSAlignment
, OriginPtr
,
5345 kShadowTLSAlignment
, ArgSize
);
5347 ArgKind AK
= classifyArgument(A
);
5348 if (AK
== AK_GeneralPurpose
&& GpOffset
>= AMD64GpEndOffset
)
5350 if (AK
== AK_FloatingPoint
&& FpOffset
>= AMD64FpEndOffset
)
5352 Value
*ShadowBase
, *OriginBase
= nullptr;
5354 case AK_GeneralPurpose
:
5355 ShadowBase
= getShadowPtrForVAArgument(IRB
, GpOffset
);
5356 if (MS
.TrackOrigins
)
5357 OriginBase
= getOriginPtrForVAArgument(IRB
, GpOffset
);
5359 assert(GpOffset
<= kParamTLSSize
);
5361 case AK_FloatingPoint
:
5362 ShadowBase
= getShadowPtrForVAArgument(IRB
, FpOffset
);
5363 if (MS
.TrackOrigins
)
5364 OriginBase
= getOriginPtrForVAArgument(IRB
, FpOffset
);
5366 assert(FpOffset
<= kParamTLSSize
);
5371 uint64_t ArgSize
= DL
.getTypeAllocSize(A
->getType());
5372 uint64_t AlignedSize
= alignTo(ArgSize
, 8);
5373 unsigned BaseOffset
= OverflowOffset
;
5374 ShadowBase
= getShadowPtrForVAArgument(IRB
, OverflowOffset
);
5375 if (MS
.TrackOrigins
) {
5376 OriginBase
= getOriginPtrForVAArgument(IRB
, OverflowOffset
);
5378 OverflowOffset
+= AlignedSize
;
5379 if (OverflowOffset
> kParamTLSSize
) {
5380 // We have no space to copy shadow there.
5381 CleanUnusedTLS(IRB
, ShadowBase
, BaseOffset
);
5385 // Take fixed arguments into account for GpOffset and FpOffset,
5386 // but don't actually store shadows for them.
5387 // TODO(glider): don't call get*PtrForVAArgument() for them.
5390 Value
*Shadow
= MSV
.getShadow(A
);
5391 IRB
.CreateAlignedStore(Shadow
, ShadowBase
, kShadowTLSAlignment
);
5392 if (MS
.TrackOrigins
) {
5393 Value
*Origin
= MSV
.getOrigin(A
);
5394 TypeSize StoreSize
= DL
.getTypeStoreSize(Shadow
->getType());
5395 MSV
.paintOrigin(IRB
, Origin
, OriginBase
, StoreSize
,
5396 std::max(kShadowTLSAlignment
, kMinOriginAlignment
));
5400 Constant
*OverflowSize
=
5401 ConstantInt::get(IRB
.getInt64Ty(), OverflowOffset
- AMD64FpEndOffset
);
5402 IRB
.CreateStore(OverflowSize
, MS
.VAArgOverflowSizeTLS
);
5405 void finalizeInstrumentation() override
{
5406 assert(!VAArgOverflowSize
&& !VAArgTLSCopy
&&
5407 "finalizeInstrumentation called twice");
5408 if (!VAStartInstrumentationList
.empty()) {
5409 // If there is a va_start in this function, make a backup copy of
5410 // va_arg_tls somewhere in the function entry block.
5411 IRBuilder
<> IRB(MSV
.FnPrologueEnd
);
5413 IRB
.CreateLoad(IRB
.getInt64Ty(), MS
.VAArgOverflowSizeTLS
);
5414 Value
*CopySize
= IRB
.CreateAdd(
5415 ConstantInt::get(MS
.IntptrTy
, AMD64FpEndOffset
), VAArgOverflowSize
);
5416 VAArgTLSCopy
= IRB
.CreateAlloca(Type::getInt8Ty(*MS
.C
), CopySize
);
5417 VAArgTLSCopy
->setAlignment(kShadowTLSAlignment
);
5418 IRB
.CreateMemSet(VAArgTLSCopy
, Constant::getNullValue(IRB
.getInt8Ty()),
5419 CopySize
, kShadowTLSAlignment
, false);
5421 Value
*SrcSize
= IRB
.CreateBinaryIntrinsic(
5422 Intrinsic::umin
, CopySize
,
5423 ConstantInt::get(MS
.IntptrTy
, kParamTLSSize
));
5424 IRB
.CreateMemCpy(VAArgTLSCopy
, kShadowTLSAlignment
, MS
.VAArgTLS
,
5425 kShadowTLSAlignment
, SrcSize
);
5426 if (MS
.TrackOrigins
) {
5427 VAArgTLSOriginCopy
= IRB
.CreateAlloca(Type::getInt8Ty(*MS
.C
), CopySize
);
5428 VAArgTLSOriginCopy
->setAlignment(kShadowTLSAlignment
);
5429 IRB
.CreateMemCpy(VAArgTLSOriginCopy
, kShadowTLSAlignment
,
5430 MS
.VAArgOriginTLS
, kShadowTLSAlignment
, SrcSize
);
5434 // Instrument va_start.
5435 // Copy va_list shadow from the backup copy of the TLS contents.
5436 for (CallInst
*OrigInst
: VAStartInstrumentationList
) {
5437 NextNodeIRBuilder
IRB(OrigInst
);
5438 Value
*VAListTag
= OrigInst
->getArgOperand(0);
5440 Value
*RegSaveAreaPtrPtr
= IRB
.CreateIntToPtr(
5441 IRB
.CreateAdd(IRB
.CreatePtrToInt(VAListTag
, MS
.IntptrTy
),
5442 ConstantInt::get(MS
.IntptrTy
, 16)),
5444 Value
*RegSaveAreaPtr
= IRB
.CreateLoad(MS
.PtrTy
, RegSaveAreaPtrPtr
);
5445 Value
*RegSaveAreaShadowPtr
, *RegSaveAreaOriginPtr
;
5446 const Align Alignment
= Align(16);
5447 std::tie(RegSaveAreaShadowPtr
, RegSaveAreaOriginPtr
) =
5448 MSV
.getShadowOriginPtr(RegSaveAreaPtr
, IRB
, IRB
.getInt8Ty(),
5449 Alignment
, /*isStore*/ true);
5450 IRB
.CreateMemCpy(RegSaveAreaShadowPtr
, Alignment
, VAArgTLSCopy
, Alignment
,
5452 if (MS
.TrackOrigins
)
5453 IRB
.CreateMemCpy(RegSaveAreaOriginPtr
, Alignment
, VAArgTLSOriginCopy
,
5454 Alignment
, AMD64FpEndOffset
);
5455 Value
*OverflowArgAreaPtrPtr
= IRB
.CreateIntToPtr(
5456 IRB
.CreateAdd(IRB
.CreatePtrToInt(VAListTag
, MS
.IntptrTy
),
5457 ConstantInt::get(MS
.IntptrTy
, 8)),
5459 Value
*OverflowArgAreaPtr
=
5460 IRB
.CreateLoad(MS
.PtrTy
, OverflowArgAreaPtrPtr
);
5461 Value
*OverflowArgAreaShadowPtr
, *OverflowArgAreaOriginPtr
;
5462 std::tie(OverflowArgAreaShadowPtr
, OverflowArgAreaOriginPtr
) =
5463 MSV
.getShadowOriginPtr(OverflowArgAreaPtr
, IRB
, IRB
.getInt8Ty(),
5464 Alignment
, /*isStore*/ true);
5465 Value
*SrcPtr
= IRB
.CreateConstGEP1_32(IRB
.getInt8Ty(), VAArgTLSCopy
,
5467 IRB
.CreateMemCpy(OverflowArgAreaShadowPtr
, Alignment
, SrcPtr
, Alignment
,
5469 if (MS
.TrackOrigins
) {
5470 SrcPtr
= IRB
.CreateConstGEP1_32(IRB
.getInt8Ty(), VAArgTLSOriginCopy
,
5472 IRB
.CreateMemCpy(OverflowArgAreaOriginPtr
, Alignment
, SrcPtr
, Alignment
,
5479 /// AArch64-specific implementation of VarArgHelper.
5480 struct VarArgAArch64Helper
: public VarArgHelperBase
{
5481 static const unsigned kAArch64GrArgSize
= 64;
5482 static const unsigned kAArch64VrArgSize
= 128;
5484 static const unsigned AArch64GrBegOffset
= 0;
5485 static const unsigned AArch64GrEndOffset
= kAArch64GrArgSize
;
5486 // Make VR space aligned to 16 bytes.
5487 static const unsigned AArch64VrBegOffset
= AArch64GrEndOffset
;
5488 static const unsigned AArch64VrEndOffset
=
5489 AArch64VrBegOffset
+ kAArch64VrArgSize
;
5490 static const unsigned AArch64VAEndOffset
= AArch64VrEndOffset
;
5492 AllocaInst
*VAArgTLSCopy
= nullptr;
5493 Value
*VAArgOverflowSize
= nullptr;
5495 enum ArgKind
{ AK_GeneralPurpose
, AK_FloatingPoint
, AK_Memory
};
5497 VarArgAArch64Helper(Function
&F
, MemorySanitizer
&MS
,
5498 MemorySanitizerVisitor
&MSV
)
5499 : VarArgHelperBase(F
, MS
, MSV
, /*VAListTagSize=*/32) {}
5501 // A very rough approximation of aarch64 argument classification rules.
5502 std::pair
<ArgKind
, uint64_t> classifyArgument(Type
*T
) {
5503 if (T
->isIntOrPtrTy() && T
->getPrimitiveSizeInBits() <= 64)
5504 return {AK_GeneralPurpose
, 1};
5505 if (T
->isFloatingPointTy() && T
->getPrimitiveSizeInBits() <= 128)
5506 return {AK_FloatingPoint
, 1};
5508 if (T
->isArrayTy()) {
5509 auto R
= classifyArgument(T
->getArrayElementType());
5510 R
.second
*= T
->getScalarType()->getArrayNumElements();
5514 if (const FixedVectorType
*FV
= dyn_cast
<FixedVectorType
>(T
)) {
5515 auto R
= classifyArgument(FV
->getScalarType());
5516 R
.second
*= FV
->getNumElements();
5520 LLVM_DEBUG(errs() << "Unknown vararg type: " << *T
<< "\n");
5521 return {AK_Memory
, 0};
5524 // The instrumentation stores the argument shadow in a non ABI-specific
5525 // format because it does not know which argument is named (since Clang,
5526 // like x86_64 case, lowers the va_args in the frontend and this pass only
5527 // sees the low level code that deals with va_list internals).
5528 // The first seven GR registers are saved in the first 56 bytes of the
5529 // va_arg tls arra, followed by the first 8 FP/SIMD registers, and then
5530 // the remaining arguments.
5531 // Using constant offset within the va_arg TLS array allows fast copy
5532 // in the finalize instrumentation.
5533 void visitCallBase(CallBase
&CB
, IRBuilder
<> &IRB
) override
{
5534 unsigned GrOffset
= AArch64GrBegOffset
;
5535 unsigned VrOffset
= AArch64VrBegOffset
;
5536 unsigned OverflowOffset
= AArch64VAEndOffset
;
5538 const DataLayout
&DL
= F
.getDataLayout();
5539 for (const auto &[ArgNo
, A
] : llvm::enumerate(CB
.args())) {
5540 bool IsFixed
= ArgNo
< CB
.getFunctionType()->getNumParams();
5541 auto [AK
, RegNum
] = classifyArgument(A
->getType());
5542 if (AK
== AK_GeneralPurpose
&&
5543 (GrOffset
+ RegNum
* 8) > AArch64GrEndOffset
)
5545 if (AK
== AK_FloatingPoint
&&
5546 (VrOffset
+ RegNum
* 16) > AArch64VrEndOffset
)
5550 case AK_GeneralPurpose
:
5551 Base
= getShadowPtrForVAArgument(IRB
, GrOffset
);
5552 GrOffset
+= 8 * RegNum
;
5554 case AK_FloatingPoint
:
5555 Base
= getShadowPtrForVAArgument(IRB
, VrOffset
);
5556 VrOffset
+= 16 * RegNum
;
5559 // Don't count fixed arguments in the overflow area - va_start will
5560 // skip right over them.
5563 uint64_t ArgSize
= DL
.getTypeAllocSize(A
->getType());
5564 uint64_t AlignedSize
= alignTo(ArgSize
, 8);
5565 unsigned BaseOffset
= OverflowOffset
;
5566 Base
= getShadowPtrForVAArgument(IRB
, BaseOffset
);
5567 OverflowOffset
+= AlignedSize
;
5568 if (OverflowOffset
> kParamTLSSize
) {
5569 // We have no space to copy shadow there.
5570 CleanUnusedTLS(IRB
, Base
, BaseOffset
);
5575 // Count Gp/Vr fixed arguments to their respective offsets, but don't
5576 // bother to actually store a shadow.
5579 IRB
.CreateAlignedStore(MSV
.getShadow(A
), Base
, kShadowTLSAlignment
);
5581 Constant
*OverflowSize
=
5582 ConstantInt::get(IRB
.getInt64Ty(), OverflowOffset
- AArch64VAEndOffset
);
5583 IRB
.CreateStore(OverflowSize
, MS
.VAArgOverflowSizeTLS
);
5586 // Retrieve a va_list field of 'void*' size.
5587 Value
*getVAField64(IRBuilder
<> &IRB
, Value
*VAListTag
, int offset
) {
5588 Value
*SaveAreaPtrPtr
= IRB
.CreateIntToPtr(
5589 IRB
.CreateAdd(IRB
.CreatePtrToInt(VAListTag
, MS
.IntptrTy
),
5590 ConstantInt::get(MS
.IntptrTy
, offset
)),
5592 return IRB
.CreateLoad(Type::getInt64Ty(*MS
.C
), SaveAreaPtrPtr
);
5595 // Retrieve a va_list field of 'int' size.
5596 Value
*getVAField32(IRBuilder
<> &IRB
, Value
*VAListTag
, int offset
) {
5597 Value
*SaveAreaPtr
= IRB
.CreateIntToPtr(
5598 IRB
.CreateAdd(IRB
.CreatePtrToInt(VAListTag
, MS
.IntptrTy
),
5599 ConstantInt::get(MS
.IntptrTy
, offset
)),
5601 Value
*SaveArea32
= IRB
.CreateLoad(IRB
.getInt32Ty(), SaveAreaPtr
);
5602 return IRB
.CreateSExt(SaveArea32
, MS
.IntptrTy
);
5605 void finalizeInstrumentation() override
{
5606 assert(!VAArgOverflowSize
&& !VAArgTLSCopy
&&
5607 "finalizeInstrumentation called twice");
5608 if (!VAStartInstrumentationList
.empty()) {
5609 // If there is a va_start in this function, make a backup copy of
5610 // va_arg_tls somewhere in the function entry block.
5611 IRBuilder
<> IRB(MSV
.FnPrologueEnd
);
5613 IRB
.CreateLoad(IRB
.getInt64Ty(), MS
.VAArgOverflowSizeTLS
);
5614 Value
*CopySize
= IRB
.CreateAdd(
5615 ConstantInt::get(MS
.IntptrTy
, AArch64VAEndOffset
), VAArgOverflowSize
);
5616 VAArgTLSCopy
= IRB
.CreateAlloca(Type::getInt8Ty(*MS
.C
), CopySize
);
5617 VAArgTLSCopy
->setAlignment(kShadowTLSAlignment
);
5618 IRB
.CreateMemSet(VAArgTLSCopy
, Constant::getNullValue(IRB
.getInt8Ty()),
5619 CopySize
, kShadowTLSAlignment
, false);
5621 Value
*SrcSize
= IRB
.CreateBinaryIntrinsic(
5622 Intrinsic::umin
, CopySize
,
5623 ConstantInt::get(MS
.IntptrTy
, kParamTLSSize
));
5624 IRB
.CreateMemCpy(VAArgTLSCopy
, kShadowTLSAlignment
, MS
.VAArgTLS
,
5625 kShadowTLSAlignment
, SrcSize
);
5628 Value
*GrArgSize
= ConstantInt::get(MS
.IntptrTy
, kAArch64GrArgSize
);
5629 Value
*VrArgSize
= ConstantInt::get(MS
.IntptrTy
, kAArch64VrArgSize
);
5631 // Instrument va_start, copy va_list shadow from the backup copy of
5632 // the TLS contents.
5633 for (CallInst
*OrigInst
: VAStartInstrumentationList
) {
5634 NextNodeIRBuilder
IRB(OrigInst
);
5636 Value
*VAListTag
= OrigInst
->getArgOperand(0);
5638 // The variadic ABI for AArch64 creates two areas to save the incoming
5639 // argument registers (one for 64-bit general register xn-x7 and another
5640 // for 128-bit FP/SIMD vn-v7).
5641 // We need then to propagate the shadow arguments on both regions
5642 // 'va::__gr_top + va::__gr_offs' and 'va::__vr_top + va::__vr_offs'.
5643 // The remaining arguments are saved on shadow for 'va::stack'.
5644 // One caveat is it requires only to propagate the non-named arguments,
5645 // however on the call site instrumentation 'all' the arguments are
5646 // saved. So to copy the shadow values from the va_arg TLS array
5647 // we need to adjust the offset for both GR and VR fields based on
5648 // the __{gr,vr}_offs value (since they are stores based on incoming
5649 // named arguments).
5650 Type
*RegSaveAreaPtrTy
= IRB
.getPtrTy();
5652 // Read the stack pointer from the va_list.
5653 Value
*StackSaveAreaPtr
=
5654 IRB
.CreateIntToPtr(getVAField64(IRB
, VAListTag
, 0), RegSaveAreaPtrTy
);
5656 // Read both the __gr_top and __gr_off and add them up.
5657 Value
*GrTopSaveAreaPtr
= getVAField64(IRB
, VAListTag
, 8);
5658 Value
*GrOffSaveArea
= getVAField32(IRB
, VAListTag
, 24);
5660 Value
*GrRegSaveAreaPtr
= IRB
.CreateIntToPtr(
5661 IRB
.CreateAdd(GrTopSaveAreaPtr
, GrOffSaveArea
), RegSaveAreaPtrTy
);
5663 // Read both the __vr_top and __vr_off and add them up.
5664 Value
*VrTopSaveAreaPtr
= getVAField64(IRB
, VAListTag
, 16);
5665 Value
*VrOffSaveArea
= getVAField32(IRB
, VAListTag
, 28);
5667 Value
*VrRegSaveAreaPtr
= IRB
.CreateIntToPtr(
5668 IRB
.CreateAdd(VrTopSaveAreaPtr
, VrOffSaveArea
), RegSaveAreaPtrTy
);
5670 // It does not know how many named arguments is being used and, on the
5671 // callsite all the arguments were saved. Since __gr_off is defined as
5672 // '0 - ((8 - named_gr) * 8)', the idea is to just propagate the variadic
5673 // argument by ignoring the bytes of shadow from named arguments.
5674 Value
*GrRegSaveAreaShadowPtrOff
=
5675 IRB
.CreateAdd(GrArgSize
, GrOffSaveArea
);
5677 Value
*GrRegSaveAreaShadowPtr
=
5678 MSV
.getShadowOriginPtr(GrRegSaveAreaPtr
, IRB
, IRB
.getInt8Ty(),
5679 Align(8), /*isStore*/ true)
5683 IRB
.CreateInBoundsPtrAdd(VAArgTLSCopy
, GrRegSaveAreaShadowPtrOff
);
5684 Value
*GrCopySize
= IRB
.CreateSub(GrArgSize
, GrRegSaveAreaShadowPtrOff
);
5686 IRB
.CreateMemCpy(GrRegSaveAreaShadowPtr
, Align(8), GrSrcPtr
, Align(8),
5689 // Again, but for FP/SIMD values.
5690 Value
*VrRegSaveAreaShadowPtrOff
=
5691 IRB
.CreateAdd(VrArgSize
, VrOffSaveArea
);
5693 Value
*VrRegSaveAreaShadowPtr
=
5694 MSV
.getShadowOriginPtr(VrRegSaveAreaPtr
, IRB
, IRB
.getInt8Ty(),
5695 Align(8), /*isStore*/ true)
5698 Value
*VrSrcPtr
= IRB
.CreateInBoundsPtrAdd(
5699 IRB
.CreateInBoundsPtrAdd(VAArgTLSCopy
,
5700 IRB
.getInt32(AArch64VrBegOffset
)),
5701 VrRegSaveAreaShadowPtrOff
);
5702 Value
*VrCopySize
= IRB
.CreateSub(VrArgSize
, VrRegSaveAreaShadowPtrOff
);
5704 IRB
.CreateMemCpy(VrRegSaveAreaShadowPtr
, Align(8), VrSrcPtr
, Align(8),
5707 // And finally for remaining arguments.
5708 Value
*StackSaveAreaShadowPtr
=
5709 MSV
.getShadowOriginPtr(StackSaveAreaPtr
, IRB
, IRB
.getInt8Ty(),
5710 Align(16), /*isStore*/ true)
5713 Value
*StackSrcPtr
= IRB
.CreateInBoundsPtrAdd(
5714 VAArgTLSCopy
, IRB
.getInt32(AArch64VAEndOffset
));
5716 IRB
.CreateMemCpy(StackSaveAreaShadowPtr
, Align(16), StackSrcPtr
,
5717 Align(16), VAArgOverflowSize
);
5722 /// PowerPC-specific implementation of VarArgHelper.
5723 struct VarArgPowerPCHelper
: public VarArgHelperBase
{
5724 AllocaInst
*VAArgTLSCopy
= nullptr;
5725 Value
*VAArgSize
= nullptr;
5727 VarArgPowerPCHelper(Function
&F
, MemorySanitizer
&MS
,
5728 MemorySanitizerVisitor
&MSV
, unsigned VAListTagSize
)
5729 : VarArgHelperBase(F
, MS
, MSV
, VAListTagSize
) {}
5731 void visitCallBase(CallBase
&CB
, IRBuilder
<> &IRB
) override
{
5732 // For PowerPC, we need to deal with alignment of stack arguments -
5733 // they are mostly aligned to 8 bytes, but vectors and i128 arrays
5734 // are aligned to 16 bytes, byvals can be aligned to 8 or 16 bytes,
5735 // For that reason, we compute current offset from stack pointer (which is
5736 // always properly aligned), and offset for the first vararg, then subtract
5739 Triple
TargetTriple(F
.getParent()->getTargetTriple());
5740 // Parameter save area starts at 48 bytes from frame pointer for ABIv1,
5741 // and 32 bytes for ABIv2. This is usually determined by target
5742 // endianness, but in theory could be overridden by function attribute.
5743 if (TargetTriple
.isPPC64()) {
5744 if (TargetTriple
.isPPC64ELFv2ABI())
5749 // Parameter save area is 8 bytes from frame pointer in PPC32
5752 unsigned VAArgOffset
= VAArgBase
;
5753 const DataLayout
&DL
= F
.getDataLayout();
5754 for (const auto &[ArgNo
, A
] : llvm::enumerate(CB
.args())) {
5755 bool IsFixed
= ArgNo
< CB
.getFunctionType()->getNumParams();
5756 bool IsByVal
= CB
.paramHasAttr(ArgNo
, Attribute::ByVal
);
5758 assert(A
->getType()->isPointerTy());
5759 Type
*RealTy
= CB
.getParamByValType(ArgNo
);
5760 uint64_t ArgSize
= DL
.getTypeAllocSize(RealTy
);
5761 Align ArgAlign
= CB
.getParamAlign(ArgNo
).value_or(Align(8));
5763 ArgAlign
= Align(8);
5764 VAArgOffset
= alignTo(VAArgOffset
, ArgAlign
);
5767 getShadowPtrForVAArgument(IRB
, VAArgOffset
- VAArgBase
, ArgSize
);
5769 Value
*AShadowPtr
, *AOriginPtr
;
5770 std::tie(AShadowPtr
, AOriginPtr
) =
5771 MSV
.getShadowOriginPtr(A
, IRB
, IRB
.getInt8Ty(),
5772 kShadowTLSAlignment
, /*isStore*/ false);
5774 IRB
.CreateMemCpy(Base
, kShadowTLSAlignment
, AShadowPtr
,
5775 kShadowTLSAlignment
, ArgSize
);
5778 VAArgOffset
+= alignTo(ArgSize
, Align(8));
5781 uint64_t ArgSize
= DL
.getTypeAllocSize(A
->getType());
5782 Align ArgAlign
= Align(8);
5783 if (A
->getType()->isArrayTy()) {
5784 // Arrays are aligned to element size, except for long double
5785 // arrays, which are aligned to 8 bytes.
5786 Type
*ElementTy
= A
->getType()->getArrayElementType();
5787 if (!ElementTy
->isPPC_FP128Ty())
5788 ArgAlign
= Align(DL
.getTypeAllocSize(ElementTy
));
5789 } else if (A
->getType()->isVectorTy()) {
5790 // Vectors are naturally aligned.
5791 ArgAlign
= Align(ArgSize
);
5794 ArgAlign
= Align(8);
5795 VAArgOffset
= alignTo(VAArgOffset
, ArgAlign
);
5796 if (DL
.isBigEndian()) {
5797 // Adjusting the shadow for argument with size < 8 to match the
5798 // placement of bits in big endian system
5800 VAArgOffset
+= (8 - ArgSize
);
5804 getShadowPtrForVAArgument(IRB
, VAArgOffset
- VAArgBase
, ArgSize
);
5806 IRB
.CreateAlignedStore(MSV
.getShadow(A
), Base
, kShadowTLSAlignment
);
5808 VAArgOffset
+= ArgSize
;
5809 VAArgOffset
= alignTo(VAArgOffset
, Align(8));
5812 VAArgBase
= VAArgOffset
;
5815 Constant
*TotalVAArgSize
=
5816 ConstantInt::get(MS
.IntptrTy
, VAArgOffset
- VAArgBase
);
5817 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
5818 // a new class member i.e. it is the total size of all VarArgs.
5819 IRB
.CreateStore(TotalVAArgSize
, MS
.VAArgOverflowSizeTLS
);
5822 void finalizeInstrumentation() override
{
5823 assert(!VAArgSize
&& !VAArgTLSCopy
&&
5824 "finalizeInstrumentation called twice");
5825 IRBuilder
<> IRB(MSV
.FnPrologueEnd
);
5826 VAArgSize
= IRB
.CreateLoad(IRB
.getInt64Ty(), MS
.VAArgOverflowSizeTLS
);
5827 Value
*CopySize
= VAArgSize
;
5829 if (!VAStartInstrumentationList
.empty()) {
5830 // If there is a va_start in this function, make a backup copy of
5831 // va_arg_tls somewhere in the function entry block.
5833 VAArgTLSCopy
= IRB
.CreateAlloca(Type::getInt8Ty(*MS
.C
), CopySize
);
5834 VAArgTLSCopy
->setAlignment(kShadowTLSAlignment
);
5835 IRB
.CreateMemSet(VAArgTLSCopy
, Constant::getNullValue(IRB
.getInt8Ty()),
5836 CopySize
, kShadowTLSAlignment
, false);
5838 Value
*SrcSize
= IRB
.CreateBinaryIntrinsic(
5839 Intrinsic::umin
, CopySize
,
5840 ConstantInt::get(IRB
.getInt64Ty(), kParamTLSSize
));
5841 IRB
.CreateMemCpy(VAArgTLSCopy
, kShadowTLSAlignment
, MS
.VAArgTLS
,
5842 kShadowTLSAlignment
, SrcSize
);
5845 // Instrument va_start.
5846 // Copy va_list shadow from the backup copy of the TLS contents.
5847 Triple
TargetTriple(F
.getParent()->getTargetTriple());
5848 for (CallInst
*OrigInst
: VAStartInstrumentationList
) {
5849 NextNodeIRBuilder
IRB(OrigInst
);
5850 Value
*VAListTag
= OrigInst
->getArgOperand(0);
5851 Value
*RegSaveAreaPtrPtr
= IRB
.CreatePtrToInt(VAListTag
, MS
.IntptrTy
);
5853 // In PPC32 va_list_tag is a struct, whereas in PPC64 it's a pointer
5854 if (!TargetTriple
.isPPC64()) {
5856 IRB
.CreateAdd(RegSaveAreaPtrPtr
, ConstantInt::get(MS
.IntptrTy
, 8));
5858 RegSaveAreaPtrPtr
= IRB
.CreateIntToPtr(RegSaveAreaPtrPtr
, MS
.PtrTy
);
5860 Value
*RegSaveAreaPtr
= IRB
.CreateLoad(MS
.PtrTy
, RegSaveAreaPtrPtr
);
5861 Value
*RegSaveAreaShadowPtr
, *RegSaveAreaOriginPtr
;
5862 const DataLayout
&DL
= F
.getDataLayout();
5863 unsigned IntptrSize
= DL
.getTypeStoreSize(MS
.IntptrTy
);
5864 const Align Alignment
= Align(IntptrSize
);
5865 std::tie(RegSaveAreaShadowPtr
, RegSaveAreaOriginPtr
) =
5866 MSV
.getShadowOriginPtr(RegSaveAreaPtr
, IRB
, IRB
.getInt8Ty(),
5867 Alignment
, /*isStore*/ true);
5868 IRB
.CreateMemCpy(RegSaveAreaShadowPtr
, Alignment
, VAArgTLSCopy
, Alignment
,
5874 /// SystemZ-specific implementation of VarArgHelper.
5875 struct VarArgSystemZHelper
: public VarArgHelperBase
{
5876 static const unsigned SystemZGpOffset
= 16;
5877 static const unsigned SystemZGpEndOffset
= 56;
5878 static const unsigned SystemZFpOffset
= 128;
5879 static const unsigned SystemZFpEndOffset
= 160;
5880 static const unsigned SystemZMaxVrArgs
= 8;
5881 static const unsigned SystemZRegSaveAreaSize
= 160;
5882 static const unsigned SystemZOverflowOffset
= 160;
5883 static const unsigned SystemZVAListTagSize
= 32;
5884 static const unsigned SystemZOverflowArgAreaPtrOffset
= 16;
5885 static const unsigned SystemZRegSaveAreaPtrOffset
= 24;
5887 bool IsSoftFloatABI
;
5888 AllocaInst
*VAArgTLSCopy
= nullptr;
5889 AllocaInst
*VAArgTLSOriginCopy
= nullptr;
5890 Value
*VAArgOverflowSize
= nullptr;
5892 enum class ArgKind
{
5900 enum class ShadowExtension
{ None
, Zero
, Sign
};
5902 VarArgSystemZHelper(Function
&F
, MemorySanitizer
&MS
,
5903 MemorySanitizerVisitor
&MSV
)
5904 : VarArgHelperBase(F
, MS
, MSV
, SystemZVAListTagSize
),
5905 IsSoftFloatABI(F
.getFnAttribute("use-soft-float").getValueAsBool()) {}
5907 ArgKind
classifyArgument(Type
*T
) {
5908 // T is a SystemZABIInfo::classifyArgumentType() output, and there are
5909 // only a few possibilities of what it can be. In particular, enums, single
5910 // element structs and large types have already been taken care of.
5912 // Some i128 and fp128 arguments are converted to pointers only in the
5914 if (T
->isIntegerTy(128) || T
->isFP128Ty())
5915 return ArgKind::Indirect
;
5916 if (T
->isFloatingPointTy())
5917 return IsSoftFloatABI
? ArgKind::GeneralPurpose
: ArgKind::FloatingPoint
;
5918 if (T
->isIntegerTy() || T
->isPointerTy())
5919 return ArgKind::GeneralPurpose
;
5920 if (T
->isVectorTy())
5921 return ArgKind::Vector
;
5922 return ArgKind::Memory
;
5925 ShadowExtension
getShadowExtension(const CallBase
&CB
, unsigned ArgNo
) {
5926 // ABI says: "One of the simple integer types no more than 64 bits wide.
5927 // ... If such an argument is shorter than 64 bits, replace it by a full
5928 // 64-bit integer representing the same number, using sign or zero
5929 // extension". Shadow for an integer argument has the same type as the
5930 // argument itself, so it can be sign or zero extended as well.
5931 bool ZExt
= CB
.paramHasAttr(ArgNo
, Attribute::ZExt
);
5932 bool SExt
= CB
.paramHasAttr(ArgNo
, Attribute::SExt
);
5935 return ShadowExtension::Zero
;
5939 return ShadowExtension::Sign
;
5941 return ShadowExtension::None
;
5944 void visitCallBase(CallBase
&CB
, IRBuilder
<> &IRB
) override
{
5945 unsigned GpOffset
= SystemZGpOffset
;
5946 unsigned FpOffset
= SystemZFpOffset
;
5947 unsigned VrIndex
= 0;
5948 unsigned OverflowOffset
= SystemZOverflowOffset
;
5949 const DataLayout
&DL
= F
.getDataLayout();
5950 for (const auto &[ArgNo
, A
] : llvm::enumerate(CB
.args())) {
5951 bool IsFixed
= ArgNo
< CB
.getFunctionType()->getNumParams();
5952 // SystemZABIInfo does not produce ByVal parameters.
5953 assert(!CB
.paramHasAttr(ArgNo
, Attribute::ByVal
));
5954 Type
*T
= A
->getType();
5955 ArgKind AK
= classifyArgument(T
);
5956 if (AK
== ArgKind::Indirect
) {
5958 AK
= ArgKind::GeneralPurpose
;
5960 if (AK
== ArgKind::GeneralPurpose
&& GpOffset
>= SystemZGpEndOffset
)
5961 AK
= ArgKind::Memory
;
5962 if (AK
== ArgKind::FloatingPoint
&& FpOffset
>= SystemZFpEndOffset
)
5963 AK
= ArgKind::Memory
;
5964 if (AK
== ArgKind::Vector
&& (VrIndex
>= SystemZMaxVrArgs
|| !IsFixed
))
5965 AK
= ArgKind::Memory
;
5966 Value
*ShadowBase
= nullptr;
5967 Value
*OriginBase
= nullptr;
5968 ShadowExtension SE
= ShadowExtension::None
;
5970 case ArgKind::GeneralPurpose
: {
5971 // Always keep track of GpOffset, but store shadow only for varargs.
5972 uint64_t ArgSize
= 8;
5973 if (GpOffset
+ ArgSize
<= kParamTLSSize
) {
5975 SE
= getShadowExtension(CB
, ArgNo
);
5976 uint64_t GapSize
= 0;
5977 if (SE
== ShadowExtension::None
) {
5978 uint64_t ArgAllocSize
= DL
.getTypeAllocSize(T
);
5979 assert(ArgAllocSize
<= ArgSize
);
5980 GapSize
= ArgSize
- ArgAllocSize
;
5982 ShadowBase
= getShadowAddrForVAArgument(IRB
, GpOffset
+ GapSize
);
5983 if (MS
.TrackOrigins
)
5984 OriginBase
= getOriginPtrForVAArgument(IRB
, GpOffset
+ GapSize
);
5986 GpOffset
+= ArgSize
;
5988 GpOffset
= kParamTLSSize
;
5992 case ArgKind::FloatingPoint
: {
5993 // Always keep track of FpOffset, but store shadow only for varargs.
5994 uint64_t ArgSize
= 8;
5995 if (FpOffset
+ ArgSize
<= kParamTLSSize
) {
5997 // PoP says: "A short floating-point datum requires only the
5998 // left-most 32 bit positions of a floating-point register".
5999 // Therefore, in contrast to AK_GeneralPurpose and AK_Memory,
6000 // don't extend shadow and don't mind the gap.
6001 ShadowBase
= getShadowAddrForVAArgument(IRB
, FpOffset
);
6002 if (MS
.TrackOrigins
)
6003 OriginBase
= getOriginPtrForVAArgument(IRB
, FpOffset
);
6005 FpOffset
+= ArgSize
;
6007 FpOffset
= kParamTLSSize
;
6011 case ArgKind::Vector
: {
6012 // Keep track of VrIndex. No need to store shadow, since vector varargs
6013 // go through AK_Memory.
6018 case ArgKind::Memory
: {
6019 // Keep track of OverflowOffset and store shadow only for varargs.
6020 // Ignore fixed args, since we need to copy only the vararg portion of
6021 // the overflow area shadow.
6023 uint64_t ArgAllocSize
= DL
.getTypeAllocSize(T
);
6024 uint64_t ArgSize
= alignTo(ArgAllocSize
, 8);
6025 if (OverflowOffset
+ ArgSize
<= kParamTLSSize
) {
6026 SE
= getShadowExtension(CB
, ArgNo
);
6028 SE
== ShadowExtension::None
? ArgSize
- ArgAllocSize
: 0;
6030 getShadowAddrForVAArgument(IRB
, OverflowOffset
+ GapSize
);
6031 if (MS
.TrackOrigins
)
6033 getOriginPtrForVAArgument(IRB
, OverflowOffset
+ GapSize
);
6034 OverflowOffset
+= ArgSize
;
6036 OverflowOffset
= kParamTLSSize
;
6041 case ArgKind::Indirect
:
6042 llvm_unreachable("Indirect must be converted to GeneralPurpose");
6044 if (ShadowBase
== nullptr)
6046 Value
*Shadow
= MSV
.getShadow(A
);
6047 if (SE
!= ShadowExtension::None
)
6048 Shadow
= MSV
.CreateShadowCast(IRB
, Shadow
, IRB
.getInt64Ty(),
6049 /*Signed*/ SE
== ShadowExtension::Sign
);
6050 ShadowBase
= IRB
.CreateIntToPtr(ShadowBase
, MS
.PtrTy
, "_msarg_va_s");
6051 IRB
.CreateStore(Shadow
, ShadowBase
);
6052 if (MS
.TrackOrigins
) {
6053 Value
*Origin
= MSV
.getOrigin(A
);
6054 TypeSize StoreSize
= DL
.getTypeStoreSize(Shadow
->getType());
6055 MSV
.paintOrigin(IRB
, Origin
, OriginBase
, StoreSize
,
6056 kMinOriginAlignment
);
6059 Constant
*OverflowSize
= ConstantInt::get(
6060 IRB
.getInt64Ty(), OverflowOffset
- SystemZOverflowOffset
);
6061 IRB
.CreateStore(OverflowSize
, MS
.VAArgOverflowSizeTLS
);
6064 void copyRegSaveArea(IRBuilder
<> &IRB
, Value
*VAListTag
) {
6065 Value
*RegSaveAreaPtrPtr
= IRB
.CreateIntToPtr(
6067 IRB
.CreatePtrToInt(VAListTag
, MS
.IntptrTy
),
6068 ConstantInt::get(MS
.IntptrTy
, SystemZRegSaveAreaPtrOffset
)),
6070 Value
*RegSaveAreaPtr
= IRB
.CreateLoad(MS
.PtrTy
, RegSaveAreaPtrPtr
);
6071 Value
*RegSaveAreaShadowPtr
, *RegSaveAreaOriginPtr
;
6072 const Align Alignment
= Align(8);
6073 std::tie(RegSaveAreaShadowPtr
, RegSaveAreaOriginPtr
) =
6074 MSV
.getShadowOriginPtr(RegSaveAreaPtr
, IRB
, IRB
.getInt8Ty(), Alignment
,
6076 // TODO(iii): copy only fragments filled by visitCallBase()
6077 // TODO(iii): support packed-stack && !use-soft-float
6078 // For use-soft-float functions, it is enough to copy just the GPRs.
6079 unsigned RegSaveAreaSize
=
6080 IsSoftFloatABI
? SystemZGpEndOffset
: SystemZRegSaveAreaSize
;
6081 IRB
.CreateMemCpy(RegSaveAreaShadowPtr
, Alignment
, VAArgTLSCopy
, Alignment
,
6083 if (MS
.TrackOrigins
)
6084 IRB
.CreateMemCpy(RegSaveAreaOriginPtr
, Alignment
, VAArgTLSOriginCopy
,
6085 Alignment
, RegSaveAreaSize
);
6088 // FIXME: This implementation limits OverflowOffset to kParamTLSSize, so we
6089 // don't know real overflow size and can't clear shadow beyond kParamTLSSize.
6090 void copyOverflowArea(IRBuilder
<> &IRB
, Value
*VAListTag
) {
6091 Value
*OverflowArgAreaPtrPtr
= IRB
.CreateIntToPtr(
6093 IRB
.CreatePtrToInt(VAListTag
, MS
.IntptrTy
),
6094 ConstantInt::get(MS
.IntptrTy
, SystemZOverflowArgAreaPtrOffset
)),
6096 Value
*OverflowArgAreaPtr
= IRB
.CreateLoad(MS
.PtrTy
, OverflowArgAreaPtrPtr
);
6097 Value
*OverflowArgAreaShadowPtr
, *OverflowArgAreaOriginPtr
;
6098 const Align Alignment
= Align(8);
6099 std::tie(OverflowArgAreaShadowPtr
, OverflowArgAreaOriginPtr
) =
6100 MSV
.getShadowOriginPtr(OverflowArgAreaPtr
, IRB
, IRB
.getInt8Ty(),
6101 Alignment
, /*isStore*/ true);
6102 Value
*SrcPtr
= IRB
.CreateConstGEP1_32(IRB
.getInt8Ty(), VAArgTLSCopy
,
6103 SystemZOverflowOffset
);
6104 IRB
.CreateMemCpy(OverflowArgAreaShadowPtr
, Alignment
, SrcPtr
, Alignment
,
6106 if (MS
.TrackOrigins
) {
6107 SrcPtr
= IRB
.CreateConstGEP1_32(IRB
.getInt8Ty(), VAArgTLSOriginCopy
,
6108 SystemZOverflowOffset
);
6109 IRB
.CreateMemCpy(OverflowArgAreaOriginPtr
, Alignment
, SrcPtr
, Alignment
,
6114 void finalizeInstrumentation() override
{
6115 assert(!VAArgOverflowSize
&& !VAArgTLSCopy
&&
6116 "finalizeInstrumentation called twice");
6117 if (!VAStartInstrumentationList
.empty()) {
6118 // If there is a va_start in this function, make a backup copy of
6119 // va_arg_tls somewhere in the function entry block.
6120 IRBuilder
<> IRB(MSV
.FnPrologueEnd
);
6122 IRB
.CreateLoad(IRB
.getInt64Ty(), MS
.VAArgOverflowSizeTLS
);
6124 IRB
.CreateAdd(ConstantInt::get(MS
.IntptrTy
, SystemZOverflowOffset
),
6126 VAArgTLSCopy
= IRB
.CreateAlloca(Type::getInt8Ty(*MS
.C
), CopySize
);
6127 VAArgTLSCopy
->setAlignment(kShadowTLSAlignment
);
6128 IRB
.CreateMemSet(VAArgTLSCopy
, Constant::getNullValue(IRB
.getInt8Ty()),
6129 CopySize
, kShadowTLSAlignment
, false);
6131 Value
*SrcSize
= IRB
.CreateBinaryIntrinsic(
6132 Intrinsic::umin
, CopySize
,
6133 ConstantInt::get(MS
.IntptrTy
, kParamTLSSize
));
6134 IRB
.CreateMemCpy(VAArgTLSCopy
, kShadowTLSAlignment
, MS
.VAArgTLS
,
6135 kShadowTLSAlignment
, SrcSize
);
6136 if (MS
.TrackOrigins
) {
6137 VAArgTLSOriginCopy
= IRB
.CreateAlloca(Type::getInt8Ty(*MS
.C
), CopySize
);
6138 VAArgTLSOriginCopy
->setAlignment(kShadowTLSAlignment
);
6139 IRB
.CreateMemCpy(VAArgTLSOriginCopy
, kShadowTLSAlignment
,
6140 MS
.VAArgOriginTLS
, kShadowTLSAlignment
, SrcSize
);
6144 // Instrument va_start.
6145 // Copy va_list shadow from the backup copy of the TLS contents.
6146 for (CallInst
*OrigInst
: VAStartInstrumentationList
) {
6147 NextNodeIRBuilder
IRB(OrigInst
);
6148 Value
*VAListTag
= OrigInst
->getArgOperand(0);
6149 copyRegSaveArea(IRB
, VAListTag
);
6150 copyOverflowArea(IRB
, VAListTag
);
6155 /// i386-specific implementation of VarArgHelper.
6156 struct VarArgI386Helper
: public VarArgHelperBase
{
6157 AllocaInst
*VAArgTLSCopy
= nullptr;
6158 Value
*VAArgSize
= nullptr;
6160 VarArgI386Helper(Function
&F
, MemorySanitizer
&MS
,
6161 MemorySanitizerVisitor
&MSV
)
6162 : VarArgHelperBase(F
, MS
, MSV
, /*VAListTagSize=*/4) {}
6164 void visitCallBase(CallBase
&CB
, IRBuilder
<> &IRB
) override
{
6165 const DataLayout
&DL
= F
.getDataLayout();
6166 unsigned IntptrSize
= DL
.getTypeStoreSize(MS
.IntptrTy
);
6167 unsigned VAArgOffset
= 0;
6168 for (const auto &[ArgNo
, A
] : llvm::enumerate(CB
.args())) {
6169 bool IsFixed
= ArgNo
< CB
.getFunctionType()->getNumParams();
6170 bool IsByVal
= CB
.paramHasAttr(ArgNo
, Attribute::ByVal
);
6172 assert(A
->getType()->isPointerTy());
6173 Type
*RealTy
= CB
.getParamByValType(ArgNo
);
6174 uint64_t ArgSize
= DL
.getTypeAllocSize(RealTy
);
6175 Align ArgAlign
= CB
.getParamAlign(ArgNo
).value_or(Align(IntptrSize
));
6176 if (ArgAlign
< IntptrSize
)
6177 ArgAlign
= Align(IntptrSize
);
6178 VAArgOffset
= alignTo(VAArgOffset
, ArgAlign
);
6180 Value
*Base
= getShadowPtrForVAArgument(IRB
, VAArgOffset
, ArgSize
);
6182 Value
*AShadowPtr
, *AOriginPtr
;
6183 std::tie(AShadowPtr
, AOriginPtr
) =
6184 MSV
.getShadowOriginPtr(A
, IRB
, IRB
.getInt8Ty(),
6185 kShadowTLSAlignment
, /*isStore*/ false);
6187 IRB
.CreateMemCpy(Base
, kShadowTLSAlignment
, AShadowPtr
,
6188 kShadowTLSAlignment
, ArgSize
);
6190 VAArgOffset
+= alignTo(ArgSize
, Align(IntptrSize
));
6194 uint64_t ArgSize
= DL
.getTypeAllocSize(A
->getType());
6195 Align ArgAlign
= Align(IntptrSize
);
6196 VAArgOffset
= alignTo(VAArgOffset
, ArgAlign
);
6197 if (DL
.isBigEndian()) {
6198 // Adjusting the shadow for argument with size < IntptrSize to match
6199 // the placement of bits in big endian system
6200 if (ArgSize
< IntptrSize
)
6201 VAArgOffset
+= (IntptrSize
- ArgSize
);
6204 Base
= getShadowPtrForVAArgument(IRB
, VAArgOffset
, ArgSize
);
6206 IRB
.CreateAlignedStore(MSV
.getShadow(A
), Base
, kShadowTLSAlignment
);
6207 VAArgOffset
+= ArgSize
;
6208 VAArgOffset
= alignTo(VAArgOffset
, Align(IntptrSize
));
6213 Constant
*TotalVAArgSize
= ConstantInt::get(MS
.IntptrTy
, VAArgOffset
);
6214 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
6215 // a new class member i.e. it is the total size of all VarArgs.
6216 IRB
.CreateStore(TotalVAArgSize
, MS
.VAArgOverflowSizeTLS
);
6219 void finalizeInstrumentation() override
{
6220 assert(!VAArgSize
&& !VAArgTLSCopy
&&
6221 "finalizeInstrumentation called twice");
6222 IRBuilder
<> IRB(MSV
.FnPrologueEnd
);
6223 VAArgSize
= IRB
.CreateLoad(IRB
.getInt64Ty(), MS
.VAArgOverflowSizeTLS
);
6224 Value
*CopySize
= VAArgSize
;
6226 if (!VAStartInstrumentationList
.empty()) {
6227 // If there is a va_start in this function, make a backup copy of
6228 // va_arg_tls somewhere in the function entry block.
6229 VAArgTLSCopy
= IRB
.CreateAlloca(Type::getInt8Ty(*MS
.C
), CopySize
);
6230 VAArgTLSCopy
->setAlignment(kShadowTLSAlignment
);
6231 IRB
.CreateMemSet(VAArgTLSCopy
, Constant::getNullValue(IRB
.getInt8Ty()),
6232 CopySize
, kShadowTLSAlignment
, false);
6234 Value
*SrcSize
= IRB
.CreateBinaryIntrinsic(
6235 Intrinsic::umin
, CopySize
,
6236 ConstantInt::get(IRB
.getInt64Ty(), kParamTLSSize
));
6237 IRB
.CreateMemCpy(VAArgTLSCopy
, kShadowTLSAlignment
, MS
.VAArgTLS
,
6238 kShadowTLSAlignment
, SrcSize
);
6241 // Instrument va_start.
6242 // Copy va_list shadow from the backup copy of the TLS contents.
6243 for (CallInst
*OrigInst
: VAStartInstrumentationList
) {
6244 NextNodeIRBuilder
IRB(OrigInst
);
6245 Value
*VAListTag
= OrigInst
->getArgOperand(0);
6246 Type
*RegSaveAreaPtrTy
= PointerType::getUnqual(*MS
.C
);
6247 Value
*RegSaveAreaPtrPtr
=
6248 IRB
.CreateIntToPtr(IRB
.CreatePtrToInt(VAListTag
, MS
.IntptrTy
),
6249 PointerType::get(*MS
.C
, 0));
6250 Value
*RegSaveAreaPtr
=
6251 IRB
.CreateLoad(RegSaveAreaPtrTy
, RegSaveAreaPtrPtr
);
6252 Value
*RegSaveAreaShadowPtr
, *RegSaveAreaOriginPtr
;
6253 const DataLayout
&DL
= F
.getDataLayout();
6254 unsigned IntptrSize
= DL
.getTypeStoreSize(MS
.IntptrTy
);
6255 const Align Alignment
= Align(IntptrSize
);
6256 std::tie(RegSaveAreaShadowPtr
, RegSaveAreaOriginPtr
) =
6257 MSV
.getShadowOriginPtr(RegSaveAreaPtr
, IRB
, IRB
.getInt8Ty(),
6258 Alignment
, /*isStore*/ true);
6259 IRB
.CreateMemCpy(RegSaveAreaShadowPtr
, Alignment
, VAArgTLSCopy
, Alignment
,
6265 /// Implementation of VarArgHelper that is used for ARM32, MIPS, RISCV,
6267 struct VarArgGenericHelper
: public VarArgHelperBase
{
6268 AllocaInst
*VAArgTLSCopy
= nullptr;
6269 Value
*VAArgSize
= nullptr;
6271 VarArgGenericHelper(Function
&F
, MemorySanitizer
&MS
,
6272 MemorySanitizerVisitor
&MSV
, const unsigned VAListTagSize
)
6273 : VarArgHelperBase(F
, MS
, MSV
, VAListTagSize
) {}
6275 void visitCallBase(CallBase
&CB
, IRBuilder
<> &IRB
) override
{
6276 unsigned VAArgOffset
= 0;
6277 const DataLayout
&DL
= F
.getDataLayout();
6278 unsigned IntptrSize
= DL
.getTypeStoreSize(MS
.IntptrTy
);
6279 for (const auto &[ArgNo
, A
] : llvm::enumerate(CB
.args())) {
6280 bool IsFixed
= ArgNo
< CB
.getFunctionType()->getNumParams();
6283 uint64_t ArgSize
= DL
.getTypeAllocSize(A
->getType());
6284 if (DL
.isBigEndian()) {
6285 // Adjusting the shadow for argument with size < IntptrSize to match the
6286 // placement of bits in big endian system
6287 if (ArgSize
< IntptrSize
)
6288 VAArgOffset
+= (IntptrSize
- ArgSize
);
6290 Value
*Base
= getShadowPtrForVAArgument(IRB
, VAArgOffset
, ArgSize
);
6291 VAArgOffset
+= ArgSize
;
6292 VAArgOffset
= alignTo(VAArgOffset
, IntptrSize
);
6295 IRB
.CreateAlignedStore(MSV
.getShadow(A
), Base
, kShadowTLSAlignment
);
6298 Constant
*TotalVAArgSize
= ConstantInt::get(MS
.IntptrTy
, VAArgOffset
);
6299 // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
6300 // a new class member i.e. it is the total size of all VarArgs.
6301 IRB
.CreateStore(TotalVAArgSize
, MS
.VAArgOverflowSizeTLS
);
6304 void finalizeInstrumentation() override
{
6305 assert(!VAArgSize
&& !VAArgTLSCopy
&&
6306 "finalizeInstrumentation called twice");
6307 IRBuilder
<> IRB(MSV
.FnPrologueEnd
);
6308 VAArgSize
= IRB
.CreateLoad(IRB
.getInt64Ty(), MS
.VAArgOverflowSizeTLS
);
6309 Value
*CopySize
= VAArgSize
;
6311 if (!VAStartInstrumentationList
.empty()) {
6312 // If there is a va_start in this function, make a backup copy of
6313 // va_arg_tls somewhere in the function entry block.
6314 VAArgTLSCopy
= IRB
.CreateAlloca(Type::getInt8Ty(*MS
.C
), CopySize
);
6315 VAArgTLSCopy
->setAlignment(kShadowTLSAlignment
);
6316 IRB
.CreateMemSet(VAArgTLSCopy
, Constant::getNullValue(IRB
.getInt8Ty()),
6317 CopySize
, kShadowTLSAlignment
, false);
6319 Value
*SrcSize
= IRB
.CreateBinaryIntrinsic(
6320 Intrinsic::umin
, CopySize
,
6321 ConstantInt::get(IRB
.getInt64Ty(), kParamTLSSize
));
6322 IRB
.CreateMemCpy(VAArgTLSCopy
, kShadowTLSAlignment
, MS
.VAArgTLS
,
6323 kShadowTLSAlignment
, SrcSize
);
6326 // Instrument va_start.
6327 // Copy va_list shadow from the backup copy of the TLS contents.
6328 for (CallInst
*OrigInst
: VAStartInstrumentationList
) {
6329 NextNodeIRBuilder
IRB(OrigInst
);
6330 Value
*VAListTag
= OrigInst
->getArgOperand(0);
6331 Type
*RegSaveAreaPtrTy
= PointerType::getUnqual(*MS
.C
);
6332 Value
*RegSaveAreaPtrPtr
=
6333 IRB
.CreateIntToPtr(IRB
.CreatePtrToInt(VAListTag
, MS
.IntptrTy
),
6334 PointerType::get(*MS
.C
, 0));
6335 Value
*RegSaveAreaPtr
=
6336 IRB
.CreateLoad(RegSaveAreaPtrTy
, RegSaveAreaPtrPtr
);
6337 Value
*RegSaveAreaShadowPtr
, *RegSaveAreaOriginPtr
;
6338 const DataLayout
&DL
= F
.getDataLayout();
6339 unsigned IntptrSize
= DL
.getTypeStoreSize(MS
.IntptrTy
);
6340 const Align Alignment
= Align(IntptrSize
);
6341 std::tie(RegSaveAreaShadowPtr
, RegSaveAreaOriginPtr
) =
6342 MSV
.getShadowOriginPtr(RegSaveAreaPtr
, IRB
, IRB
.getInt8Ty(),
6343 Alignment
, /*isStore*/ true);
6344 IRB
.CreateMemCpy(RegSaveAreaShadowPtr
, Alignment
, VAArgTLSCopy
, Alignment
,
6350 // ARM32, Loongarch64, MIPS and RISCV share the same calling conventions
6351 // regarding VAArgs.
6352 using VarArgARM32Helper
= VarArgGenericHelper
;
6353 using VarArgRISCVHelper
= VarArgGenericHelper
;
6354 using VarArgMIPSHelper
= VarArgGenericHelper
;
6355 using VarArgLoongArch64Helper
= VarArgGenericHelper
;
6357 /// A no-op implementation of VarArgHelper.
6358 struct VarArgNoOpHelper
: public VarArgHelper
{
6359 VarArgNoOpHelper(Function
&F
, MemorySanitizer
&MS
,
6360 MemorySanitizerVisitor
&MSV
) {}
6362 void visitCallBase(CallBase
&CB
, IRBuilder
<> &IRB
) override
{}
6364 void visitVAStartInst(VAStartInst
&I
) override
{}
6366 void visitVACopyInst(VACopyInst
&I
) override
{}
6368 void finalizeInstrumentation() override
{}
6371 } // end anonymous namespace
6373 static VarArgHelper
*CreateVarArgHelper(Function
&Func
, MemorySanitizer
&Msan
,
6374 MemorySanitizerVisitor
&Visitor
) {
6375 // VarArg handling is only implemented on AMD64. False positives are possible
6376 // on other platforms.
6377 Triple
TargetTriple(Func
.getParent()->getTargetTriple());
6379 if (TargetTriple
.getArch() == Triple::x86
)
6380 return new VarArgI386Helper(Func
, Msan
, Visitor
);
6382 if (TargetTriple
.getArch() == Triple::x86_64
)
6383 return new VarArgAMD64Helper(Func
, Msan
, Visitor
);
6385 if (TargetTriple
.isARM())
6386 return new VarArgARM32Helper(Func
, Msan
, Visitor
, /*VAListTagSize=*/4);
6388 if (TargetTriple
.isAArch64())
6389 return new VarArgAArch64Helper(Func
, Msan
, Visitor
);
6391 if (TargetTriple
.isSystemZ())
6392 return new VarArgSystemZHelper(Func
, Msan
, Visitor
);
6394 // On PowerPC32 VAListTag is a struct
6395 // {char, char, i16 padding, char *, char *}
6396 if (TargetTriple
.isPPC32())
6397 return new VarArgPowerPCHelper(Func
, Msan
, Visitor
, /*VAListTagSize=*/12);
6399 if (TargetTriple
.isPPC64())
6400 return new VarArgPowerPCHelper(Func
, Msan
, Visitor
, /*VAListTagSize=*/8);
6402 if (TargetTriple
.isRISCV32())
6403 return new VarArgRISCVHelper(Func
, Msan
, Visitor
, /*VAListTagSize=*/4);
6405 if (TargetTriple
.isRISCV64())
6406 return new VarArgRISCVHelper(Func
, Msan
, Visitor
, /*VAListTagSize=*/8);
6408 if (TargetTriple
.isMIPS32())
6409 return new VarArgMIPSHelper(Func
, Msan
, Visitor
, /*VAListTagSize=*/4);
6411 if (TargetTriple
.isMIPS64())
6412 return new VarArgMIPSHelper(Func
, Msan
, Visitor
, /*VAListTagSize=*/8);
6414 if (TargetTriple
.isLoongArch64())
6415 return new VarArgLoongArch64Helper(Func
, Msan
, Visitor
,
6416 /*VAListTagSize=*/8);
6418 return new VarArgNoOpHelper(Func
, Msan
, Visitor
);
6421 bool MemorySanitizer::sanitizeFunction(Function
&F
, TargetLibraryInfo
&TLI
) {
6422 if (!CompileKernel
&& F
.getName() == kMsanModuleCtorName
)
6425 if (F
.hasFnAttribute(Attribute::DisableSanitizerInstrumentation
))
6428 MemorySanitizerVisitor
Visitor(F
, *this, TLI
);
6430 // Clear out memory attributes.
6432 B
.addAttribute(Attribute::Memory
).addAttribute(Attribute::Speculatable
);
6435 return Visitor
.runOnFunction();