[AArch64] Fix movk parsing with an .equ operand (#124428)
[llvm-project.git] / llvm / lib / Transforms / Instrumentation / MemorySanitizer.cpp
blob56d3eb10d73e952ebb247403f3b05ef6346bc919
1 //===- MemorySanitizer.cpp - detector of uninitialized reads --------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// This file is a part of MemorySanitizer, a detector of uninitialized
11 /// reads.
12 ///
13 /// The algorithm of the tool is similar to Memcheck
14 /// (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.
21 ///
22 /// But there are differences too. The first and the major one:
23 /// compiler instrumentation instead of binary instrumentation. This
24 /// gives us much better register allocation, possible compiler
25 /// optimizations and a fast start-up. But this brings the major issue
26 /// as well: msan needs to see all program events, including system
27 /// calls and reads/writes in system libraries, so we either need to
28 /// compile *everything* with msan or use a binary translation
29 /// component (e.g. DynamoRIO) to instrument pre-built libraries.
30 /// Another difference from Memcheck is that we use 8 shadow bits per
31 /// byte of application memory and use a direct shadow mapping. This
32 /// greatly simplifies the instrumentation code and avoids races on
33 /// shadow updates (Memcheck is single-threaded so races are not a
34 /// concern there. Memcheck uses 2 shadow bits per byte with a slow
35 /// path storage that uses 8 bits per byte).
36 ///
37 /// The default value of shadow is 0, which means "clean" (not poisoned).
38 ///
39 /// Every module initializer should call __msan_init to ensure that the
40 /// shadow memory is ready. On error, __msan_warning is called. Since
41 /// parameters and return values may be passed via registers, we have a
42 /// specialized thread-local shadow for return values
43 /// (__msan_retval_tls) and parameters (__msan_param_tls).
44 ///
45 /// Origin tracking.
46 ///
47 /// MemorySanitizer can track origins (allocation points) of all uninitialized
48 /// values. This behavior is controlled with a flag (msan-track-origins) and is
49 /// disabled by default.
50 ///
51 /// Origins are 4-byte values created and interpreted by the runtime library.
52 /// They are stored in a second shadow mapping, one 4-byte value for 4 bytes
53 /// of application memory. Propagation of origins is basically a bunch of
54 /// "select" instructions that pick the origin of a dirty argument, if an
55 /// instruction has one.
56 ///
57 /// Every 4 aligned, consecutive bytes of application memory have one origin
58 /// value associated with them. If these bytes contain uninitialized data
59 /// coming from 2 different allocations, the last store wins. Because of this,
60 /// MemorySanitizer reports can show unrelated origins, but this is unlikely in
61 /// practice.
62 ///
63 /// Origins are meaningless for fully initialized values, so MemorySanitizer
64 /// avoids storing origin to memory when a fully initialized value is stored.
65 /// This way it avoids needless overwriting origin of the 4-byte region on
66 /// a short (i.e. 1 byte) clean store, and it is also good for performance.
67 ///
68 /// Atomic handling.
69 ///
70 /// Ideally, every atomic store of application value should update the
71 /// corresponding shadow location in an atomic way. Unfortunately, atomic store
72 /// of two disjoint locations can not be done without severe slowdown.
73 ///
74 /// Therefore, we implement an approximation that may err on the safe side.
75 /// In this implementation, every atomically accessed location in the program
76 /// may only change from (partially) uninitialized to fully initialized, but
77 /// not the other way around. We load the shadow _after_ the application load,
78 /// and we store the shadow _before_ the app store. Also, we always store clean
79 /// shadow (if the application store is atomic). This way, if the store-load
80 /// pair constitutes a happens-before arc, shadow store and load are correctly
81 /// ordered such that the load will get either the value that was stored, or
82 /// some later value (which is always clean).
83 ///
84 /// This does not work very well with Compare-And-Swap (CAS) and
85 /// Read-Modify-Write (RMW) operations. To follow the above logic, CAS and RMW
86 /// must store the new shadow before the app operation, and load the shadow
87 /// after the app operation. Computers don't work this way. Current
88 /// implementation ignores the load aspect of CAS/RMW, always returning a clean
89 /// value. It implements the store part as a simple atomic store by storing a
90 /// clean shadow.
91 ///
92 /// Instrumenting inline assembly.
93 ///
94 /// For inline assembly code LLVM has little idea about which memory locations
95 /// become initialized depending on the arguments. It can be possible to figure
96 /// out which arguments are meant to point to inputs and outputs, but the
97 /// actual semantics can be only visible at runtime. In the Linux kernel it's
98 /// also possible that the arguments only indicate the offset for a base taken
99 /// from a segment register, so it's dangerous to treat any asm() arguments as
100 /// pointers. We take a conservative approach generating calls to
101 /// __msan_instrument_asm_store(ptr, size)
102 /// , which defer the memory unpoisoning to the runtime library.
103 /// The latter can perform more complex address checks to figure out whether
104 /// it's safe to touch the shadow memory.
105 /// Like with atomic operations, we call __msan_instrument_asm_store() before
106 /// the assembly call, so that changes to the shadow memory will be seen by
107 /// other threads together with main memory initialization.
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
115 /// instrumentation.
116 /// Shadow and origin values for a particular X-byte memory location
117 /// (X=1,2,4,8) are accessed through pointers obtained via the
118 /// __msan_metadata_ptr_for_load_X(ptr)
119 /// __msan_metadata_ptr_for_store_X(ptr)
120 /// functions. The corresponding functions check that the X-byte accesses
121 /// are possible and returns the pointers to shadow and origin memory.
122 /// Arbitrary sized accesses are handled with:
123 /// __msan_metadata_ptr_for_load_n(ptr, size)
124 /// __msan_metadata_ptr_for_store_n(ptr, size);
125 /// Note that the sanitizer code has to deal with how shadow/origin pairs
126 /// returned by the these functions are represented in different ABIs. In
127 /// the X86_64 ABI they are returned in RDX:RAX, 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
136 /// function;
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
144 /// moment.
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"
205 #include <algorithm>
206 #include <cassert>
207 #include <cstddef>
208 #include <cstdint>
209 #include <memory>
210 #include <string>
211 #include <tuple>
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,
241 cl::init(0));
243 static cl::opt<bool> ClKeepGoing("msan-keep-going",
244 cl::desc("keep going after reporting a UMR"),
245 cl::Hidden, cl::init(false));
247 static cl::opt<bool>
248 ClPoisonStack("msan-poison-stack",
249 cl::desc("poison uninitialized stack variables"), cl::Hidden,
250 cl::init(true));
252 static cl::opt<bool> ClPoisonStackWithCall(
253 "msan-poison-stack-with-call",
254 cl::desc("poison uninitialized stack variables with a call"), cl::Hidden,
255 cl::init(false));
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));
262 static cl::opt<bool>
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,
269 cl::init(true));
271 static cl::opt<bool>
272 ClHandleICmp("msan-handle-icmp",
273 cl::desc("propagate shadow through ICmpEQ and ICmpNE"),
274 cl::Hidden, cl::init(true));
276 static cl::opt<bool>
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",
283 cl::desc(
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
290 // local variables.
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,
298 cl::init(true));
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(
312 "msan-eager-checks",
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",
330 cl::desc(
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));
336 static cl::opt<bool>
337 ClEnableKmsan("msan-kernel",
338 cl::desc("Enable KernelMemorySanitizer instrumentation"),
339 cl::Hidden, cl::init(false));
341 static cl::opt<bool>
342 ClDisableChecks("msan-disable-checks",
343 cl::desc("Apply no_sanitize to the whole file"), cl::Hidden,
344 cl::init(false));
346 static cl::opt<bool>
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
353 static cl::opt<bool>
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));
376 static cl::opt<int>
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";
385 namespace {
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 {
392 uint64_t AndMask;
393 uint64_t XorMask;
394 uint64_t ShadowBase;
395 uint64_t OriginBase;
398 struct PlatformMemoryMapParams {
399 const MemoryMapParams *bits32;
400 const MemoryMapParams *bits64;
403 } // end anonymous namespace
405 // i386 Linux
406 static const MemoryMapParams Linux_I386_MemoryMapParams = {
407 0x000080000000, // AndMask
408 0, // XorMask (not used)
409 0, // ShadowBase (not used)
410 0x000040000000, // OriginBase
413 // x86_64 Linux
414 static const MemoryMapParams Linux_X86_64_MemoryMapParams = {
415 0, // AndMask (not used)
416 0x500000000000, // XorMask
417 0, // ShadowBase (not used)
418 0x100000000000, // OriginBase
421 // mips32 Linux
422 // FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
423 // after picking good constants
425 // mips64 Linux
426 static const MemoryMapParams Linux_MIPS64_MemoryMapParams = {
427 0, // AndMask (not used)
428 0x008000000000, // XorMask
429 0, // ShadowBase (not used)
430 0x002000000000, // OriginBase
433 // ppc32 Linux
434 // FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
435 // after picking good constants
437 // ppc64 Linux
438 static const MemoryMapParams Linux_PowerPC64_MemoryMapParams = {
439 0xE00000000000, // AndMask
440 0x100000000000, // XorMask
441 0x080000000000, // ShadowBase
442 0x1C0000000000, // OriginBase
445 // s390x Linux
446 static const MemoryMapParams Linux_S390X_MemoryMapParams = {
447 0xC00000000000, // AndMask
448 0, // XorMask (not used)
449 0x080000000000, // ShadowBase
450 0x1C0000000000, // OriginBase
453 // arm32 Linux
454 // FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
455 // after picking good constants
457 // aarch64 Linux
458 static const MemoryMapParams Linux_AArch64_MemoryMapParams = {
459 0, // AndMask (not used)
460 0x0B00000000000, // XorMask
461 0, // ShadowBase (not used)
462 0x0200000000000, // OriginBase
465 // loongarch64 Linux
466 static const MemoryMapParams Linux_LoongArch64_MemoryMapParams = {
467 0, // AndMask (not used)
468 0x500000000000, // XorMask
469 0, // ShadowBase (not used)
470 0x100000000000, // OriginBase
473 // riscv32 Linux
474 // FIXME: Remove -msan-origin-base -msan-and-mask added by PR #109284 to tests
475 // after picking good constants
477 // aarch64 FreeBSD
478 static const MemoryMapParams FreeBSD_AArch64_MemoryMapParams = {
479 0x1800000000000, // AndMask
480 0x0400000000000, // XorMask
481 0x0200000000000, // ShadowBase
482 0x0700000000000, // OriginBase
485 // i386 FreeBSD
486 static const MemoryMapParams FreeBSD_I386_MemoryMapParams = {
487 0x000180000000, // AndMask
488 0x000040000000, // XorMask
489 0x000020000000, // ShadowBase
490 0x000700000000, // OriginBase
493 // x86_64 FreeBSD
494 static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams = {
495 0xc00000000000, // AndMask
496 0x200000000000, // XorMask
497 0x100000000000, // ShadowBase
498 0x380000000000, // OriginBase
501 // x86_64 NetBSD
502 static const MemoryMapParams NetBSD_X86_64_MemoryMapParams = {
503 0, // AndMask
504 0x500000000000, // XorMask
505 0, // ShadowBase
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 = {
515 nullptr,
516 &Linux_MIPS64_MemoryMapParams,
519 static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams = {
520 nullptr,
521 &Linux_PowerPC64_MemoryMapParams,
524 static const PlatformMemoryMapParams Linux_S390_MemoryMapParams = {
525 nullptr,
526 &Linux_S390X_MemoryMapParams,
529 static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams = {
530 nullptr,
531 &Linux_AArch64_MemoryMapParams,
534 static const PlatformMemoryMapParams Linux_LoongArch_MemoryMapParams = {
535 nullptr,
536 &Linux_LoongArch64_MemoryMapParams,
539 static const PlatformMemoryMapParams FreeBSD_ARM_MemoryMapParams = {
540 nullptr,
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 = {
550 nullptr,
551 &NetBSD_X86_64_MemoryMapParams,
554 namespace {
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
561 /// the module.
562 class MemorySanitizer {
563 public:
564 MemorySanitizer(Module &M, MemorySanitizerOptions Options)
565 : CompileKernel(Options.Kernel), TrackOrigins(Options.TrackOrigins),
566 Recover(Options.Recover), EagerChecks(Options.EagerChecks) {
567 initializeModule(M);
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);
578 private:
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,
595 ArgsTy... Args);
597 /// True if we're compiling the Linux kernel.
598 bool CompileKernel;
599 /// Track origins (allocation points) of uninitialized values.
600 int TrackOrigins;
601 bool Recover;
602 bool EagerChecks;
604 Triple TargetTriple;
605 LLVMContext *C;
606 Type *IntptrTy; ///< Integer type with the size of a ptr in default AS.
607 Type *OriginTy;
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
611 // in KMSAN.
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.
617 Value *ParamTLS;
619 /// Thread-local origin storage for function parameters.
620 Value *ParamOriginTLS;
622 /// Thread-local shadow storage for function return value.
623 Value *RetvalTLS;
625 /// Thread-local origin storage for function return value.
626 Value *RetvalOriginTLS;
628 /// Thread-local shadow storage for in-register va_arg function.
629 Value *VAArgTLS;
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
648 /// allocation.
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.
674 Type *MsanMetadata;
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,
704 /*InitArgTypes=*/{},
705 /*InitArgs=*/{},
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) {
709 if (!ClWithComdat) {
710 appendToGlobalCtors(M, Ctor, 0);
711 return;
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,
726 bool EagerChecks)
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) {
739 insertModuleCtor(M);
740 Modified = true;
743 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
744 for (Function &F : M) {
745 if (F.empty())
746 continue;
747 MemorySanitizer Msan(*F.getParent(), Options);
748 Modified |=
749 Msan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F));
752 if (!Modified)
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>();
760 return PA;
763 void MemorySanitizerPass::printPipeline(
764 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
765 static_cast<PassInfoMixin<MemorySanitizerPass> *>(this)->printPipeline(
766 OS, MapClassName2PassName);
767 OS << '<';
768 if (Options.Recover)
769 OS << "recover;";
770 if (Options.Kernel)
771 OS << "kernel;";
772 if (Options.EagerChecks)
773 OS << "eager-checks;";
774 OS << "track-origins=" << Options.TrackOrigins;
775 OS << '>';
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,
784 StringRef Str) {
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>
791 FunctionCallee
792 MemorySanitizer::getOrInsertMsanMetadataFunction(Module &M, StringRef Name,
793 ArgsTy... Args) {
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) {
806 IRBuilder<> IRB(*C);
808 // These will be initialized in insertKmsanPrologue().
809 RetvalTLS = nullptr;
810 RetvalOriginTLS = nullptr;
811 ParamTLS = nullptr;
812 ParamOriginTLS = nullptr;
813 VAArgTLS = 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
822 // runtime library.
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,
829 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) {
869 IRBuilder<> IRB(*C);
871 // Create the callback.
872 // FIXME: this function should have "Cold" calling conv,
873 // which is not yet implemented.
874 if (TrackOrigins) {
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());
880 } else {
881 StringRef WarningFnName =
882 Recover ? "__msan_warning" : "__msan_warning_noreturn";
883 WarningFn = M.getOrInsertFunction(WarningFnName, IRB.getVoidTy());
886 // Create the global TLS variables.
887 RetvalTLS =
888 getOrInsertGlobal(M, "__msan_retval_tls",
889 ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8));
891 RetvalOriginTLS = getOrInsertGlobal(M, "__msan_retval_origin_tls", OriginTy);
893 ParamTLS =
894 getOrInsertGlobal(M, "__msan_param_tls",
895 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
897 ParamOriginTLS =
898 getOrInsertGlobal(M, "__msan_param_origin_tls",
899 ArrayType::get(OriginTy, kParamTLSSize / 4));
901 VAArgTLS =
902 getOrInsertGlobal(M, "__msan_va_arg_tls",
903 ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
905 VAArgOriginTLS =
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;
913 AccessSizeIndex++) {
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,
924 IRB.getInt32Ty());
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)
942 return;
944 IRBuilder<> IRB(*C);
945 // Initialize callbacks that are common for kernel and userspace
946 // instrumentation.
947 MsanChainOriginFn = M.getOrInsertFunction(
948 "__msan_chain_origin",
949 TLI.getAttrList(C, {0}, /*Signed=*/false, /*Ret=*/true), IRB.getInt32Ty(),
950 IRB.getInt32Ty());
951 MsanSetOriginFn = M.getOrInsertFunction(
952 "__msan_set_origin", TLI.getAttrList(C, {2}, /*Signed=*/false),
953 IRB.getVoidTy(), PtrTy, IntptrTy, IRB.getInt32Ty());
954 MemmoveFn =
955 M.getOrInsertFunction("__msan_memmove", PtrTy, PtrTy, PtrTy, IntptrTy);
956 MemcpyFn =
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);
965 if (CompileKernel) {
966 createKernelApi(M, TLI);
967 } else {
968 createUserspaceApi(M, TLI);
970 CallbacksInitialized = true;
973 FunctionCallee MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore,
974 int size) {
975 FunctionCallee *Fns =
976 isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
977 switch (size) {
978 case 1:
979 return Fns[0];
980 case 2:
981 return Fns[1];
982 case 4:
983 return Fns[2];
984 case 8:
985 return Fns[3];
986 default:
987 return nullptr;
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;
1008 } else {
1009 switch (TargetTriple.getOS()) {
1010 case Triple::FreeBSD:
1011 switch (TargetTriple.getArch()) {
1012 case Triple::aarch64:
1013 MapParams = FreeBSD_ARM_MemoryMapParams.bits64;
1014 break;
1015 case Triple::x86_64:
1016 MapParams = FreeBSD_X86_MemoryMapParams.bits64;
1017 break;
1018 case Triple::x86:
1019 MapParams = FreeBSD_X86_MemoryMapParams.bits32;
1020 break;
1021 default:
1022 report_fatal_error("unsupported architecture");
1024 break;
1025 case Triple::NetBSD:
1026 switch (TargetTriple.getArch()) {
1027 case Triple::x86_64:
1028 MapParams = NetBSD_X86_MemoryMapParams.bits64;
1029 break;
1030 default:
1031 report_fatal_error("unsupported architecture");
1033 break;
1034 case Triple::Linux:
1035 switch (TargetTriple.getArch()) {
1036 case Triple::x86_64:
1037 MapParams = Linux_X86_MemoryMapParams.bits64;
1038 break;
1039 case Triple::x86:
1040 MapParams = Linux_X86_MemoryMapParams.bits32;
1041 break;
1042 case Triple::mips64:
1043 case Triple::mips64el:
1044 MapParams = Linux_MIPS_MemoryMapParams.bits64;
1045 break;
1046 case Triple::ppc64:
1047 case Triple::ppc64le:
1048 MapParams = Linux_PowerPC_MemoryMapParams.bits64;
1049 break;
1050 case Triple::systemz:
1051 MapParams = Linux_S390_MemoryMapParams.bits64;
1052 break;
1053 case Triple::aarch64:
1054 case Triple::aarch64_be:
1055 MapParams = Linux_ARM_MemoryMapParams.bits64;
1056 break;
1057 case Triple::loongarch64:
1058 MapParams = Linux_LoongArch_MemoryMapParams.bits64;
1059 break;
1060 default:
1061 report_fatal_error("unsupported architecture");
1063 break;
1064 default:
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) {
1079 if (TrackOrigins)
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");
1086 if (Recover)
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");
1095 namespace {
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)
1137 return 0;
1138 return Log2_32_Ceil((TypeSizeFixed + 7) / 8);
1141 namespace {
1143 /// Helper class to attach debug information of the given instruction onto new
1144 /// instructions inserted after.
1145 class NextNodeIRBuilder : public IRBuilder<> {
1146 public:
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
1157 /// non-zero.
1158 struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
1159 Function &F;
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.
1170 bool InsertChecks;
1171 bool PropagateShadow;
1172 bool PoisonStack;
1173 bool PoisonUndef;
1175 struct ShadowOriginAndInsertPoint {
1176 Value *Shadow;
1177 Value *Origin;
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);
1208 FnPrologueEnd =
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))
1225 return false;
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)
1243 return V;
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)
1251 return Origin;
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);
1270 Value *RoundUp =
1271 IRB.CreateAdd(Size, ConstantInt::get(MS.IntptrTy, kOriginSize - 1));
1272 Value *End =
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);
1280 return;
1283 unsigned Size = TS.getFixedValue();
1285 unsigned Ofs = 0;
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)
1292 : IntptrOriginPtr;
1293 IRB.CreateAlignedStore(IntptrOrigin, Ptr, CurrentAlignment);
1294 Ofs += IntptrSize / kOriginSize;
1295 CurrentAlignment = IntptrAlignment;
1299 for (unsigned i = Ofs; i < (Size + kOriginSize - 1) / kOriginSize; ++i) {
1300 Value *GEP =
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
1317 // ignored.
1318 return;
1320 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1321 // Copy origin as the value is definitely uninitialized.
1322 paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
1323 OriginAlignment);
1324 return;
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);
1339 } else {
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,
1345 OriginAlignment);
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");
1364 (void)NewSI;
1366 if (SI->isAtomic())
1367 SI->setOrdering(addReleaseOrdering(SI->getOrdering()));
1369 if (MS.TrackOrigins && !SI->isAtomic())
1370 storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
1371 OriginAlignment);
1375 // Returns true if Debug Location corresponds to multiple warnings.
1376 bool shouldDisambiguateWarningLocation(const DebugLoc &DebugLoc) {
1377 if (MS.TrackOrigins < 2)
1378 return false;
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) {
1389 if (!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();
1413 else
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
1417 // at the very end.
1420 void materializeOneCheck(IRBuilder<> &IRB, Value *ConvertedShadow,
1421 Value *Origin) {
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);
1437 } else {
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
1453 // correct origin.
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.
1466 continue;
1468 if (llvm::isKnownNonZero(ConvertedShadow, DL)) {
1469 // Report as the value is definitely uninitialized.
1470 insertWarningFn(IRB, ShadowData.Origin);
1471 if (!MS.Recover)
1472 return; // Always fail and stop here, not need to check the rest.
1473 // Skip entire instruction,
1474 continue;
1476 // Fallback to runtime check, which still can be optimized out later.
1479 if (!Combine) {
1480 materializeOneCheck(IRB, ConvertedShadow, ShadowData.Origin);
1481 continue;
1484 if (!Shadow) {
1485 Shadow = ConvertedShadow;
1486 continue;
1489 Shadow = convertToBool(Shadow, IRB, "_mscmp");
1490 ConvertedShadow = convertToBool(ConvertedShadow, IRB, "_mscmp");
1491 Shadow = IRB.CreateOr(Shadow, ConvertedShadow, "_msor");
1494 if (Shadow) {
1495 assert(Combine);
1496 IRBuilder<> IRB(Instruction);
1497 materializeOneCheck(IRB, Shadow, nullptr);
1501 void materializeChecks() {
1502 #ifndef NDEBUG
1503 // For assert below.
1504 SmallPtrSet<Instruction *, 16> Done;
1505 #endif
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));
1519 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()))
1555 visit(*BB);
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));
1569 if (PNO)
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();
1596 return true;
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()) {
1605 return nullptr;
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))
1610 return IT;
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");
1627 return Res;
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,
1635 IRBuilder<> &IRB) {
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);
1646 else
1647 Aggregator = ShadowBool;
1650 return Aggregator;
1653 // Extract combined shadow of array elements
1654 Value *collapseArrayShadow(ArrayType *Array, Value *Shadow,
1655 IRBuilder<> &IRB) {
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);
1667 return Aggregator;
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);
1681 unsigned BitWidth =
1682 V->getType()->getPrimitiveSizeInBits().getFixedValue();
1683 return IRB.CreateBitCast(V, IntegerType::get(*MS.C, BitWidth));
1685 return V;
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.
1695 return V;
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());
1705 return MS.IntptrTy;
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);
1715 return MS.PtrTy;
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));
1746 return OffsetLong;
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());
1761 if (!VectTy) {
1762 assert(Addr->getType()->isPointerTy());
1763 } else {
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) {
1770 ShadowLong =
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)
1781 OriginLong =
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,
1795 ArgsTy... Args) {
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,
1806 IRBuilder<> &IRB,
1807 Type *ShadowTy,
1808 bool isStore) {
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);
1815 if (Getter) {
1816 ShadowOriginPtrs = createMetadataCall(IRB, Getter, AddrCast);
1817 } else {
1818 Value *SizeVal = ConstantInt::get(MS.IntptrTy, Size);
1819 ShadowOriginPtrs = createMetadataCall(
1820 IRB,
1821 isStore ? MS.MsanMetadataPtrForStoreN : MS.MsanMetadataPtrForLoadN,
1822 AddrCast, SizeVal);
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,
1835 IRBuilder<> &IRB,
1836 Type *ShadowTy,
1837 bool isStore) {
1838 VectorType *VectTy = dyn_cast<VectorType>(Addr->getType());
1839 if (!VectTy) {
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) {
1853 Value *OneAddr =
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,
1868 Type *ShadowTy,
1869 MaybeAlign Alignment,
1870 bool isStore) {
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);
1881 if (ArgOffset)
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)
1889 return nullptr;
1890 Value *Base = IRB.CreatePointerCast(MS.ParamOriginTLS, MS.IntptrTy);
1891 if (ArgOffset)
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)
1916 return;
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);
1924 if (!ShadowTy)
1925 return nullptr;
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
1932 /// (initialized).
1933 Constant *getCleanShadow(Value *V) { return getCleanShadow(V->getType()); }
1935 /// Create a dirty shadow of a given shadow type.
1936 Constant *getPoisonedShadow(Type *ShadowTy) {
1937 assert(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);
1957 if (!ShadowTy)
1958 return nullptr;
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];
1975 if (!Shadow) {
1976 LLVM_DEBUG(dbgs() << "No shadow: " << *V << "\n" << *(I->getParent()));
1977 (void)I;
1978 assert(Shadow && "No shadow for a value");
1980 return Shadow;
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");
1986 (void)U;
1987 return AllOnes;
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];
1992 if (ShadowPtr)
1993 return ShadowPtr;
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"));
2003 if (A == &FArg) {
2004 ShadowPtr = getCleanShadow(V);
2005 setOrigin(A, getCleanOrigin());
2006 break;
2008 continue;
2011 unsigned Size = FArg.hasByValAttr()
2012 ? DL.getTypeAllocSize(FArg.getParamByValType())
2013 : DL.getTypeAllocSize(FArg.getType());
2015 if (A == &FArg) {
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,
2026 /*isStore*/ true);
2027 if (!PropagateShadow || Overflow) {
2028 // ParamTLS overflow.
2029 EntryIRB.CreateMemSet(
2030 CpShadowPtr, Constant::getNullValue(EntryIRB.getInt8Ty()),
2031 Size, ArgAlign);
2032 } else {
2033 Value *Base = getShadowPtrForArgument(EntryIRB, ArgOffset);
2034 const Align CopyAlign = std::min(ArgAlign, kShadowTLSAlignment);
2035 Value *Cpy = EntryIRB.CreateMemCpy(CpShadowPtr, CopyAlign, Base,
2036 CopyAlign, Size);
2037 LLVM_DEBUG(dbgs() << " ByValCpy: " << *Cpy << "\n");
2038 (void)Cpy;
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(
2046 CpOriginPtr,
2047 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginPtr,
2048 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
2049 OriginSize);
2054 if (!PropagateShadow || Overflow || FArg.hasByValAttr() ||
2055 (MS.EagerChecks && FArg.hasAttribute(Attribute::NoUndef))) {
2056 ShadowPtr = getCleanShadow(V);
2057 setOrigin(A, getCleanOrigin());
2058 } else {
2059 // Shadow over TLS
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));
2068 LLVM_DEBUG(dbgs()
2069 << " ARG: " << FArg << " ==> " << *ShadowPtr << "\n");
2070 break;
2073 ArgOffset += alignTo(Size, kShadowTLSAlignment);
2075 assert(ShadowPtr && "Could not find shadow for an argument");
2076 return ShadowPtr;
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)
2090 return nullptr;
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");
2101 return 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) {
2114 assert(Shadow);
2115 if (!InsertChecks)
2116 return;
2118 if (!DebugCounter::shouldExecute(DebugInsertCheck)) {
2119 LLVM_DEBUG(dbgs() << "Skipping check of " << *Shadow << " before "
2120 << *OrigIns << "\n");
2121 return;
2123 #ifndef NDEBUG
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 "
2128 "types");
2129 #endif
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) {
2139 assert(Val);
2140 Value *Shadow, *Origin;
2141 if (ClCheckConstantShadow) {
2142 Shadow = getShadow(Val);
2143 if (!Shadow)
2144 return;
2145 Origin = getOrigin(Val);
2146 } else {
2147 Shadow = dyn_cast_or_null<Instruction>(getShadow(Val));
2148 if (!Shadow)
2149 return;
2150 Origin = dyn_cast_or_null<Instruction>(getOrigin(Val));
2152 insertShadowCheck(Shadow, Origin, OrigIns);
2155 AtomicOrdering addReleaseOrdering(AtomicOrdering a) {
2156 switch (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) {
2190 switch (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))
2227 return;
2228 // Don't want to visit if we're in the prologue
2229 if (isInPrologue(I))
2230 return;
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());
2236 return;
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);
2257 setShadow(&I,
2258 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
2259 } else {
2260 setShadow(&I, getCleanShadow(&I));
2263 if (ClCheckAccessAddress)
2264 insertShadowCheck(I.getPointerOperand(), &I);
2266 if (I.isAtomic())
2267 I.setOrdering(addAcquireOrdering(I.getOrdering()));
2269 if (MS.TrackOrigins) {
2270 if (PropagateShadow) {
2271 const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
2272 setOrigin(
2273 &I, IRB.CreateAlignedLoad(MS.OriginTy, OriginPtr, OriginAlignment));
2274 } else {
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),
2297 /*isStore*/ true)
2298 .first;
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) {
2316 handleCASOrRMW(I);
2317 I.setOrdering(addReleaseOrdering(I.getOrdering()));
2320 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
2321 handleCASOrRMW(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),
2330 "_msprop"));
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),
2340 "_msprop"));
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(),
2349 "_msprop"));
2350 setOriginForNaryOp(I);
2353 // Casts.
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())
2378 return;
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;
2472 IRBuilder<> &IRB;
2473 MemorySanitizerVisitor *MSV;
2475 public:
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) {
2482 assert(OpShadow);
2483 if (!Shadow)
2484 Shadow = OpShadow;
2485 else {
2486 OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
2487 Shadow = IRB.CreateOr(Shadow, OpShadow, "_msprop");
2491 if (MSV->MS.TrackOrigins) {
2492 assert(OpOrigin);
2493 if (!Origin) {
2494 Origin = OpOrigin;
2495 } else {
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);
2504 return *this;
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
2515 /// and origin.
2516 void Done(Instruction *I) {
2517 if (CombineShadow) {
2518 assert(Shadow);
2519 Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(I));
2520 MSV->setShadow(I, Shadow);
2522 if (MSV->MS.TrackOrigins) {
2523 assert(Origin);
2524 MSV->setOrigin(I, Origin);
2528 /// Store the current combined value at the specified origin
2529 /// location.
2530 void DoneAndStoreOrigin(TypeSize TS, Value *OriginPtr) {
2531 if (MSV->MS.TrackOrigins) {
2532 assert(Origin);
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)
2544 return;
2545 IRBuilder<> IRB(&I);
2546 OriginCombiner OC(this, IRB);
2547 for (Use &Op : I.operands())
2548 OC.Add(Op.get());
2549 OC.Done(&I);
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
2561 /// necessary.
2562 Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy,
2563 bool Signed = false) {
2564 Type *srcTy = V->getType();
2565 if (srcTy == dstTy)
2566 return V;
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));
2579 Value *V2 =
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)
2589 return V;
2590 if (V->getType()->isPtrOrPtrVectorTy())
2591 return IRB.CreatePtrToInt(V, ShadowTy);
2592 else
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())
2601 SC.Add(Op.get());
2602 SC.Done(&I);
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,
2617 Value *OtherArg) {
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));
2630 } else {
2631 Elements.push_back(ConstantInt::get(EltTy, 1));
2634 ShadowMul = ConstantVector::get(Elements);
2635 } else {
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);
2640 } else {
2641 ShadowMul = ConstantInt::get(Ty, 1);
2645 IRBuilder<> IRB(&I);
2646 setShadow(&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));
2658 else
2659 handleShadowOr(I);
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
2706 // Sc = Sa | Sb
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);
2717 Value *RHS =
2718 IRB.CreateICmpEQ(IRB.CreateAnd(IRB.CreateXor(Sc, MinusOne), C), Zero);
2719 Value *Si = IRB.CreateAnd(LHS, RHS);
2720 Si->setName("_msprop_icmp");
2721 setShadow(&I, Si);
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) {
2749 if (IsSigned) {
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.
2756 APInt MinVal =
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);
2772 setShadow(&I, Si);
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) {
2781 Constant *constOp;
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();
2790 } else {
2791 handleShadowOr(I);
2792 return;
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),
2801 "_msprop_icmp_s");
2802 setShadow(&I, Shadow);
2803 setOrigin(&I, getOrigin(op));
2804 } else {
2805 handleShadowOr(I);
2809 void visitICmpInst(ICmpInst &I) {
2810 if (!ClHandleICmp) {
2811 handleShadowOr(I);
2812 return;
2814 if (I.isEquality()) {
2815 handleEqualityComparison(I);
2816 return;
2819 assert(I.isRelational());
2820 if (ClHandleICmpExact) {
2821 handleRelationalComparisonExact(I);
2822 return;
2824 if (I.isSigned()) {
2825 handleSignedRelationalComparison(I);
2826 return;
2829 assert(I.isUnsigned());
2830 if ((isa<Constant>(I.getOperand(0)) || isa<Constant>(I.getOperand(1)))) {
2831 handleRelationalComparisonExact(I);
2832 return;
2835 handleShadowOr(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);
2846 Value *S2Conv =
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);
2865 Value *S2Conv =
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(),
2869 {S0, S1, V2});
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
2898 /// alignment.
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();
2916 // Same as memcpy.
2917 void visitMemSetInst(MemSetInst &I) {
2918 IRBuilder<> IRB(&I);
2919 IRB.CreateCall(
2920 MS.MemsetFn,
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);
2953 return true;
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);
2972 setShadow(&I,
2973 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
2974 } else {
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));
2984 else
2985 setOrigin(&I, getCleanOrigin());
2987 return true;
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()))
2999 return false;
3001 unsigned NumArgOperands = I.arg_size();
3002 for (unsigned i = 0; i < NumArgOperands; ++i) {
3003 Type *Ty = I.getArgOperand(i)->getType();
3004 if (Ty != RetTy)
3005 return false;
3008 IRBuilder<> IRB(&I);
3009 ShadowAndOriginCombiner SC(this, IRB);
3010 for (unsigned i = 0; i < NumArgOperands; ++i)
3011 SC.Add(I.getArgOperand(i));
3012 SC.Done(&I);
3014 return true;
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)
3030 return false;
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))
3047 return true;
3049 // FIXME: detect and handle SSE maskstore/maskload
3050 return false;
3053 bool handleUnknownIntrinsic(IntrinsicInst &I) {
3054 if (handleUnknownIntrinsicUnlogged(I)) {
3055 if (ClDumpStrictIntrinsics)
3056 dumpInst(I);
3058 LLVM_DEBUG(dbgs() << "UNKNOWN INTRINSIC HANDLED HEURISTICALLY: " << I
3059 << "\n");
3060 return true;
3061 } else
3062 return false;
3065 void handleInvariantGroup(IntrinsicInst &I) {
3066 setShadow(&I, getShadow(&I, 0));
3067 setOrigin(&I, getOrigin(&I, 0));
3070 void handleLifetimeStart(IntrinsicInst &I) {
3071 if (!PoisonStack)
3072 return;
3073 AllocaInst *AI = llvm::findAllocaForValue(I.getArgOperand(1));
3074 if (!AI)
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),
3084 getShadow(Op)));
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)
3113 // or
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) {
3134 case 2:
3135 CopyOp = I.getArgOperand(0);
3136 ConvertOp = I.getArgOperand(1);
3137 break;
3138 case 1:
3139 ConvertOp = I.getArgOperand(0);
3140 CopyOp = nullptr;
3141 break;
3142 default:
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);
3163 } else {
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
3170 // ConvertOp.
3171 if (CopyOp) {
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));
3183 } else {
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
3249 // intrinsic.
3250 Intrinsic::ID getSignedPackIntrinsic(Intrinsic::ID id) {
3251 switch (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;
3274 default:
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
3296 // back.
3297 Type *T =
3298 MMXEltSizeInBits ? getMMXVectorTy(MMXEltSizeInBits) : S1->getType();
3299 if (MMXEltSizeInBits) {
3300 S1 = IRB.CreateBitCast(S1, T);
3301 S2 = IRB.CreateBitCast(S2, T);
3303 Value *S1_ext =
3304 IRB.CreateSExt(IRB.CreateICmpNE(S1, Constant::getNullValue(T)), T);
3305 Value *S2_ext =
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));
3317 setShadow(&I, S);
3318 setOriginForNaryOp(I);
3321 // Convert `Mask` into `<n x i1>`.
3322 Constant *createDppMask(unsigned Width, unsigned Mask) {
3323 SmallVector<Constant *, 4> R(Width);
3324 for (auto &M : R) {
3325 M = ConstantInt::getBool(F.getContext(), Mask & 1);
3326 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,
3334 unsigned DstMask) {
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
3353 // product.
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
3358 // output.
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);
3376 if (Width == 8) {
3377 // First 4 elements of shadow are already calculated. `makeDppShadow`
3378 // operats on 32 bit masks, so we can just shift masks, and repeat.
3379 SI1 = IRB.CreateOr(
3380 SI1, findDppPoisonedOutput(IRB, S, SrcMask << 4, DstMask << 4));
3382 // Extend to real size of shadow, poisoning either all or none bits of an
3383 // element.
3384 S = IRB.CreateSExt(SI1, S->getType(), "_msdpp");
3386 setShadow(&I, S);
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);
3414 setShadow(C, Sc);
3415 setOrigin(C, Oc);
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)),
3434 ResTy);
3435 S = IRB.CreateLShr(S, ZeroBitsPerResultElement);
3436 S = IRB.CreateBitCast(S, getShadowTy(&I));
3437 setShadow(&I, S);
3438 setOriginForNaryOp(I);
3441 // Instrument multiply-add intrinsic.
3442 void handleVectorPmaddIntrinsic(IntrinsicInst &I,
3443 unsigned MMXEltSizeInBits = 0) {
3444 Type *ResTy =
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)),
3452 ResTy);
3453 S = IRB.CreateBitCast(S, getShadowTy(&I));
3454 setShadow(&I, S);
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
3460 // all-ones shadow.
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);
3469 setShadow(&I, S);
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));
3482 setShadow(&I, S);
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));
3491 setShadow(&I, S);
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);
3509 setShadow(&I, S);
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);
3526 setShadow(&I, S);
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();
3534 Value *ShadowPtr =
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) {
3544 if (!InsertChecks)
3545 return;
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)
3560 : getCleanOrigin();
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());
3579 return;
3582 Type *ShadowTy = getShadowTy(&I);
3583 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
3584 auto [ShadowPtr, OriginPtr] =
3585 getShadowOriginPtr(Ptr, IRB, ElementShadowTy, Align, /*isStore*/ false);
3587 Value *Shadow =
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)),
3633 "_msmaskedptrs");
3634 insertShadowCheck(MaskedPtrShadow, getOrigin(Ptrs), &I);
3637 if (!PropagateShadow) {
3638 setShadow(&I, getCleanShadow(&I));
3639 setOrigin(&I, getCleanOrigin());
3640 return;
3643 Type *ShadowTy = getShadowTy(&I);
3644 Type *ElementShadowTy = cast<VectorType>(ShadowTy)->getElementType();
3645 auto [ShadowPtrs, OriginPtrs] = getShadowOriginPtr(
3646 Ptrs, IRB, ElementShadowTy, Alignment, /*isStore*/ false);
3648 Value *Shadow =
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)),
3671 "_msmaskedptrs");
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);
3700 Value *ShadowPtr;
3701 Value *OriginPtr;
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)
3708 return;
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());
3732 return;
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)
3743 return;
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)),
3769 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);
3774 setShadow(&I, 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) {
3781 Mask.append(2, X);
3783 return Mask;
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)
3791 // or
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);
3796 unsigned Width =
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));
3808 SOC.Done(&I);
3811 // Instrument _mm_*_sd|ss intrinsics
3812 void handleUnarySdSsIntrinsic(IntrinsicInst &I) {
3813 IRBuilder<> IRB(&I);
3814 unsigned Width =
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++)
3822 Mask.push_back(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);
3844 unsigned Width =
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++)
3853 Mask.push_back(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));
3871 SC.Done(&I);
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);
3899 Value *ShadowElt1 =
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)
3957 if (useLane) {
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
3973 // e.g., 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);
3989 if (useLane)
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);
3999 CallInst *CI =
4000 IRB.CreateIntrinsic(IRB.getVoidTy(), I.getIntrinsicID(), ShadowArgs);
4001 setShadow(&I, CI);
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),
4017 OutputOriginPtr);
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)
4027 /// we compute:
4028 /// shadow[out] =
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
4036 /// (tbl{1,2,3,4}).
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();
4057 i++) {
4058 Value *Arg = I.getArgOperand(i);
4059 ShadowArgs.push_back(Arg);
4062 CallInst *CI =
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();
4068 i++) {
4069 Value *Shadow =
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) {
4081 handleShadowOr(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);
4093 break;
4094 case Intrinsic::abs:
4095 handleAbsIntrinsic(I);
4096 break;
4097 case Intrinsic::is_fpclass:
4098 handleIsFpClass(I);
4099 break;
4100 case Intrinsic::lifetime_start:
4101 handleLifetimeStart(I);
4102 break;
4103 case Intrinsic::launder_invariant_group:
4104 case Intrinsic::strip_invariant_group:
4105 handleInvariantGroup(I);
4106 break;
4107 case Intrinsic::bswap:
4108 handleBswap(I);
4109 break;
4110 case Intrinsic::ctlz:
4111 case Intrinsic::cttz:
4112 handleCountZeroes(I);
4113 break;
4114 case Intrinsic::masked_compressstore:
4115 handleMaskedCompressStore(I);
4116 break;
4117 case Intrinsic::masked_expandload:
4118 handleMaskedExpandLoad(I);
4119 break;
4120 case Intrinsic::masked_gather:
4121 handleMaskedGather(I);
4122 break;
4123 case Intrinsic::masked_scatter:
4124 handleMaskedScatter(I);
4125 break;
4126 case Intrinsic::masked_store:
4127 handleMaskedStore(I);
4128 break;
4129 case Intrinsic::masked_load:
4130 handleMaskedLoad(I);
4131 break;
4132 case Intrinsic::vector_reduce_and:
4133 handleVectorReduceAndIntrinsic(I);
4134 break;
4135 case Intrinsic::vector_reduce_or:
4136 handleVectorReduceOrIntrinsic(I);
4137 break;
4138 case Intrinsic::vector_reduce_add:
4139 case Intrinsic::vector_reduce_xor:
4140 case Intrinsic::vector_reduce_mul:
4141 handleVectorReduceIntrinsic(I);
4142 break;
4143 case Intrinsic::x86_sse_stmxcsr:
4144 handleStmxcsr(I);
4145 break;
4146 case Intrinsic::x86_sse_ldmxcsr:
4147 handleLdmxcsr(I);
4148 break;
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);
4161 break;
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);
4172 break;
4173 case Intrinsic::x86_sse_cvtps2pi:
4174 case Intrinsic::x86_sse_cvttps2pi:
4175 handleVectorConvertIntrinsic(I, 2);
4176 break;
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);
4266 break;
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);
4286 break;
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);
4297 break;
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);
4306 break;
4308 case Intrinsic::x86_avx_dp_ps_256:
4309 case Intrinsic::x86_sse41_dppd:
4310 case Intrinsic::x86_sse41_dpps:
4311 handleDppIntrinsic(I);
4312 break;
4314 case Intrinsic::x86_mmx_packsswb:
4315 case Intrinsic::x86_mmx_packuswb:
4316 handleVectorPackIntrinsic(I, 16);
4317 break;
4319 case Intrinsic::x86_mmx_packssdw:
4320 handleVectorPackIntrinsic(I, 32);
4321 break;
4323 case Intrinsic::x86_mmx_psad_bw:
4324 handleVectorSadIntrinsic(I, true);
4325 break;
4326 case Intrinsic::x86_sse2_psad_bw:
4327 case Intrinsic::x86_avx2_psad_bw:
4328 handleVectorSadIntrinsic(I);
4329 break;
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);
4336 break;
4338 case Intrinsic::x86_ssse3_pmadd_ub_sw:
4339 handleVectorPmaddIntrinsic(I, 8);
4340 break;
4342 case Intrinsic::x86_mmx_pmadd_wd:
4343 handleVectorPmaddIntrinsic(I, 16);
4344 break;
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);
4373 break;
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);
4380 break;
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);
4391 break;
4393 case Intrinsic::x86_pclmulqdq:
4394 case Intrinsic::x86_pclmulqdq_256:
4395 case Intrinsic::x86_pclmulqdq_512:
4396 handlePclmulIntrinsic(I);
4397 break;
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);
4404 break;
4406 case Intrinsic::x86_sse41_round_sd:
4407 case Intrinsic::x86_sse41_round_ss:
4408 handleUnarySdSsIntrinsic(I);
4409 break;
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);
4416 break;
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);
4437 break;
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);
4466 break;
4469 case Intrinsic::fshl:
4470 case Intrinsic::fshr:
4471 handleFunnelShift(I);
4472 break;
4474 case Intrinsic::is_constant:
4475 // The result of llvm.is.constant() is always defined.
4476 setShadow(&I, getCleanShadow(&I));
4477 setOrigin(&I, getCleanOrigin());
4478 break;
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);
4487 break;
4490 case Intrinsic::aarch64_neon_st2lane:
4491 case Intrinsic::aarch64_neon_st3lane:
4492 case Intrinsic::aarch64_neon_st4lane: {
4493 handleNEONVectorStoreIntrinsic(I, true);
4494 break;
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);
4516 break;
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);
4526 break;
4529 default:
4530 if (!handleUnknownIntrinsic(I))
4531 visitInstruction(I);
4532 break;
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),
4555 /*isStore*/ false);
4556 Value *DstShadowPtr =
4557 getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
4558 /*isStore*/ true)
4559 .first;
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),
4583 /*isStore*/ true)
4584 .first;
4586 // Atomic store always paints clean shadow/origin. See file header.
4587 IRB.CreateMemSet(DstShadowPtr, getCleanShadow(IRB.getInt8Ty()), Size,
4588 Align(1));
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);
4600 else
4601 visitInstruction(CB);
4602 return;
4604 LibFunc LF;
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
4608 // instrumentation.
4609 switch (LF) {
4610 case LibFunc_atomic_load:
4611 if (!isa<CallInst>(CB)) {
4612 llvm::errs() << "MSAN -- cannot instrument invoke of libatomic load."
4613 "Ignoring!\n";
4614 break;
4616 visitLibAtomicLoad(CB);
4617 return;
4618 case LibFunc_atomic_store:
4619 visitLibAtomicStore(CB);
4620 return;
4621 default:
4622 break;
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.
4634 AttributeMask B;
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");
4657 continue;
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);
4664 continue;
4667 unsigned Size = 0;
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;
4674 if (EagerCheck) {
4675 insertShadowCheck(A, &CB);
4676 Size = DL.getTypeAllocSize(A->getType());
4677 } else {
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");
4686 if (ByVal) {
4687 // ByVal requires some special handling as it's too big for a single
4688 // load
4689 assert(A->getType()->isPointerTy() &&
4690 "ByVal argument is not a pointer!");
4691 Size = DL.getTypeAllocSize(CB.getParamByValType(i));
4692 if (ArgOffset + Size > kParamTLSSize)
4693 break;
4694 const MaybeAlign ParamAlignment(CB.getParamAlign(i));
4695 MaybeAlign Alignment = std::nullopt;
4696 if (ParamAlignment)
4697 Alignment = std::min(*ParamAlignment, kShadowTLSAlignment);
4698 Value *AShadowPtr, *AOriginPtr;
4699 std::tie(AShadowPtr, AOriginPtr) =
4700 getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), Alignment,
4701 /*isStore*/ false);
4702 if (!PropagateShadow) {
4703 Store = IRB.CreateMemSet(ArgShadowBase,
4704 Constant::getNullValue(IRB.getInt8Ty()),
4705 Size, Alignment);
4706 } else {
4707 Store = IRB.CreateMemCpy(ArgShadowBase, Alignment, AShadowPtr,
4708 Alignment, Size);
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);
4714 IRB.CreateMemCpy(
4715 ArgOriginBase,
4716 /* by origin_tls[ArgOffset] */ kMinOriginAlignment,
4717 AOriginPtr,
4718 /* by getShadowOriginPtr */ kMinOriginAlignment, OriginSize);
4721 } else {
4722 // Any other parameters mean we need bit-grained tracking of uninit
4723 // data
4724 Size = DL.getTypeAllocSize(A->getType());
4725 if (ArgOffset + Size > kParamTLSSize)
4726 break;
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));
4735 (void)Store;
4736 assert(Store != nullptr);
4737 LLVM_DEBUG(dbgs() << " Param:" << *Store << "\n");
4739 assert(Size != 0);
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())
4751 return;
4752 // Don't emit the epilogue for musttail call returns.
4753 if (isa<CallInst>(CB) && cast<CallInst>(CB).isMustTailCall())
4754 return;
4756 if (MayCheckCall && CB.hasRetAttr(Attribute::NoUndef)) {
4757 setShadow(&CB, getCleanShadow(&CB));
4758 setOrigin(&CB, getCleanOrigin());
4759 return;
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());
4771 } else {
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());
4779 return;
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,
4790 "_msret");
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();
4803 return false;
4806 void visitReturnInst(ReturnInst &I) {
4807 IRBuilder<> IRB(&I);
4808 Value *RetVal = I.getReturnValue();
4809 if (!RetVal)
4810 return;
4811 // Don't emit the epilogue for musttail call returns.
4812 if (isAMustTailRetVal(RetVal))
4813 return;
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;
4823 if (EagerCheck) {
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
4830 // check
4831 if (StoreShadow) {
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());
4843 return;
4846 ShadowPHINodes.push_back(&I);
4847 setShadow(&I, IRB.CreatePHI(getShadowTy(&I), I.getNumIncomingValues(),
4848 "_msphi_s"));
4849 if (MS.TrackOrigins)
4850 setOrigin(
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,
4859 IntConst);
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});
4869 } else {
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});
4884 } else {
4885 IRB.CreateCall(MS.MsanSetAllocaOriginNoDescriptionFn, {&I, Len, Idptr});
4890 void poisonAllocaKmsan(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
4891 Value *Descr = getLocalVarDescription(I);
4892 if (PoisonStack) {
4893 IRB.CreateCall(MS.MsanPoisonAllocaFn, {&I, Len, Descr});
4894 } else {
4895 IRB.CreateCall(MS.MsanUnpoisonAllocaFn, {&I, Len});
4899 void instrumentAlloca(AllocaInst &I, Instruction *InsPoint = nullptr) {
4900 if (!InsPoint)
4901 InsPoint = &I;
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);
4912 else
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);
4946 Value *Sa1;
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()));
4952 } else {
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");
4966 setShadow(&I, Sa);
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) {
4981 // Do nothing.
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");
5020 setShadow(&I, Res);
5021 setOriginForNaryOp(I);
5024 void dumpInst(Instruction &I) {
5025 if (CallInst *CI = dyn_cast<CallInst>(&I)) {
5026 errs() << "ZZZ call " << CI->getCalledFunction()->getName() << "\n";
5027 } else {
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,
5050 bool isOutput) {
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) {
5059 assert(!isOutput);
5060 return;
5062 if (!ElemTy->isSized())
5063 return;
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});
5068 } else {
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
5072 // instructions.
5073 auto [ShadowPtr, _] =
5074 getShadowOriginPtrUserspace(Operand, IRB, IRB.getInt8Ty(), Align(1));
5075 if (Size <= 32)
5076 IRB.CreateAlignedStore(getCleanShadow(ElemTy), ShadowPtr, Align(1));
5077 else
5078 IRB.CreateMemSet(ShadowPtr, ConstantInt::getNullValue(IRB.getInt8Ty()),
5079 SizeVal, Align(1));
5083 /// Get the number of output arguments returned by pointers.
5084 int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
5085 int NumRetOutputs = 0;
5086 int NumOutputs = 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);
5091 if (ST)
5092 NumRetOutputs = ST->getNumElements();
5093 else
5094 NumRetOutputs = 1;
5096 InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints();
5097 for (const InlineAsm::ConstraintInfo &Info : Constraints) {
5098 switch (Info.Type) {
5099 case InlineAsm::isOutput:
5100 NumOutputs++;
5101 break;
5102 default:
5103 break;
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
5142 // remains valid.
5143 for (int i = 0; i < OutputArgs; i++) {
5144 Value *Operand = CB->getOperand(i);
5145 instrumentAsmArgument(Operand, CB->getParamElementType(i), I, IRB, DL,
5146 /*isOutput*/ true);
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)
5162 dumpInst(I);
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 {
5175 Function &F;
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,
5199 unsigned ArgSize) {
5200 // Make sure we don't overflow __msan_va_arg_tls.
5201 if (ArgOffset + ArgSize > kParamTLSSize)
5202 return nullptr;
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
5211 // overflow.
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
5220 // clean.
5221 if (BaseOffset >= kParamTLSSize)
5222 return;
5223 Value *TailSize =
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)
5242 return;
5243 VAStartInstrumentationList.push_back(&I);
5244 unpoisonVAListTagForInst(I);
5247 void visitVACopyInst(VACopyInst &I) override {
5248 if (F.getCallingConv() == CallingConv::Win64)
5249 return;
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;
5279 break;
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())
5288 return AK_Memory;
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;
5295 return AK_Memory;
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
5305 // order.
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);
5315 if (IsByVal) {
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.
5319 if (IsFixed)
5320 continue;
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,
5340 /*isStore*/ false);
5341 IRB.CreateMemCpy(ShadowBase, kShadowTLSAlignment, ShadowPtr,
5342 kShadowTLSAlignment, ArgSize);
5343 if (MS.TrackOrigins)
5344 IRB.CreateMemCpy(OriginBase, kShadowTLSAlignment, OriginPtr,
5345 kShadowTLSAlignment, ArgSize);
5346 } else {
5347 ArgKind AK = classifyArgument(A);
5348 if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
5349 AK = AK_Memory;
5350 if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
5351 AK = AK_Memory;
5352 Value *ShadowBase, *OriginBase = nullptr;
5353 switch (AK) {
5354 case AK_GeneralPurpose:
5355 ShadowBase = getShadowPtrForVAArgument(IRB, GpOffset);
5356 if (MS.TrackOrigins)
5357 OriginBase = getOriginPtrForVAArgument(IRB, GpOffset);
5358 GpOffset += 8;
5359 assert(GpOffset <= kParamTLSSize);
5360 break;
5361 case AK_FloatingPoint:
5362 ShadowBase = getShadowPtrForVAArgument(IRB, FpOffset);
5363 if (MS.TrackOrigins)
5364 OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
5365 FpOffset += 16;
5366 assert(FpOffset <= kParamTLSSize);
5367 break;
5368 case AK_Memory:
5369 if (IsFixed)
5370 continue;
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);
5382 continue;
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.
5388 if (IsFixed)
5389 continue;
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);
5412 VAArgOverflowSize =
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)),
5443 MS.PtrTy);
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,
5451 AMD64FpEndOffset);
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)),
5458 MS.PtrTy);
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,
5466 AMD64FpEndOffset);
5467 IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
5468 VAArgOverflowSize);
5469 if (MS.TrackOrigins) {
5470 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
5471 AMD64FpEndOffset);
5472 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
5473 VAArgOverflowSize);
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();
5511 return R;
5514 if (const FixedVectorType *FV = dyn_cast<FixedVectorType>(T)) {
5515 auto R = classifyArgument(FV->getScalarType());
5516 R.second *= FV->getNumElements();
5517 return R;
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)
5544 AK = AK_Memory;
5545 if (AK == AK_FloatingPoint &&
5546 (VrOffset + RegNum * 16) > AArch64VrEndOffset)
5547 AK = AK_Memory;
5548 Value *Base;
5549 switch (AK) {
5550 case AK_GeneralPurpose:
5551 Base = getShadowPtrForVAArgument(IRB, GrOffset);
5552 GrOffset += 8 * RegNum;
5553 break;
5554 case AK_FloatingPoint:
5555 Base = getShadowPtrForVAArgument(IRB, VrOffset);
5556 VrOffset += 16 * RegNum;
5557 break;
5558 case AK_Memory:
5559 // Don't count fixed arguments in the overflow area - va_start will
5560 // skip right over them.
5561 if (IsFixed)
5562 continue;
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);
5571 continue;
5573 break;
5575 // Count Gp/Vr fixed arguments to their respective offsets, but don't
5576 // bother to actually store a shadow.
5577 if (IsFixed)
5578 continue;
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)),
5591 MS.PtrTy);
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)),
5600 MS.PtrTy);
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);
5612 VAArgOverflowSize =
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)
5680 .first;
5682 Value *GrSrcPtr =
5683 IRB.CreateInBoundsPtrAdd(VAArgTLSCopy, GrRegSaveAreaShadowPtrOff);
5684 Value *GrCopySize = IRB.CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
5686 IRB.CreateMemCpy(GrRegSaveAreaShadowPtr, Align(8), GrSrcPtr, Align(8),
5687 GrCopySize);
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)
5696 .first;
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),
5705 VrCopySize);
5707 // And finally for remaining arguments.
5708 Value *StackSaveAreaShadowPtr =
5709 MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.getInt8Ty(),
5710 Align(16), /*isStore*/ true)
5711 .first;
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
5737 // them.
5738 unsigned VAArgBase;
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())
5745 VAArgBase = 32;
5746 else
5747 VAArgBase = 48;
5748 } else {
5749 // Parameter save area is 8 bytes from frame pointer in PPC32
5750 VAArgBase = 8;
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);
5757 if (IsByVal) {
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));
5762 if (ArgAlign < 8)
5763 ArgAlign = Align(8);
5764 VAArgOffset = alignTo(VAArgOffset, ArgAlign);
5765 if (!IsFixed) {
5766 Value *Base =
5767 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
5768 if (Base) {
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));
5779 } else {
5780 Value *Base;
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);
5793 if (ArgAlign < 8)
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
5799 if (ArgSize < 8)
5800 VAArgOffset += (8 - ArgSize);
5802 if (!IsFixed) {
5803 Base =
5804 getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
5805 if (Base)
5806 IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
5808 VAArgOffset += ArgSize;
5809 VAArgOffset = alignTo(VAArgOffset, Align(8));
5811 if (IsFixed)
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()) {
5855 RegSaveAreaPtrPtr =
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,
5869 CopySize);
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 {
5893 GeneralPurpose,
5894 FloatingPoint,
5895 Vector,
5896 Memory,
5897 Indirect,
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
5913 // back end.
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);
5933 if (ZExt) {
5934 assert(!SExt);
5935 return ShadowExtension::Zero;
5937 if (SExt) {
5938 assert(!ZExt);
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) {
5957 T = MS.PtrTy;
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;
5969 switch (AK) {
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) {
5974 if (!IsFixed) {
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;
5987 } else {
5988 GpOffset = kParamTLSSize;
5990 break;
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) {
5996 if (!IsFixed) {
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;
6006 } else {
6007 FpOffset = kParamTLSSize;
6009 break;
6011 case ArgKind::Vector: {
6012 // Keep track of VrIndex. No need to store shadow, since vector varargs
6013 // go through AK_Memory.
6014 assert(IsFixed);
6015 VrIndex++;
6016 break;
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.
6022 if (!IsFixed) {
6023 uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
6024 uint64_t ArgSize = alignTo(ArgAllocSize, 8);
6025 if (OverflowOffset + ArgSize <= kParamTLSSize) {
6026 SE = getShadowExtension(CB, ArgNo);
6027 uint64_t GapSize =
6028 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
6029 ShadowBase =
6030 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
6031 if (MS.TrackOrigins)
6032 OriginBase =
6033 getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
6034 OverflowOffset += ArgSize;
6035 } else {
6036 OverflowOffset = kParamTLSSize;
6039 break;
6041 case ArgKind::Indirect:
6042 llvm_unreachable("Indirect must be converted to GeneralPurpose");
6044 if (ShadowBase == nullptr)
6045 continue;
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(
6066 IRB.CreateAdd(
6067 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
6068 ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
6069 MS.PtrTy);
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,
6075 /*isStore*/ true);
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,
6082 RegSaveAreaSize);
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(
6092 IRB.CreateAdd(
6093 IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
6094 ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
6095 MS.PtrTy);
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,
6105 VAArgOverflowSize);
6106 if (MS.TrackOrigins) {
6107 SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
6108 SystemZOverflowOffset);
6109 IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
6110 VAArgOverflowSize);
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);
6121 VAArgOverflowSize =
6122 IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
6123 Value *CopySize =
6124 IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
6125 VAArgOverflowSize);
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);
6171 if (IsByVal) {
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);
6179 if (!IsFixed) {
6180 Value *Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
6181 if (Base) {
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));
6192 } else {
6193 Value *Base;
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);
6203 if (!IsFixed) {
6204 Base = getShadowPtrForVAArgument(IRB, VAArgOffset, ArgSize);
6205 if (Base)
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,
6260 CopySize);
6265 /// Implementation of VarArgHelper that is used for ARM32, MIPS, RISCV,
6266 /// LoongArch64.
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();
6281 if (IsFixed)
6282 continue;
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);
6293 if (!Base)
6294 continue;
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,
6345 CopySize);
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)
6423 return false;
6425 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
6426 return false;
6428 MemorySanitizerVisitor Visitor(F, *this, TLI);
6430 // Clear out memory attributes.
6431 AttributeMask B;
6432 B.addAttribute(Attribute::Memory).addAttribute(Attribute::Speculatable);
6433 F.removeFnAttrs(B);
6435 return Visitor.runOnFunction();