106f32e7eSjoerg //===- MemorySanitizer.cpp - detector of uninitialized reads --------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg /// \file
1006f32e7eSjoerg /// This file is a part of MemorySanitizer, a detector of uninitialized
1106f32e7eSjoerg /// reads.
1206f32e7eSjoerg ///
1306f32e7eSjoerg /// The algorithm of the tool is similar to Memcheck
1406f32e7eSjoerg /// (http://goo.gl/QKbem). We associate a few shadow bits with every
1506f32e7eSjoerg /// byte of the application memory, poison the shadow of the malloc-ed
1606f32e7eSjoerg /// or alloca-ed memory, load the shadow bits on every memory read,
1706f32e7eSjoerg /// propagate the shadow bits through some of the arithmetic
1806f32e7eSjoerg /// instruction (including MOV), store the shadow bits on every memory
1906f32e7eSjoerg /// write, report a bug on some other instructions (e.g. JMP) if the
2006f32e7eSjoerg /// associated shadow is poisoned.
2106f32e7eSjoerg ///
2206f32e7eSjoerg /// But there are differences too. The first and the major one:
2306f32e7eSjoerg /// compiler instrumentation instead of binary instrumentation. This
2406f32e7eSjoerg /// gives us much better register allocation, possible compiler
2506f32e7eSjoerg /// optimizations and a fast start-up. But this brings the major issue
2606f32e7eSjoerg /// as well: msan needs to see all program events, including system
2706f32e7eSjoerg /// calls and reads/writes in system libraries, so we either need to
2806f32e7eSjoerg /// compile *everything* with msan or use a binary translation
2906f32e7eSjoerg /// component (e.g. DynamoRIO) to instrument pre-built libraries.
3006f32e7eSjoerg /// Another difference from Memcheck is that we use 8 shadow bits per
3106f32e7eSjoerg /// byte of application memory and use a direct shadow mapping. This
3206f32e7eSjoerg /// greatly simplifies the instrumentation code and avoids races on
3306f32e7eSjoerg /// shadow updates (Memcheck is single-threaded so races are not a
3406f32e7eSjoerg /// concern there. Memcheck uses 2 shadow bits per byte with a slow
3506f32e7eSjoerg /// path storage that uses 8 bits per byte).
3606f32e7eSjoerg ///
3706f32e7eSjoerg /// The default value of shadow is 0, which means "clean" (not poisoned).
3806f32e7eSjoerg ///
3906f32e7eSjoerg /// Every module initializer should call __msan_init to ensure that the
4006f32e7eSjoerg /// shadow memory is ready. On error, __msan_warning is called. Since
4106f32e7eSjoerg /// parameters and return values may be passed via registers, we have a
4206f32e7eSjoerg /// specialized thread-local shadow for return values
4306f32e7eSjoerg /// (__msan_retval_tls) and parameters (__msan_param_tls).
4406f32e7eSjoerg ///
4506f32e7eSjoerg ///                           Origin tracking.
4606f32e7eSjoerg ///
4706f32e7eSjoerg /// MemorySanitizer can track origins (allocation points) of all uninitialized
4806f32e7eSjoerg /// values. This behavior is controlled with a flag (msan-track-origins) and is
4906f32e7eSjoerg /// disabled by default.
5006f32e7eSjoerg ///
5106f32e7eSjoerg /// Origins are 4-byte values created and interpreted by the runtime library.
5206f32e7eSjoerg /// They are stored in a second shadow mapping, one 4-byte value for 4 bytes
5306f32e7eSjoerg /// of application memory. Propagation of origins is basically a bunch of
5406f32e7eSjoerg /// "select" instructions that pick the origin of a dirty argument, if an
5506f32e7eSjoerg /// instruction has one.
5606f32e7eSjoerg ///
5706f32e7eSjoerg /// Every 4 aligned, consecutive bytes of application memory have one origin
5806f32e7eSjoerg /// value associated with them. If these bytes contain uninitialized data
5906f32e7eSjoerg /// coming from 2 different allocations, the last store wins. Because of this,
6006f32e7eSjoerg /// MemorySanitizer reports can show unrelated origins, but this is unlikely in
6106f32e7eSjoerg /// practice.
6206f32e7eSjoerg ///
6306f32e7eSjoerg /// Origins are meaningless for fully initialized values, so MemorySanitizer
6406f32e7eSjoerg /// avoids storing origin to memory when a fully initialized value is stored.
65*da58b97aSjoerg /// This way it avoids needless overwriting origin of the 4-byte region on
6606f32e7eSjoerg /// a short (i.e. 1 byte) clean store, and it is also good for performance.
6706f32e7eSjoerg ///
6806f32e7eSjoerg ///                            Atomic handling.
6906f32e7eSjoerg ///
7006f32e7eSjoerg /// Ideally, every atomic store of application value should update the
7106f32e7eSjoerg /// corresponding shadow location in an atomic way. Unfortunately, atomic store
7206f32e7eSjoerg /// of two disjoint locations can not be done without severe slowdown.
7306f32e7eSjoerg ///
7406f32e7eSjoerg /// Therefore, we implement an approximation that may err on the safe side.
7506f32e7eSjoerg /// In this implementation, every atomically accessed location in the program
7606f32e7eSjoerg /// may only change from (partially) uninitialized to fully initialized, but
7706f32e7eSjoerg /// not the other way around. We load the shadow _after_ the application load,
7806f32e7eSjoerg /// and we store the shadow _before_ the app store. Also, we always store clean
7906f32e7eSjoerg /// shadow (if the application store is atomic). This way, if the store-load
8006f32e7eSjoerg /// pair constitutes a happens-before arc, shadow store and load are correctly
8106f32e7eSjoerg /// ordered such that the load will get either the value that was stored, or
8206f32e7eSjoerg /// some later value (which is always clean).
8306f32e7eSjoerg ///
8406f32e7eSjoerg /// This does not work very well with Compare-And-Swap (CAS) and
8506f32e7eSjoerg /// Read-Modify-Write (RMW) operations. To follow the above logic, CAS and RMW
8606f32e7eSjoerg /// must store the new shadow before the app operation, and load the shadow
8706f32e7eSjoerg /// after the app operation. Computers don't work this way. Current
8806f32e7eSjoerg /// implementation ignores the load aspect of CAS/RMW, always returning a clean
8906f32e7eSjoerg /// value. It implements the store part as a simple atomic store by storing a
9006f32e7eSjoerg /// clean shadow.
9106f32e7eSjoerg ///
9206f32e7eSjoerg ///                      Instrumenting inline assembly.
9306f32e7eSjoerg ///
9406f32e7eSjoerg /// For inline assembly code LLVM has little idea about which memory locations
9506f32e7eSjoerg /// become initialized depending on the arguments. It can be possible to figure
9606f32e7eSjoerg /// out which arguments are meant to point to inputs and outputs, but the
9706f32e7eSjoerg /// actual semantics can be only visible at runtime. In the Linux kernel it's
9806f32e7eSjoerg /// also possible that the arguments only indicate the offset for a base taken
9906f32e7eSjoerg /// from a segment register, so it's dangerous to treat any asm() arguments as
10006f32e7eSjoerg /// pointers. We take a conservative approach generating calls to
10106f32e7eSjoerg ///   __msan_instrument_asm_store(ptr, size)
10206f32e7eSjoerg /// , which defer the memory unpoisoning to the runtime library.
10306f32e7eSjoerg /// The latter can perform more complex address checks to figure out whether
10406f32e7eSjoerg /// it's safe to touch the shadow memory.
10506f32e7eSjoerg /// Like with atomic operations, we call __msan_instrument_asm_store() before
10606f32e7eSjoerg /// the assembly call, so that changes to the shadow memory will be seen by
10706f32e7eSjoerg /// other threads together with main memory initialization.
10806f32e7eSjoerg ///
10906f32e7eSjoerg ///                  KernelMemorySanitizer (KMSAN) implementation.
11006f32e7eSjoerg ///
11106f32e7eSjoerg /// The major differences between KMSAN and MSan instrumentation are:
11206f32e7eSjoerg ///  - KMSAN always tracks the origins and implies msan-keep-going=true;
11306f32e7eSjoerg ///  - KMSAN allocates shadow and origin memory for each page separately, so
11406f32e7eSjoerg ///    there are no explicit accesses to shadow and origin in the
11506f32e7eSjoerg ///    instrumentation.
11606f32e7eSjoerg ///    Shadow and origin values for a particular X-byte memory location
11706f32e7eSjoerg ///    (X=1,2,4,8) are accessed through pointers obtained via the
11806f32e7eSjoerg ///      __msan_metadata_ptr_for_load_X(ptr)
11906f32e7eSjoerg ///      __msan_metadata_ptr_for_store_X(ptr)
12006f32e7eSjoerg ///    functions. The corresponding functions check that the X-byte accesses
12106f32e7eSjoerg ///    are possible and returns the pointers to shadow and origin memory.
12206f32e7eSjoerg ///    Arbitrary sized accesses are handled with:
12306f32e7eSjoerg ///      __msan_metadata_ptr_for_load_n(ptr, size)
12406f32e7eSjoerg ///      __msan_metadata_ptr_for_store_n(ptr, size);
12506f32e7eSjoerg ///  - TLS variables are stored in a single per-task struct. A call to a
12606f32e7eSjoerg ///    function __msan_get_context_state() returning a pointer to that struct
12706f32e7eSjoerg ///    is inserted into every instrumented function before the entry block;
12806f32e7eSjoerg ///  - __msan_warning() takes a 32-bit origin parameter;
12906f32e7eSjoerg ///  - local variables are poisoned with __msan_poison_alloca() upon function
13006f32e7eSjoerg ///    entry and unpoisoned with __msan_unpoison_alloca() before leaving the
13106f32e7eSjoerg ///    function;
13206f32e7eSjoerg ///  - the pass doesn't declare any global variables or add global constructors
13306f32e7eSjoerg ///    to the translation unit.
13406f32e7eSjoerg ///
13506f32e7eSjoerg /// Also, KMSAN currently ignores uninitialized memory passed into inline asm
13606f32e7eSjoerg /// calls, making sure we're on the safe side wrt. possible false positives.
13706f32e7eSjoerg ///
13806f32e7eSjoerg ///  KernelMemorySanitizer only supports X86_64 at the moment.
13906f32e7eSjoerg ///
140*da58b97aSjoerg //
141*da58b97aSjoerg // FIXME: This sanitizer does not yet handle scalable vectors
142*da58b97aSjoerg //
14306f32e7eSjoerg //===----------------------------------------------------------------------===//
14406f32e7eSjoerg 
14506f32e7eSjoerg #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
14606f32e7eSjoerg #include "llvm/ADT/APInt.h"
14706f32e7eSjoerg #include "llvm/ADT/ArrayRef.h"
14806f32e7eSjoerg #include "llvm/ADT/DepthFirstIterator.h"
14906f32e7eSjoerg #include "llvm/ADT/SmallSet.h"
15006f32e7eSjoerg #include "llvm/ADT/SmallString.h"
15106f32e7eSjoerg #include "llvm/ADT/SmallVector.h"
15206f32e7eSjoerg #include "llvm/ADT/StringExtras.h"
15306f32e7eSjoerg #include "llvm/ADT/StringRef.h"
15406f32e7eSjoerg #include "llvm/ADT/Triple.h"
15506f32e7eSjoerg #include "llvm/Analysis/TargetLibraryInfo.h"
156*da58b97aSjoerg #include "llvm/Analysis/ValueTracking.h"
15706f32e7eSjoerg #include "llvm/IR/Argument.h"
15806f32e7eSjoerg #include "llvm/IR/Attributes.h"
15906f32e7eSjoerg #include "llvm/IR/BasicBlock.h"
16006f32e7eSjoerg #include "llvm/IR/CallingConv.h"
16106f32e7eSjoerg #include "llvm/IR/Constant.h"
16206f32e7eSjoerg #include "llvm/IR/Constants.h"
16306f32e7eSjoerg #include "llvm/IR/DataLayout.h"
16406f32e7eSjoerg #include "llvm/IR/DerivedTypes.h"
16506f32e7eSjoerg #include "llvm/IR/Function.h"
16606f32e7eSjoerg #include "llvm/IR/GlobalValue.h"
16706f32e7eSjoerg #include "llvm/IR/GlobalVariable.h"
16806f32e7eSjoerg #include "llvm/IR/IRBuilder.h"
16906f32e7eSjoerg #include "llvm/IR/InlineAsm.h"
17006f32e7eSjoerg #include "llvm/IR/InstVisitor.h"
17106f32e7eSjoerg #include "llvm/IR/InstrTypes.h"
17206f32e7eSjoerg #include "llvm/IR/Instruction.h"
17306f32e7eSjoerg #include "llvm/IR/Instructions.h"
17406f32e7eSjoerg #include "llvm/IR/IntrinsicInst.h"
17506f32e7eSjoerg #include "llvm/IR/Intrinsics.h"
176*da58b97aSjoerg #include "llvm/IR/IntrinsicsX86.h"
17706f32e7eSjoerg #include "llvm/IR/LLVMContext.h"
17806f32e7eSjoerg #include "llvm/IR/MDBuilder.h"
17906f32e7eSjoerg #include "llvm/IR/Module.h"
18006f32e7eSjoerg #include "llvm/IR/Type.h"
18106f32e7eSjoerg #include "llvm/IR/Value.h"
18206f32e7eSjoerg #include "llvm/IR/ValueMap.h"
183*da58b97aSjoerg #include "llvm/InitializePasses.h"
18406f32e7eSjoerg #include "llvm/Pass.h"
18506f32e7eSjoerg #include "llvm/Support/AtomicOrdering.h"
18606f32e7eSjoerg #include "llvm/Support/Casting.h"
18706f32e7eSjoerg #include "llvm/Support/CommandLine.h"
18806f32e7eSjoerg #include "llvm/Support/Compiler.h"
18906f32e7eSjoerg #include "llvm/Support/Debug.h"
19006f32e7eSjoerg #include "llvm/Support/ErrorHandling.h"
19106f32e7eSjoerg #include "llvm/Support/MathExtras.h"
19206f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
19306f32e7eSjoerg #include "llvm/Transforms/Instrumentation.h"
19406f32e7eSjoerg #include "llvm/Transforms/Utils/BasicBlockUtils.h"
19506f32e7eSjoerg #include "llvm/Transforms/Utils/Local.h"
19606f32e7eSjoerg #include "llvm/Transforms/Utils/ModuleUtils.h"
19706f32e7eSjoerg #include <algorithm>
19806f32e7eSjoerg #include <cassert>
19906f32e7eSjoerg #include <cstddef>
20006f32e7eSjoerg #include <cstdint>
20106f32e7eSjoerg #include <memory>
20206f32e7eSjoerg #include <string>
20306f32e7eSjoerg #include <tuple>
20406f32e7eSjoerg 
20506f32e7eSjoerg using namespace llvm;
20606f32e7eSjoerg 
20706f32e7eSjoerg #define DEBUG_TYPE "msan"
20806f32e7eSjoerg 
20906f32e7eSjoerg static const unsigned kOriginSize = 4;
210*da58b97aSjoerg static const Align kMinOriginAlignment = Align(4);
211*da58b97aSjoerg static const Align kShadowTLSAlignment = Align(8);
21206f32e7eSjoerg 
21306f32e7eSjoerg // These constants must be kept in sync with the ones in msan.h.
21406f32e7eSjoerg static const unsigned kParamTLSSize = 800;
21506f32e7eSjoerg static const unsigned kRetvalTLSSize = 800;
21606f32e7eSjoerg 
21706f32e7eSjoerg // Accesses sizes are powers of two: 1, 2, 4, 8.
21806f32e7eSjoerg static const size_t kNumberOfAccessSizes = 4;
21906f32e7eSjoerg 
22006f32e7eSjoerg /// Track origins of uninitialized values.
22106f32e7eSjoerg ///
22206f32e7eSjoerg /// Adds a section to MemorySanitizer report that points to the allocation
22306f32e7eSjoerg /// (stack or heap) the uninitialized bits came from originally.
22406f32e7eSjoerg static cl::opt<int> ClTrackOrigins("msan-track-origins",
22506f32e7eSjoerg        cl::desc("Track origins (allocation sites) of poisoned memory"),
22606f32e7eSjoerg        cl::Hidden, cl::init(0));
22706f32e7eSjoerg 
22806f32e7eSjoerg static cl::opt<bool> ClKeepGoing("msan-keep-going",
22906f32e7eSjoerg        cl::desc("keep going after reporting a UMR"),
23006f32e7eSjoerg        cl::Hidden, cl::init(false));
23106f32e7eSjoerg 
23206f32e7eSjoerg static cl::opt<bool> ClPoisonStack("msan-poison-stack",
23306f32e7eSjoerg        cl::desc("poison uninitialized stack variables"),
23406f32e7eSjoerg        cl::Hidden, cl::init(true));
23506f32e7eSjoerg 
23606f32e7eSjoerg static cl::opt<bool> ClPoisonStackWithCall("msan-poison-stack-with-call",
23706f32e7eSjoerg        cl::desc("poison uninitialized stack variables with a call"),
23806f32e7eSjoerg        cl::Hidden, cl::init(false));
23906f32e7eSjoerg 
24006f32e7eSjoerg static cl::opt<int> ClPoisonStackPattern("msan-poison-stack-pattern",
24106f32e7eSjoerg        cl::desc("poison uninitialized stack variables with the given pattern"),
24206f32e7eSjoerg        cl::Hidden, cl::init(0xff));
24306f32e7eSjoerg 
24406f32e7eSjoerg static cl::opt<bool> ClPoisonUndef("msan-poison-undef",
24506f32e7eSjoerg        cl::desc("poison undef temps"),
24606f32e7eSjoerg        cl::Hidden, cl::init(true));
24706f32e7eSjoerg 
24806f32e7eSjoerg static cl::opt<bool> ClHandleICmp("msan-handle-icmp",
24906f32e7eSjoerg        cl::desc("propagate shadow through ICmpEQ and ICmpNE"),
25006f32e7eSjoerg        cl::Hidden, cl::init(true));
25106f32e7eSjoerg 
25206f32e7eSjoerg static cl::opt<bool> ClHandleICmpExact("msan-handle-icmp-exact",
25306f32e7eSjoerg        cl::desc("exact handling of relational integer ICmp"),
25406f32e7eSjoerg        cl::Hidden, cl::init(false));
25506f32e7eSjoerg 
25606f32e7eSjoerg static cl::opt<bool> ClHandleLifetimeIntrinsics(
25706f32e7eSjoerg     "msan-handle-lifetime-intrinsics",
25806f32e7eSjoerg     cl::desc(
25906f32e7eSjoerg         "when possible, poison scoped variables at the beginning of the scope "
26006f32e7eSjoerg         "(slower, but more precise)"),
26106f32e7eSjoerg     cl::Hidden, cl::init(true));
26206f32e7eSjoerg 
26306f32e7eSjoerg // When compiling the Linux kernel, we sometimes see false positives related to
26406f32e7eSjoerg // MSan being unable to understand that inline assembly calls may initialize
26506f32e7eSjoerg // local variables.
26606f32e7eSjoerg // This flag makes the compiler conservatively unpoison every memory location
26706f32e7eSjoerg // passed into an assembly call. Note that this may cause false positives.
26806f32e7eSjoerg // Because it's impossible to figure out the array sizes, we can only unpoison
26906f32e7eSjoerg // the first sizeof(type) bytes for each type* pointer.
27006f32e7eSjoerg // The instrumentation is only enabled in KMSAN builds, and only if
27106f32e7eSjoerg // -msan-handle-asm-conservative is on. This is done because we may want to
27206f32e7eSjoerg // quickly disable assembly instrumentation when it breaks.
27306f32e7eSjoerg static cl::opt<bool> ClHandleAsmConservative(
27406f32e7eSjoerg     "msan-handle-asm-conservative",
27506f32e7eSjoerg     cl::desc("conservative handling of inline assembly"), cl::Hidden,
27606f32e7eSjoerg     cl::init(true));
27706f32e7eSjoerg 
27806f32e7eSjoerg // This flag controls whether we check the shadow of the address
27906f32e7eSjoerg // operand of load or store. Such bugs are very rare, since load from
28006f32e7eSjoerg // a garbage address typically results in SEGV, but still happen
28106f32e7eSjoerg // (e.g. only lower bits of address are garbage, or the access happens
28206f32e7eSjoerg // early at program startup where malloc-ed memory is more likely to
28306f32e7eSjoerg // be zeroed. As of 2012-08-28 this flag adds 20% slowdown.
28406f32e7eSjoerg static cl::opt<bool> ClCheckAccessAddress("msan-check-access-address",
28506f32e7eSjoerg        cl::desc("report accesses through a pointer which has poisoned shadow"),
28606f32e7eSjoerg        cl::Hidden, cl::init(true));
28706f32e7eSjoerg 
288*da58b97aSjoerg static cl::opt<bool> ClEagerChecks(
289*da58b97aSjoerg     "msan-eager-checks",
290*da58b97aSjoerg     cl::desc("check arguments and return values at function call boundaries"),
291*da58b97aSjoerg     cl::Hidden, cl::init(false));
292*da58b97aSjoerg 
29306f32e7eSjoerg static cl::opt<bool> ClDumpStrictInstructions("msan-dump-strict-instructions",
29406f32e7eSjoerg        cl::desc("print out instructions with default strict semantics"),
29506f32e7eSjoerg        cl::Hidden, cl::init(false));
29606f32e7eSjoerg 
29706f32e7eSjoerg static cl::opt<int> ClInstrumentationWithCallThreshold(
29806f32e7eSjoerg     "msan-instrumentation-with-call-threshold",
29906f32e7eSjoerg     cl::desc(
30006f32e7eSjoerg         "If the function being instrumented requires more than "
30106f32e7eSjoerg         "this number of checks and origin stores, use callbacks instead of "
30206f32e7eSjoerg         "inline checks (-1 means never use callbacks)."),
30306f32e7eSjoerg     cl::Hidden, cl::init(3500));
30406f32e7eSjoerg 
30506f32e7eSjoerg static cl::opt<bool>
30606f32e7eSjoerg     ClEnableKmsan("msan-kernel",
30706f32e7eSjoerg                   cl::desc("Enable KernelMemorySanitizer instrumentation"),
30806f32e7eSjoerg                   cl::Hidden, cl::init(false));
30906f32e7eSjoerg 
31006f32e7eSjoerg // This is an experiment to enable handling of cases where shadow is a non-zero
31106f32e7eSjoerg // compile-time constant. For some unexplainable reason they were silently
31206f32e7eSjoerg // ignored in the instrumentation.
31306f32e7eSjoerg static cl::opt<bool> ClCheckConstantShadow("msan-check-constant-shadow",
31406f32e7eSjoerg        cl::desc("Insert checks for constant shadow values"),
31506f32e7eSjoerg        cl::Hidden, cl::init(false));
31606f32e7eSjoerg 
31706f32e7eSjoerg // This is off by default because of a bug in gold:
31806f32e7eSjoerg // https://sourceware.org/bugzilla/show_bug.cgi?id=19002
31906f32e7eSjoerg static cl::opt<bool> ClWithComdat("msan-with-comdat",
32006f32e7eSjoerg        cl::desc("Place MSan constructors in comdat sections"),
32106f32e7eSjoerg        cl::Hidden, cl::init(false));
32206f32e7eSjoerg 
32306f32e7eSjoerg // These options allow to specify custom memory map parameters
32406f32e7eSjoerg // See MemoryMapParams for details.
32506f32e7eSjoerg static cl::opt<uint64_t> ClAndMask("msan-and-mask",
32606f32e7eSjoerg                                    cl::desc("Define custom MSan AndMask"),
32706f32e7eSjoerg                                    cl::Hidden, cl::init(0));
32806f32e7eSjoerg 
32906f32e7eSjoerg static cl::opt<uint64_t> ClXorMask("msan-xor-mask",
33006f32e7eSjoerg                                    cl::desc("Define custom MSan XorMask"),
33106f32e7eSjoerg                                    cl::Hidden, cl::init(0));
33206f32e7eSjoerg 
33306f32e7eSjoerg static cl::opt<uint64_t> ClShadowBase("msan-shadow-base",
33406f32e7eSjoerg                                       cl::desc("Define custom MSan ShadowBase"),
33506f32e7eSjoerg                                       cl::Hidden, cl::init(0));
33606f32e7eSjoerg 
33706f32e7eSjoerg static cl::opt<uint64_t> ClOriginBase("msan-origin-base",
33806f32e7eSjoerg                                       cl::desc("Define custom MSan OriginBase"),
33906f32e7eSjoerg                                       cl::Hidden, cl::init(0));
34006f32e7eSjoerg 
341*da58b97aSjoerg const char kMsanModuleCtorName[] = "msan.module_ctor";
342*da58b97aSjoerg const char kMsanInitName[] = "__msan_init";
34306f32e7eSjoerg 
34406f32e7eSjoerg namespace {
34506f32e7eSjoerg 
34606f32e7eSjoerg // Memory map parameters used in application-to-shadow address calculation.
34706f32e7eSjoerg // Offset = (Addr & ~AndMask) ^ XorMask
34806f32e7eSjoerg // Shadow = ShadowBase + Offset
34906f32e7eSjoerg // Origin = OriginBase + Offset
35006f32e7eSjoerg struct MemoryMapParams {
35106f32e7eSjoerg   uint64_t AndMask;
35206f32e7eSjoerg   uint64_t XorMask;
35306f32e7eSjoerg   uint64_t ShadowBase;
35406f32e7eSjoerg   uint64_t OriginBase;
35506f32e7eSjoerg };
35606f32e7eSjoerg 
35706f32e7eSjoerg struct PlatformMemoryMapParams {
35806f32e7eSjoerg   const MemoryMapParams *bits32;
35906f32e7eSjoerg   const MemoryMapParams *bits64;
36006f32e7eSjoerg };
36106f32e7eSjoerg 
36206f32e7eSjoerg } // end anonymous namespace
36306f32e7eSjoerg 
36406f32e7eSjoerg // i386 Linux
36506f32e7eSjoerg static const MemoryMapParams Linux_I386_MemoryMapParams = {
36606f32e7eSjoerg   0x000080000000,  // AndMask
36706f32e7eSjoerg   0,               // XorMask (not used)
36806f32e7eSjoerg   0,               // ShadowBase (not used)
36906f32e7eSjoerg   0x000040000000,  // OriginBase
37006f32e7eSjoerg };
37106f32e7eSjoerg 
37206f32e7eSjoerg // x86_64 Linux
37306f32e7eSjoerg static const MemoryMapParams Linux_X86_64_MemoryMapParams = {
37406f32e7eSjoerg #ifdef MSAN_LINUX_X86_64_OLD_MAPPING
37506f32e7eSjoerg   0x400000000000,  // AndMask
37606f32e7eSjoerg   0,               // XorMask (not used)
37706f32e7eSjoerg   0,               // ShadowBase (not used)
37806f32e7eSjoerg   0x200000000000,  // OriginBase
37906f32e7eSjoerg #else
38006f32e7eSjoerg   0,               // AndMask (not used)
38106f32e7eSjoerg   0x500000000000,  // XorMask
38206f32e7eSjoerg   0,               // ShadowBase (not used)
38306f32e7eSjoerg   0x100000000000,  // OriginBase
38406f32e7eSjoerg #endif
38506f32e7eSjoerg };
38606f32e7eSjoerg 
38706f32e7eSjoerg // mips64 Linux
38806f32e7eSjoerg static const MemoryMapParams Linux_MIPS64_MemoryMapParams = {
38906f32e7eSjoerg   0,               // AndMask (not used)
39006f32e7eSjoerg   0x008000000000,  // XorMask
39106f32e7eSjoerg   0,               // ShadowBase (not used)
39206f32e7eSjoerg   0x002000000000,  // OriginBase
39306f32e7eSjoerg };
39406f32e7eSjoerg 
39506f32e7eSjoerg // ppc64 Linux
39606f32e7eSjoerg static const MemoryMapParams Linux_PowerPC64_MemoryMapParams = {
39706f32e7eSjoerg   0xE00000000000,  // AndMask
39806f32e7eSjoerg   0x100000000000,  // XorMask
39906f32e7eSjoerg   0x080000000000,  // ShadowBase
40006f32e7eSjoerg   0x1C0000000000,  // OriginBase
40106f32e7eSjoerg };
40206f32e7eSjoerg 
403*da58b97aSjoerg // s390x Linux
404*da58b97aSjoerg static const MemoryMapParams Linux_S390X_MemoryMapParams = {
405*da58b97aSjoerg     0xC00000000000, // AndMask
406*da58b97aSjoerg     0,              // XorMask (not used)
407*da58b97aSjoerg     0x080000000000, // ShadowBase
408*da58b97aSjoerg     0x1C0000000000, // OriginBase
409*da58b97aSjoerg };
410*da58b97aSjoerg 
41106f32e7eSjoerg // aarch64 Linux
41206f32e7eSjoerg static const MemoryMapParams Linux_AArch64_MemoryMapParams = {
41306f32e7eSjoerg   0,               // AndMask (not used)
41406f32e7eSjoerg   0x06000000000,   // XorMask
41506f32e7eSjoerg   0,               // ShadowBase (not used)
41606f32e7eSjoerg   0x01000000000,   // OriginBase
41706f32e7eSjoerg };
41806f32e7eSjoerg 
41906f32e7eSjoerg // i386 FreeBSD
42006f32e7eSjoerg static const MemoryMapParams FreeBSD_I386_MemoryMapParams = {
42106f32e7eSjoerg   0x000180000000,  // AndMask
42206f32e7eSjoerg   0x000040000000,  // XorMask
42306f32e7eSjoerg   0x000020000000,  // ShadowBase
42406f32e7eSjoerg   0x000700000000,  // OriginBase
42506f32e7eSjoerg };
42606f32e7eSjoerg 
42706f32e7eSjoerg // x86_64 FreeBSD
42806f32e7eSjoerg static const MemoryMapParams FreeBSD_X86_64_MemoryMapParams = {
42906f32e7eSjoerg   0xc00000000000,  // AndMask
43006f32e7eSjoerg   0x200000000000,  // XorMask
43106f32e7eSjoerg   0x100000000000,  // ShadowBase
43206f32e7eSjoerg   0x380000000000,  // OriginBase
43306f32e7eSjoerg };
43406f32e7eSjoerg 
43506f32e7eSjoerg // x86_64 NetBSD
43606f32e7eSjoerg static const MemoryMapParams NetBSD_X86_64_MemoryMapParams = {
43706f32e7eSjoerg   0,               // AndMask
43806f32e7eSjoerg   0x500000000000,  // XorMask
43906f32e7eSjoerg   0,               // ShadowBase
44006f32e7eSjoerg   0x100000000000,  // OriginBase
44106f32e7eSjoerg };
44206f32e7eSjoerg 
44306f32e7eSjoerg static const PlatformMemoryMapParams Linux_X86_MemoryMapParams = {
44406f32e7eSjoerg   &Linux_I386_MemoryMapParams,
44506f32e7eSjoerg   &Linux_X86_64_MemoryMapParams,
44606f32e7eSjoerg };
44706f32e7eSjoerg 
44806f32e7eSjoerg static const PlatformMemoryMapParams Linux_MIPS_MemoryMapParams = {
44906f32e7eSjoerg   nullptr,
45006f32e7eSjoerg   &Linux_MIPS64_MemoryMapParams,
45106f32e7eSjoerg };
45206f32e7eSjoerg 
45306f32e7eSjoerg static const PlatformMemoryMapParams Linux_PowerPC_MemoryMapParams = {
45406f32e7eSjoerg   nullptr,
45506f32e7eSjoerg   &Linux_PowerPC64_MemoryMapParams,
45606f32e7eSjoerg };
45706f32e7eSjoerg 
458*da58b97aSjoerg static const PlatformMemoryMapParams Linux_S390_MemoryMapParams = {
459*da58b97aSjoerg     nullptr,
460*da58b97aSjoerg     &Linux_S390X_MemoryMapParams,
461*da58b97aSjoerg };
462*da58b97aSjoerg 
46306f32e7eSjoerg static const PlatformMemoryMapParams Linux_ARM_MemoryMapParams = {
46406f32e7eSjoerg   nullptr,
46506f32e7eSjoerg   &Linux_AArch64_MemoryMapParams,
46606f32e7eSjoerg };
46706f32e7eSjoerg 
46806f32e7eSjoerg static const PlatformMemoryMapParams FreeBSD_X86_MemoryMapParams = {
46906f32e7eSjoerg   &FreeBSD_I386_MemoryMapParams,
47006f32e7eSjoerg   &FreeBSD_X86_64_MemoryMapParams,
47106f32e7eSjoerg };
47206f32e7eSjoerg 
47306f32e7eSjoerg static const PlatformMemoryMapParams NetBSD_X86_MemoryMapParams = {
47406f32e7eSjoerg   nullptr,
47506f32e7eSjoerg   &NetBSD_X86_64_MemoryMapParams,
47606f32e7eSjoerg };
47706f32e7eSjoerg 
47806f32e7eSjoerg namespace {
47906f32e7eSjoerg 
48006f32e7eSjoerg /// Instrument functions of a module to detect uninitialized reads.
48106f32e7eSjoerg ///
48206f32e7eSjoerg /// Instantiating MemorySanitizer inserts the msan runtime library API function
48306f32e7eSjoerg /// declarations into the module if they don't exist already. Instantiating
48406f32e7eSjoerg /// ensures the __msan_init function is in the list of global constructors for
48506f32e7eSjoerg /// the module.
48606f32e7eSjoerg class MemorySanitizer {
48706f32e7eSjoerg public:
MemorySanitizer(Module & M,MemorySanitizerOptions Options)48806f32e7eSjoerg   MemorySanitizer(Module &M, MemorySanitizerOptions Options)
48906f32e7eSjoerg       : CompileKernel(Options.Kernel), TrackOrigins(Options.TrackOrigins),
49006f32e7eSjoerg         Recover(Options.Recover) {
49106f32e7eSjoerg     initializeModule(M);
49206f32e7eSjoerg   }
49306f32e7eSjoerg 
49406f32e7eSjoerg   // MSan cannot be moved or copied because of MapParams.
49506f32e7eSjoerg   MemorySanitizer(MemorySanitizer &&) = delete;
49606f32e7eSjoerg   MemorySanitizer &operator=(MemorySanitizer &&) = delete;
49706f32e7eSjoerg   MemorySanitizer(const MemorySanitizer &) = delete;
49806f32e7eSjoerg   MemorySanitizer &operator=(const MemorySanitizer &) = delete;
49906f32e7eSjoerg 
50006f32e7eSjoerg   bool sanitizeFunction(Function &F, TargetLibraryInfo &TLI);
50106f32e7eSjoerg 
50206f32e7eSjoerg private:
50306f32e7eSjoerg   friend struct MemorySanitizerVisitor;
50406f32e7eSjoerg   friend struct VarArgAMD64Helper;
50506f32e7eSjoerg   friend struct VarArgMIPS64Helper;
50606f32e7eSjoerg   friend struct VarArgAArch64Helper;
50706f32e7eSjoerg   friend struct VarArgPowerPC64Helper;
508*da58b97aSjoerg   friend struct VarArgSystemZHelper;
50906f32e7eSjoerg 
51006f32e7eSjoerg   void initializeModule(Module &M);
51106f32e7eSjoerg   void initializeCallbacks(Module &M);
51206f32e7eSjoerg   void createKernelApi(Module &M);
51306f32e7eSjoerg   void createUserspaceApi(Module &M);
51406f32e7eSjoerg 
51506f32e7eSjoerg   /// True if we're compiling the Linux kernel.
51606f32e7eSjoerg   bool CompileKernel;
51706f32e7eSjoerg   /// Track origins (allocation points) of uninitialized values.
51806f32e7eSjoerg   int TrackOrigins;
51906f32e7eSjoerg   bool Recover;
52006f32e7eSjoerg 
52106f32e7eSjoerg   LLVMContext *C;
52206f32e7eSjoerg   Type *IntptrTy;
52306f32e7eSjoerg   Type *OriginTy;
52406f32e7eSjoerg 
52506f32e7eSjoerg   // XxxTLS variables represent the per-thread state in MSan and per-task state
52606f32e7eSjoerg   // in KMSAN.
52706f32e7eSjoerg   // For the userspace these point to thread-local globals. In the kernel land
52806f32e7eSjoerg   // they point to the members of a per-task struct obtained via a call to
52906f32e7eSjoerg   // __msan_get_context_state().
53006f32e7eSjoerg 
53106f32e7eSjoerg   /// Thread-local shadow storage for function parameters.
53206f32e7eSjoerg   Value *ParamTLS;
53306f32e7eSjoerg 
53406f32e7eSjoerg   /// Thread-local origin storage for function parameters.
53506f32e7eSjoerg   Value *ParamOriginTLS;
53606f32e7eSjoerg 
53706f32e7eSjoerg   /// Thread-local shadow storage for function return value.
53806f32e7eSjoerg   Value *RetvalTLS;
53906f32e7eSjoerg 
54006f32e7eSjoerg   /// Thread-local origin storage for function return value.
54106f32e7eSjoerg   Value *RetvalOriginTLS;
54206f32e7eSjoerg 
54306f32e7eSjoerg   /// Thread-local shadow storage for in-register va_arg function
54406f32e7eSjoerg   /// parameters (x86_64-specific).
54506f32e7eSjoerg   Value *VAArgTLS;
54606f32e7eSjoerg 
54706f32e7eSjoerg   /// Thread-local shadow storage for in-register va_arg function
54806f32e7eSjoerg   /// parameters (x86_64-specific).
54906f32e7eSjoerg   Value *VAArgOriginTLS;
55006f32e7eSjoerg 
55106f32e7eSjoerg   /// Thread-local shadow storage for va_arg overflow area
55206f32e7eSjoerg   /// (x86_64-specific).
55306f32e7eSjoerg   Value *VAArgOverflowSizeTLS;
55406f32e7eSjoerg 
55506f32e7eSjoerg   /// Are the instrumentation callbacks set up?
55606f32e7eSjoerg   bool CallbacksInitialized = false;
55706f32e7eSjoerg 
55806f32e7eSjoerg   /// The run-time callback to print a warning.
55906f32e7eSjoerg   FunctionCallee WarningFn;
56006f32e7eSjoerg 
56106f32e7eSjoerg   // These arrays are indexed by log2(AccessSize).
56206f32e7eSjoerg   FunctionCallee MaybeWarningFn[kNumberOfAccessSizes];
56306f32e7eSjoerg   FunctionCallee MaybeStoreOriginFn[kNumberOfAccessSizes];
56406f32e7eSjoerg 
56506f32e7eSjoerg   /// Run-time helper that generates a new origin value for a stack
56606f32e7eSjoerg   /// allocation.
56706f32e7eSjoerg   FunctionCallee MsanSetAllocaOrigin4Fn;
56806f32e7eSjoerg 
56906f32e7eSjoerg   /// Run-time helper that poisons stack on function entry.
57006f32e7eSjoerg   FunctionCallee MsanPoisonStackFn;
57106f32e7eSjoerg 
57206f32e7eSjoerg   /// Run-time helper that records a store (or any event) of an
57306f32e7eSjoerg   /// uninitialized value and returns an updated origin id encoding this info.
57406f32e7eSjoerg   FunctionCallee MsanChainOriginFn;
57506f32e7eSjoerg 
576*da58b97aSjoerg   /// Run-time helper that paints an origin over a region.
577*da58b97aSjoerg   FunctionCallee MsanSetOriginFn;
578*da58b97aSjoerg 
57906f32e7eSjoerg   /// MSan runtime replacements for memmove, memcpy and memset.
58006f32e7eSjoerg   FunctionCallee MemmoveFn, MemcpyFn, MemsetFn;
58106f32e7eSjoerg 
58206f32e7eSjoerg   /// KMSAN callback for task-local function argument shadow.
58306f32e7eSjoerg   StructType *MsanContextStateTy;
58406f32e7eSjoerg   FunctionCallee MsanGetContextStateFn;
58506f32e7eSjoerg 
58606f32e7eSjoerg   /// Functions for poisoning/unpoisoning local variables
58706f32e7eSjoerg   FunctionCallee MsanPoisonAllocaFn, MsanUnpoisonAllocaFn;
58806f32e7eSjoerg 
58906f32e7eSjoerg   /// Each of the MsanMetadataPtrXxx functions returns a pair of shadow/origin
59006f32e7eSjoerg   /// pointers.
59106f32e7eSjoerg   FunctionCallee MsanMetadataPtrForLoadN, MsanMetadataPtrForStoreN;
59206f32e7eSjoerg   FunctionCallee MsanMetadataPtrForLoad_1_8[4];
59306f32e7eSjoerg   FunctionCallee MsanMetadataPtrForStore_1_8[4];
59406f32e7eSjoerg   FunctionCallee MsanInstrumentAsmStoreFn;
59506f32e7eSjoerg 
59606f32e7eSjoerg   /// Helper to choose between different MsanMetadataPtrXxx().
59706f32e7eSjoerg   FunctionCallee getKmsanShadowOriginAccessFn(bool isStore, int size);
59806f32e7eSjoerg 
59906f32e7eSjoerg   /// Memory map parameters used in application-to-shadow calculation.
60006f32e7eSjoerg   const MemoryMapParams *MapParams;
60106f32e7eSjoerg 
60206f32e7eSjoerg   /// Custom memory map parameters used when -msan-shadow-base or
60306f32e7eSjoerg   // -msan-origin-base is provided.
60406f32e7eSjoerg   MemoryMapParams CustomMapParams;
60506f32e7eSjoerg 
60606f32e7eSjoerg   MDNode *ColdCallWeights;
60706f32e7eSjoerg 
60806f32e7eSjoerg   /// Branch weights for origin store.
60906f32e7eSjoerg   MDNode *OriginStoreWeights;
61006f32e7eSjoerg };
61106f32e7eSjoerg 
insertModuleCtor(Module & M)61206f32e7eSjoerg void insertModuleCtor(Module &M) {
61306f32e7eSjoerg   getOrCreateSanitizerCtorAndInitFunctions(
61406f32e7eSjoerg       M, kMsanModuleCtorName, kMsanInitName,
61506f32e7eSjoerg       /*InitArgTypes=*/{},
61606f32e7eSjoerg       /*InitArgs=*/{},
61706f32e7eSjoerg       // This callback is invoked when the functions are created the first
61806f32e7eSjoerg       // time. Hook them into the global ctors list in that case:
61906f32e7eSjoerg       [&](Function *Ctor, FunctionCallee) {
62006f32e7eSjoerg         if (!ClWithComdat) {
62106f32e7eSjoerg           appendToGlobalCtors(M, Ctor, 0);
62206f32e7eSjoerg           return;
62306f32e7eSjoerg         }
62406f32e7eSjoerg         Comdat *MsanCtorComdat = M.getOrInsertComdat(kMsanModuleCtorName);
62506f32e7eSjoerg         Ctor->setComdat(MsanCtorComdat);
62606f32e7eSjoerg         appendToGlobalCtors(M, Ctor, 0, Ctor);
62706f32e7eSjoerg       });
62806f32e7eSjoerg }
62906f32e7eSjoerg 
63006f32e7eSjoerg /// A legacy function pass for msan instrumentation.
63106f32e7eSjoerg ///
632*da58b97aSjoerg /// Instruments functions to detect uninitialized reads.
63306f32e7eSjoerg struct MemorySanitizerLegacyPass : public FunctionPass {
63406f32e7eSjoerg   // Pass identification, replacement for typeid.
63506f32e7eSjoerg   static char ID;
63606f32e7eSjoerg 
MemorySanitizerLegacyPass__anonb9e144640211::MemorySanitizerLegacyPass63706f32e7eSjoerg   MemorySanitizerLegacyPass(MemorySanitizerOptions Options = {})
638*da58b97aSjoerg       : FunctionPass(ID), Options(Options) {
639*da58b97aSjoerg     initializeMemorySanitizerLegacyPassPass(*PassRegistry::getPassRegistry());
640*da58b97aSjoerg   }
getPassName__anonb9e144640211::MemorySanitizerLegacyPass64106f32e7eSjoerg   StringRef getPassName() const override { return "MemorySanitizerLegacyPass"; }
64206f32e7eSjoerg 
getAnalysisUsage__anonb9e144640211::MemorySanitizerLegacyPass64306f32e7eSjoerg   void getAnalysisUsage(AnalysisUsage &AU) const override {
64406f32e7eSjoerg     AU.addRequired<TargetLibraryInfoWrapperPass>();
64506f32e7eSjoerg   }
64606f32e7eSjoerg 
runOnFunction__anonb9e144640211::MemorySanitizerLegacyPass64706f32e7eSjoerg   bool runOnFunction(Function &F) override {
64806f32e7eSjoerg     return MSan->sanitizeFunction(
64906f32e7eSjoerg         F, getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F));
65006f32e7eSjoerg   }
65106f32e7eSjoerg   bool doInitialization(Module &M) override;
65206f32e7eSjoerg 
65306f32e7eSjoerg   Optional<MemorySanitizer> MSan;
65406f32e7eSjoerg   MemorySanitizerOptions Options;
65506f32e7eSjoerg };
65606f32e7eSjoerg 
getOptOrDefault(const cl::opt<T> & Opt,T Default)65706f32e7eSjoerg template <class T> T getOptOrDefault(const cl::opt<T> &Opt, T Default) {
65806f32e7eSjoerg   return (Opt.getNumOccurrences() > 0) ? Opt : Default;
65906f32e7eSjoerg }
66006f32e7eSjoerg 
66106f32e7eSjoerg } // end anonymous namespace
66206f32e7eSjoerg 
MemorySanitizerOptions(int TO,bool R,bool K)66306f32e7eSjoerg MemorySanitizerOptions::MemorySanitizerOptions(int TO, bool R, bool K)
66406f32e7eSjoerg     : Kernel(getOptOrDefault(ClEnableKmsan, K)),
66506f32e7eSjoerg       TrackOrigins(getOptOrDefault(ClTrackOrigins, Kernel ? 2 : TO)),
66606f32e7eSjoerg       Recover(getOptOrDefault(ClKeepGoing, Kernel || R)) {}
66706f32e7eSjoerg 
run(Function & F,FunctionAnalysisManager & FAM)66806f32e7eSjoerg PreservedAnalyses MemorySanitizerPass::run(Function &F,
66906f32e7eSjoerg                                            FunctionAnalysisManager &FAM) {
67006f32e7eSjoerg   MemorySanitizer Msan(*F.getParent(), Options);
67106f32e7eSjoerg   if (Msan.sanitizeFunction(F, FAM.getResult<TargetLibraryAnalysis>(F)))
67206f32e7eSjoerg     return PreservedAnalyses::none();
67306f32e7eSjoerg   return PreservedAnalyses::all();
67406f32e7eSjoerg }
67506f32e7eSjoerg 
run(Module & M,ModuleAnalysisManager & AM)67606f32e7eSjoerg PreservedAnalyses MemorySanitizerPass::run(Module &M,
67706f32e7eSjoerg                                            ModuleAnalysisManager &AM) {
67806f32e7eSjoerg   if (Options.Kernel)
67906f32e7eSjoerg     return PreservedAnalyses::all();
68006f32e7eSjoerg   insertModuleCtor(M);
68106f32e7eSjoerg   return PreservedAnalyses::none();
68206f32e7eSjoerg }
68306f32e7eSjoerg 
68406f32e7eSjoerg char MemorySanitizerLegacyPass::ID = 0;
68506f32e7eSjoerg 
68606f32e7eSjoerg INITIALIZE_PASS_BEGIN(MemorySanitizerLegacyPass, "msan",
68706f32e7eSjoerg                       "MemorySanitizer: detects uninitialized reads.", false,
68806f32e7eSjoerg                       false)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)68906f32e7eSjoerg INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
69006f32e7eSjoerg INITIALIZE_PASS_END(MemorySanitizerLegacyPass, "msan",
69106f32e7eSjoerg                     "MemorySanitizer: detects uninitialized reads.", false,
69206f32e7eSjoerg                     false)
69306f32e7eSjoerg 
69406f32e7eSjoerg FunctionPass *
69506f32e7eSjoerg llvm::createMemorySanitizerLegacyPassPass(MemorySanitizerOptions Options) {
69606f32e7eSjoerg   return new MemorySanitizerLegacyPass(Options);
69706f32e7eSjoerg }
69806f32e7eSjoerg 
69906f32e7eSjoerg /// Create a non-const global initialized with the given string.
70006f32e7eSjoerg ///
70106f32e7eSjoerg /// Creates a writable global for Str so that we can pass it to the
70206f32e7eSjoerg /// run-time lib. Runtime uses first 4 bytes of the string to store the
70306f32e7eSjoerg /// frame ID, so the string needs to be mutable.
createPrivateNonConstGlobalForString(Module & M,StringRef Str)70406f32e7eSjoerg static GlobalVariable *createPrivateNonConstGlobalForString(Module &M,
70506f32e7eSjoerg                                                             StringRef Str) {
70606f32e7eSjoerg   Constant *StrConst = ConstantDataArray::getString(M.getContext(), Str);
70706f32e7eSjoerg   return new GlobalVariable(M, StrConst->getType(), /*isConstant=*/false,
70806f32e7eSjoerg                             GlobalValue::PrivateLinkage, StrConst, "");
70906f32e7eSjoerg }
71006f32e7eSjoerg 
71106f32e7eSjoerg /// Create KMSAN API callbacks.
createKernelApi(Module & M)71206f32e7eSjoerg void MemorySanitizer::createKernelApi(Module &M) {
71306f32e7eSjoerg   IRBuilder<> IRB(*C);
71406f32e7eSjoerg 
71506f32e7eSjoerg   // These will be initialized in insertKmsanPrologue().
71606f32e7eSjoerg   RetvalTLS = nullptr;
71706f32e7eSjoerg   RetvalOriginTLS = nullptr;
71806f32e7eSjoerg   ParamTLS = nullptr;
71906f32e7eSjoerg   ParamOriginTLS = nullptr;
72006f32e7eSjoerg   VAArgTLS = nullptr;
72106f32e7eSjoerg   VAArgOriginTLS = nullptr;
72206f32e7eSjoerg   VAArgOverflowSizeTLS = nullptr;
72306f32e7eSjoerg 
72406f32e7eSjoerg   WarningFn = M.getOrInsertFunction("__msan_warning", IRB.getVoidTy(),
72506f32e7eSjoerg                                     IRB.getInt32Ty());
72606f32e7eSjoerg   // Requests the per-task context state (kmsan_context_state*) from the
72706f32e7eSjoerg   // runtime library.
72806f32e7eSjoerg   MsanContextStateTy = StructType::get(
72906f32e7eSjoerg       ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
73006f32e7eSjoerg       ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8),
73106f32e7eSjoerg       ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8),
73206f32e7eSjoerg       ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8), /* va_arg_origin */
73306f32e7eSjoerg       IRB.getInt64Ty(), ArrayType::get(OriginTy, kParamTLSSize / 4), OriginTy,
73406f32e7eSjoerg       OriginTy);
73506f32e7eSjoerg   MsanGetContextStateFn = M.getOrInsertFunction(
73606f32e7eSjoerg       "__msan_get_context_state", PointerType::get(MsanContextStateTy, 0));
73706f32e7eSjoerg 
73806f32e7eSjoerg   Type *RetTy = StructType::get(PointerType::get(IRB.getInt8Ty(), 0),
73906f32e7eSjoerg                                 PointerType::get(IRB.getInt32Ty(), 0));
74006f32e7eSjoerg 
74106f32e7eSjoerg   for (int ind = 0, size = 1; ind < 4; ind++, size <<= 1) {
74206f32e7eSjoerg     std::string name_load =
74306f32e7eSjoerg         "__msan_metadata_ptr_for_load_" + std::to_string(size);
74406f32e7eSjoerg     std::string name_store =
74506f32e7eSjoerg         "__msan_metadata_ptr_for_store_" + std::to_string(size);
74606f32e7eSjoerg     MsanMetadataPtrForLoad_1_8[ind] = M.getOrInsertFunction(
74706f32e7eSjoerg         name_load, RetTy, PointerType::get(IRB.getInt8Ty(), 0));
74806f32e7eSjoerg     MsanMetadataPtrForStore_1_8[ind] = M.getOrInsertFunction(
74906f32e7eSjoerg         name_store, RetTy, PointerType::get(IRB.getInt8Ty(), 0));
75006f32e7eSjoerg   }
75106f32e7eSjoerg 
75206f32e7eSjoerg   MsanMetadataPtrForLoadN = M.getOrInsertFunction(
75306f32e7eSjoerg       "__msan_metadata_ptr_for_load_n", RetTy,
75406f32e7eSjoerg       PointerType::get(IRB.getInt8Ty(), 0), IRB.getInt64Ty());
75506f32e7eSjoerg   MsanMetadataPtrForStoreN = M.getOrInsertFunction(
75606f32e7eSjoerg       "__msan_metadata_ptr_for_store_n", RetTy,
75706f32e7eSjoerg       PointerType::get(IRB.getInt8Ty(), 0), IRB.getInt64Ty());
75806f32e7eSjoerg 
75906f32e7eSjoerg   // Functions for poisoning and unpoisoning memory.
76006f32e7eSjoerg   MsanPoisonAllocaFn =
76106f32e7eSjoerg       M.getOrInsertFunction("__msan_poison_alloca", IRB.getVoidTy(),
76206f32e7eSjoerg                             IRB.getInt8PtrTy(), IntptrTy, IRB.getInt8PtrTy());
76306f32e7eSjoerg   MsanUnpoisonAllocaFn = M.getOrInsertFunction(
76406f32e7eSjoerg       "__msan_unpoison_alloca", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy);
76506f32e7eSjoerg }
76606f32e7eSjoerg 
getOrInsertGlobal(Module & M,StringRef Name,Type * Ty)76706f32e7eSjoerg static Constant *getOrInsertGlobal(Module &M, StringRef Name, Type *Ty) {
76806f32e7eSjoerg   return M.getOrInsertGlobal(Name, Ty, [&] {
76906f32e7eSjoerg     return new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
77006f32e7eSjoerg                               nullptr, Name, nullptr,
77106f32e7eSjoerg                               GlobalVariable::InitialExecTLSModel);
77206f32e7eSjoerg   });
77306f32e7eSjoerg }
77406f32e7eSjoerg 
77506f32e7eSjoerg /// Insert declarations for userspace-specific functions and globals.
createUserspaceApi(Module & M)77606f32e7eSjoerg void MemorySanitizer::createUserspaceApi(Module &M) {
77706f32e7eSjoerg   IRBuilder<> IRB(*C);
778*da58b97aSjoerg 
77906f32e7eSjoerg   // Create the callback.
78006f32e7eSjoerg   // FIXME: this function should have "Cold" calling conv,
78106f32e7eSjoerg   // which is not yet implemented.
782*da58b97aSjoerg   StringRef WarningFnName = Recover ? "__msan_warning_with_origin"
783*da58b97aSjoerg                                     : "__msan_warning_with_origin_noreturn";
784*da58b97aSjoerg   WarningFn =
785*da58b97aSjoerg       M.getOrInsertFunction(WarningFnName, IRB.getVoidTy(), IRB.getInt32Ty());
78606f32e7eSjoerg 
78706f32e7eSjoerg   // Create the global TLS variables.
78806f32e7eSjoerg   RetvalTLS =
78906f32e7eSjoerg       getOrInsertGlobal(M, "__msan_retval_tls",
79006f32e7eSjoerg                         ArrayType::get(IRB.getInt64Ty(), kRetvalTLSSize / 8));
79106f32e7eSjoerg 
79206f32e7eSjoerg   RetvalOriginTLS = getOrInsertGlobal(M, "__msan_retval_origin_tls", OriginTy);
79306f32e7eSjoerg 
79406f32e7eSjoerg   ParamTLS =
79506f32e7eSjoerg       getOrInsertGlobal(M, "__msan_param_tls",
79606f32e7eSjoerg                         ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
79706f32e7eSjoerg 
79806f32e7eSjoerg   ParamOriginTLS =
79906f32e7eSjoerg       getOrInsertGlobal(M, "__msan_param_origin_tls",
80006f32e7eSjoerg                         ArrayType::get(OriginTy, kParamTLSSize / 4));
80106f32e7eSjoerg 
80206f32e7eSjoerg   VAArgTLS =
80306f32e7eSjoerg       getOrInsertGlobal(M, "__msan_va_arg_tls",
80406f32e7eSjoerg                         ArrayType::get(IRB.getInt64Ty(), kParamTLSSize / 8));
80506f32e7eSjoerg 
80606f32e7eSjoerg   VAArgOriginTLS =
80706f32e7eSjoerg       getOrInsertGlobal(M, "__msan_va_arg_origin_tls",
80806f32e7eSjoerg                         ArrayType::get(OriginTy, kParamTLSSize / 4));
80906f32e7eSjoerg 
81006f32e7eSjoerg   VAArgOverflowSizeTLS =
81106f32e7eSjoerg       getOrInsertGlobal(M, "__msan_va_arg_overflow_size_tls", IRB.getInt64Ty());
81206f32e7eSjoerg 
81306f32e7eSjoerg   for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
81406f32e7eSjoerg        AccessSizeIndex++) {
81506f32e7eSjoerg     unsigned AccessSize = 1 << AccessSizeIndex;
81606f32e7eSjoerg     std::string FunctionName = "__msan_maybe_warning_" + itostr(AccessSize);
817*da58b97aSjoerg     SmallVector<std::pair<unsigned, Attribute>, 2> MaybeWarningFnAttrs;
818*da58b97aSjoerg     MaybeWarningFnAttrs.push_back(std::make_pair(
819*da58b97aSjoerg         AttributeList::FirstArgIndex, Attribute::get(*C, Attribute::ZExt)));
820*da58b97aSjoerg     MaybeWarningFnAttrs.push_back(std::make_pair(
821*da58b97aSjoerg         AttributeList::FirstArgIndex + 1, Attribute::get(*C, Attribute::ZExt)));
82206f32e7eSjoerg     MaybeWarningFn[AccessSizeIndex] = M.getOrInsertFunction(
823*da58b97aSjoerg         FunctionName, AttributeList::get(*C, MaybeWarningFnAttrs),
824*da58b97aSjoerg         IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt32Ty());
82506f32e7eSjoerg 
82606f32e7eSjoerg     FunctionName = "__msan_maybe_store_origin_" + itostr(AccessSize);
827*da58b97aSjoerg     SmallVector<std::pair<unsigned, Attribute>, 2> MaybeStoreOriginFnAttrs;
828*da58b97aSjoerg     MaybeStoreOriginFnAttrs.push_back(std::make_pair(
829*da58b97aSjoerg         AttributeList::FirstArgIndex, Attribute::get(*C, Attribute::ZExt)));
830*da58b97aSjoerg     MaybeStoreOriginFnAttrs.push_back(std::make_pair(
831*da58b97aSjoerg         AttributeList::FirstArgIndex + 2, Attribute::get(*C, Attribute::ZExt)));
83206f32e7eSjoerg     MaybeStoreOriginFn[AccessSizeIndex] = M.getOrInsertFunction(
833*da58b97aSjoerg         FunctionName, AttributeList::get(*C, MaybeStoreOriginFnAttrs),
834*da58b97aSjoerg         IRB.getVoidTy(), IRB.getIntNTy(AccessSize * 8), IRB.getInt8PtrTy(),
835*da58b97aSjoerg         IRB.getInt32Ty());
83606f32e7eSjoerg   }
83706f32e7eSjoerg 
83806f32e7eSjoerg   MsanSetAllocaOrigin4Fn = M.getOrInsertFunction(
83906f32e7eSjoerg     "__msan_set_alloca_origin4", IRB.getVoidTy(), IRB.getInt8PtrTy(), IntptrTy,
84006f32e7eSjoerg     IRB.getInt8PtrTy(), IntptrTy);
84106f32e7eSjoerg   MsanPoisonStackFn =
84206f32e7eSjoerg       M.getOrInsertFunction("__msan_poison_stack", IRB.getVoidTy(),
84306f32e7eSjoerg                             IRB.getInt8PtrTy(), IntptrTy);
84406f32e7eSjoerg }
84506f32e7eSjoerg 
84606f32e7eSjoerg /// Insert extern declaration of runtime-provided functions and globals.
initializeCallbacks(Module & M)84706f32e7eSjoerg void MemorySanitizer::initializeCallbacks(Module &M) {
84806f32e7eSjoerg   // Only do this once.
84906f32e7eSjoerg   if (CallbacksInitialized)
85006f32e7eSjoerg     return;
85106f32e7eSjoerg 
85206f32e7eSjoerg   IRBuilder<> IRB(*C);
85306f32e7eSjoerg   // Initialize callbacks that are common for kernel and userspace
85406f32e7eSjoerg   // instrumentation.
85506f32e7eSjoerg   MsanChainOriginFn = M.getOrInsertFunction(
85606f32e7eSjoerg     "__msan_chain_origin", IRB.getInt32Ty(), IRB.getInt32Ty());
857*da58b97aSjoerg   MsanSetOriginFn =
858*da58b97aSjoerg       M.getOrInsertFunction("__msan_set_origin", IRB.getVoidTy(),
859*da58b97aSjoerg                             IRB.getInt8PtrTy(), IntptrTy, IRB.getInt32Ty());
86006f32e7eSjoerg   MemmoveFn = M.getOrInsertFunction(
86106f32e7eSjoerg     "__msan_memmove", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
86206f32e7eSjoerg     IRB.getInt8PtrTy(), IntptrTy);
86306f32e7eSjoerg   MemcpyFn = M.getOrInsertFunction(
86406f32e7eSjoerg     "__msan_memcpy", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
86506f32e7eSjoerg     IntptrTy);
86606f32e7eSjoerg   MemsetFn = M.getOrInsertFunction(
86706f32e7eSjoerg     "__msan_memset", IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IRB.getInt32Ty(),
86806f32e7eSjoerg     IntptrTy);
86906f32e7eSjoerg 
87006f32e7eSjoerg   MsanInstrumentAsmStoreFn =
87106f32e7eSjoerg       M.getOrInsertFunction("__msan_instrument_asm_store", IRB.getVoidTy(),
87206f32e7eSjoerg                             PointerType::get(IRB.getInt8Ty(), 0), IntptrTy);
87306f32e7eSjoerg 
87406f32e7eSjoerg   if (CompileKernel) {
87506f32e7eSjoerg     createKernelApi(M);
87606f32e7eSjoerg   } else {
87706f32e7eSjoerg     createUserspaceApi(M);
87806f32e7eSjoerg   }
87906f32e7eSjoerg   CallbacksInitialized = true;
88006f32e7eSjoerg }
88106f32e7eSjoerg 
getKmsanShadowOriginAccessFn(bool isStore,int size)88206f32e7eSjoerg FunctionCallee MemorySanitizer::getKmsanShadowOriginAccessFn(bool isStore,
88306f32e7eSjoerg                                                              int size) {
88406f32e7eSjoerg   FunctionCallee *Fns =
88506f32e7eSjoerg       isStore ? MsanMetadataPtrForStore_1_8 : MsanMetadataPtrForLoad_1_8;
88606f32e7eSjoerg   switch (size) {
88706f32e7eSjoerg   case 1:
88806f32e7eSjoerg     return Fns[0];
88906f32e7eSjoerg   case 2:
89006f32e7eSjoerg     return Fns[1];
89106f32e7eSjoerg   case 4:
89206f32e7eSjoerg     return Fns[2];
89306f32e7eSjoerg   case 8:
89406f32e7eSjoerg     return Fns[3];
89506f32e7eSjoerg   default:
89606f32e7eSjoerg     return nullptr;
89706f32e7eSjoerg   }
89806f32e7eSjoerg }
89906f32e7eSjoerg 
90006f32e7eSjoerg /// Module-level initialization.
90106f32e7eSjoerg ///
90206f32e7eSjoerg /// inserts a call to __msan_init to the module's constructor list.
initializeModule(Module & M)90306f32e7eSjoerg void MemorySanitizer::initializeModule(Module &M) {
90406f32e7eSjoerg   auto &DL = M.getDataLayout();
90506f32e7eSjoerg 
90606f32e7eSjoerg   bool ShadowPassed = ClShadowBase.getNumOccurrences() > 0;
90706f32e7eSjoerg   bool OriginPassed = ClOriginBase.getNumOccurrences() > 0;
90806f32e7eSjoerg   // Check the overrides first
90906f32e7eSjoerg   if (ShadowPassed || OriginPassed) {
91006f32e7eSjoerg     CustomMapParams.AndMask = ClAndMask;
91106f32e7eSjoerg     CustomMapParams.XorMask = ClXorMask;
91206f32e7eSjoerg     CustomMapParams.ShadowBase = ClShadowBase;
91306f32e7eSjoerg     CustomMapParams.OriginBase = ClOriginBase;
91406f32e7eSjoerg     MapParams = &CustomMapParams;
91506f32e7eSjoerg   } else {
91606f32e7eSjoerg     Triple TargetTriple(M.getTargetTriple());
91706f32e7eSjoerg     switch (TargetTriple.getOS()) {
91806f32e7eSjoerg       case Triple::FreeBSD:
91906f32e7eSjoerg         switch (TargetTriple.getArch()) {
92006f32e7eSjoerg           case Triple::x86_64:
92106f32e7eSjoerg             MapParams = FreeBSD_X86_MemoryMapParams.bits64;
92206f32e7eSjoerg             break;
92306f32e7eSjoerg           case Triple::x86:
92406f32e7eSjoerg             MapParams = FreeBSD_X86_MemoryMapParams.bits32;
92506f32e7eSjoerg             break;
92606f32e7eSjoerg           default:
92706f32e7eSjoerg             report_fatal_error("unsupported architecture");
92806f32e7eSjoerg         }
92906f32e7eSjoerg         break;
93006f32e7eSjoerg       case Triple::NetBSD:
93106f32e7eSjoerg         switch (TargetTriple.getArch()) {
93206f32e7eSjoerg           case Triple::x86_64:
93306f32e7eSjoerg             MapParams = NetBSD_X86_MemoryMapParams.bits64;
93406f32e7eSjoerg             break;
93506f32e7eSjoerg           default:
93606f32e7eSjoerg             report_fatal_error("unsupported architecture");
93706f32e7eSjoerg         }
93806f32e7eSjoerg         break;
93906f32e7eSjoerg       case Triple::Linux:
94006f32e7eSjoerg         switch (TargetTriple.getArch()) {
94106f32e7eSjoerg           case Triple::x86_64:
94206f32e7eSjoerg             MapParams = Linux_X86_MemoryMapParams.bits64;
94306f32e7eSjoerg             break;
94406f32e7eSjoerg           case Triple::x86:
94506f32e7eSjoerg             MapParams = Linux_X86_MemoryMapParams.bits32;
94606f32e7eSjoerg             break;
94706f32e7eSjoerg           case Triple::mips64:
94806f32e7eSjoerg           case Triple::mips64el:
94906f32e7eSjoerg             MapParams = Linux_MIPS_MemoryMapParams.bits64;
95006f32e7eSjoerg             break;
95106f32e7eSjoerg           case Triple::ppc64:
95206f32e7eSjoerg           case Triple::ppc64le:
95306f32e7eSjoerg             MapParams = Linux_PowerPC_MemoryMapParams.bits64;
95406f32e7eSjoerg             break;
955*da58b97aSjoerg           case Triple::systemz:
956*da58b97aSjoerg             MapParams = Linux_S390_MemoryMapParams.bits64;
957*da58b97aSjoerg             break;
95806f32e7eSjoerg           case Triple::aarch64:
95906f32e7eSjoerg           case Triple::aarch64_be:
96006f32e7eSjoerg             MapParams = Linux_ARM_MemoryMapParams.bits64;
96106f32e7eSjoerg             break;
96206f32e7eSjoerg           default:
96306f32e7eSjoerg             report_fatal_error("unsupported architecture");
96406f32e7eSjoerg         }
96506f32e7eSjoerg         break;
96606f32e7eSjoerg       default:
96706f32e7eSjoerg         report_fatal_error("unsupported operating system");
96806f32e7eSjoerg     }
96906f32e7eSjoerg   }
97006f32e7eSjoerg 
97106f32e7eSjoerg   C = &(M.getContext());
97206f32e7eSjoerg   IRBuilder<> IRB(*C);
97306f32e7eSjoerg   IntptrTy = IRB.getIntPtrTy(DL);
97406f32e7eSjoerg   OriginTy = IRB.getInt32Ty();
97506f32e7eSjoerg 
97606f32e7eSjoerg   ColdCallWeights = MDBuilder(*C).createBranchWeights(1, 1000);
97706f32e7eSjoerg   OriginStoreWeights = MDBuilder(*C).createBranchWeights(1, 1000);
97806f32e7eSjoerg 
97906f32e7eSjoerg   if (!CompileKernel) {
98006f32e7eSjoerg     if (TrackOrigins)
98106f32e7eSjoerg       M.getOrInsertGlobal("__msan_track_origins", IRB.getInt32Ty(), [&] {
98206f32e7eSjoerg         return new GlobalVariable(
98306f32e7eSjoerg             M, IRB.getInt32Ty(), true, GlobalValue::WeakODRLinkage,
98406f32e7eSjoerg             IRB.getInt32(TrackOrigins), "__msan_track_origins");
98506f32e7eSjoerg       });
98606f32e7eSjoerg 
98706f32e7eSjoerg     if (Recover)
98806f32e7eSjoerg       M.getOrInsertGlobal("__msan_keep_going", IRB.getInt32Ty(), [&] {
98906f32e7eSjoerg         return new GlobalVariable(M, IRB.getInt32Ty(), true,
99006f32e7eSjoerg                                   GlobalValue::WeakODRLinkage,
99106f32e7eSjoerg                                   IRB.getInt32(Recover), "__msan_keep_going");
99206f32e7eSjoerg       });
99306f32e7eSjoerg }
99406f32e7eSjoerg }
99506f32e7eSjoerg 
doInitialization(Module & M)99606f32e7eSjoerg bool MemorySanitizerLegacyPass::doInitialization(Module &M) {
99706f32e7eSjoerg   if (!Options.Kernel)
99806f32e7eSjoerg     insertModuleCtor(M);
99906f32e7eSjoerg   MSan.emplace(M, Options);
100006f32e7eSjoerg   return true;
100106f32e7eSjoerg }
100206f32e7eSjoerg 
100306f32e7eSjoerg namespace {
100406f32e7eSjoerg 
100506f32e7eSjoerg /// A helper class that handles instrumentation of VarArg
100606f32e7eSjoerg /// functions on a particular platform.
100706f32e7eSjoerg ///
100806f32e7eSjoerg /// Implementations are expected to insert the instrumentation
100906f32e7eSjoerg /// necessary to propagate argument shadow through VarArg function
101006f32e7eSjoerg /// calls. Visit* methods are called during an InstVisitor pass over
101106f32e7eSjoerg /// the function, and should avoid creating new basic blocks. A new
101206f32e7eSjoerg /// instance of this class is created for each instrumented function.
101306f32e7eSjoerg struct VarArgHelper {
101406f32e7eSjoerg   virtual ~VarArgHelper() = default;
101506f32e7eSjoerg 
1016*da58b97aSjoerg   /// Visit a CallBase.
1017*da58b97aSjoerg   virtual void visitCallBase(CallBase &CB, IRBuilder<> &IRB) = 0;
101806f32e7eSjoerg 
101906f32e7eSjoerg   /// Visit a va_start call.
102006f32e7eSjoerg   virtual void visitVAStartInst(VAStartInst &I) = 0;
102106f32e7eSjoerg 
102206f32e7eSjoerg   /// Visit a va_copy call.
102306f32e7eSjoerg   virtual void visitVACopyInst(VACopyInst &I) = 0;
102406f32e7eSjoerg 
102506f32e7eSjoerg   /// Finalize function instrumentation.
102606f32e7eSjoerg   ///
102706f32e7eSjoerg   /// This method is called after visiting all interesting (see above)
102806f32e7eSjoerg   /// instructions in a function.
102906f32e7eSjoerg   virtual void finalizeInstrumentation() = 0;
103006f32e7eSjoerg };
103106f32e7eSjoerg 
103206f32e7eSjoerg struct MemorySanitizerVisitor;
103306f32e7eSjoerg 
103406f32e7eSjoerg } // end anonymous namespace
103506f32e7eSjoerg 
103606f32e7eSjoerg static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
103706f32e7eSjoerg                                         MemorySanitizerVisitor &Visitor);
103806f32e7eSjoerg 
TypeSizeToSizeIndex(unsigned TypeSize)103906f32e7eSjoerg static unsigned TypeSizeToSizeIndex(unsigned TypeSize) {
104006f32e7eSjoerg   if (TypeSize <= 8) return 0;
104106f32e7eSjoerg   return Log2_32_Ceil((TypeSize + 7) / 8);
104206f32e7eSjoerg }
104306f32e7eSjoerg 
104406f32e7eSjoerg namespace {
104506f32e7eSjoerg 
104606f32e7eSjoerg /// This class does all the work for a given function. Store and Load
104706f32e7eSjoerg /// instructions store and load corresponding shadow and origin
104806f32e7eSjoerg /// values. Most instructions propagate shadow from arguments to their
104906f32e7eSjoerg /// return values. Certain instructions (most importantly, BranchInst)
105006f32e7eSjoerg /// test their argument shadow and print reports (with a runtime call) if it's
105106f32e7eSjoerg /// non-zero.
105206f32e7eSjoerg struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
105306f32e7eSjoerg   Function &F;
105406f32e7eSjoerg   MemorySanitizer &MS;
105506f32e7eSjoerg   SmallVector<PHINode *, 16> ShadowPHINodes, OriginPHINodes;
105606f32e7eSjoerg   ValueMap<Value*, Value*> ShadowMap, OriginMap;
105706f32e7eSjoerg   std::unique_ptr<VarArgHelper> VAHelper;
105806f32e7eSjoerg   const TargetLibraryInfo *TLI;
1059*da58b97aSjoerg   Instruction *FnPrologueEnd;
106006f32e7eSjoerg 
106106f32e7eSjoerg   // The following flags disable parts of MSan instrumentation based on
1062*da58b97aSjoerg   // exclusion list contents and command-line options.
106306f32e7eSjoerg   bool InsertChecks;
106406f32e7eSjoerg   bool PropagateShadow;
106506f32e7eSjoerg   bool PoisonStack;
106606f32e7eSjoerg   bool PoisonUndef;
106706f32e7eSjoerg 
106806f32e7eSjoerg   struct ShadowOriginAndInsertPoint {
106906f32e7eSjoerg     Value *Shadow;
107006f32e7eSjoerg     Value *Origin;
107106f32e7eSjoerg     Instruction *OrigIns;
107206f32e7eSjoerg 
ShadowOriginAndInsertPoint__anonb9e144640811::MemorySanitizerVisitor::ShadowOriginAndInsertPoint107306f32e7eSjoerg     ShadowOriginAndInsertPoint(Value *S, Value *O, Instruction *I)
107406f32e7eSjoerg       : Shadow(S), Origin(O), OrigIns(I) {}
107506f32e7eSjoerg   };
107606f32e7eSjoerg   SmallVector<ShadowOriginAndInsertPoint, 16> InstrumentationList;
107706f32e7eSjoerg   bool InstrumentLifetimeStart = ClHandleLifetimeIntrinsics;
107806f32e7eSjoerg   SmallSet<AllocaInst *, 16> AllocaSet;
107906f32e7eSjoerg   SmallVector<std::pair<IntrinsicInst *, AllocaInst *>, 16> LifetimeStartList;
108006f32e7eSjoerg   SmallVector<StoreInst *, 16> StoreList;
108106f32e7eSjoerg 
MemorySanitizerVisitor__anonb9e144640811::MemorySanitizerVisitor108206f32e7eSjoerg   MemorySanitizerVisitor(Function &F, MemorySanitizer &MS,
108306f32e7eSjoerg                          const TargetLibraryInfo &TLI)
108406f32e7eSjoerg       : F(F), MS(MS), VAHelper(CreateVarArgHelper(F, MS, *this)), TLI(&TLI) {
108506f32e7eSjoerg     bool SanitizeFunction = F.hasFnAttribute(Attribute::SanitizeMemory);
108606f32e7eSjoerg     InsertChecks = SanitizeFunction;
108706f32e7eSjoerg     PropagateShadow = SanitizeFunction;
108806f32e7eSjoerg     PoisonStack = SanitizeFunction && ClPoisonStack;
108906f32e7eSjoerg     PoisonUndef = SanitizeFunction && ClPoisonUndef;
1090*da58b97aSjoerg 
1091*da58b97aSjoerg     // In the presence of unreachable blocks, we may see Phi nodes with
1092*da58b97aSjoerg     // incoming nodes from such blocks. Since InstVisitor skips unreachable
1093*da58b97aSjoerg     // blocks, such nodes will not have any shadow value associated with them.
1094*da58b97aSjoerg     // It's easier to remove unreachable blocks than deal with missing shadow.
1095*da58b97aSjoerg     removeUnreachableBlocks(F);
109606f32e7eSjoerg 
109706f32e7eSjoerg     MS.initializeCallbacks(*F.getParent());
1098*da58b97aSjoerg     FnPrologueEnd = IRBuilder<>(F.getEntryBlock().getFirstNonPHI())
1099*da58b97aSjoerg                         .CreateIntrinsic(Intrinsic::donothing, {}, {});
1100*da58b97aSjoerg 
1101*da58b97aSjoerg     if (MS.CompileKernel) {
1102*da58b97aSjoerg       IRBuilder<> IRB(FnPrologueEnd);
1103*da58b97aSjoerg       insertKmsanPrologue(IRB);
1104*da58b97aSjoerg     }
110506f32e7eSjoerg 
110606f32e7eSjoerg     LLVM_DEBUG(if (!InsertChecks) dbgs()
110706f32e7eSjoerg                << "MemorySanitizer is not inserting checks into '"
110806f32e7eSjoerg                << F.getName() << "'\n");
110906f32e7eSjoerg   }
111006f32e7eSjoerg 
isInPrologue__anonb9e144640811::MemorySanitizerVisitor1111*da58b97aSjoerg   bool isInPrologue(Instruction &I) {
1112*da58b97aSjoerg     return I.getParent() == FnPrologueEnd->getParent() &&
1113*da58b97aSjoerg            (&I == FnPrologueEnd || I.comesBefore(FnPrologueEnd));
1114*da58b97aSjoerg   }
1115*da58b97aSjoerg 
updateOrigin__anonb9e144640811::MemorySanitizerVisitor111606f32e7eSjoerg   Value *updateOrigin(Value *V, IRBuilder<> &IRB) {
111706f32e7eSjoerg     if (MS.TrackOrigins <= 1) return V;
111806f32e7eSjoerg     return IRB.CreateCall(MS.MsanChainOriginFn, V);
111906f32e7eSjoerg   }
112006f32e7eSjoerg 
originToIntptr__anonb9e144640811::MemorySanitizerVisitor112106f32e7eSjoerg   Value *originToIntptr(IRBuilder<> &IRB, Value *Origin) {
112206f32e7eSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
112306f32e7eSjoerg     unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
112406f32e7eSjoerg     if (IntptrSize == kOriginSize) return Origin;
112506f32e7eSjoerg     assert(IntptrSize == kOriginSize * 2);
112606f32e7eSjoerg     Origin = IRB.CreateIntCast(Origin, MS.IntptrTy, /* isSigned */ false);
112706f32e7eSjoerg     return IRB.CreateOr(Origin, IRB.CreateShl(Origin, kOriginSize * 8));
112806f32e7eSjoerg   }
112906f32e7eSjoerg 
113006f32e7eSjoerg   /// Fill memory range with the given origin value.
paintOrigin__anonb9e144640811::MemorySanitizerVisitor113106f32e7eSjoerg   void paintOrigin(IRBuilder<> &IRB, Value *Origin, Value *OriginPtr,
1132*da58b97aSjoerg                    unsigned Size, Align Alignment) {
113306f32e7eSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
1134*da58b97aSjoerg     const Align IntptrAlignment = DL.getABITypeAlign(MS.IntptrTy);
113506f32e7eSjoerg     unsigned IntptrSize = DL.getTypeStoreSize(MS.IntptrTy);
113606f32e7eSjoerg     assert(IntptrAlignment >= kMinOriginAlignment);
113706f32e7eSjoerg     assert(IntptrSize >= kOriginSize);
113806f32e7eSjoerg 
113906f32e7eSjoerg     unsigned Ofs = 0;
1140*da58b97aSjoerg     Align CurrentAlignment = Alignment;
114106f32e7eSjoerg     if (Alignment >= IntptrAlignment && IntptrSize > kOriginSize) {
114206f32e7eSjoerg       Value *IntptrOrigin = originToIntptr(IRB, Origin);
114306f32e7eSjoerg       Value *IntptrOriginPtr =
114406f32e7eSjoerg           IRB.CreatePointerCast(OriginPtr, PointerType::get(MS.IntptrTy, 0));
114506f32e7eSjoerg       for (unsigned i = 0; i < Size / IntptrSize; ++i) {
114606f32e7eSjoerg         Value *Ptr = i ? IRB.CreateConstGEP1_32(MS.IntptrTy, IntptrOriginPtr, i)
114706f32e7eSjoerg                        : IntptrOriginPtr;
114806f32e7eSjoerg         IRB.CreateAlignedStore(IntptrOrigin, Ptr, CurrentAlignment);
114906f32e7eSjoerg         Ofs += IntptrSize / kOriginSize;
115006f32e7eSjoerg         CurrentAlignment = IntptrAlignment;
115106f32e7eSjoerg       }
115206f32e7eSjoerg     }
115306f32e7eSjoerg 
115406f32e7eSjoerg     for (unsigned i = Ofs; i < (Size + kOriginSize - 1) / kOriginSize; ++i) {
115506f32e7eSjoerg       Value *GEP =
115606f32e7eSjoerg           i ? IRB.CreateConstGEP1_32(MS.OriginTy, OriginPtr, i) : OriginPtr;
115706f32e7eSjoerg       IRB.CreateAlignedStore(Origin, GEP, CurrentAlignment);
115806f32e7eSjoerg       CurrentAlignment = kMinOriginAlignment;
115906f32e7eSjoerg     }
116006f32e7eSjoerg   }
116106f32e7eSjoerg 
storeOrigin__anonb9e144640811::MemorySanitizerVisitor116206f32e7eSjoerg   void storeOrigin(IRBuilder<> &IRB, Value *Addr, Value *Shadow, Value *Origin,
1163*da58b97aSjoerg                    Value *OriginPtr, Align Alignment, bool AsCall) {
116406f32e7eSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
1165*da58b97aSjoerg     const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
116606f32e7eSjoerg     unsigned StoreSize = DL.getTypeStoreSize(Shadow->getType());
1167*da58b97aSjoerg     Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
1168*da58b97aSjoerg     if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
116906f32e7eSjoerg       if (ClCheckConstantShadow && !ConstantShadow->isZeroValue())
117006f32e7eSjoerg         paintOrigin(IRB, updateOrigin(Origin, IRB), OriginPtr, StoreSize,
117106f32e7eSjoerg                     OriginAlignment);
117206f32e7eSjoerg       return;
117306f32e7eSjoerg     }
117406f32e7eSjoerg 
1175*da58b97aSjoerg     unsigned TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
117606f32e7eSjoerg     unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
117706f32e7eSjoerg     if (AsCall && SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
117806f32e7eSjoerg       FunctionCallee Fn = MS.MaybeStoreOriginFn[SizeIndex];
1179*da58b97aSjoerg       Value *ConvertedShadow2 =
1180*da58b97aSjoerg           IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1181*da58b97aSjoerg       CallBase *CB = IRB.CreateCall(
1182*da58b97aSjoerg           Fn, {ConvertedShadow2,
1183*da58b97aSjoerg                IRB.CreatePointerCast(Addr, IRB.getInt8PtrTy()), Origin});
1184*da58b97aSjoerg       CB->addParamAttr(0, Attribute::ZExt);
1185*da58b97aSjoerg       CB->addParamAttr(2, Attribute::ZExt);
118606f32e7eSjoerg     } else {
1187*da58b97aSjoerg       Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
118806f32e7eSjoerg       Instruction *CheckTerm = SplitBlockAndInsertIfThen(
118906f32e7eSjoerg           Cmp, &*IRB.GetInsertPoint(), false, MS.OriginStoreWeights);
119006f32e7eSjoerg       IRBuilder<> IRBNew(CheckTerm);
119106f32e7eSjoerg       paintOrigin(IRBNew, updateOrigin(Origin, IRBNew), OriginPtr, StoreSize,
119206f32e7eSjoerg                   OriginAlignment);
119306f32e7eSjoerg     }
119406f32e7eSjoerg   }
119506f32e7eSjoerg 
materializeStores__anonb9e144640811::MemorySanitizerVisitor119606f32e7eSjoerg   void materializeStores(bool InstrumentWithCalls) {
119706f32e7eSjoerg     for (StoreInst *SI : StoreList) {
119806f32e7eSjoerg       IRBuilder<> IRB(SI);
119906f32e7eSjoerg       Value *Val = SI->getValueOperand();
120006f32e7eSjoerg       Value *Addr = SI->getPointerOperand();
120106f32e7eSjoerg       Value *Shadow = SI->isAtomic() ? getCleanShadow(Val) : getShadow(Val);
120206f32e7eSjoerg       Value *ShadowPtr, *OriginPtr;
120306f32e7eSjoerg       Type *ShadowTy = Shadow->getType();
1204*da58b97aSjoerg       const Align Alignment = assumeAligned(SI->getAlignment());
1205*da58b97aSjoerg       const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
120606f32e7eSjoerg       std::tie(ShadowPtr, OriginPtr) =
120706f32e7eSjoerg           getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ true);
120806f32e7eSjoerg 
120906f32e7eSjoerg       StoreInst *NewSI = IRB.CreateAlignedStore(Shadow, ShadowPtr, Alignment);
121006f32e7eSjoerg       LLVM_DEBUG(dbgs() << "  STORE: " << *NewSI << "\n");
121106f32e7eSjoerg       (void)NewSI;
121206f32e7eSjoerg 
121306f32e7eSjoerg       if (SI->isAtomic())
121406f32e7eSjoerg         SI->setOrdering(addReleaseOrdering(SI->getOrdering()));
121506f32e7eSjoerg 
121606f32e7eSjoerg       if (MS.TrackOrigins && !SI->isAtomic())
121706f32e7eSjoerg         storeOrigin(IRB, Addr, Shadow, getOrigin(Val), OriginPtr,
121806f32e7eSjoerg                     OriginAlignment, InstrumentWithCalls);
121906f32e7eSjoerg     }
122006f32e7eSjoerg   }
122106f32e7eSjoerg 
122206f32e7eSjoerg   /// Helper function to insert a warning at IRB's current insert point.
insertWarningFn__anonb9e144640811::MemorySanitizerVisitor122306f32e7eSjoerg   void insertWarningFn(IRBuilder<> &IRB, Value *Origin) {
122406f32e7eSjoerg     if (!Origin)
122506f32e7eSjoerg       Origin = (Value *)IRB.getInt32(0);
1226*da58b97aSjoerg     assert(Origin->getType()->isIntegerTy());
1227*da58b97aSjoerg     IRB.CreateCall(MS.WarningFn, Origin)->setCannotMerge();
122806f32e7eSjoerg     // FIXME: Insert UnreachableInst if !MS.Recover?
122906f32e7eSjoerg     // This may invalidate some of the following checks and needs to be done
123006f32e7eSjoerg     // at the very end.
123106f32e7eSjoerg   }
123206f32e7eSjoerg 
materializeOneCheck__anonb9e144640811::MemorySanitizerVisitor123306f32e7eSjoerg   void materializeOneCheck(Instruction *OrigIns, Value *Shadow, Value *Origin,
123406f32e7eSjoerg                            bool AsCall) {
123506f32e7eSjoerg     IRBuilder<> IRB(OrigIns);
123606f32e7eSjoerg     LLVM_DEBUG(dbgs() << "  SHAD0 : " << *Shadow << "\n");
1237*da58b97aSjoerg     Value *ConvertedShadow = convertShadowToScalar(Shadow, IRB);
123806f32e7eSjoerg     LLVM_DEBUG(dbgs() << "  SHAD1 : " << *ConvertedShadow << "\n");
123906f32e7eSjoerg 
1240*da58b97aSjoerg     if (auto *ConstantShadow = dyn_cast<Constant>(ConvertedShadow)) {
124106f32e7eSjoerg       if (ClCheckConstantShadow && !ConstantShadow->isZeroValue()) {
124206f32e7eSjoerg         insertWarningFn(IRB, Origin);
124306f32e7eSjoerg       }
124406f32e7eSjoerg       return;
124506f32e7eSjoerg     }
124606f32e7eSjoerg 
124706f32e7eSjoerg     const DataLayout &DL = OrigIns->getModule()->getDataLayout();
124806f32e7eSjoerg 
124906f32e7eSjoerg     unsigned TypeSizeInBits = DL.getTypeSizeInBits(ConvertedShadow->getType());
125006f32e7eSjoerg     unsigned SizeIndex = TypeSizeToSizeIndex(TypeSizeInBits);
125106f32e7eSjoerg     if (AsCall && SizeIndex < kNumberOfAccessSizes && !MS.CompileKernel) {
125206f32e7eSjoerg       FunctionCallee Fn = MS.MaybeWarningFn[SizeIndex];
125306f32e7eSjoerg       Value *ConvertedShadow2 =
125406f32e7eSjoerg           IRB.CreateZExt(ConvertedShadow, IRB.getIntNTy(8 * (1 << SizeIndex)));
1255*da58b97aSjoerg       CallBase *CB = IRB.CreateCall(
1256*da58b97aSjoerg           Fn, {ConvertedShadow2,
1257*da58b97aSjoerg                MS.TrackOrigins && Origin ? Origin : (Value *)IRB.getInt32(0)});
1258*da58b97aSjoerg       CB->addParamAttr(0, Attribute::ZExt);
1259*da58b97aSjoerg       CB->addParamAttr(1, Attribute::ZExt);
126006f32e7eSjoerg     } else {
1261*da58b97aSjoerg       Value *Cmp = convertToBool(ConvertedShadow, IRB, "_mscmp");
126206f32e7eSjoerg       Instruction *CheckTerm = SplitBlockAndInsertIfThen(
126306f32e7eSjoerg           Cmp, OrigIns,
126406f32e7eSjoerg           /* Unreachable */ !MS.Recover, MS.ColdCallWeights);
126506f32e7eSjoerg 
126606f32e7eSjoerg       IRB.SetInsertPoint(CheckTerm);
126706f32e7eSjoerg       insertWarningFn(IRB, Origin);
126806f32e7eSjoerg       LLVM_DEBUG(dbgs() << "  CHECK: " << *Cmp << "\n");
126906f32e7eSjoerg     }
127006f32e7eSjoerg   }
127106f32e7eSjoerg 
materializeChecks__anonb9e144640811::MemorySanitizerVisitor127206f32e7eSjoerg   void materializeChecks(bool InstrumentWithCalls) {
127306f32e7eSjoerg     for (const auto &ShadowData : InstrumentationList) {
127406f32e7eSjoerg       Instruction *OrigIns = ShadowData.OrigIns;
127506f32e7eSjoerg       Value *Shadow = ShadowData.Shadow;
127606f32e7eSjoerg       Value *Origin = ShadowData.Origin;
127706f32e7eSjoerg       materializeOneCheck(OrigIns, Shadow, Origin, InstrumentWithCalls);
127806f32e7eSjoerg     }
127906f32e7eSjoerg     LLVM_DEBUG(dbgs() << "DONE:\n" << F);
128006f32e7eSjoerg   }
128106f32e7eSjoerg 
1282*da58b97aSjoerg   // Returns the last instruction in the new prologue
insertKmsanPrologue__anonb9e144640811::MemorySanitizerVisitor1283*da58b97aSjoerg   void insertKmsanPrologue(IRBuilder<> &IRB) {
128406f32e7eSjoerg     Value *ContextState = IRB.CreateCall(MS.MsanGetContextStateFn, {});
128506f32e7eSjoerg     Constant *Zero = IRB.getInt32(0);
128606f32e7eSjoerg     MS.ParamTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
128706f32e7eSjoerg                                 {Zero, IRB.getInt32(0)}, "param_shadow");
128806f32e7eSjoerg     MS.RetvalTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
128906f32e7eSjoerg                                  {Zero, IRB.getInt32(1)}, "retval_shadow");
129006f32e7eSjoerg     MS.VAArgTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
129106f32e7eSjoerg                                 {Zero, IRB.getInt32(2)}, "va_arg_shadow");
129206f32e7eSjoerg     MS.VAArgOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
129306f32e7eSjoerg                                       {Zero, IRB.getInt32(3)}, "va_arg_origin");
129406f32e7eSjoerg     MS.VAArgOverflowSizeTLS =
129506f32e7eSjoerg         IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
129606f32e7eSjoerg                       {Zero, IRB.getInt32(4)}, "va_arg_overflow_size");
129706f32e7eSjoerg     MS.ParamOriginTLS = IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
129806f32e7eSjoerg                                       {Zero, IRB.getInt32(5)}, "param_origin");
129906f32e7eSjoerg     MS.RetvalOriginTLS =
130006f32e7eSjoerg         IRB.CreateGEP(MS.MsanContextStateTy, ContextState,
130106f32e7eSjoerg                       {Zero, IRB.getInt32(6)}, "retval_origin");
130206f32e7eSjoerg   }
130306f32e7eSjoerg 
130406f32e7eSjoerg   /// Add MemorySanitizer instrumentation to a function.
runOnFunction__anonb9e144640811::MemorySanitizerVisitor130506f32e7eSjoerg   bool runOnFunction() {
130606f32e7eSjoerg     // Iterate all BBs in depth-first order and create shadow instructions
130706f32e7eSjoerg     // for all instructions (where applicable).
130806f32e7eSjoerg     // For PHI nodes we create dummy shadow PHIs which will be finalized later.
1309*da58b97aSjoerg     for (BasicBlock *BB : depth_first(FnPrologueEnd->getParent()))
131006f32e7eSjoerg       visit(*BB);
131106f32e7eSjoerg 
131206f32e7eSjoerg     // Finalize PHI nodes.
131306f32e7eSjoerg     for (PHINode *PN : ShadowPHINodes) {
131406f32e7eSjoerg       PHINode *PNS = cast<PHINode>(getShadow(PN));
131506f32e7eSjoerg       PHINode *PNO = MS.TrackOrigins ? cast<PHINode>(getOrigin(PN)) : nullptr;
131606f32e7eSjoerg       size_t NumValues = PN->getNumIncomingValues();
131706f32e7eSjoerg       for (size_t v = 0; v < NumValues; v++) {
131806f32e7eSjoerg         PNS->addIncoming(getShadow(PN, v), PN->getIncomingBlock(v));
131906f32e7eSjoerg         if (PNO) PNO->addIncoming(getOrigin(PN, v), PN->getIncomingBlock(v));
132006f32e7eSjoerg       }
132106f32e7eSjoerg     }
132206f32e7eSjoerg 
132306f32e7eSjoerg     VAHelper->finalizeInstrumentation();
132406f32e7eSjoerg 
132506f32e7eSjoerg     // Poison llvm.lifetime.start intrinsics, if we haven't fallen back to
132606f32e7eSjoerg     // instrumenting only allocas.
132706f32e7eSjoerg     if (InstrumentLifetimeStart) {
132806f32e7eSjoerg       for (auto Item : LifetimeStartList) {
132906f32e7eSjoerg         instrumentAlloca(*Item.second, Item.first);
133006f32e7eSjoerg         AllocaSet.erase(Item.second);
133106f32e7eSjoerg       }
133206f32e7eSjoerg     }
133306f32e7eSjoerg     // Poison the allocas for which we didn't instrument the corresponding
133406f32e7eSjoerg     // lifetime intrinsics.
133506f32e7eSjoerg     for (AllocaInst *AI : AllocaSet)
133606f32e7eSjoerg       instrumentAlloca(*AI);
133706f32e7eSjoerg 
133806f32e7eSjoerg     bool InstrumentWithCalls = ClInstrumentationWithCallThreshold >= 0 &&
133906f32e7eSjoerg                                InstrumentationList.size() + StoreList.size() >
134006f32e7eSjoerg                                    (unsigned)ClInstrumentationWithCallThreshold;
134106f32e7eSjoerg 
134206f32e7eSjoerg     // Insert shadow value checks.
134306f32e7eSjoerg     materializeChecks(InstrumentWithCalls);
134406f32e7eSjoerg 
134506f32e7eSjoerg     // Delayed instrumentation of StoreInst.
134606f32e7eSjoerg     // This may not add new address checks.
134706f32e7eSjoerg     materializeStores(InstrumentWithCalls);
134806f32e7eSjoerg 
134906f32e7eSjoerg     return true;
135006f32e7eSjoerg   }
135106f32e7eSjoerg 
135206f32e7eSjoerg   /// Compute the shadow type that corresponds to a given Value.
getShadowTy__anonb9e144640811::MemorySanitizerVisitor135306f32e7eSjoerg   Type *getShadowTy(Value *V) {
135406f32e7eSjoerg     return getShadowTy(V->getType());
135506f32e7eSjoerg   }
135606f32e7eSjoerg 
135706f32e7eSjoerg   /// Compute the shadow type that corresponds to a given Type.
getShadowTy__anonb9e144640811::MemorySanitizerVisitor135806f32e7eSjoerg   Type *getShadowTy(Type *OrigTy) {
135906f32e7eSjoerg     if (!OrigTy->isSized()) {
136006f32e7eSjoerg       return nullptr;
136106f32e7eSjoerg     }
136206f32e7eSjoerg     // For integer type, shadow is the same as the original type.
136306f32e7eSjoerg     // This may return weird-sized types like i1.
136406f32e7eSjoerg     if (IntegerType *IT = dyn_cast<IntegerType>(OrigTy))
136506f32e7eSjoerg       return IT;
136606f32e7eSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
136706f32e7eSjoerg     if (VectorType *VT = dyn_cast<VectorType>(OrigTy)) {
136806f32e7eSjoerg       uint32_t EltSize = DL.getTypeSizeInBits(VT->getElementType());
1369*da58b97aSjoerg       return FixedVectorType::get(IntegerType::get(*MS.C, EltSize),
1370*da58b97aSjoerg                                   cast<FixedVectorType>(VT)->getNumElements());
137106f32e7eSjoerg     }
137206f32e7eSjoerg     if (ArrayType *AT = dyn_cast<ArrayType>(OrigTy)) {
137306f32e7eSjoerg       return ArrayType::get(getShadowTy(AT->getElementType()),
137406f32e7eSjoerg                             AT->getNumElements());
137506f32e7eSjoerg     }
137606f32e7eSjoerg     if (StructType *ST = dyn_cast<StructType>(OrigTy)) {
137706f32e7eSjoerg       SmallVector<Type*, 4> Elements;
137806f32e7eSjoerg       for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
137906f32e7eSjoerg         Elements.push_back(getShadowTy(ST->getElementType(i)));
138006f32e7eSjoerg       StructType *Res = StructType::get(*MS.C, Elements, ST->isPacked());
138106f32e7eSjoerg       LLVM_DEBUG(dbgs() << "getShadowTy: " << *ST << " ===> " << *Res << "\n");
138206f32e7eSjoerg       return Res;
138306f32e7eSjoerg     }
138406f32e7eSjoerg     uint32_t TypeSize = DL.getTypeSizeInBits(OrigTy);
138506f32e7eSjoerg     return IntegerType::get(*MS.C, TypeSize);
138606f32e7eSjoerg   }
138706f32e7eSjoerg 
138806f32e7eSjoerg   /// Flatten a vector type.
getShadowTyNoVec__anonb9e144640811::MemorySanitizerVisitor138906f32e7eSjoerg   Type *getShadowTyNoVec(Type *ty) {
139006f32e7eSjoerg     if (VectorType *vt = dyn_cast<VectorType>(ty))
1391*da58b97aSjoerg       return IntegerType::get(*MS.C,
1392*da58b97aSjoerg                               vt->getPrimitiveSizeInBits().getFixedSize());
139306f32e7eSjoerg     return ty;
139406f32e7eSjoerg   }
139506f32e7eSjoerg 
1396*da58b97aSjoerg   /// Extract combined shadow of struct elements as a bool
collapseStructShadow__anonb9e144640811::MemorySanitizerVisitor1397*da58b97aSjoerg   Value *collapseStructShadow(StructType *Struct, Value *Shadow,
1398*da58b97aSjoerg                               IRBuilder<> &IRB) {
1399*da58b97aSjoerg     Value *FalseVal = IRB.getIntN(/* width */ 1, /* value */ 0);
1400*da58b97aSjoerg     Value *Aggregator = FalseVal;
1401*da58b97aSjoerg 
1402*da58b97aSjoerg     for (unsigned Idx = 0; Idx < Struct->getNumElements(); Idx++) {
1403*da58b97aSjoerg       // Combine by ORing together each element's bool shadow
1404*da58b97aSjoerg       Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1405*da58b97aSjoerg       Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1406*da58b97aSjoerg       Value *ShadowBool = convertToBool(ShadowInner, IRB);
1407*da58b97aSjoerg 
1408*da58b97aSjoerg       if (Aggregator != FalseVal)
1409*da58b97aSjoerg         Aggregator = IRB.CreateOr(Aggregator, ShadowBool);
1410*da58b97aSjoerg       else
1411*da58b97aSjoerg         Aggregator = ShadowBool;
1412*da58b97aSjoerg     }
1413*da58b97aSjoerg 
1414*da58b97aSjoerg     return Aggregator;
1415*da58b97aSjoerg   }
1416*da58b97aSjoerg 
1417*da58b97aSjoerg   // Extract combined shadow of array elements
collapseArrayShadow__anonb9e144640811::MemorySanitizerVisitor1418*da58b97aSjoerg   Value *collapseArrayShadow(ArrayType *Array, Value *Shadow,
1419*da58b97aSjoerg                              IRBuilder<> &IRB) {
1420*da58b97aSjoerg     if (!Array->getNumElements())
1421*da58b97aSjoerg       return IRB.getIntN(/* width */ 1, /* value */ 0);
1422*da58b97aSjoerg 
1423*da58b97aSjoerg     Value *FirstItem = IRB.CreateExtractValue(Shadow, 0);
1424*da58b97aSjoerg     Value *Aggregator = convertShadowToScalar(FirstItem, IRB);
1425*da58b97aSjoerg 
1426*da58b97aSjoerg     for (unsigned Idx = 1; Idx < Array->getNumElements(); Idx++) {
1427*da58b97aSjoerg       Value *ShadowItem = IRB.CreateExtractValue(Shadow, Idx);
1428*da58b97aSjoerg       Value *ShadowInner = convertShadowToScalar(ShadowItem, IRB);
1429*da58b97aSjoerg       Aggregator = IRB.CreateOr(Aggregator, ShadowInner);
1430*da58b97aSjoerg     }
1431*da58b97aSjoerg     return Aggregator;
1432*da58b97aSjoerg   }
1433*da58b97aSjoerg 
1434*da58b97aSjoerg   /// Convert a shadow value to it's flattened variant. The resulting
1435*da58b97aSjoerg   /// shadow may not necessarily have the same bit width as the input
1436*da58b97aSjoerg   /// value, but it will always be comparable to zero.
convertShadowToScalar__anonb9e144640811::MemorySanitizerVisitor1437*da58b97aSjoerg   Value *convertShadowToScalar(Value *V, IRBuilder<> &IRB) {
1438*da58b97aSjoerg     if (StructType *Struct = dyn_cast<StructType>(V->getType()))
1439*da58b97aSjoerg       return collapseStructShadow(Struct, V, IRB);
1440*da58b97aSjoerg     if (ArrayType *Array = dyn_cast<ArrayType>(V->getType()))
1441*da58b97aSjoerg       return collapseArrayShadow(Array, V, IRB);
144206f32e7eSjoerg     Type *Ty = V->getType();
144306f32e7eSjoerg     Type *NoVecTy = getShadowTyNoVec(Ty);
144406f32e7eSjoerg     if (Ty == NoVecTy) return V;
144506f32e7eSjoerg     return IRB.CreateBitCast(V, NoVecTy);
144606f32e7eSjoerg   }
144706f32e7eSjoerg 
1448*da58b97aSjoerg   // Convert a scalar value to an i1 by comparing with 0
convertToBool__anonb9e144640811::MemorySanitizerVisitor1449*da58b97aSjoerg   Value *convertToBool(Value *V, IRBuilder<> &IRB, const Twine &name = "") {
1450*da58b97aSjoerg     Type *VTy = V->getType();
1451*da58b97aSjoerg     assert(VTy->isIntegerTy());
1452*da58b97aSjoerg     if (VTy->getIntegerBitWidth() == 1)
1453*da58b97aSjoerg       // Just converting a bool to a bool, so do nothing.
1454*da58b97aSjoerg       return V;
1455*da58b97aSjoerg     return IRB.CreateICmpNE(V, ConstantInt::get(VTy, 0), name);
1456*da58b97aSjoerg   }
1457*da58b97aSjoerg 
145806f32e7eSjoerg   /// Compute the integer shadow offset that corresponds to a given
145906f32e7eSjoerg   /// application address.
146006f32e7eSjoerg   ///
146106f32e7eSjoerg   /// Offset = (Addr & ~AndMask) ^ XorMask
getShadowPtrOffset__anonb9e144640811::MemorySanitizerVisitor146206f32e7eSjoerg   Value *getShadowPtrOffset(Value *Addr, IRBuilder<> &IRB) {
146306f32e7eSjoerg     Value *OffsetLong = IRB.CreatePointerCast(Addr, MS.IntptrTy);
146406f32e7eSjoerg 
146506f32e7eSjoerg     uint64_t AndMask = MS.MapParams->AndMask;
146606f32e7eSjoerg     if (AndMask)
146706f32e7eSjoerg       OffsetLong =
146806f32e7eSjoerg           IRB.CreateAnd(OffsetLong, ConstantInt::get(MS.IntptrTy, ~AndMask));
146906f32e7eSjoerg 
147006f32e7eSjoerg     uint64_t XorMask = MS.MapParams->XorMask;
147106f32e7eSjoerg     if (XorMask)
147206f32e7eSjoerg       OffsetLong =
147306f32e7eSjoerg           IRB.CreateXor(OffsetLong, ConstantInt::get(MS.IntptrTy, XorMask));
147406f32e7eSjoerg     return OffsetLong;
147506f32e7eSjoerg   }
147606f32e7eSjoerg 
147706f32e7eSjoerg   /// Compute the shadow and origin addresses corresponding to a given
147806f32e7eSjoerg   /// application address.
147906f32e7eSjoerg   ///
148006f32e7eSjoerg   /// Shadow = ShadowBase + Offset
148106f32e7eSjoerg   /// Origin = (OriginBase + Offset) & ~3ULL
1482*da58b97aSjoerg   std::pair<Value *, Value *>
getShadowOriginPtrUserspace__anonb9e144640811::MemorySanitizerVisitor1483*da58b97aSjoerg   getShadowOriginPtrUserspace(Value *Addr, IRBuilder<> &IRB, Type *ShadowTy,
1484*da58b97aSjoerg                               MaybeAlign Alignment) {
148506f32e7eSjoerg     Value *ShadowOffset = getShadowPtrOffset(Addr, IRB);
148606f32e7eSjoerg     Value *ShadowLong = ShadowOffset;
148706f32e7eSjoerg     uint64_t ShadowBase = MS.MapParams->ShadowBase;
148806f32e7eSjoerg     if (ShadowBase != 0) {
148906f32e7eSjoerg       ShadowLong =
149006f32e7eSjoerg         IRB.CreateAdd(ShadowLong,
149106f32e7eSjoerg                       ConstantInt::get(MS.IntptrTy, ShadowBase));
149206f32e7eSjoerg     }
149306f32e7eSjoerg     Value *ShadowPtr =
149406f32e7eSjoerg         IRB.CreateIntToPtr(ShadowLong, PointerType::get(ShadowTy, 0));
149506f32e7eSjoerg     Value *OriginPtr = nullptr;
149606f32e7eSjoerg     if (MS.TrackOrigins) {
149706f32e7eSjoerg       Value *OriginLong = ShadowOffset;
149806f32e7eSjoerg       uint64_t OriginBase = MS.MapParams->OriginBase;
149906f32e7eSjoerg       if (OriginBase != 0)
150006f32e7eSjoerg         OriginLong = IRB.CreateAdd(OriginLong,
150106f32e7eSjoerg                                    ConstantInt::get(MS.IntptrTy, OriginBase));
1502*da58b97aSjoerg       if (!Alignment || *Alignment < kMinOriginAlignment) {
1503*da58b97aSjoerg         uint64_t Mask = kMinOriginAlignment.value() - 1;
150406f32e7eSjoerg         OriginLong =
150506f32e7eSjoerg             IRB.CreateAnd(OriginLong, ConstantInt::get(MS.IntptrTy, ~Mask));
150606f32e7eSjoerg       }
150706f32e7eSjoerg       OriginPtr =
150806f32e7eSjoerg           IRB.CreateIntToPtr(OriginLong, PointerType::get(MS.OriginTy, 0));
150906f32e7eSjoerg     }
151006f32e7eSjoerg     return std::make_pair(ShadowPtr, OriginPtr);
151106f32e7eSjoerg   }
151206f32e7eSjoerg 
getShadowOriginPtrKernel__anonb9e144640811::MemorySanitizerVisitor1513*da58b97aSjoerg   std::pair<Value *, Value *> getShadowOriginPtrKernel(Value *Addr,
1514*da58b97aSjoerg                                                        IRBuilder<> &IRB,
1515*da58b97aSjoerg                                                        Type *ShadowTy,
1516*da58b97aSjoerg                                                        bool isStore) {
151706f32e7eSjoerg     Value *ShadowOriginPtrs;
151806f32e7eSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
151906f32e7eSjoerg     int Size = DL.getTypeStoreSize(ShadowTy);
152006f32e7eSjoerg 
152106f32e7eSjoerg     FunctionCallee Getter = MS.getKmsanShadowOriginAccessFn(isStore, Size);
152206f32e7eSjoerg     Value *AddrCast =
152306f32e7eSjoerg         IRB.CreatePointerCast(Addr, PointerType::get(IRB.getInt8Ty(), 0));
152406f32e7eSjoerg     if (Getter) {
152506f32e7eSjoerg       ShadowOriginPtrs = IRB.CreateCall(Getter, AddrCast);
152606f32e7eSjoerg     } else {
152706f32e7eSjoerg       Value *SizeVal = ConstantInt::get(MS.IntptrTy, Size);
152806f32e7eSjoerg       ShadowOriginPtrs = IRB.CreateCall(isStore ? MS.MsanMetadataPtrForStoreN
152906f32e7eSjoerg                                                 : MS.MsanMetadataPtrForLoadN,
153006f32e7eSjoerg                                         {AddrCast, SizeVal});
153106f32e7eSjoerg     }
153206f32e7eSjoerg     Value *ShadowPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 0);
153306f32e7eSjoerg     ShadowPtr = IRB.CreatePointerCast(ShadowPtr, PointerType::get(ShadowTy, 0));
153406f32e7eSjoerg     Value *OriginPtr = IRB.CreateExtractValue(ShadowOriginPtrs, 1);
153506f32e7eSjoerg 
153606f32e7eSjoerg     return std::make_pair(ShadowPtr, OriginPtr);
153706f32e7eSjoerg   }
153806f32e7eSjoerg 
getShadowOriginPtr__anonb9e144640811::MemorySanitizerVisitor153906f32e7eSjoerg   std::pair<Value *, Value *> getShadowOriginPtr(Value *Addr, IRBuilder<> &IRB,
154006f32e7eSjoerg                                                  Type *ShadowTy,
1541*da58b97aSjoerg                                                  MaybeAlign Alignment,
154206f32e7eSjoerg                                                  bool isStore) {
154306f32e7eSjoerg     if (MS.CompileKernel)
1544*da58b97aSjoerg       return getShadowOriginPtrKernel(Addr, IRB, ShadowTy, isStore);
1545*da58b97aSjoerg     return getShadowOriginPtrUserspace(Addr, IRB, ShadowTy, Alignment);
154606f32e7eSjoerg   }
154706f32e7eSjoerg 
154806f32e7eSjoerg   /// Compute the shadow address for a given function argument.
154906f32e7eSjoerg   ///
155006f32e7eSjoerg   /// Shadow = ParamTLS+ArgOffset.
getShadowPtrForArgument__anonb9e144640811::MemorySanitizerVisitor155106f32e7eSjoerg   Value *getShadowPtrForArgument(Value *A, IRBuilder<> &IRB,
155206f32e7eSjoerg                                  int ArgOffset) {
155306f32e7eSjoerg     Value *Base = IRB.CreatePointerCast(MS.ParamTLS, MS.IntptrTy);
155406f32e7eSjoerg     if (ArgOffset)
155506f32e7eSjoerg       Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
155606f32e7eSjoerg     return IRB.CreateIntToPtr(Base, PointerType::get(getShadowTy(A), 0),
155706f32e7eSjoerg                               "_msarg");
155806f32e7eSjoerg   }
155906f32e7eSjoerg 
156006f32e7eSjoerg   /// Compute the origin address for a given function argument.
getOriginPtrForArgument__anonb9e144640811::MemorySanitizerVisitor156106f32e7eSjoerg   Value *getOriginPtrForArgument(Value *A, IRBuilder<> &IRB,
156206f32e7eSjoerg                                  int ArgOffset) {
156306f32e7eSjoerg     if (!MS.TrackOrigins)
156406f32e7eSjoerg       return nullptr;
156506f32e7eSjoerg     Value *Base = IRB.CreatePointerCast(MS.ParamOriginTLS, MS.IntptrTy);
156606f32e7eSjoerg     if (ArgOffset)
156706f32e7eSjoerg       Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
156806f32e7eSjoerg     return IRB.CreateIntToPtr(Base, PointerType::get(MS.OriginTy, 0),
156906f32e7eSjoerg                               "_msarg_o");
157006f32e7eSjoerg   }
157106f32e7eSjoerg 
157206f32e7eSjoerg   /// Compute the shadow address for a retval.
getShadowPtrForRetval__anonb9e144640811::MemorySanitizerVisitor157306f32e7eSjoerg   Value *getShadowPtrForRetval(Value *A, IRBuilder<> &IRB) {
157406f32e7eSjoerg     return IRB.CreatePointerCast(MS.RetvalTLS,
157506f32e7eSjoerg                                  PointerType::get(getShadowTy(A), 0),
157606f32e7eSjoerg                                  "_msret");
157706f32e7eSjoerg   }
157806f32e7eSjoerg 
157906f32e7eSjoerg   /// Compute the origin address for a retval.
getOriginPtrForRetval__anonb9e144640811::MemorySanitizerVisitor158006f32e7eSjoerg   Value *getOriginPtrForRetval(IRBuilder<> &IRB) {
158106f32e7eSjoerg     // We keep a single origin for the entire retval. Might be too optimistic.
158206f32e7eSjoerg     return MS.RetvalOriginTLS;
158306f32e7eSjoerg   }
158406f32e7eSjoerg 
158506f32e7eSjoerg   /// Set SV to be the shadow value for V.
setShadow__anonb9e144640811::MemorySanitizerVisitor158606f32e7eSjoerg   void setShadow(Value *V, Value *SV) {
158706f32e7eSjoerg     assert(!ShadowMap.count(V) && "Values may only have one shadow");
158806f32e7eSjoerg     ShadowMap[V] = PropagateShadow ? SV : getCleanShadow(V);
158906f32e7eSjoerg   }
159006f32e7eSjoerg 
159106f32e7eSjoerg   /// Set Origin to be the origin value for V.
setOrigin__anonb9e144640811::MemorySanitizerVisitor159206f32e7eSjoerg   void setOrigin(Value *V, Value *Origin) {
159306f32e7eSjoerg     if (!MS.TrackOrigins) return;
159406f32e7eSjoerg     assert(!OriginMap.count(V) && "Values may only have one origin");
159506f32e7eSjoerg     LLVM_DEBUG(dbgs() << "ORIGIN: " << *V << "  ==> " << *Origin << "\n");
159606f32e7eSjoerg     OriginMap[V] = Origin;
159706f32e7eSjoerg   }
159806f32e7eSjoerg 
getCleanShadow__anonb9e144640811::MemorySanitizerVisitor159906f32e7eSjoerg   Constant *getCleanShadow(Type *OrigTy) {
160006f32e7eSjoerg     Type *ShadowTy = getShadowTy(OrigTy);
160106f32e7eSjoerg     if (!ShadowTy)
160206f32e7eSjoerg       return nullptr;
160306f32e7eSjoerg     return Constant::getNullValue(ShadowTy);
160406f32e7eSjoerg   }
160506f32e7eSjoerg 
160606f32e7eSjoerg   /// Create a clean shadow value for a given value.
160706f32e7eSjoerg   ///
160806f32e7eSjoerg   /// Clean shadow (all zeroes) means all bits of the value are defined
160906f32e7eSjoerg   /// (initialized).
getCleanShadow__anonb9e144640811::MemorySanitizerVisitor161006f32e7eSjoerg   Constant *getCleanShadow(Value *V) {
161106f32e7eSjoerg     return getCleanShadow(V->getType());
161206f32e7eSjoerg   }
161306f32e7eSjoerg 
161406f32e7eSjoerg   /// Create a dirty shadow of a given shadow type.
getPoisonedShadow__anonb9e144640811::MemorySanitizerVisitor161506f32e7eSjoerg   Constant *getPoisonedShadow(Type *ShadowTy) {
161606f32e7eSjoerg     assert(ShadowTy);
161706f32e7eSjoerg     if (isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy))
161806f32e7eSjoerg       return Constant::getAllOnesValue(ShadowTy);
161906f32e7eSjoerg     if (ArrayType *AT = dyn_cast<ArrayType>(ShadowTy)) {
162006f32e7eSjoerg       SmallVector<Constant *, 4> Vals(AT->getNumElements(),
162106f32e7eSjoerg                                       getPoisonedShadow(AT->getElementType()));
162206f32e7eSjoerg       return ConstantArray::get(AT, Vals);
162306f32e7eSjoerg     }
162406f32e7eSjoerg     if (StructType *ST = dyn_cast<StructType>(ShadowTy)) {
162506f32e7eSjoerg       SmallVector<Constant *, 4> Vals;
162606f32e7eSjoerg       for (unsigned i = 0, n = ST->getNumElements(); i < n; i++)
162706f32e7eSjoerg         Vals.push_back(getPoisonedShadow(ST->getElementType(i)));
162806f32e7eSjoerg       return ConstantStruct::get(ST, Vals);
162906f32e7eSjoerg     }
163006f32e7eSjoerg     llvm_unreachable("Unexpected shadow type");
163106f32e7eSjoerg   }
163206f32e7eSjoerg 
163306f32e7eSjoerg   /// Create a dirty shadow for a given value.
getPoisonedShadow__anonb9e144640811::MemorySanitizerVisitor163406f32e7eSjoerg   Constant *getPoisonedShadow(Value *V) {
163506f32e7eSjoerg     Type *ShadowTy = getShadowTy(V);
163606f32e7eSjoerg     if (!ShadowTy)
163706f32e7eSjoerg       return nullptr;
163806f32e7eSjoerg     return getPoisonedShadow(ShadowTy);
163906f32e7eSjoerg   }
164006f32e7eSjoerg 
164106f32e7eSjoerg   /// Create a clean (zero) origin.
getCleanOrigin__anonb9e144640811::MemorySanitizerVisitor164206f32e7eSjoerg   Value *getCleanOrigin() {
164306f32e7eSjoerg     return Constant::getNullValue(MS.OriginTy);
164406f32e7eSjoerg   }
164506f32e7eSjoerg 
164606f32e7eSjoerg   /// Get the shadow value for a given Value.
164706f32e7eSjoerg   ///
164806f32e7eSjoerg   /// This function either returns the value set earlier with setShadow,
164906f32e7eSjoerg   /// or extracts if from ParamTLS (for function arguments).
getShadow__anonb9e144640811::MemorySanitizerVisitor165006f32e7eSjoerg   Value *getShadow(Value *V) {
165106f32e7eSjoerg     if (!PropagateShadow) return getCleanShadow(V);
165206f32e7eSjoerg     if (Instruction *I = dyn_cast<Instruction>(V)) {
165306f32e7eSjoerg       if (I->getMetadata("nosanitize"))
165406f32e7eSjoerg         return getCleanShadow(V);
165506f32e7eSjoerg       // For instructions the shadow is already stored in the map.
165606f32e7eSjoerg       Value *Shadow = ShadowMap[V];
165706f32e7eSjoerg       if (!Shadow) {
165806f32e7eSjoerg         LLVM_DEBUG(dbgs() << "No shadow: " << *V << "\n" << *(I->getParent()));
165906f32e7eSjoerg         (void)I;
166006f32e7eSjoerg         assert(Shadow && "No shadow for a value");
166106f32e7eSjoerg       }
166206f32e7eSjoerg       return Shadow;
166306f32e7eSjoerg     }
166406f32e7eSjoerg     if (UndefValue *U = dyn_cast<UndefValue>(V)) {
166506f32e7eSjoerg       Value *AllOnes = PoisonUndef ? getPoisonedShadow(V) : getCleanShadow(V);
166606f32e7eSjoerg       LLVM_DEBUG(dbgs() << "Undef: " << *U << " ==> " << *AllOnes << "\n");
166706f32e7eSjoerg       (void)U;
166806f32e7eSjoerg       return AllOnes;
166906f32e7eSjoerg     }
167006f32e7eSjoerg     if (Argument *A = dyn_cast<Argument>(V)) {
167106f32e7eSjoerg       // For arguments we compute the shadow on demand and store it in the map.
167206f32e7eSjoerg       Value **ShadowPtr = &ShadowMap[V];
167306f32e7eSjoerg       if (*ShadowPtr)
167406f32e7eSjoerg         return *ShadowPtr;
167506f32e7eSjoerg       Function *F = A->getParent();
1676*da58b97aSjoerg       IRBuilder<> EntryIRB(FnPrologueEnd);
167706f32e7eSjoerg       unsigned ArgOffset = 0;
167806f32e7eSjoerg       const DataLayout &DL = F->getParent()->getDataLayout();
167906f32e7eSjoerg       for (auto &FArg : F->args()) {
168006f32e7eSjoerg         if (!FArg.getType()->isSized()) {
168106f32e7eSjoerg           LLVM_DEBUG(dbgs() << "Arg is not sized\n");
168206f32e7eSjoerg           continue;
168306f32e7eSjoerg         }
1684*da58b97aSjoerg 
1685*da58b97aSjoerg         bool FArgByVal = FArg.hasByValAttr();
1686*da58b97aSjoerg         bool FArgNoUndef = FArg.hasAttribute(Attribute::NoUndef);
1687*da58b97aSjoerg         bool FArgEagerCheck = ClEagerChecks && !FArgByVal && FArgNoUndef;
168806f32e7eSjoerg         unsigned Size =
168906f32e7eSjoerg             FArg.hasByValAttr()
1690*da58b97aSjoerg                 ? DL.getTypeAllocSize(FArg.getParamByValType())
169106f32e7eSjoerg                 : DL.getTypeAllocSize(FArg.getType());
1692*da58b97aSjoerg 
169306f32e7eSjoerg         if (A == &FArg) {
169406f32e7eSjoerg           bool Overflow = ArgOffset + Size > kParamTLSSize;
1695*da58b97aSjoerg           if (FArgEagerCheck) {
1696*da58b97aSjoerg             *ShadowPtr = getCleanShadow(V);
1697*da58b97aSjoerg             setOrigin(A, getCleanOrigin());
1698*da58b97aSjoerg             continue;
1699*da58b97aSjoerg           } else if (FArgByVal) {
170006f32e7eSjoerg             Value *Base = getShadowPtrForArgument(&FArg, EntryIRB, ArgOffset);
170106f32e7eSjoerg             // ByVal pointer itself has clean shadow. We copy the actual
170206f32e7eSjoerg             // argument shadow to the underlying memory.
170306f32e7eSjoerg             // Figure out maximal valid memcpy alignment.
1704*da58b97aSjoerg             const Align ArgAlign = DL.getValueOrABITypeAlignment(
1705*da58b97aSjoerg                 MaybeAlign(FArg.getParamAlignment()), FArg.getParamByValType());
170606f32e7eSjoerg             Value *CpShadowPtr =
170706f32e7eSjoerg                 getShadowOriginPtr(V, EntryIRB, EntryIRB.getInt8Ty(), ArgAlign,
170806f32e7eSjoerg                                    /*isStore*/ true)
170906f32e7eSjoerg                     .first;
171006f32e7eSjoerg             // TODO(glider): need to copy origins.
171106f32e7eSjoerg             if (Overflow) {
171206f32e7eSjoerg               // ParamTLS overflow.
171306f32e7eSjoerg               EntryIRB.CreateMemSet(
171406f32e7eSjoerg                   CpShadowPtr, Constant::getNullValue(EntryIRB.getInt8Ty()),
171506f32e7eSjoerg                   Size, ArgAlign);
171606f32e7eSjoerg             } else {
1717*da58b97aSjoerg               const Align CopyAlign = std::min(ArgAlign, kShadowTLSAlignment);
171806f32e7eSjoerg               Value *Cpy = EntryIRB.CreateMemCpy(CpShadowPtr, CopyAlign, Base,
171906f32e7eSjoerg                                                  CopyAlign, Size);
172006f32e7eSjoerg               LLVM_DEBUG(dbgs() << "  ByValCpy: " << *Cpy << "\n");
172106f32e7eSjoerg               (void)Cpy;
172206f32e7eSjoerg             }
172306f32e7eSjoerg             *ShadowPtr = getCleanShadow(V);
172406f32e7eSjoerg           } else {
1725*da58b97aSjoerg             // Shadow over TLS
1726*da58b97aSjoerg             Value *Base = getShadowPtrForArgument(&FArg, EntryIRB, ArgOffset);
172706f32e7eSjoerg             if (Overflow) {
172806f32e7eSjoerg               // ParamTLS overflow.
172906f32e7eSjoerg               *ShadowPtr = getCleanShadow(V);
173006f32e7eSjoerg             } else {
173106f32e7eSjoerg               *ShadowPtr = EntryIRB.CreateAlignedLoad(getShadowTy(&FArg), Base,
173206f32e7eSjoerg                                                       kShadowTLSAlignment);
173306f32e7eSjoerg             }
173406f32e7eSjoerg           }
173506f32e7eSjoerg           LLVM_DEBUG(dbgs()
173606f32e7eSjoerg                      << "  ARG:    " << FArg << " ==> " << **ShadowPtr << "\n");
173706f32e7eSjoerg           if (MS.TrackOrigins && !Overflow) {
173806f32e7eSjoerg             Value *OriginPtr =
173906f32e7eSjoerg                 getOriginPtrForArgument(&FArg, EntryIRB, ArgOffset);
174006f32e7eSjoerg             setOrigin(A, EntryIRB.CreateLoad(MS.OriginTy, OriginPtr));
174106f32e7eSjoerg           } else {
174206f32e7eSjoerg             setOrigin(A, getCleanOrigin());
174306f32e7eSjoerg           }
1744*da58b97aSjoerg 
1745*da58b97aSjoerg           break;
174606f32e7eSjoerg         }
1747*da58b97aSjoerg 
1748*da58b97aSjoerg         if (!FArgEagerCheck)
174906f32e7eSjoerg           ArgOffset += alignTo(Size, kShadowTLSAlignment);
175006f32e7eSjoerg       }
175106f32e7eSjoerg       assert(*ShadowPtr && "Could not find shadow for an argument");
175206f32e7eSjoerg       return *ShadowPtr;
175306f32e7eSjoerg     }
175406f32e7eSjoerg     // For everything else the shadow is zero.
175506f32e7eSjoerg     return getCleanShadow(V);
175606f32e7eSjoerg   }
175706f32e7eSjoerg 
175806f32e7eSjoerg   /// Get the shadow for i-th argument of the instruction I.
getShadow__anonb9e144640811::MemorySanitizerVisitor175906f32e7eSjoerg   Value *getShadow(Instruction *I, int i) {
176006f32e7eSjoerg     return getShadow(I->getOperand(i));
176106f32e7eSjoerg   }
176206f32e7eSjoerg 
176306f32e7eSjoerg   /// Get the origin for a value.
getOrigin__anonb9e144640811::MemorySanitizerVisitor176406f32e7eSjoerg   Value *getOrigin(Value *V) {
176506f32e7eSjoerg     if (!MS.TrackOrigins) return nullptr;
176606f32e7eSjoerg     if (!PropagateShadow) return getCleanOrigin();
176706f32e7eSjoerg     if (isa<Constant>(V)) return getCleanOrigin();
176806f32e7eSjoerg     assert((isa<Instruction>(V) || isa<Argument>(V)) &&
176906f32e7eSjoerg            "Unexpected value type in getOrigin()");
177006f32e7eSjoerg     if (Instruction *I = dyn_cast<Instruction>(V)) {
177106f32e7eSjoerg       if (I->getMetadata("nosanitize"))
177206f32e7eSjoerg         return getCleanOrigin();
177306f32e7eSjoerg     }
177406f32e7eSjoerg     Value *Origin = OriginMap[V];
177506f32e7eSjoerg     assert(Origin && "Missing origin");
177606f32e7eSjoerg     return Origin;
177706f32e7eSjoerg   }
177806f32e7eSjoerg 
177906f32e7eSjoerg   /// Get the origin for i-th argument of the instruction I.
getOrigin__anonb9e144640811::MemorySanitizerVisitor178006f32e7eSjoerg   Value *getOrigin(Instruction *I, int i) {
178106f32e7eSjoerg     return getOrigin(I->getOperand(i));
178206f32e7eSjoerg   }
178306f32e7eSjoerg 
178406f32e7eSjoerg   /// Remember the place where a shadow check should be inserted.
178506f32e7eSjoerg   ///
178606f32e7eSjoerg   /// This location will be later instrumented with a check that will print a
178706f32e7eSjoerg   /// UMR warning in runtime if the shadow value is not 0.
insertShadowCheck__anonb9e144640811::MemorySanitizerVisitor178806f32e7eSjoerg   void insertShadowCheck(Value *Shadow, Value *Origin, Instruction *OrigIns) {
178906f32e7eSjoerg     assert(Shadow);
179006f32e7eSjoerg     if (!InsertChecks) return;
179106f32e7eSjoerg #ifndef NDEBUG
179206f32e7eSjoerg     Type *ShadowTy = Shadow->getType();
1793*da58b97aSjoerg     assert((isa<IntegerType>(ShadowTy) || isa<VectorType>(ShadowTy) ||
1794*da58b97aSjoerg             isa<StructType>(ShadowTy) || isa<ArrayType>(ShadowTy)) &&
1795*da58b97aSjoerg            "Can only insert checks for integer, vector, and aggregate shadow "
1796*da58b97aSjoerg            "types");
179706f32e7eSjoerg #endif
179806f32e7eSjoerg     InstrumentationList.push_back(
179906f32e7eSjoerg         ShadowOriginAndInsertPoint(Shadow, Origin, OrigIns));
180006f32e7eSjoerg   }
180106f32e7eSjoerg 
180206f32e7eSjoerg   /// Remember the place where a shadow check should be inserted.
180306f32e7eSjoerg   ///
180406f32e7eSjoerg   /// This location will be later instrumented with a check that will print a
180506f32e7eSjoerg   /// UMR warning in runtime if the value is not fully defined.
insertShadowCheck__anonb9e144640811::MemorySanitizerVisitor180606f32e7eSjoerg   void insertShadowCheck(Value *Val, Instruction *OrigIns) {
180706f32e7eSjoerg     assert(Val);
180806f32e7eSjoerg     Value *Shadow, *Origin;
180906f32e7eSjoerg     if (ClCheckConstantShadow) {
181006f32e7eSjoerg       Shadow = getShadow(Val);
181106f32e7eSjoerg       if (!Shadow) return;
181206f32e7eSjoerg       Origin = getOrigin(Val);
181306f32e7eSjoerg     } else {
181406f32e7eSjoerg       Shadow = dyn_cast_or_null<Instruction>(getShadow(Val));
181506f32e7eSjoerg       if (!Shadow) return;
181606f32e7eSjoerg       Origin = dyn_cast_or_null<Instruction>(getOrigin(Val));
181706f32e7eSjoerg     }
181806f32e7eSjoerg     insertShadowCheck(Shadow, Origin, OrigIns);
181906f32e7eSjoerg   }
182006f32e7eSjoerg 
addReleaseOrdering__anonb9e144640811::MemorySanitizerVisitor182106f32e7eSjoerg   AtomicOrdering addReleaseOrdering(AtomicOrdering a) {
182206f32e7eSjoerg     switch (a) {
182306f32e7eSjoerg       case AtomicOrdering::NotAtomic:
182406f32e7eSjoerg         return AtomicOrdering::NotAtomic;
182506f32e7eSjoerg       case AtomicOrdering::Unordered:
182606f32e7eSjoerg       case AtomicOrdering::Monotonic:
182706f32e7eSjoerg       case AtomicOrdering::Release:
182806f32e7eSjoerg         return AtomicOrdering::Release;
182906f32e7eSjoerg       case AtomicOrdering::Acquire:
183006f32e7eSjoerg       case AtomicOrdering::AcquireRelease:
183106f32e7eSjoerg         return AtomicOrdering::AcquireRelease;
183206f32e7eSjoerg       case AtomicOrdering::SequentiallyConsistent:
183306f32e7eSjoerg         return AtomicOrdering::SequentiallyConsistent;
183406f32e7eSjoerg     }
183506f32e7eSjoerg     llvm_unreachable("Unknown ordering");
183606f32e7eSjoerg   }
183706f32e7eSjoerg 
makeAddReleaseOrderingTable__anonb9e144640811::MemorySanitizerVisitor1838*da58b97aSjoerg   Value *makeAddReleaseOrderingTable(IRBuilder<> &IRB) {
1839*da58b97aSjoerg     constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
1840*da58b97aSjoerg     uint32_t OrderingTable[NumOrderings] = {};
1841*da58b97aSjoerg 
1842*da58b97aSjoerg     OrderingTable[(int)AtomicOrderingCABI::relaxed] =
1843*da58b97aSjoerg         OrderingTable[(int)AtomicOrderingCABI::release] =
1844*da58b97aSjoerg             (int)AtomicOrderingCABI::release;
1845*da58b97aSjoerg     OrderingTable[(int)AtomicOrderingCABI::consume] =
1846*da58b97aSjoerg         OrderingTable[(int)AtomicOrderingCABI::acquire] =
1847*da58b97aSjoerg             OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
1848*da58b97aSjoerg                 (int)AtomicOrderingCABI::acq_rel;
1849*da58b97aSjoerg     OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
1850*da58b97aSjoerg         (int)AtomicOrderingCABI::seq_cst;
1851*da58b97aSjoerg 
1852*da58b97aSjoerg     return ConstantDataVector::get(IRB.getContext(),
1853*da58b97aSjoerg                                    makeArrayRef(OrderingTable, NumOrderings));
1854*da58b97aSjoerg   }
1855*da58b97aSjoerg 
addAcquireOrdering__anonb9e144640811::MemorySanitizerVisitor185606f32e7eSjoerg   AtomicOrdering addAcquireOrdering(AtomicOrdering a) {
185706f32e7eSjoerg     switch (a) {
185806f32e7eSjoerg       case AtomicOrdering::NotAtomic:
185906f32e7eSjoerg         return AtomicOrdering::NotAtomic;
186006f32e7eSjoerg       case AtomicOrdering::Unordered:
186106f32e7eSjoerg       case AtomicOrdering::Monotonic:
186206f32e7eSjoerg       case AtomicOrdering::Acquire:
186306f32e7eSjoerg         return AtomicOrdering::Acquire;
186406f32e7eSjoerg       case AtomicOrdering::Release:
186506f32e7eSjoerg       case AtomicOrdering::AcquireRelease:
186606f32e7eSjoerg         return AtomicOrdering::AcquireRelease;
186706f32e7eSjoerg       case AtomicOrdering::SequentiallyConsistent:
186806f32e7eSjoerg         return AtomicOrdering::SequentiallyConsistent;
186906f32e7eSjoerg     }
187006f32e7eSjoerg     llvm_unreachable("Unknown ordering");
187106f32e7eSjoerg   }
187206f32e7eSjoerg 
makeAddAcquireOrderingTable__anonb9e144640811::MemorySanitizerVisitor1873*da58b97aSjoerg   Value *makeAddAcquireOrderingTable(IRBuilder<> &IRB) {
1874*da58b97aSjoerg     constexpr int NumOrderings = (int)AtomicOrderingCABI::seq_cst + 1;
1875*da58b97aSjoerg     uint32_t OrderingTable[NumOrderings] = {};
1876*da58b97aSjoerg 
1877*da58b97aSjoerg     OrderingTable[(int)AtomicOrderingCABI::relaxed] =
1878*da58b97aSjoerg         OrderingTable[(int)AtomicOrderingCABI::acquire] =
1879*da58b97aSjoerg             OrderingTable[(int)AtomicOrderingCABI::consume] =
1880*da58b97aSjoerg                 (int)AtomicOrderingCABI::acquire;
1881*da58b97aSjoerg     OrderingTable[(int)AtomicOrderingCABI::release] =
1882*da58b97aSjoerg         OrderingTable[(int)AtomicOrderingCABI::acq_rel] =
1883*da58b97aSjoerg             (int)AtomicOrderingCABI::acq_rel;
1884*da58b97aSjoerg     OrderingTable[(int)AtomicOrderingCABI::seq_cst] =
1885*da58b97aSjoerg         (int)AtomicOrderingCABI::seq_cst;
1886*da58b97aSjoerg 
1887*da58b97aSjoerg     return ConstantDataVector::get(IRB.getContext(),
1888*da58b97aSjoerg                                    makeArrayRef(OrderingTable, NumOrderings));
1889*da58b97aSjoerg   }
1890*da58b97aSjoerg 
189106f32e7eSjoerg   // ------------------- Visitors.
189206f32e7eSjoerg   using InstVisitor<MemorySanitizerVisitor>::visit;
visit__anonb9e144640811::MemorySanitizerVisitor189306f32e7eSjoerg   void visit(Instruction &I) {
1894*da58b97aSjoerg     if (I.getMetadata("nosanitize"))
1895*da58b97aSjoerg       return;
1896*da58b97aSjoerg     // Don't want to visit if we're in the prologue
1897*da58b97aSjoerg     if (isInPrologue(I))
1898*da58b97aSjoerg       return;
189906f32e7eSjoerg     InstVisitor<MemorySanitizerVisitor>::visit(I);
190006f32e7eSjoerg   }
190106f32e7eSjoerg 
190206f32e7eSjoerg   /// Instrument LoadInst
190306f32e7eSjoerg   ///
190406f32e7eSjoerg   /// Loads the corresponding shadow and (optionally) origin.
190506f32e7eSjoerg   /// Optionally, checks that the load address is fully defined.
visitLoadInst__anonb9e144640811::MemorySanitizerVisitor190606f32e7eSjoerg   void visitLoadInst(LoadInst &I) {
190706f32e7eSjoerg     assert(I.getType()->isSized() && "Load type must have size");
190806f32e7eSjoerg     assert(!I.getMetadata("nosanitize"));
190906f32e7eSjoerg     IRBuilder<> IRB(I.getNextNode());
191006f32e7eSjoerg     Type *ShadowTy = getShadowTy(&I);
191106f32e7eSjoerg     Value *Addr = I.getPointerOperand();
1912*da58b97aSjoerg     Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
1913*da58b97aSjoerg     const Align Alignment = assumeAligned(I.getAlignment());
191406f32e7eSjoerg     if (PropagateShadow) {
191506f32e7eSjoerg       std::tie(ShadowPtr, OriginPtr) =
191606f32e7eSjoerg           getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
191706f32e7eSjoerg       setShadow(&I,
191806f32e7eSjoerg                 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
191906f32e7eSjoerg     } else {
192006f32e7eSjoerg       setShadow(&I, getCleanShadow(&I));
192106f32e7eSjoerg     }
192206f32e7eSjoerg 
192306f32e7eSjoerg     if (ClCheckAccessAddress)
192406f32e7eSjoerg       insertShadowCheck(I.getPointerOperand(), &I);
192506f32e7eSjoerg 
192606f32e7eSjoerg     if (I.isAtomic())
192706f32e7eSjoerg       I.setOrdering(addAcquireOrdering(I.getOrdering()));
192806f32e7eSjoerg 
192906f32e7eSjoerg     if (MS.TrackOrigins) {
193006f32e7eSjoerg       if (PropagateShadow) {
1931*da58b97aSjoerg         const Align OriginAlignment = std::max(kMinOriginAlignment, Alignment);
193206f32e7eSjoerg         setOrigin(
193306f32e7eSjoerg             &I, IRB.CreateAlignedLoad(MS.OriginTy, OriginPtr, OriginAlignment));
193406f32e7eSjoerg       } else {
193506f32e7eSjoerg         setOrigin(&I, getCleanOrigin());
193606f32e7eSjoerg       }
193706f32e7eSjoerg     }
193806f32e7eSjoerg   }
193906f32e7eSjoerg 
194006f32e7eSjoerg   /// Instrument StoreInst
194106f32e7eSjoerg   ///
194206f32e7eSjoerg   /// Stores the corresponding shadow and (optionally) origin.
194306f32e7eSjoerg   /// Optionally, checks that the store address is fully defined.
visitStoreInst__anonb9e144640811::MemorySanitizerVisitor194406f32e7eSjoerg   void visitStoreInst(StoreInst &I) {
194506f32e7eSjoerg     StoreList.push_back(&I);
194606f32e7eSjoerg     if (ClCheckAccessAddress)
194706f32e7eSjoerg       insertShadowCheck(I.getPointerOperand(), &I);
194806f32e7eSjoerg   }
194906f32e7eSjoerg 
handleCASOrRMW__anonb9e144640811::MemorySanitizerVisitor195006f32e7eSjoerg   void handleCASOrRMW(Instruction &I) {
195106f32e7eSjoerg     assert(isa<AtomicRMWInst>(I) || isa<AtomicCmpXchgInst>(I));
195206f32e7eSjoerg 
195306f32e7eSjoerg     IRBuilder<> IRB(&I);
195406f32e7eSjoerg     Value *Addr = I.getOperand(0);
1955*da58b97aSjoerg     Value *Val = I.getOperand(1);
1956*da58b97aSjoerg     Value *ShadowPtr = getShadowOriginPtr(Addr, IRB, Val->getType(), Align(1),
1957*da58b97aSjoerg                                           /*isStore*/ true)
195806f32e7eSjoerg                            .first;
195906f32e7eSjoerg 
196006f32e7eSjoerg     if (ClCheckAccessAddress)
196106f32e7eSjoerg       insertShadowCheck(Addr, &I);
196206f32e7eSjoerg 
196306f32e7eSjoerg     // Only test the conditional argument of cmpxchg instruction.
196406f32e7eSjoerg     // The other argument can potentially be uninitialized, but we can not
196506f32e7eSjoerg     // detect this situation reliably without possible false positives.
196606f32e7eSjoerg     if (isa<AtomicCmpXchgInst>(I))
1967*da58b97aSjoerg       insertShadowCheck(Val, &I);
196806f32e7eSjoerg 
1969*da58b97aSjoerg     IRB.CreateStore(getCleanShadow(Val), ShadowPtr);
197006f32e7eSjoerg 
197106f32e7eSjoerg     setShadow(&I, getCleanShadow(&I));
197206f32e7eSjoerg     setOrigin(&I, getCleanOrigin());
197306f32e7eSjoerg   }
197406f32e7eSjoerg 
visitAtomicRMWInst__anonb9e144640811::MemorySanitizerVisitor197506f32e7eSjoerg   void visitAtomicRMWInst(AtomicRMWInst &I) {
197606f32e7eSjoerg     handleCASOrRMW(I);
197706f32e7eSjoerg     I.setOrdering(addReleaseOrdering(I.getOrdering()));
197806f32e7eSjoerg   }
197906f32e7eSjoerg 
visitAtomicCmpXchgInst__anonb9e144640811::MemorySanitizerVisitor198006f32e7eSjoerg   void visitAtomicCmpXchgInst(AtomicCmpXchgInst &I) {
198106f32e7eSjoerg     handleCASOrRMW(I);
198206f32e7eSjoerg     I.setSuccessOrdering(addReleaseOrdering(I.getSuccessOrdering()));
198306f32e7eSjoerg   }
198406f32e7eSjoerg 
198506f32e7eSjoerg   // Vector manipulation.
visitExtractElementInst__anonb9e144640811::MemorySanitizerVisitor198606f32e7eSjoerg   void visitExtractElementInst(ExtractElementInst &I) {
198706f32e7eSjoerg     insertShadowCheck(I.getOperand(1), &I);
198806f32e7eSjoerg     IRBuilder<> IRB(&I);
198906f32e7eSjoerg     setShadow(&I, IRB.CreateExtractElement(getShadow(&I, 0), I.getOperand(1),
199006f32e7eSjoerg               "_msprop"));
199106f32e7eSjoerg     setOrigin(&I, getOrigin(&I, 0));
199206f32e7eSjoerg   }
199306f32e7eSjoerg 
visitInsertElementInst__anonb9e144640811::MemorySanitizerVisitor199406f32e7eSjoerg   void visitInsertElementInst(InsertElementInst &I) {
199506f32e7eSjoerg     insertShadowCheck(I.getOperand(2), &I);
199606f32e7eSjoerg     IRBuilder<> IRB(&I);
199706f32e7eSjoerg     setShadow(&I, IRB.CreateInsertElement(getShadow(&I, 0), getShadow(&I, 1),
199806f32e7eSjoerg               I.getOperand(2), "_msprop"));
199906f32e7eSjoerg     setOriginForNaryOp(I);
200006f32e7eSjoerg   }
200106f32e7eSjoerg 
visitShuffleVectorInst__anonb9e144640811::MemorySanitizerVisitor200206f32e7eSjoerg   void visitShuffleVectorInst(ShuffleVectorInst &I) {
200306f32e7eSjoerg     IRBuilder<> IRB(&I);
200406f32e7eSjoerg     setShadow(&I, IRB.CreateShuffleVector(getShadow(&I, 0), getShadow(&I, 1),
2005*da58b97aSjoerg                                           I.getShuffleMask(), "_msprop"));
200606f32e7eSjoerg     setOriginForNaryOp(I);
200706f32e7eSjoerg   }
200806f32e7eSjoerg 
200906f32e7eSjoerg   // Casts.
visitSExtInst__anonb9e144640811::MemorySanitizerVisitor201006f32e7eSjoerg   void visitSExtInst(SExtInst &I) {
201106f32e7eSjoerg     IRBuilder<> IRB(&I);
201206f32e7eSjoerg     setShadow(&I, IRB.CreateSExt(getShadow(&I, 0), I.getType(), "_msprop"));
201306f32e7eSjoerg     setOrigin(&I, getOrigin(&I, 0));
201406f32e7eSjoerg   }
201506f32e7eSjoerg 
visitZExtInst__anonb9e144640811::MemorySanitizerVisitor201606f32e7eSjoerg   void visitZExtInst(ZExtInst &I) {
201706f32e7eSjoerg     IRBuilder<> IRB(&I);
201806f32e7eSjoerg     setShadow(&I, IRB.CreateZExt(getShadow(&I, 0), I.getType(), "_msprop"));
201906f32e7eSjoerg     setOrigin(&I, getOrigin(&I, 0));
202006f32e7eSjoerg   }
202106f32e7eSjoerg 
visitTruncInst__anonb9e144640811::MemorySanitizerVisitor202206f32e7eSjoerg   void visitTruncInst(TruncInst &I) {
202306f32e7eSjoerg     IRBuilder<> IRB(&I);
202406f32e7eSjoerg     setShadow(&I, IRB.CreateTrunc(getShadow(&I, 0), I.getType(), "_msprop"));
202506f32e7eSjoerg     setOrigin(&I, getOrigin(&I, 0));
202606f32e7eSjoerg   }
202706f32e7eSjoerg 
visitBitCastInst__anonb9e144640811::MemorySanitizerVisitor202806f32e7eSjoerg   void visitBitCastInst(BitCastInst &I) {
202906f32e7eSjoerg     // Special case: if this is the bitcast (there is exactly 1 allowed) between
203006f32e7eSjoerg     // a musttail call and a ret, don't instrument. New instructions are not
203106f32e7eSjoerg     // allowed after a musttail call.
203206f32e7eSjoerg     if (auto *CI = dyn_cast<CallInst>(I.getOperand(0)))
203306f32e7eSjoerg       if (CI->isMustTailCall())
203406f32e7eSjoerg         return;
203506f32e7eSjoerg     IRBuilder<> IRB(&I);
203606f32e7eSjoerg     setShadow(&I, IRB.CreateBitCast(getShadow(&I, 0), getShadowTy(&I)));
203706f32e7eSjoerg     setOrigin(&I, getOrigin(&I, 0));
203806f32e7eSjoerg   }
203906f32e7eSjoerg 
visitPtrToIntInst__anonb9e144640811::MemorySanitizerVisitor204006f32e7eSjoerg   void visitPtrToIntInst(PtrToIntInst &I) {
204106f32e7eSjoerg     IRBuilder<> IRB(&I);
204206f32e7eSjoerg     setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
204306f32e7eSjoerg              "_msprop_ptrtoint"));
204406f32e7eSjoerg     setOrigin(&I, getOrigin(&I, 0));
204506f32e7eSjoerg   }
204606f32e7eSjoerg 
visitIntToPtrInst__anonb9e144640811::MemorySanitizerVisitor204706f32e7eSjoerg   void visitIntToPtrInst(IntToPtrInst &I) {
204806f32e7eSjoerg     IRBuilder<> IRB(&I);
204906f32e7eSjoerg     setShadow(&I, IRB.CreateIntCast(getShadow(&I, 0), getShadowTy(&I), false,
205006f32e7eSjoerg              "_msprop_inttoptr"));
205106f32e7eSjoerg     setOrigin(&I, getOrigin(&I, 0));
205206f32e7eSjoerg   }
205306f32e7eSjoerg 
visitFPToSIInst__anonb9e144640811::MemorySanitizerVisitor205406f32e7eSjoerg   void visitFPToSIInst(CastInst& I) { handleShadowOr(I); }
visitFPToUIInst__anonb9e144640811::MemorySanitizerVisitor205506f32e7eSjoerg   void visitFPToUIInst(CastInst& I) { handleShadowOr(I); }
visitSIToFPInst__anonb9e144640811::MemorySanitizerVisitor205606f32e7eSjoerg   void visitSIToFPInst(CastInst& I) { handleShadowOr(I); }
visitUIToFPInst__anonb9e144640811::MemorySanitizerVisitor205706f32e7eSjoerg   void visitUIToFPInst(CastInst& I) { handleShadowOr(I); }
visitFPExtInst__anonb9e144640811::MemorySanitizerVisitor205806f32e7eSjoerg   void visitFPExtInst(CastInst& I) { handleShadowOr(I); }
visitFPTruncInst__anonb9e144640811::MemorySanitizerVisitor205906f32e7eSjoerg   void visitFPTruncInst(CastInst& I) { handleShadowOr(I); }
206006f32e7eSjoerg 
206106f32e7eSjoerg   /// Propagate shadow for bitwise AND.
206206f32e7eSjoerg   ///
206306f32e7eSjoerg   /// This code is exact, i.e. if, for example, a bit in the left argument
206406f32e7eSjoerg   /// is defined and 0, then neither the value not definedness of the
206506f32e7eSjoerg   /// corresponding bit in B don't affect the resulting shadow.
visitAnd__anonb9e144640811::MemorySanitizerVisitor206606f32e7eSjoerg   void visitAnd(BinaryOperator &I) {
206706f32e7eSjoerg     IRBuilder<> IRB(&I);
206806f32e7eSjoerg     //  "And" of 0 and a poisoned value results in unpoisoned value.
206906f32e7eSjoerg     //  1&1 => 1;     0&1 => 0;     p&1 => p;
207006f32e7eSjoerg     //  1&0 => 0;     0&0 => 0;     p&0 => 0;
207106f32e7eSjoerg     //  1&p => p;     0&p => 0;     p&p => p;
207206f32e7eSjoerg     //  S = (S1 & S2) | (V1 & S2) | (S1 & V2)
207306f32e7eSjoerg     Value *S1 = getShadow(&I, 0);
207406f32e7eSjoerg     Value *S2 = getShadow(&I, 1);
207506f32e7eSjoerg     Value *V1 = I.getOperand(0);
207606f32e7eSjoerg     Value *V2 = I.getOperand(1);
207706f32e7eSjoerg     if (V1->getType() != S1->getType()) {
207806f32e7eSjoerg       V1 = IRB.CreateIntCast(V1, S1->getType(), false);
207906f32e7eSjoerg       V2 = IRB.CreateIntCast(V2, S2->getType(), false);
208006f32e7eSjoerg     }
208106f32e7eSjoerg     Value *S1S2 = IRB.CreateAnd(S1, S2);
208206f32e7eSjoerg     Value *V1S2 = IRB.CreateAnd(V1, S2);
208306f32e7eSjoerg     Value *S1V2 = IRB.CreateAnd(S1, V2);
208406f32e7eSjoerg     setShadow(&I, IRB.CreateOr({S1S2, V1S2, S1V2}));
208506f32e7eSjoerg     setOriginForNaryOp(I);
208606f32e7eSjoerg   }
208706f32e7eSjoerg 
visitOr__anonb9e144640811::MemorySanitizerVisitor208806f32e7eSjoerg   void visitOr(BinaryOperator &I) {
208906f32e7eSjoerg     IRBuilder<> IRB(&I);
209006f32e7eSjoerg     //  "Or" of 1 and a poisoned value results in unpoisoned value.
209106f32e7eSjoerg     //  1|1 => 1;     0|1 => 1;     p|1 => 1;
209206f32e7eSjoerg     //  1|0 => 1;     0|0 => 0;     p|0 => p;
209306f32e7eSjoerg     //  1|p => 1;     0|p => p;     p|p => p;
209406f32e7eSjoerg     //  S = (S1 & S2) | (~V1 & S2) | (S1 & ~V2)
209506f32e7eSjoerg     Value *S1 = getShadow(&I, 0);
209606f32e7eSjoerg     Value *S2 = getShadow(&I, 1);
209706f32e7eSjoerg     Value *V1 = IRB.CreateNot(I.getOperand(0));
209806f32e7eSjoerg     Value *V2 = IRB.CreateNot(I.getOperand(1));
209906f32e7eSjoerg     if (V1->getType() != S1->getType()) {
210006f32e7eSjoerg       V1 = IRB.CreateIntCast(V1, S1->getType(), false);
210106f32e7eSjoerg       V2 = IRB.CreateIntCast(V2, S2->getType(), false);
210206f32e7eSjoerg     }
210306f32e7eSjoerg     Value *S1S2 = IRB.CreateAnd(S1, S2);
210406f32e7eSjoerg     Value *V1S2 = IRB.CreateAnd(V1, S2);
210506f32e7eSjoerg     Value *S1V2 = IRB.CreateAnd(S1, V2);
210606f32e7eSjoerg     setShadow(&I, IRB.CreateOr({S1S2, V1S2, S1V2}));
210706f32e7eSjoerg     setOriginForNaryOp(I);
210806f32e7eSjoerg   }
210906f32e7eSjoerg 
211006f32e7eSjoerg   /// Default propagation of shadow and/or origin.
211106f32e7eSjoerg   ///
211206f32e7eSjoerg   /// This class implements the general case of shadow propagation, used in all
211306f32e7eSjoerg   /// cases where we don't know and/or don't care about what the operation
211406f32e7eSjoerg   /// actually does. It converts all input shadow values to a common type
211506f32e7eSjoerg   /// (extending or truncating as necessary), and bitwise OR's them.
211606f32e7eSjoerg   ///
211706f32e7eSjoerg   /// This is much cheaper than inserting checks (i.e. requiring inputs to be
211806f32e7eSjoerg   /// fully initialized), and less prone to false positives.
211906f32e7eSjoerg   ///
212006f32e7eSjoerg   /// This class also implements the general case of origin propagation. For a
212106f32e7eSjoerg   /// Nary operation, result origin is set to the origin of an argument that is
212206f32e7eSjoerg   /// not entirely initialized. If there is more than one such arguments, the
212306f32e7eSjoerg   /// rightmost of them is picked. It does not matter which one is picked if all
212406f32e7eSjoerg   /// arguments are initialized.
212506f32e7eSjoerg   template <bool CombineShadow>
212606f32e7eSjoerg   class Combiner {
212706f32e7eSjoerg     Value *Shadow = nullptr;
212806f32e7eSjoerg     Value *Origin = nullptr;
212906f32e7eSjoerg     IRBuilder<> &IRB;
213006f32e7eSjoerg     MemorySanitizerVisitor *MSV;
213106f32e7eSjoerg 
213206f32e7eSjoerg   public:
Combiner(MemorySanitizerVisitor * MSV,IRBuilder<> & IRB)213306f32e7eSjoerg     Combiner(MemorySanitizerVisitor *MSV, IRBuilder<> &IRB)
213406f32e7eSjoerg         : IRB(IRB), MSV(MSV) {}
213506f32e7eSjoerg 
213606f32e7eSjoerg     /// Add a pair of shadow and origin values to the mix.
Add(Value * OpShadow,Value * OpOrigin)213706f32e7eSjoerg     Combiner &Add(Value *OpShadow, Value *OpOrigin) {
213806f32e7eSjoerg       if (CombineShadow) {
213906f32e7eSjoerg         assert(OpShadow);
214006f32e7eSjoerg         if (!Shadow)
214106f32e7eSjoerg           Shadow = OpShadow;
214206f32e7eSjoerg         else {
214306f32e7eSjoerg           OpShadow = MSV->CreateShadowCast(IRB, OpShadow, Shadow->getType());
214406f32e7eSjoerg           Shadow = IRB.CreateOr(Shadow, OpShadow, "_msprop");
214506f32e7eSjoerg         }
214606f32e7eSjoerg       }
214706f32e7eSjoerg 
214806f32e7eSjoerg       if (MSV->MS.TrackOrigins) {
214906f32e7eSjoerg         assert(OpOrigin);
215006f32e7eSjoerg         if (!Origin) {
215106f32e7eSjoerg           Origin = OpOrigin;
215206f32e7eSjoerg         } else {
215306f32e7eSjoerg           Constant *ConstOrigin = dyn_cast<Constant>(OpOrigin);
215406f32e7eSjoerg           // No point in adding something that might result in 0 origin value.
215506f32e7eSjoerg           if (!ConstOrigin || !ConstOrigin->isNullValue()) {
2156*da58b97aSjoerg             Value *FlatShadow = MSV->convertShadowToScalar(OpShadow, IRB);
215706f32e7eSjoerg             Value *Cond =
215806f32e7eSjoerg                 IRB.CreateICmpNE(FlatShadow, MSV->getCleanShadow(FlatShadow));
215906f32e7eSjoerg             Origin = IRB.CreateSelect(Cond, OpOrigin, Origin);
216006f32e7eSjoerg           }
216106f32e7eSjoerg         }
216206f32e7eSjoerg       }
216306f32e7eSjoerg       return *this;
216406f32e7eSjoerg     }
216506f32e7eSjoerg 
216606f32e7eSjoerg     /// Add an application value to the mix.
Add(Value * V)216706f32e7eSjoerg     Combiner &Add(Value *V) {
216806f32e7eSjoerg       Value *OpShadow = MSV->getShadow(V);
216906f32e7eSjoerg       Value *OpOrigin = MSV->MS.TrackOrigins ? MSV->getOrigin(V) : nullptr;
217006f32e7eSjoerg       return Add(OpShadow, OpOrigin);
217106f32e7eSjoerg     }
217206f32e7eSjoerg 
217306f32e7eSjoerg     /// Set the current combined values as the given instruction's shadow
217406f32e7eSjoerg     /// and origin.
Done(Instruction * I)217506f32e7eSjoerg     void Done(Instruction *I) {
217606f32e7eSjoerg       if (CombineShadow) {
217706f32e7eSjoerg         assert(Shadow);
217806f32e7eSjoerg         Shadow = MSV->CreateShadowCast(IRB, Shadow, MSV->getShadowTy(I));
217906f32e7eSjoerg         MSV->setShadow(I, Shadow);
218006f32e7eSjoerg       }
218106f32e7eSjoerg       if (MSV->MS.TrackOrigins) {
218206f32e7eSjoerg         assert(Origin);
218306f32e7eSjoerg         MSV->setOrigin(I, Origin);
218406f32e7eSjoerg       }
218506f32e7eSjoerg     }
218606f32e7eSjoerg   };
218706f32e7eSjoerg 
218806f32e7eSjoerg   using ShadowAndOriginCombiner = Combiner<true>;
218906f32e7eSjoerg   using OriginCombiner = Combiner<false>;
219006f32e7eSjoerg 
219106f32e7eSjoerg   /// Propagate origin for arbitrary operation.
setOriginForNaryOp__anonb9e144640811::MemorySanitizerVisitor219206f32e7eSjoerg   void setOriginForNaryOp(Instruction &I) {
219306f32e7eSjoerg     if (!MS.TrackOrigins) return;
219406f32e7eSjoerg     IRBuilder<> IRB(&I);
219506f32e7eSjoerg     OriginCombiner OC(this, IRB);
2196*da58b97aSjoerg     for (Use &Op : I.operands())
2197*da58b97aSjoerg       OC.Add(Op.get());
219806f32e7eSjoerg     OC.Done(&I);
219906f32e7eSjoerg   }
220006f32e7eSjoerg 
VectorOrPrimitiveTypeSizeInBits__anonb9e144640811::MemorySanitizerVisitor220106f32e7eSjoerg   size_t VectorOrPrimitiveTypeSizeInBits(Type *Ty) {
220206f32e7eSjoerg     assert(!(Ty->isVectorTy() && Ty->getScalarType()->isPointerTy()) &&
220306f32e7eSjoerg            "Vector of pointers is not a valid shadow type");
2204*da58b97aSjoerg     return Ty->isVectorTy() ? cast<FixedVectorType>(Ty)->getNumElements() *
2205*da58b97aSjoerg                                   Ty->getScalarSizeInBits()
2206*da58b97aSjoerg                             : Ty->getPrimitiveSizeInBits();
220706f32e7eSjoerg   }
220806f32e7eSjoerg 
220906f32e7eSjoerg   /// Cast between two shadow types, extending or truncating as
221006f32e7eSjoerg   /// necessary.
CreateShadowCast__anonb9e144640811::MemorySanitizerVisitor221106f32e7eSjoerg   Value *CreateShadowCast(IRBuilder<> &IRB, Value *V, Type *dstTy,
221206f32e7eSjoerg                           bool Signed = false) {
221306f32e7eSjoerg     Type *srcTy = V->getType();
221406f32e7eSjoerg     size_t srcSizeInBits = VectorOrPrimitiveTypeSizeInBits(srcTy);
221506f32e7eSjoerg     size_t dstSizeInBits = VectorOrPrimitiveTypeSizeInBits(dstTy);
221606f32e7eSjoerg     if (srcSizeInBits > 1 && dstSizeInBits == 1)
221706f32e7eSjoerg       return IRB.CreateICmpNE(V, getCleanShadow(V));
221806f32e7eSjoerg 
221906f32e7eSjoerg     if (dstTy->isIntegerTy() && srcTy->isIntegerTy())
222006f32e7eSjoerg       return IRB.CreateIntCast(V, dstTy, Signed);
222106f32e7eSjoerg     if (dstTy->isVectorTy() && srcTy->isVectorTy() &&
2222*da58b97aSjoerg         cast<FixedVectorType>(dstTy)->getNumElements() ==
2223*da58b97aSjoerg             cast<FixedVectorType>(srcTy)->getNumElements())
222406f32e7eSjoerg       return IRB.CreateIntCast(V, dstTy, Signed);
222506f32e7eSjoerg     Value *V1 = IRB.CreateBitCast(V, Type::getIntNTy(*MS.C, srcSizeInBits));
222606f32e7eSjoerg     Value *V2 =
222706f32e7eSjoerg       IRB.CreateIntCast(V1, Type::getIntNTy(*MS.C, dstSizeInBits), Signed);
222806f32e7eSjoerg     return IRB.CreateBitCast(V2, dstTy);
222906f32e7eSjoerg     // TODO: handle struct types.
223006f32e7eSjoerg   }
223106f32e7eSjoerg 
223206f32e7eSjoerg   /// Cast an application value to the type of its own shadow.
CreateAppToShadowCast__anonb9e144640811::MemorySanitizerVisitor223306f32e7eSjoerg   Value *CreateAppToShadowCast(IRBuilder<> &IRB, Value *V) {
223406f32e7eSjoerg     Type *ShadowTy = getShadowTy(V);
223506f32e7eSjoerg     if (V->getType() == ShadowTy)
223606f32e7eSjoerg       return V;
223706f32e7eSjoerg     if (V->getType()->isPtrOrPtrVectorTy())
223806f32e7eSjoerg       return IRB.CreatePtrToInt(V, ShadowTy);
223906f32e7eSjoerg     else
224006f32e7eSjoerg       return IRB.CreateBitCast(V, ShadowTy);
224106f32e7eSjoerg   }
224206f32e7eSjoerg 
224306f32e7eSjoerg   /// Propagate shadow for arbitrary operation.
handleShadowOr__anonb9e144640811::MemorySanitizerVisitor224406f32e7eSjoerg   void handleShadowOr(Instruction &I) {
224506f32e7eSjoerg     IRBuilder<> IRB(&I);
224606f32e7eSjoerg     ShadowAndOriginCombiner SC(this, IRB);
2247*da58b97aSjoerg     for (Use &Op : I.operands())
2248*da58b97aSjoerg       SC.Add(Op.get());
224906f32e7eSjoerg     SC.Done(&I);
225006f32e7eSjoerg   }
225106f32e7eSjoerg 
visitFNeg__anonb9e144640811::MemorySanitizerVisitor225206f32e7eSjoerg   void visitFNeg(UnaryOperator &I) { handleShadowOr(I); }
225306f32e7eSjoerg 
225406f32e7eSjoerg   // Handle multiplication by constant.
225506f32e7eSjoerg   //
225606f32e7eSjoerg   // Handle a special case of multiplication by constant that may have one or
225706f32e7eSjoerg   // more zeros in the lower bits. This makes corresponding number of lower bits
225806f32e7eSjoerg   // of the result zero as well. We model it by shifting the other operand
225906f32e7eSjoerg   // shadow left by the required number of bits. Effectively, we transform
226006f32e7eSjoerg   // (X * (A * 2**B)) to ((X << B) * A) and instrument (X << B) as (Sx << B).
226106f32e7eSjoerg   // We use multiplication by 2**N instead of shift to cover the case of
226206f32e7eSjoerg   // multiplication by 0, which may occur in some elements of a vector operand.
handleMulByConstant__anonb9e144640811::MemorySanitizerVisitor226306f32e7eSjoerg   void handleMulByConstant(BinaryOperator &I, Constant *ConstArg,
226406f32e7eSjoerg                            Value *OtherArg) {
226506f32e7eSjoerg     Constant *ShadowMul;
226606f32e7eSjoerg     Type *Ty = ConstArg->getType();
2267*da58b97aSjoerg     if (auto *VTy = dyn_cast<VectorType>(Ty)) {
2268*da58b97aSjoerg       unsigned NumElements = cast<FixedVectorType>(VTy)->getNumElements();
2269*da58b97aSjoerg       Type *EltTy = VTy->getElementType();
227006f32e7eSjoerg       SmallVector<Constant *, 16> Elements;
227106f32e7eSjoerg       for (unsigned Idx = 0; Idx < NumElements; ++Idx) {
227206f32e7eSjoerg         if (ConstantInt *Elt =
227306f32e7eSjoerg                 dyn_cast<ConstantInt>(ConstArg->getAggregateElement(Idx))) {
227406f32e7eSjoerg           const APInt &V = Elt->getValue();
227506f32e7eSjoerg           APInt V2 = APInt(V.getBitWidth(), 1) << V.countTrailingZeros();
227606f32e7eSjoerg           Elements.push_back(ConstantInt::get(EltTy, V2));
227706f32e7eSjoerg         } else {
227806f32e7eSjoerg           Elements.push_back(ConstantInt::get(EltTy, 1));
227906f32e7eSjoerg         }
228006f32e7eSjoerg       }
228106f32e7eSjoerg       ShadowMul = ConstantVector::get(Elements);
228206f32e7eSjoerg     } else {
228306f32e7eSjoerg       if (ConstantInt *Elt = dyn_cast<ConstantInt>(ConstArg)) {
228406f32e7eSjoerg         const APInt &V = Elt->getValue();
228506f32e7eSjoerg         APInt V2 = APInt(V.getBitWidth(), 1) << V.countTrailingZeros();
228606f32e7eSjoerg         ShadowMul = ConstantInt::get(Ty, V2);
228706f32e7eSjoerg       } else {
228806f32e7eSjoerg         ShadowMul = ConstantInt::get(Ty, 1);
228906f32e7eSjoerg       }
229006f32e7eSjoerg     }
229106f32e7eSjoerg 
229206f32e7eSjoerg     IRBuilder<> IRB(&I);
229306f32e7eSjoerg     setShadow(&I,
229406f32e7eSjoerg               IRB.CreateMul(getShadow(OtherArg), ShadowMul, "msprop_mul_cst"));
229506f32e7eSjoerg     setOrigin(&I, getOrigin(OtherArg));
229606f32e7eSjoerg   }
229706f32e7eSjoerg 
visitMul__anonb9e144640811::MemorySanitizerVisitor229806f32e7eSjoerg   void visitMul(BinaryOperator &I) {
229906f32e7eSjoerg     Constant *constOp0 = dyn_cast<Constant>(I.getOperand(0));
230006f32e7eSjoerg     Constant *constOp1 = dyn_cast<Constant>(I.getOperand(1));
230106f32e7eSjoerg     if (constOp0 && !constOp1)
230206f32e7eSjoerg       handleMulByConstant(I, constOp0, I.getOperand(1));
230306f32e7eSjoerg     else if (constOp1 && !constOp0)
230406f32e7eSjoerg       handleMulByConstant(I, constOp1, I.getOperand(0));
230506f32e7eSjoerg     else
230606f32e7eSjoerg       handleShadowOr(I);
230706f32e7eSjoerg   }
230806f32e7eSjoerg 
visitFAdd__anonb9e144640811::MemorySanitizerVisitor230906f32e7eSjoerg   void visitFAdd(BinaryOperator &I) { handleShadowOr(I); }
visitFSub__anonb9e144640811::MemorySanitizerVisitor231006f32e7eSjoerg   void visitFSub(BinaryOperator &I) { handleShadowOr(I); }
visitFMul__anonb9e144640811::MemorySanitizerVisitor231106f32e7eSjoerg   void visitFMul(BinaryOperator &I) { handleShadowOr(I); }
visitAdd__anonb9e144640811::MemorySanitizerVisitor231206f32e7eSjoerg   void visitAdd(BinaryOperator &I) { handleShadowOr(I); }
visitSub__anonb9e144640811::MemorySanitizerVisitor231306f32e7eSjoerg   void visitSub(BinaryOperator &I) { handleShadowOr(I); }
visitXor__anonb9e144640811::MemorySanitizerVisitor231406f32e7eSjoerg   void visitXor(BinaryOperator &I) { handleShadowOr(I); }
231506f32e7eSjoerg 
handleIntegerDiv__anonb9e144640811::MemorySanitizerVisitor231606f32e7eSjoerg   void handleIntegerDiv(Instruction &I) {
231706f32e7eSjoerg     IRBuilder<> IRB(&I);
231806f32e7eSjoerg     // Strict on the second argument.
231906f32e7eSjoerg     insertShadowCheck(I.getOperand(1), &I);
232006f32e7eSjoerg     setShadow(&I, getShadow(&I, 0));
232106f32e7eSjoerg     setOrigin(&I, getOrigin(&I, 0));
232206f32e7eSjoerg   }
232306f32e7eSjoerg 
visitUDiv__anonb9e144640811::MemorySanitizerVisitor232406f32e7eSjoerg   void visitUDiv(BinaryOperator &I) { handleIntegerDiv(I); }
visitSDiv__anonb9e144640811::MemorySanitizerVisitor232506f32e7eSjoerg   void visitSDiv(BinaryOperator &I) { handleIntegerDiv(I); }
visitURem__anonb9e144640811::MemorySanitizerVisitor232606f32e7eSjoerg   void visitURem(BinaryOperator &I) { handleIntegerDiv(I); }
visitSRem__anonb9e144640811::MemorySanitizerVisitor232706f32e7eSjoerg   void visitSRem(BinaryOperator &I) { handleIntegerDiv(I); }
232806f32e7eSjoerg 
232906f32e7eSjoerg   // Floating point division is side-effect free. We can not require that the
233006f32e7eSjoerg   // divisor is fully initialized and must propagate shadow. See PR37523.
visitFDiv__anonb9e144640811::MemorySanitizerVisitor233106f32e7eSjoerg   void visitFDiv(BinaryOperator &I) { handleShadowOr(I); }
visitFRem__anonb9e144640811::MemorySanitizerVisitor233206f32e7eSjoerg   void visitFRem(BinaryOperator &I) { handleShadowOr(I); }
233306f32e7eSjoerg 
233406f32e7eSjoerg   /// Instrument == and != comparisons.
233506f32e7eSjoerg   ///
233606f32e7eSjoerg   /// Sometimes the comparison result is known even if some of the bits of the
233706f32e7eSjoerg   /// arguments are not.
handleEqualityComparison__anonb9e144640811::MemorySanitizerVisitor233806f32e7eSjoerg   void handleEqualityComparison(ICmpInst &I) {
233906f32e7eSjoerg     IRBuilder<> IRB(&I);
234006f32e7eSjoerg     Value *A = I.getOperand(0);
234106f32e7eSjoerg     Value *B = I.getOperand(1);
234206f32e7eSjoerg     Value *Sa = getShadow(A);
234306f32e7eSjoerg     Value *Sb = getShadow(B);
234406f32e7eSjoerg 
234506f32e7eSjoerg     // Get rid of pointers and vectors of pointers.
234606f32e7eSjoerg     // For ints (and vectors of ints), types of A and Sa match,
234706f32e7eSjoerg     // and this is a no-op.
234806f32e7eSjoerg     A = IRB.CreatePointerCast(A, Sa->getType());
234906f32e7eSjoerg     B = IRB.CreatePointerCast(B, Sb->getType());
235006f32e7eSjoerg 
235106f32e7eSjoerg     // A == B  <==>  (C = A^B) == 0
235206f32e7eSjoerg     // A != B  <==>  (C = A^B) != 0
235306f32e7eSjoerg     // Sc = Sa | Sb
235406f32e7eSjoerg     Value *C = IRB.CreateXor(A, B);
235506f32e7eSjoerg     Value *Sc = IRB.CreateOr(Sa, Sb);
235606f32e7eSjoerg     // Now dealing with i = (C == 0) comparison (or C != 0, does not matter now)
235706f32e7eSjoerg     // Result is defined if one of the following is true
235806f32e7eSjoerg     // * there is a defined 1 bit in C
235906f32e7eSjoerg     // * C is fully defined
236006f32e7eSjoerg     // Si = !(C & ~Sc) && Sc
236106f32e7eSjoerg     Value *Zero = Constant::getNullValue(Sc->getType());
236206f32e7eSjoerg     Value *MinusOne = Constant::getAllOnesValue(Sc->getType());
236306f32e7eSjoerg     Value *Si =
236406f32e7eSjoerg       IRB.CreateAnd(IRB.CreateICmpNE(Sc, Zero),
236506f32e7eSjoerg                     IRB.CreateICmpEQ(
236606f32e7eSjoerg                       IRB.CreateAnd(IRB.CreateXor(Sc, MinusOne), C), Zero));
236706f32e7eSjoerg     Si->setName("_msprop_icmp");
236806f32e7eSjoerg     setShadow(&I, Si);
236906f32e7eSjoerg     setOriginForNaryOp(I);
237006f32e7eSjoerg   }
237106f32e7eSjoerg 
237206f32e7eSjoerg   /// Build the lowest possible value of V, taking into account V's
237306f32e7eSjoerg   ///        uninitialized bits.
getLowestPossibleValue__anonb9e144640811::MemorySanitizerVisitor237406f32e7eSjoerg   Value *getLowestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
237506f32e7eSjoerg                                 bool isSigned) {
237606f32e7eSjoerg     if (isSigned) {
237706f32e7eSjoerg       // Split shadow into sign bit and other bits.
237806f32e7eSjoerg       Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
237906f32e7eSjoerg       Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
238006f32e7eSjoerg       // Maximise the undefined shadow bit, minimize other undefined bits.
238106f32e7eSjoerg       return
238206f32e7eSjoerg         IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaOtherBits)), SaSignBit);
238306f32e7eSjoerg     } else {
238406f32e7eSjoerg       // Minimize undefined bits.
238506f32e7eSjoerg       return IRB.CreateAnd(A, IRB.CreateNot(Sa));
238606f32e7eSjoerg     }
238706f32e7eSjoerg   }
238806f32e7eSjoerg 
238906f32e7eSjoerg   /// Build the highest possible value of V, taking into account V's
239006f32e7eSjoerg   ///        uninitialized bits.
getHighestPossibleValue__anonb9e144640811::MemorySanitizerVisitor239106f32e7eSjoerg   Value *getHighestPossibleValue(IRBuilder<> &IRB, Value *A, Value *Sa,
239206f32e7eSjoerg                                 bool isSigned) {
239306f32e7eSjoerg     if (isSigned) {
239406f32e7eSjoerg       // Split shadow into sign bit and other bits.
239506f32e7eSjoerg       Value *SaOtherBits = IRB.CreateLShr(IRB.CreateShl(Sa, 1), 1);
239606f32e7eSjoerg       Value *SaSignBit = IRB.CreateXor(Sa, SaOtherBits);
239706f32e7eSjoerg       // Minimise the undefined shadow bit, maximise other undefined bits.
239806f32e7eSjoerg       return
239906f32e7eSjoerg         IRB.CreateOr(IRB.CreateAnd(A, IRB.CreateNot(SaSignBit)), SaOtherBits);
240006f32e7eSjoerg     } else {
240106f32e7eSjoerg       // Maximize undefined bits.
240206f32e7eSjoerg       return IRB.CreateOr(A, Sa);
240306f32e7eSjoerg     }
240406f32e7eSjoerg   }
240506f32e7eSjoerg 
240606f32e7eSjoerg   /// Instrument relational comparisons.
240706f32e7eSjoerg   ///
240806f32e7eSjoerg   /// This function does exact shadow propagation for all relational
240906f32e7eSjoerg   /// comparisons of integers, pointers and vectors of those.
241006f32e7eSjoerg   /// FIXME: output seems suboptimal when one of the operands is a constant
handleRelationalComparisonExact__anonb9e144640811::MemorySanitizerVisitor241106f32e7eSjoerg   void handleRelationalComparisonExact(ICmpInst &I) {
241206f32e7eSjoerg     IRBuilder<> IRB(&I);
241306f32e7eSjoerg     Value *A = I.getOperand(0);
241406f32e7eSjoerg     Value *B = I.getOperand(1);
241506f32e7eSjoerg     Value *Sa = getShadow(A);
241606f32e7eSjoerg     Value *Sb = getShadow(B);
241706f32e7eSjoerg 
241806f32e7eSjoerg     // Get rid of pointers and vectors of pointers.
241906f32e7eSjoerg     // For ints (and vectors of ints), types of A and Sa match,
242006f32e7eSjoerg     // and this is a no-op.
242106f32e7eSjoerg     A = IRB.CreatePointerCast(A, Sa->getType());
242206f32e7eSjoerg     B = IRB.CreatePointerCast(B, Sb->getType());
242306f32e7eSjoerg 
242406f32e7eSjoerg     // Let [a0, a1] be the interval of possible values of A, taking into account
242506f32e7eSjoerg     // its undefined bits. Let [b0, b1] be the interval of possible values of B.
242606f32e7eSjoerg     // Then (A cmp B) is defined iff (a0 cmp b1) == (a1 cmp b0).
242706f32e7eSjoerg     bool IsSigned = I.isSigned();
242806f32e7eSjoerg     Value *S1 = IRB.CreateICmp(I.getPredicate(),
242906f32e7eSjoerg                                getLowestPossibleValue(IRB, A, Sa, IsSigned),
243006f32e7eSjoerg                                getHighestPossibleValue(IRB, B, Sb, IsSigned));
243106f32e7eSjoerg     Value *S2 = IRB.CreateICmp(I.getPredicate(),
243206f32e7eSjoerg                                getHighestPossibleValue(IRB, A, Sa, IsSigned),
243306f32e7eSjoerg                                getLowestPossibleValue(IRB, B, Sb, IsSigned));
243406f32e7eSjoerg     Value *Si = IRB.CreateXor(S1, S2);
243506f32e7eSjoerg     setShadow(&I, Si);
243606f32e7eSjoerg     setOriginForNaryOp(I);
243706f32e7eSjoerg   }
243806f32e7eSjoerg 
243906f32e7eSjoerg   /// Instrument signed relational comparisons.
244006f32e7eSjoerg   ///
244106f32e7eSjoerg   /// Handle sign bit tests: x<0, x>=0, x<=-1, x>-1 by propagating the highest
244206f32e7eSjoerg   /// bit of the shadow. Everything else is delegated to handleShadowOr().
handleSignedRelationalComparison__anonb9e144640811::MemorySanitizerVisitor244306f32e7eSjoerg   void handleSignedRelationalComparison(ICmpInst &I) {
244406f32e7eSjoerg     Constant *constOp;
244506f32e7eSjoerg     Value *op = nullptr;
244606f32e7eSjoerg     CmpInst::Predicate pre;
244706f32e7eSjoerg     if ((constOp = dyn_cast<Constant>(I.getOperand(1)))) {
244806f32e7eSjoerg       op = I.getOperand(0);
244906f32e7eSjoerg       pre = I.getPredicate();
245006f32e7eSjoerg     } else if ((constOp = dyn_cast<Constant>(I.getOperand(0)))) {
245106f32e7eSjoerg       op = I.getOperand(1);
245206f32e7eSjoerg       pre = I.getSwappedPredicate();
245306f32e7eSjoerg     } else {
245406f32e7eSjoerg       handleShadowOr(I);
245506f32e7eSjoerg       return;
245606f32e7eSjoerg     }
245706f32e7eSjoerg 
245806f32e7eSjoerg     if ((constOp->isNullValue() &&
245906f32e7eSjoerg          (pre == CmpInst::ICMP_SLT || pre == CmpInst::ICMP_SGE)) ||
246006f32e7eSjoerg         (constOp->isAllOnesValue() &&
246106f32e7eSjoerg          (pre == CmpInst::ICMP_SGT || pre == CmpInst::ICMP_SLE))) {
246206f32e7eSjoerg       IRBuilder<> IRB(&I);
246306f32e7eSjoerg       Value *Shadow = IRB.CreateICmpSLT(getShadow(op), getCleanShadow(op),
246406f32e7eSjoerg                                         "_msprop_icmp_s");
246506f32e7eSjoerg       setShadow(&I, Shadow);
246606f32e7eSjoerg       setOrigin(&I, getOrigin(op));
246706f32e7eSjoerg     } else {
246806f32e7eSjoerg       handleShadowOr(I);
246906f32e7eSjoerg     }
247006f32e7eSjoerg   }
247106f32e7eSjoerg 
visitICmpInst__anonb9e144640811::MemorySanitizerVisitor247206f32e7eSjoerg   void visitICmpInst(ICmpInst &I) {
247306f32e7eSjoerg     if (!ClHandleICmp) {
247406f32e7eSjoerg       handleShadowOr(I);
247506f32e7eSjoerg       return;
247606f32e7eSjoerg     }
247706f32e7eSjoerg     if (I.isEquality()) {
247806f32e7eSjoerg       handleEqualityComparison(I);
247906f32e7eSjoerg       return;
248006f32e7eSjoerg     }
248106f32e7eSjoerg 
248206f32e7eSjoerg     assert(I.isRelational());
248306f32e7eSjoerg     if (ClHandleICmpExact) {
248406f32e7eSjoerg       handleRelationalComparisonExact(I);
248506f32e7eSjoerg       return;
248606f32e7eSjoerg     }
248706f32e7eSjoerg     if (I.isSigned()) {
248806f32e7eSjoerg       handleSignedRelationalComparison(I);
248906f32e7eSjoerg       return;
249006f32e7eSjoerg     }
249106f32e7eSjoerg 
249206f32e7eSjoerg     assert(I.isUnsigned());
249306f32e7eSjoerg     if ((isa<Constant>(I.getOperand(0)) || isa<Constant>(I.getOperand(1)))) {
249406f32e7eSjoerg       handleRelationalComparisonExact(I);
249506f32e7eSjoerg       return;
249606f32e7eSjoerg     }
249706f32e7eSjoerg 
249806f32e7eSjoerg     handleShadowOr(I);
249906f32e7eSjoerg   }
250006f32e7eSjoerg 
visitFCmpInst__anonb9e144640811::MemorySanitizerVisitor250106f32e7eSjoerg   void visitFCmpInst(FCmpInst &I) {
250206f32e7eSjoerg     handleShadowOr(I);
250306f32e7eSjoerg   }
250406f32e7eSjoerg 
handleShift__anonb9e144640811::MemorySanitizerVisitor250506f32e7eSjoerg   void handleShift(BinaryOperator &I) {
250606f32e7eSjoerg     IRBuilder<> IRB(&I);
250706f32e7eSjoerg     // If any of the S2 bits are poisoned, the whole thing is poisoned.
250806f32e7eSjoerg     // Otherwise perform the same shift on S1.
250906f32e7eSjoerg     Value *S1 = getShadow(&I, 0);
251006f32e7eSjoerg     Value *S2 = getShadow(&I, 1);
251106f32e7eSjoerg     Value *S2Conv = IRB.CreateSExt(IRB.CreateICmpNE(S2, getCleanShadow(S2)),
251206f32e7eSjoerg                                    S2->getType());
251306f32e7eSjoerg     Value *V2 = I.getOperand(1);
251406f32e7eSjoerg     Value *Shift = IRB.CreateBinOp(I.getOpcode(), S1, V2);
251506f32e7eSjoerg     setShadow(&I, IRB.CreateOr(Shift, S2Conv));
251606f32e7eSjoerg     setOriginForNaryOp(I);
251706f32e7eSjoerg   }
251806f32e7eSjoerg 
visitShl__anonb9e144640811::MemorySanitizerVisitor251906f32e7eSjoerg   void visitShl(BinaryOperator &I) { handleShift(I); }
visitAShr__anonb9e144640811::MemorySanitizerVisitor252006f32e7eSjoerg   void visitAShr(BinaryOperator &I) { handleShift(I); }
visitLShr__anonb9e144640811::MemorySanitizerVisitor252106f32e7eSjoerg   void visitLShr(BinaryOperator &I) { handleShift(I); }
252206f32e7eSjoerg 
252306f32e7eSjoerg   /// Instrument llvm.memmove
252406f32e7eSjoerg   ///
252506f32e7eSjoerg   /// At this point we don't know if llvm.memmove will be inlined or not.
252606f32e7eSjoerg   /// If we don't instrument it and it gets inlined,
252706f32e7eSjoerg   /// our interceptor will not kick in and we will lose the memmove.
252806f32e7eSjoerg   /// If we instrument the call here, but it does not get inlined,
252906f32e7eSjoerg   /// we will memove the shadow twice: which is bad in case
253006f32e7eSjoerg   /// of overlapping regions. So, we simply lower the intrinsic to a call.
253106f32e7eSjoerg   ///
253206f32e7eSjoerg   /// Similar situation exists for memcpy and memset.
visitMemMoveInst__anonb9e144640811::MemorySanitizerVisitor253306f32e7eSjoerg   void visitMemMoveInst(MemMoveInst &I) {
253406f32e7eSjoerg     IRBuilder<> IRB(&I);
253506f32e7eSjoerg     IRB.CreateCall(
253606f32e7eSjoerg         MS.MemmoveFn,
253706f32e7eSjoerg         {IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()),
253806f32e7eSjoerg          IRB.CreatePointerCast(I.getArgOperand(1), IRB.getInt8PtrTy()),
253906f32e7eSjoerg          IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
254006f32e7eSjoerg     I.eraseFromParent();
254106f32e7eSjoerg   }
254206f32e7eSjoerg 
254306f32e7eSjoerg   // Similar to memmove: avoid copying shadow twice.
254406f32e7eSjoerg   // This is somewhat unfortunate as it may slowdown small constant memcpys.
254506f32e7eSjoerg   // FIXME: consider doing manual inline for small constant sizes and proper
254606f32e7eSjoerg   // alignment.
visitMemCpyInst__anonb9e144640811::MemorySanitizerVisitor254706f32e7eSjoerg   void visitMemCpyInst(MemCpyInst &I) {
254806f32e7eSjoerg     IRBuilder<> IRB(&I);
254906f32e7eSjoerg     IRB.CreateCall(
255006f32e7eSjoerg         MS.MemcpyFn,
255106f32e7eSjoerg         {IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()),
255206f32e7eSjoerg          IRB.CreatePointerCast(I.getArgOperand(1), IRB.getInt8PtrTy()),
255306f32e7eSjoerg          IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
255406f32e7eSjoerg     I.eraseFromParent();
255506f32e7eSjoerg   }
255606f32e7eSjoerg 
255706f32e7eSjoerg   // Same as memcpy.
visitMemSetInst__anonb9e144640811::MemorySanitizerVisitor255806f32e7eSjoerg   void visitMemSetInst(MemSetInst &I) {
255906f32e7eSjoerg     IRBuilder<> IRB(&I);
256006f32e7eSjoerg     IRB.CreateCall(
256106f32e7eSjoerg         MS.MemsetFn,
256206f32e7eSjoerg         {IRB.CreatePointerCast(I.getArgOperand(0), IRB.getInt8PtrTy()),
256306f32e7eSjoerg          IRB.CreateIntCast(I.getArgOperand(1), IRB.getInt32Ty(), false),
256406f32e7eSjoerg          IRB.CreateIntCast(I.getArgOperand(2), MS.IntptrTy, false)});
256506f32e7eSjoerg     I.eraseFromParent();
256606f32e7eSjoerg   }
256706f32e7eSjoerg 
visitVAStartInst__anonb9e144640811::MemorySanitizerVisitor256806f32e7eSjoerg   void visitVAStartInst(VAStartInst &I) {
256906f32e7eSjoerg     VAHelper->visitVAStartInst(I);
257006f32e7eSjoerg   }
257106f32e7eSjoerg 
visitVACopyInst__anonb9e144640811::MemorySanitizerVisitor257206f32e7eSjoerg   void visitVACopyInst(VACopyInst &I) {
257306f32e7eSjoerg     VAHelper->visitVACopyInst(I);
257406f32e7eSjoerg   }
257506f32e7eSjoerg 
257606f32e7eSjoerg   /// Handle vector store-like intrinsics.
257706f32e7eSjoerg   ///
257806f32e7eSjoerg   /// Instrument intrinsics that look like a simple SIMD store: writes memory,
257906f32e7eSjoerg   /// has 1 pointer argument and 1 vector argument, returns void.
handleVectorStoreIntrinsic__anonb9e144640811::MemorySanitizerVisitor258006f32e7eSjoerg   bool handleVectorStoreIntrinsic(IntrinsicInst &I) {
258106f32e7eSjoerg     IRBuilder<> IRB(&I);
258206f32e7eSjoerg     Value* Addr = I.getArgOperand(0);
258306f32e7eSjoerg     Value *Shadow = getShadow(&I, 1);
258406f32e7eSjoerg     Value *ShadowPtr, *OriginPtr;
258506f32e7eSjoerg 
258606f32e7eSjoerg     // We don't know the pointer alignment (could be unaligned SSE store!).
258706f32e7eSjoerg     // Have to assume to worst case.
258806f32e7eSjoerg     std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
2589*da58b97aSjoerg         Addr, IRB, Shadow->getType(), Align(1), /*isStore*/ true);
2590*da58b97aSjoerg     IRB.CreateAlignedStore(Shadow, ShadowPtr, Align(1));
259106f32e7eSjoerg 
259206f32e7eSjoerg     if (ClCheckAccessAddress)
259306f32e7eSjoerg       insertShadowCheck(Addr, &I);
259406f32e7eSjoerg 
259506f32e7eSjoerg     // FIXME: factor out common code from materializeStores
259606f32e7eSjoerg     if (MS.TrackOrigins) IRB.CreateStore(getOrigin(&I, 1), OriginPtr);
259706f32e7eSjoerg     return true;
259806f32e7eSjoerg   }
259906f32e7eSjoerg 
260006f32e7eSjoerg   /// Handle vector load-like intrinsics.
260106f32e7eSjoerg   ///
260206f32e7eSjoerg   /// Instrument intrinsics that look like a simple SIMD load: reads memory,
260306f32e7eSjoerg   /// has 1 pointer argument, returns a vector.
handleVectorLoadIntrinsic__anonb9e144640811::MemorySanitizerVisitor260406f32e7eSjoerg   bool handleVectorLoadIntrinsic(IntrinsicInst &I) {
260506f32e7eSjoerg     IRBuilder<> IRB(&I);
260606f32e7eSjoerg     Value *Addr = I.getArgOperand(0);
260706f32e7eSjoerg 
260806f32e7eSjoerg     Type *ShadowTy = getShadowTy(&I);
2609*da58b97aSjoerg     Value *ShadowPtr = nullptr, *OriginPtr = nullptr;
261006f32e7eSjoerg     if (PropagateShadow) {
261106f32e7eSjoerg       // We don't know the pointer alignment (could be unaligned SSE load!).
261206f32e7eSjoerg       // Have to assume to worst case.
2613*da58b97aSjoerg       const Align Alignment = Align(1);
261406f32e7eSjoerg       std::tie(ShadowPtr, OriginPtr) =
261506f32e7eSjoerg           getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
261606f32e7eSjoerg       setShadow(&I,
261706f32e7eSjoerg                 IRB.CreateAlignedLoad(ShadowTy, ShadowPtr, Alignment, "_msld"));
261806f32e7eSjoerg     } else {
261906f32e7eSjoerg       setShadow(&I, getCleanShadow(&I));
262006f32e7eSjoerg     }
262106f32e7eSjoerg 
262206f32e7eSjoerg     if (ClCheckAccessAddress)
262306f32e7eSjoerg       insertShadowCheck(Addr, &I);
262406f32e7eSjoerg 
262506f32e7eSjoerg     if (MS.TrackOrigins) {
262606f32e7eSjoerg       if (PropagateShadow)
262706f32e7eSjoerg         setOrigin(&I, IRB.CreateLoad(MS.OriginTy, OriginPtr));
262806f32e7eSjoerg       else
262906f32e7eSjoerg         setOrigin(&I, getCleanOrigin());
263006f32e7eSjoerg     }
263106f32e7eSjoerg     return true;
263206f32e7eSjoerg   }
263306f32e7eSjoerg 
263406f32e7eSjoerg   /// Handle (SIMD arithmetic)-like intrinsics.
263506f32e7eSjoerg   ///
263606f32e7eSjoerg   /// Instrument intrinsics with any number of arguments of the same type,
263706f32e7eSjoerg   /// equal to the return type. The type should be simple (no aggregates or
263806f32e7eSjoerg   /// pointers; vectors are fine).
263906f32e7eSjoerg   /// Caller guarantees that this intrinsic does not access memory.
maybeHandleSimpleNomemIntrinsic__anonb9e144640811::MemorySanitizerVisitor264006f32e7eSjoerg   bool maybeHandleSimpleNomemIntrinsic(IntrinsicInst &I) {
264106f32e7eSjoerg     Type *RetTy = I.getType();
264206f32e7eSjoerg     if (!(RetTy->isIntOrIntVectorTy() ||
264306f32e7eSjoerg           RetTy->isFPOrFPVectorTy() ||
264406f32e7eSjoerg           RetTy->isX86_MMXTy()))
264506f32e7eSjoerg       return false;
264606f32e7eSjoerg 
264706f32e7eSjoerg     unsigned NumArgOperands = I.getNumArgOperands();
264806f32e7eSjoerg     for (unsigned i = 0; i < NumArgOperands; ++i) {
264906f32e7eSjoerg       Type *Ty = I.getArgOperand(i)->getType();
265006f32e7eSjoerg       if (Ty != RetTy)
265106f32e7eSjoerg         return false;
265206f32e7eSjoerg     }
265306f32e7eSjoerg 
265406f32e7eSjoerg     IRBuilder<> IRB(&I);
265506f32e7eSjoerg     ShadowAndOriginCombiner SC(this, IRB);
265606f32e7eSjoerg     for (unsigned i = 0; i < NumArgOperands; ++i)
265706f32e7eSjoerg       SC.Add(I.getArgOperand(i));
265806f32e7eSjoerg     SC.Done(&I);
265906f32e7eSjoerg 
266006f32e7eSjoerg     return true;
266106f32e7eSjoerg   }
266206f32e7eSjoerg 
266306f32e7eSjoerg   /// Heuristically instrument unknown intrinsics.
266406f32e7eSjoerg   ///
266506f32e7eSjoerg   /// The main purpose of this code is to do something reasonable with all
266606f32e7eSjoerg   /// random intrinsics we might encounter, most importantly - SIMD intrinsics.
266706f32e7eSjoerg   /// We recognize several classes of intrinsics by their argument types and
2668*da58b97aSjoerg   /// ModRefBehaviour and apply special instrumentation when we are reasonably
266906f32e7eSjoerg   /// sure that we know what the intrinsic does.
267006f32e7eSjoerg   ///
267106f32e7eSjoerg   /// We special-case intrinsics where this approach fails. See llvm.bswap
267206f32e7eSjoerg   /// handling as an example of that.
handleUnknownIntrinsic__anonb9e144640811::MemorySanitizerVisitor267306f32e7eSjoerg   bool handleUnknownIntrinsic(IntrinsicInst &I) {
267406f32e7eSjoerg     unsigned NumArgOperands = I.getNumArgOperands();
267506f32e7eSjoerg     if (NumArgOperands == 0)
267606f32e7eSjoerg       return false;
267706f32e7eSjoerg 
267806f32e7eSjoerg     if (NumArgOperands == 2 &&
267906f32e7eSjoerg         I.getArgOperand(0)->getType()->isPointerTy() &&
268006f32e7eSjoerg         I.getArgOperand(1)->getType()->isVectorTy() &&
268106f32e7eSjoerg         I.getType()->isVoidTy() &&
268206f32e7eSjoerg         !I.onlyReadsMemory()) {
268306f32e7eSjoerg       // This looks like a vector store.
268406f32e7eSjoerg       return handleVectorStoreIntrinsic(I);
268506f32e7eSjoerg     }
268606f32e7eSjoerg 
268706f32e7eSjoerg     if (NumArgOperands == 1 &&
268806f32e7eSjoerg         I.getArgOperand(0)->getType()->isPointerTy() &&
268906f32e7eSjoerg         I.getType()->isVectorTy() &&
269006f32e7eSjoerg         I.onlyReadsMemory()) {
269106f32e7eSjoerg       // This looks like a vector load.
269206f32e7eSjoerg       return handleVectorLoadIntrinsic(I);
269306f32e7eSjoerg     }
269406f32e7eSjoerg 
269506f32e7eSjoerg     if (I.doesNotAccessMemory())
269606f32e7eSjoerg       if (maybeHandleSimpleNomemIntrinsic(I))
269706f32e7eSjoerg         return true;
269806f32e7eSjoerg 
269906f32e7eSjoerg     // FIXME: detect and handle SSE maskstore/maskload
270006f32e7eSjoerg     return false;
270106f32e7eSjoerg   }
270206f32e7eSjoerg 
handleInvariantGroup__anonb9e144640811::MemorySanitizerVisitor270306f32e7eSjoerg   void handleInvariantGroup(IntrinsicInst &I) {
270406f32e7eSjoerg     setShadow(&I, getShadow(&I, 0));
270506f32e7eSjoerg     setOrigin(&I, getOrigin(&I, 0));
270606f32e7eSjoerg   }
270706f32e7eSjoerg 
handleLifetimeStart__anonb9e144640811::MemorySanitizerVisitor270806f32e7eSjoerg   void handleLifetimeStart(IntrinsicInst &I) {
270906f32e7eSjoerg     if (!PoisonStack)
271006f32e7eSjoerg       return;
2711*da58b97aSjoerg     AllocaInst *AI = llvm::findAllocaForValue(I.getArgOperand(1));
271206f32e7eSjoerg     if (!AI)
271306f32e7eSjoerg       InstrumentLifetimeStart = false;
271406f32e7eSjoerg     LifetimeStartList.push_back(std::make_pair(&I, AI));
271506f32e7eSjoerg   }
271606f32e7eSjoerg 
handleBswap__anonb9e144640811::MemorySanitizerVisitor271706f32e7eSjoerg   void handleBswap(IntrinsicInst &I) {
271806f32e7eSjoerg     IRBuilder<> IRB(&I);
271906f32e7eSjoerg     Value *Op = I.getArgOperand(0);
272006f32e7eSjoerg     Type *OpType = Op->getType();
272106f32e7eSjoerg     Function *BswapFunc = Intrinsic::getDeclaration(
272206f32e7eSjoerg       F.getParent(), Intrinsic::bswap, makeArrayRef(&OpType, 1));
272306f32e7eSjoerg     setShadow(&I, IRB.CreateCall(BswapFunc, getShadow(Op)));
272406f32e7eSjoerg     setOrigin(&I, getOrigin(Op));
272506f32e7eSjoerg   }
272606f32e7eSjoerg 
2727*da58b97aSjoerg   // Instrument vector convert intrinsic.
272806f32e7eSjoerg   //
272906f32e7eSjoerg   // This function instruments intrinsics like cvtsi2ss:
273006f32e7eSjoerg   // %Out = int_xxx_cvtyyy(%ConvertOp)
273106f32e7eSjoerg   // or
273206f32e7eSjoerg   // %Out = int_xxx_cvtyyy(%CopyOp, %ConvertOp)
273306f32e7eSjoerg   // Intrinsic converts \p NumUsedElements elements of \p ConvertOp to the same
273406f32e7eSjoerg   // number \p Out elements, and (if has 2 arguments) copies the rest of the
273506f32e7eSjoerg   // elements from \p CopyOp.
273606f32e7eSjoerg   // In most cases conversion involves floating-point value which may trigger a
273706f32e7eSjoerg   // hardware exception when not fully initialized. For this reason we require
273806f32e7eSjoerg   // \p ConvertOp[0:NumUsedElements] to be fully initialized and trap otherwise.
273906f32e7eSjoerg   // We copy the shadow of \p CopyOp[NumUsedElements:] to \p
274006f32e7eSjoerg   // Out[NumUsedElements:]. This means that intrinsics without \p CopyOp always
274106f32e7eSjoerg   // return a fully initialized value.
handleVectorConvertIntrinsic__anonb9e144640811::MemorySanitizerVisitor2742*da58b97aSjoerg   void handleVectorConvertIntrinsic(IntrinsicInst &I, int NumUsedElements,
2743*da58b97aSjoerg                                     bool HasRoundingMode = false) {
274406f32e7eSjoerg     IRBuilder<> IRB(&I);
274506f32e7eSjoerg     Value *CopyOp, *ConvertOp;
274606f32e7eSjoerg 
2747*da58b97aSjoerg     assert((!HasRoundingMode ||
2748*da58b97aSjoerg             isa<ConstantInt>(I.getArgOperand(I.getNumArgOperands() - 1))) &&
2749*da58b97aSjoerg            "Invalid rounding mode");
2750*da58b97aSjoerg 
2751*da58b97aSjoerg     switch (I.getNumArgOperands() - HasRoundingMode) {
275206f32e7eSjoerg     case 2:
275306f32e7eSjoerg       CopyOp = I.getArgOperand(0);
275406f32e7eSjoerg       ConvertOp = I.getArgOperand(1);
275506f32e7eSjoerg       break;
275606f32e7eSjoerg     case 1:
275706f32e7eSjoerg       ConvertOp = I.getArgOperand(0);
275806f32e7eSjoerg       CopyOp = nullptr;
275906f32e7eSjoerg       break;
276006f32e7eSjoerg     default:
276106f32e7eSjoerg       llvm_unreachable("Cvt intrinsic with unsupported number of arguments.");
276206f32e7eSjoerg     }
276306f32e7eSjoerg 
276406f32e7eSjoerg     // The first *NumUsedElements* elements of ConvertOp are converted to the
276506f32e7eSjoerg     // same number of output elements. The rest of the output is copied from
276606f32e7eSjoerg     // CopyOp, or (if not available) filled with zeroes.
276706f32e7eSjoerg     // Combine shadow for elements of ConvertOp that are used in this operation,
276806f32e7eSjoerg     // and insert a check.
276906f32e7eSjoerg     // FIXME: consider propagating shadow of ConvertOp, at least in the case of
277006f32e7eSjoerg     // int->any conversion.
277106f32e7eSjoerg     Value *ConvertShadow = getShadow(ConvertOp);
277206f32e7eSjoerg     Value *AggShadow = nullptr;
277306f32e7eSjoerg     if (ConvertOp->getType()->isVectorTy()) {
277406f32e7eSjoerg       AggShadow = IRB.CreateExtractElement(
277506f32e7eSjoerg           ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), 0));
277606f32e7eSjoerg       for (int i = 1; i < NumUsedElements; ++i) {
277706f32e7eSjoerg         Value *MoreShadow = IRB.CreateExtractElement(
277806f32e7eSjoerg             ConvertShadow, ConstantInt::get(IRB.getInt32Ty(), i));
277906f32e7eSjoerg         AggShadow = IRB.CreateOr(AggShadow, MoreShadow);
278006f32e7eSjoerg       }
278106f32e7eSjoerg     } else {
278206f32e7eSjoerg       AggShadow = ConvertShadow;
278306f32e7eSjoerg     }
278406f32e7eSjoerg     assert(AggShadow->getType()->isIntegerTy());
278506f32e7eSjoerg     insertShadowCheck(AggShadow, getOrigin(ConvertOp), &I);
278606f32e7eSjoerg 
278706f32e7eSjoerg     // Build result shadow by zero-filling parts of CopyOp shadow that come from
278806f32e7eSjoerg     // ConvertOp.
278906f32e7eSjoerg     if (CopyOp) {
279006f32e7eSjoerg       assert(CopyOp->getType() == I.getType());
279106f32e7eSjoerg       assert(CopyOp->getType()->isVectorTy());
279206f32e7eSjoerg       Value *ResultShadow = getShadow(CopyOp);
2793*da58b97aSjoerg       Type *EltTy = cast<VectorType>(ResultShadow->getType())->getElementType();
279406f32e7eSjoerg       for (int i = 0; i < NumUsedElements; ++i) {
279506f32e7eSjoerg         ResultShadow = IRB.CreateInsertElement(
279606f32e7eSjoerg             ResultShadow, ConstantInt::getNullValue(EltTy),
279706f32e7eSjoerg             ConstantInt::get(IRB.getInt32Ty(), i));
279806f32e7eSjoerg       }
279906f32e7eSjoerg       setShadow(&I, ResultShadow);
280006f32e7eSjoerg       setOrigin(&I, getOrigin(CopyOp));
280106f32e7eSjoerg     } else {
280206f32e7eSjoerg       setShadow(&I, getCleanShadow(&I));
280306f32e7eSjoerg       setOrigin(&I, getCleanOrigin());
280406f32e7eSjoerg     }
280506f32e7eSjoerg   }
280606f32e7eSjoerg 
280706f32e7eSjoerg   // Given a scalar or vector, extract lower 64 bits (or less), and return all
280806f32e7eSjoerg   // zeroes if it is zero, and all ones otherwise.
Lower64ShadowExtend__anonb9e144640811::MemorySanitizerVisitor280906f32e7eSjoerg   Value *Lower64ShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
281006f32e7eSjoerg     if (S->getType()->isVectorTy())
281106f32e7eSjoerg       S = CreateShadowCast(IRB, S, IRB.getInt64Ty(), /* Signed */ true);
281206f32e7eSjoerg     assert(S->getType()->getPrimitiveSizeInBits() <= 64);
281306f32e7eSjoerg     Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
281406f32e7eSjoerg     return CreateShadowCast(IRB, S2, T, /* Signed */ true);
281506f32e7eSjoerg   }
281606f32e7eSjoerg 
281706f32e7eSjoerg   // Given a vector, extract its first element, and return all
281806f32e7eSjoerg   // zeroes if it is zero, and all ones otherwise.
LowerElementShadowExtend__anonb9e144640811::MemorySanitizerVisitor281906f32e7eSjoerg   Value *LowerElementShadowExtend(IRBuilder<> &IRB, Value *S, Type *T) {
282006f32e7eSjoerg     Value *S1 = IRB.CreateExtractElement(S, (uint64_t)0);
282106f32e7eSjoerg     Value *S2 = IRB.CreateICmpNE(S1, getCleanShadow(S1));
282206f32e7eSjoerg     return CreateShadowCast(IRB, S2, T, /* Signed */ true);
282306f32e7eSjoerg   }
282406f32e7eSjoerg 
VariableShadowExtend__anonb9e144640811::MemorySanitizerVisitor282506f32e7eSjoerg   Value *VariableShadowExtend(IRBuilder<> &IRB, Value *S) {
282606f32e7eSjoerg     Type *T = S->getType();
282706f32e7eSjoerg     assert(T->isVectorTy());
282806f32e7eSjoerg     Value *S2 = IRB.CreateICmpNE(S, getCleanShadow(S));
282906f32e7eSjoerg     return IRB.CreateSExt(S2, T);
283006f32e7eSjoerg   }
283106f32e7eSjoerg 
2832*da58b97aSjoerg   // Instrument vector shift intrinsic.
283306f32e7eSjoerg   //
283406f32e7eSjoerg   // This function instruments intrinsics like int_x86_avx2_psll_w.
283506f32e7eSjoerg   // Intrinsic shifts %In by %ShiftSize bits.
283606f32e7eSjoerg   // %ShiftSize may be a vector. In that case the lower 64 bits determine shift
283706f32e7eSjoerg   // size, and the rest is ignored. Behavior is defined even if shift size is
283806f32e7eSjoerg   // greater than register (or field) width.
handleVectorShiftIntrinsic__anonb9e144640811::MemorySanitizerVisitor283906f32e7eSjoerg   void handleVectorShiftIntrinsic(IntrinsicInst &I, bool Variable) {
284006f32e7eSjoerg     assert(I.getNumArgOperands() == 2);
284106f32e7eSjoerg     IRBuilder<> IRB(&I);
284206f32e7eSjoerg     // If any of the S2 bits are poisoned, the whole thing is poisoned.
284306f32e7eSjoerg     // Otherwise perform the same shift on S1.
284406f32e7eSjoerg     Value *S1 = getShadow(&I, 0);
284506f32e7eSjoerg     Value *S2 = getShadow(&I, 1);
284606f32e7eSjoerg     Value *S2Conv = Variable ? VariableShadowExtend(IRB, S2)
284706f32e7eSjoerg                              : Lower64ShadowExtend(IRB, S2, getShadowTy(&I));
284806f32e7eSjoerg     Value *V1 = I.getOperand(0);
284906f32e7eSjoerg     Value *V2 = I.getOperand(1);
2850*da58b97aSjoerg     Value *Shift = IRB.CreateCall(I.getFunctionType(), I.getCalledOperand(),
285106f32e7eSjoerg                                   {IRB.CreateBitCast(S1, V1->getType()), V2});
285206f32e7eSjoerg     Shift = IRB.CreateBitCast(Shift, getShadowTy(&I));
285306f32e7eSjoerg     setShadow(&I, IRB.CreateOr(Shift, S2Conv));
285406f32e7eSjoerg     setOriginForNaryOp(I);
285506f32e7eSjoerg   }
285606f32e7eSjoerg 
285706f32e7eSjoerg   // Get an X86_MMX-sized vector type.
getMMXVectorTy__anonb9e144640811::MemorySanitizerVisitor285806f32e7eSjoerg   Type *getMMXVectorTy(unsigned EltSizeInBits) {
285906f32e7eSjoerg     const unsigned X86_MMXSizeInBits = 64;
286006f32e7eSjoerg     assert(EltSizeInBits != 0 && (X86_MMXSizeInBits % EltSizeInBits) == 0 &&
286106f32e7eSjoerg            "Illegal MMX vector element size");
2862*da58b97aSjoerg     return FixedVectorType::get(IntegerType::get(*MS.C, EltSizeInBits),
286306f32e7eSjoerg                                 X86_MMXSizeInBits / EltSizeInBits);
286406f32e7eSjoerg   }
286506f32e7eSjoerg 
286606f32e7eSjoerg   // Returns a signed counterpart for an (un)signed-saturate-and-pack
286706f32e7eSjoerg   // intrinsic.
getSignedPackIntrinsic__anonb9e144640811::MemorySanitizerVisitor286806f32e7eSjoerg   Intrinsic::ID getSignedPackIntrinsic(Intrinsic::ID id) {
286906f32e7eSjoerg     switch (id) {
287006f32e7eSjoerg       case Intrinsic::x86_sse2_packsswb_128:
287106f32e7eSjoerg       case Intrinsic::x86_sse2_packuswb_128:
287206f32e7eSjoerg         return Intrinsic::x86_sse2_packsswb_128;
287306f32e7eSjoerg 
287406f32e7eSjoerg       case Intrinsic::x86_sse2_packssdw_128:
287506f32e7eSjoerg       case Intrinsic::x86_sse41_packusdw:
287606f32e7eSjoerg         return Intrinsic::x86_sse2_packssdw_128;
287706f32e7eSjoerg 
287806f32e7eSjoerg       case Intrinsic::x86_avx2_packsswb:
287906f32e7eSjoerg       case Intrinsic::x86_avx2_packuswb:
288006f32e7eSjoerg         return Intrinsic::x86_avx2_packsswb;
288106f32e7eSjoerg 
288206f32e7eSjoerg       case Intrinsic::x86_avx2_packssdw:
288306f32e7eSjoerg       case Intrinsic::x86_avx2_packusdw:
288406f32e7eSjoerg         return Intrinsic::x86_avx2_packssdw;
288506f32e7eSjoerg 
288606f32e7eSjoerg       case Intrinsic::x86_mmx_packsswb:
288706f32e7eSjoerg       case Intrinsic::x86_mmx_packuswb:
288806f32e7eSjoerg         return Intrinsic::x86_mmx_packsswb;
288906f32e7eSjoerg 
289006f32e7eSjoerg       case Intrinsic::x86_mmx_packssdw:
289106f32e7eSjoerg         return Intrinsic::x86_mmx_packssdw;
289206f32e7eSjoerg       default:
289306f32e7eSjoerg         llvm_unreachable("unexpected intrinsic id");
289406f32e7eSjoerg     }
289506f32e7eSjoerg   }
289606f32e7eSjoerg 
2897*da58b97aSjoerg   // Instrument vector pack intrinsic.
289806f32e7eSjoerg   //
289906f32e7eSjoerg   // This function instruments intrinsics like x86_mmx_packsswb, that
290006f32e7eSjoerg   // packs elements of 2 input vectors into half as many bits with saturation.
290106f32e7eSjoerg   // Shadow is propagated with the signed variant of the same intrinsic applied
290206f32e7eSjoerg   // to sext(Sa != zeroinitializer), sext(Sb != zeroinitializer).
290306f32e7eSjoerg   // EltSizeInBits is used only for x86mmx arguments.
handleVectorPackIntrinsic__anonb9e144640811::MemorySanitizerVisitor290406f32e7eSjoerg   void handleVectorPackIntrinsic(IntrinsicInst &I, unsigned EltSizeInBits = 0) {
290506f32e7eSjoerg     assert(I.getNumArgOperands() == 2);
290606f32e7eSjoerg     bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy();
290706f32e7eSjoerg     IRBuilder<> IRB(&I);
290806f32e7eSjoerg     Value *S1 = getShadow(&I, 0);
290906f32e7eSjoerg     Value *S2 = getShadow(&I, 1);
291006f32e7eSjoerg     assert(isX86_MMX || S1->getType()->isVectorTy());
291106f32e7eSjoerg 
291206f32e7eSjoerg     // SExt and ICmpNE below must apply to individual elements of input vectors.
291306f32e7eSjoerg     // In case of x86mmx arguments, cast them to appropriate vector types and
291406f32e7eSjoerg     // back.
291506f32e7eSjoerg     Type *T = isX86_MMX ? getMMXVectorTy(EltSizeInBits) : S1->getType();
291606f32e7eSjoerg     if (isX86_MMX) {
291706f32e7eSjoerg       S1 = IRB.CreateBitCast(S1, T);
291806f32e7eSjoerg       S2 = IRB.CreateBitCast(S2, T);
291906f32e7eSjoerg     }
292006f32e7eSjoerg     Value *S1_ext = IRB.CreateSExt(
292106f32e7eSjoerg         IRB.CreateICmpNE(S1, Constant::getNullValue(T)), T);
292206f32e7eSjoerg     Value *S2_ext = IRB.CreateSExt(
292306f32e7eSjoerg         IRB.CreateICmpNE(S2, Constant::getNullValue(T)), T);
292406f32e7eSjoerg     if (isX86_MMX) {
292506f32e7eSjoerg       Type *X86_MMXTy = Type::getX86_MMXTy(*MS.C);
292606f32e7eSjoerg       S1_ext = IRB.CreateBitCast(S1_ext, X86_MMXTy);
292706f32e7eSjoerg       S2_ext = IRB.CreateBitCast(S2_ext, X86_MMXTy);
292806f32e7eSjoerg     }
292906f32e7eSjoerg 
293006f32e7eSjoerg     Function *ShadowFn = Intrinsic::getDeclaration(
293106f32e7eSjoerg         F.getParent(), getSignedPackIntrinsic(I.getIntrinsicID()));
293206f32e7eSjoerg 
293306f32e7eSjoerg     Value *S =
293406f32e7eSjoerg         IRB.CreateCall(ShadowFn, {S1_ext, S2_ext}, "_msprop_vector_pack");
293506f32e7eSjoerg     if (isX86_MMX) S = IRB.CreateBitCast(S, getShadowTy(&I));
293606f32e7eSjoerg     setShadow(&I, S);
293706f32e7eSjoerg     setOriginForNaryOp(I);
293806f32e7eSjoerg   }
293906f32e7eSjoerg 
2940*da58b97aSjoerg   // Instrument sum-of-absolute-differences intrinsic.
handleVectorSadIntrinsic__anonb9e144640811::MemorySanitizerVisitor294106f32e7eSjoerg   void handleVectorSadIntrinsic(IntrinsicInst &I) {
294206f32e7eSjoerg     const unsigned SignificantBitsPerResultElement = 16;
294306f32e7eSjoerg     bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy();
294406f32e7eSjoerg     Type *ResTy = isX86_MMX ? IntegerType::get(*MS.C, 64) : I.getType();
294506f32e7eSjoerg     unsigned ZeroBitsPerResultElement =
294606f32e7eSjoerg         ResTy->getScalarSizeInBits() - SignificantBitsPerResultElement;
294706f32e7eSjoerg 
294806f32e7eSjoerg     IRBuilder<> IRB(&I);
294906f32e7eSjoerg     Value *S = IRB.CreateOr(getShadow(&I, 0), getShadow(&I, 1));
295006f32e7eSjoerg     S = IRB.CreateBitCast(S, ResTy);
295106f32e7eSjoerg     S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)),
295206f32e7eSjoerg                        ResTy);
295306f32e7eSjoerg     S = IRB.CreateLShr(S, ZeroBitsPerResultElement);
295406f32e7eSjoerg     S = IRB.CreateBitCast(S, getShadowTy(&I));
295506f32e7eSjoerg     setShadow(&I, S);
295606f32e7eSjoerg     setOriginForNaryOp(I);
295706f32e7eSjoerg   }
295806f32e7eSjoerg 
295906f32e7eSjoerg   // Instrument multiply-add intrinsic.
handleVectorPmaddIntrinsic__anonb9e144640811::MemorySanitizerVisitor296006f32e7eSjoerg   void handleVectorPmaddIntrinsic(IntrinsicInst &I,
296106f32e7eSjoerg                                   unsigned EltSizeInBits = 0) {
296206f32e7eSjoerg     bool isX86_MMX = I.getOperand(0)->getType()->isX86_MMXTy();
296306f32e7eSjoerg     Type *ResTy = isX86_MMX ? getMMXVectorTy(EltSizeInBits * 2) : I.getType();
296406f32e7eSjoerg     IRBuilder<> IRB(&I);
296506f32e7eSjoerg     Value *S = IRB.CreateOr(getShadow(&I, 0), getShadow(&I, 1));
296606f32e7eSjoerg     S = IRB.CreateBitCast(S, ResTy);
296706f32e7eSjoerg     S = IRB.CreateSExt(IRB.CreateICmpNE(S, Constant::getNullValue(ResTy)),
296806f32e7eSjoerg                        ResTy);
296906f32e7eSjoerg     S = IRB.CreateBitCast(S, getShadowTy(&I));
297006f32e7eSjoerg     setShadow(&I, S);
297106f32e7eSjoerg     setOriginForNaryOp(I);
297206f32e7eSjoerg   }
297306f32e7eSjoerg 
297406f32e7eSjoerg   // Instrument compare-packed intrinsic.
297506f32e7eSjoerg   // Basically, an or followed by sext(icmp ne 0) to end up with all-zeros or
297606f32e7eSjoerg   // all-ones shadow.
handleVectorComparePackedIntrinsic__anonb9e144640811::MemorySanitizerVisitor297706f32e7eSjoerg   void handleVectorComparePackedIntrinsic(IntrinsicInst &I) {
297806f32e7eSjoerg     IRBuilder<> IRB(&I);
297906f32e7eSjoerg     Type *ResTy = getShadowTy(&I);
298006f32e7eSjoerg     Value *S0 = IRB.CreateOr(getShadow(&I, 0), getShadow(&I, 1));
298106f32e7eSjoerg     Value *S = IRB.CreateSExt(
298206f32e7eSjoerg         IRB.CreateICmpNE(S0, Constant::getNullValue(ResTy)), ResTy);
298306f32e7eSjoerg     setShadow(&I, S);
298406f32e7eSjoerg     setOriginForNaryOp(I);
298506f32e7eSjoerg   }
298606f32e7eSjoerg 
298706f32e7eSjoerg   // Instrument compare-scalar intrinsic.
298806f32e7eSjoerg   // This handles both cmp* intrinsics which return the result in the first
298906f32e7eSjoerg   // element of a vector, and comi* which return the result as i32.
handleVectorCompareScalarIntrinsic__anonb9e144640811::MemorySanitizerVisitor299006f32e7eSjoerg   void handleVectorCompareScalarIntrinsic(IntrinsicInst &I) {
299106f32e7eSjoerg     IRBuilder<> IRB(&I);
299206f32e7eSjoerg     Value *S0 = IRB.CreateOr(getShadow(&I, 0), getShadow(&I, 1));
299306f32e7eSjoerg     Value *S = LowerElementShadowExtend(IRB, S0, getShadowTy(&I));
299406f32e7eSjoerg     setShadow(&I, S);
299506f32e7eSjoerg     setOriginForNaryOp(I);
299606f32e7eSjoerg   }
299706f32e7eSjoerg 
2998*da58b97aSjoerg   // Instrument generic vector reduction intrinsics
2999*da58b97aSjoerg   // by ORing together all their fields.
handleVectorReduceIntrinsic__anonb9e144640811::MemorySanitizerVisitor3000*da58b97aSjoerg   void handleVectorReduceIntrinsic(IntrinsicInst &I) {
3001*da58b97aSjoerg     IRBuilder<> IRB(&I);
3002*da58b97aSjoerg     Value *S = IRB.CreateOrReduce(getShadow(&I, 0));
3003*da58b97aSjoerg     setShadow(&I, S);
3004*da58b97aSjoerg     setOrigin(&I, getOrigin(&I, 0));
3005*da58b97aSjoerg   }
3006*da58b97aSjoerg 
3007*da58b97aSjoerg   // Instrument vector.reduce.or intrinsic.
3008*da58b97aSjoerg   // Valid (non-poisoned) set bits in the operand pull low the
3009*da58b97aSjoerg   // corresponding shadow bits.
handleVectorReduceOrIntrinsic__anonb9e144640811::MemorySanitizerVisitor3010*da58b97aSjoerg   void handleVectorReduceOrIntrinsic(IntrinsicInst &I) {
3011*da58b97aSjoerg     IRBuilder<> IRB(&I);
3012*da58b97aSjoerg     Value *OperandShadow = getShadow(&I, 0);
3013*da58b97aSjoerg     Value *OperandUnsetBits = IRB.CreateNot(I.getOperand(0));
3014*da58b97aSjoerg     Value *OperandUnsetOrPoison = IRB.CreateOr(OperandUnsetBits, OperandShadow);
3015*da58b97aSjoerg     // Bit N is clean if any field's bit N is 1 and unpoison
3016*da58b97aSjoerg     Value *OutShadowMask = IRB.CreateAndReduce(OperandUnsetOrPoison);
3017*da58b97aSjoerg     // Otherwise, it is clean if every field's bit N is unpoison
3018*da58b97aSjoerg     Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
3019*da58b97aSjoerg     Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
3020*da58b97aSjoerg 
3021*da58b97aSjoerg     setShadow(&I, S);
3022*da58b97aSjoerg     setOrigin(&I, getOrigin(&I, 0));
3023*da58b97aSjoerg   }
3024*da58b97aSjoerg 
3025*da58b97aSjoerg   // Instrument vector.reduce.and intrinsic.
3026*da58b97aSjoerg   // Valid (non-poisoned) unset bits in the operand pull down the
3027*da58b97aSjoerg   // corresponding shadow bits.
handleVectorReduceAndIntrinsic__anonb9e144640811::MemorySanitizerVisitor3028*da58b97aSjoerg   void handleVectorReduceAndIntrinsic(IntrinsicInst &I) {
3029*da58b97aSjoerg     IRBuilder<> IRB(&I);
3030*da58b97aSjoerg     Value *OperandShadow = getShadow(&I, 0);
3031*da58b97aSjoerg     Value *OperandSetOrPoison = IRB.CreateOr(I.getOperand(0), OperandShadow);
3032*da58b97aSjoerg     // Bit N is clean if any field's bit N is 0 and unpoison
3033*da58b97aSjoerg     Value *OutShadowMask = IRB.CreateAndReduce(OperandSetOrPoison);
3034*da58b97aSjoerg     // Otherwise, it is clean if every field's bit N is unpoison
3035*da58b97aSjoerg     Value *OrShadow = IRB.CreateOrReduce(OperandShadow);
3036*da58b97aSjoerg     Value *S = IRB.CreateAnd(OutShadowMask, OrShadow);
3037*da58b97aSjoerg 
3038*da58b97aSjoerg     setShadow(&I, S);
3039*da58b97aSjoerg     setOrigin(&I, getOrigin(&I, 0));
3040*da58b97aSjoerg   }
3041*da58b97aSjoerg 
handleStmxcsr__anonb9e144640811::MemorySanitizerVisitor304206f32e7eSjoerg   void handleStmxcsr(IntrinsicInst &I) {
304306f32e7eSjoerg     IRBuilder<> IRB(&I);
304406f32e7eSjoerg     Value* Addr = I.getArgOperand(0);
304506f32e7eSjoerg     Type *Ty = IRB.getInt32Ty();
304606f32e7eSjoerg     Value *ShadowPtr =
3047*da58b97aSjoerg         getShadowOriginPtr(Addr, IRB, Ty, Align(1), /*isStore*/ true).first;
304806f32e7eSjoerg 
304906f32e7eSjoerg     IRB.CreateStore(getCleanShadow(Ty),
305006f32e7eSjoerg                     IRB.CreatePointerCast(ShadowPtr, Ty->getPointerTo()));
305106f32e7eSjoerg 
305206f32e7eSjoerg     if (ClCheckAccessAddress)
305306f32e7eSjoerg       insertShadowCheck(Addr, &I);
305406f32e7eSjoerg   }
305506f32e7eSjoerg 
handleLdmxcsr__anonb9e144640811::MemorySanitizerVisitor305606f32e7eSjoerg   void handleLdmxcsr(IntrinsicInst &I) {
305706f32e7eSjoerg     if (!InsertChecks) return;
305806f32e7eSjoerg 
305906f32e7eSjoerg     IRBuilder<> IRB(&I);
306006f32e7eSjoerg     Value *Addr = I.getArgOperand(0);
306106f32e7eSjoerg     Type *Ty = IRB.getInt32Ty();
3062*da58b97aSjoerg     const Align Alignment = Align(1);
306306f32e7eSjoerg     Value *ShadowPtr, *OriginPtr;
306406f32e7eSjoerg     std::tie(ShadowPtr, OriginPtr) =
306506f32e7eSjoerg         getShadowOriginPtr(Addr, IRB, Ty, Alignment, /*isStore*/ false);
306606f32e7eSjoerg 
306706f32e7eSjoerg     if (ClCheckAccessAddress)
306806f32e7eSjoerg       insertShadowCheck(Addr, &I);
306906f32e7eSjoerg 
307006f32e7eSjoerg     Value *Shadow = IRB.CreateAlignedLoad(Ty, ShadowPtr, Alignment, "_ldmxcsr");
307106f32e7eSjoerg     Value *Origin = MS.TrackOrigins ? IRB.CreateLoad(MS.OriginTy, OriginPtr)
307206f32e7eSjoerg                                     : getCleanOrigin();
307306f32e7eSjoerg     insertShadowCheck(Shadow, Origin, &I);
307406f32e7eSjoerg   }
307506f32e7eSjoerg 
handleMaskedStore__anonb9e144640811::MemorySanitizerVisitor307606f32e7eSjoerg   void handleMaskedStore(IntrinsicInst &I) {
307706f32e7eSjoerg     IRBuilder<> IRB(&I);
307806f32e7eSjoerg     Value *V = I.getArgOperand(0);
307906f32e7eSjoerg     Value *Addr = I.getArgOperand(1);
3080*da58b97aSjoerg     const Align Alignment(
3081*da58b97aSjoerg         cast<ConstantInt>(I.getArgOperand(2))->getZExtValue());
308206f32e7eSjoerg     Value *Mask = I.getArgOperand(3);
308306f32e7eSjoerg     Value *Shadow = getShadow(V);
308406f32e7eSjoerg 
308506f32e7eSjoerg     Value *ShadowPtr;
308606f32e7eSjoerg     Value *OriginPtr;
308706f32e7eSjoerg     std::tie(ShadowPtr, OriginPtr) = getShadowOriginPtr(
3088*da58b97aSjoerg         Addr, IRB, Shadow->getType(), Alignment, /*isStore*/ true);
308906f32e7eSjoerg 
309006f32e7eSjoerg     if (ClCheckAccessAddress) {
309106f32e7eSjoerg       insertShadowCheck(Addr, &I);
309206f32e7eSjoerg       // Uninitialized mask is kind of like uninitialized address, but not as
309306f32e7eSjoerg       // scary.
309406f32e7eSjoerg       insertShadowCheck(Mask, &I);
309506f32e7eSjoerg     }
309606f32e7eSjoerg 
3097*da58b97aSjoerg     IRB.CreateMaskedStore(Shadow, ShadowPtr, Alignment, Mask);
309806f32e7eSjoerg 
309906f32e7eSjoerg     if (MS.TrackOrigins) {
310006f32e7eSjoerg       auto &DL = F.getParent()->getDataLayout();
310106f32e7eSjoerg       paintOrigin(IRB, getOrigin(V), OriginPtr,
310206f32e7eSjoerg                   DL.getTypeStoreSize(Shadow->getType()),
3103*da58b97aSjoerg                   std::max(Alignment, kMinOriginAlignment));
310406f32e7eSjoerg     }
310506f32e7eSjoerg   }
310606f32e7eSjoerg 
handleMaskedLoad__anonb9e144640811::MemorySanitizerVisitor310706f32e7eSjoerg   bool handleMaskedLoad(IntrinsicInst &I) {
310806f32e7eSjoerg     IRBuilder<> IRB(&I);
310906f32e7eSjoerg     Value *Addr = I.getArgOperand(0);
3110*da58b97aSjoerg     const Align Alignment(
3111*da58b97aSjoerg         cast<ConstantInt>(I.getArgOperand(1))->getZExtValue());
311206f32e7eSjoerg     Value *Mask = I.getArgOperand(2);
311306f32e7eSjoerg     Value *PassThru = I.getArgOperand(3);
311406f32e7eSjoerg 
311506f32e7eSjoerg     Type *ShadowTy = getShadowTy(&I);
311606f32e7eSjoerg     Value *ShadowPtr, *OriginPtr;
311706f32e7eSjoerg     if (PropagateShadow) {
311806f32e7eSjoerg       std::tie(ShadowPtr, OriginPtr) =
3119*da58b97aSjoerg           getShadowOriginPtr(Addr, IRB, ShadowTy, Alignment, /*isStore*/ false);
3120*da58b97aSjoerg       setShadow(&I, IRB.CreateMaskedLoad(ShadowPtr, Alignment, Mask,
312106f32e7eSjoerg                                          getShadow(PassThru), "_msmaskedld"));
312206f32e7eSjoerg     } else {
312306f32e7eSjoerg       setShadow(&I, getCleanShadow(&I));
312406f32e7eSjoerg     }
312506f32e7eSjoerg 
312606f32e7eSjoerg     if (ClCheckAccessAddress) {
312706f32e7eSjoerg       insertShadowCheck(Addr, &I);
312806f32e7eSjoerg       insertShadowCheck(Mask, &I);
312906f32e7eSjoerg     }
313006f32e7eSjoerg 
313106f32e7eSjoerg     if (MS.TrackOrigins) {
313206f32e7eSjoerg       if (PropagateShadow) {
313306f32e7eSjoerg         // Choose between PassThru's and the loaded value's origins.
313406f32e7eSjoerg         Value *MaskedPassThruShadow = IRB.CreateAnd(
313506f32e7eSjoerg             getShadow(PassThru), IRB.CreateSExt(IRB.CreateNeg(Mask), ShadowTy));
313606f32e7eSjoerg 
313706f32e7eSjoerg         Value *Acc = IRB.CreateExtractElement(
313806f32e7eSjoerg             MaskedPassThruShadow, ConstantInt::get(IRB.getInt32Ty(), 0));
3139*da58b97aSjoerg         for (int i = 1, N = cast<FixedVectorType>(PassThru->getType())
3140*da58b97aSjoerg                                 ->getNumElements();
3141*da58b97aSjoerg              i < N; ++i) {
314206f32e7eSjoerg           Value *More = IRB.CreateExtractElement(
314306f32e7eSjoerg               MaskedPassThruShadow, ConstantInt::get(IRB.getInt32Ty(), i));
314406f32e7eSjoerg           Acc = IRB.CreateOr(Acc, More);
314506f32e7eSjoerg         }
314606f32e7eSjoerg 
314706f32e7eSjoerg         Value *Origin = IRB.CreateSelect(
314806f32e7eSjoerg             IRB.CreateICmpNE(Acc, Constant::getNullValue(Acc->getType())),
314906f32e7eSjoerg             getOrigin(PassThru), IRB.CreateLoad(MS.OriginTy, OriginPtr));
315006f32e7eSjoerg 
315106f32e7eSjoerg         setOrigin(&I, Origin);
315206f32e7eSjoerg       } else {
315306f32e7eSjoerg         setOrigin(&I, getCleanOrigin());
315406f32e7eSjoerg       }
315506f32e7eSjoerg     }
315606f32e7eSjoerg     return true;
315706f32e7eSjoerg   }
315806f32e7eSjoerg 
315906f32e7eSjoerg   // Instrument BMI / BMI2 intrinsics.
316006f32e7eSjoerg   // All of these intrinsics are Z = I(X, Y)
316106f32e7eSjoerg   // where the types of all operands and the result match, and are either i32 or i64.
316206f32e7eSjoerg   // The following instrumentation happens to work for all of them:
316306f32e7eSjoerg   //   Sz = I(Sx, Y) | (sext (Sy != 0))
handleBmiIntrinsic__anonb9e144640811::MemorySanitizerVisitor316406f32e7eSjoerg   void handleBmiIntrinsic(IntrinsicInst &I) {
316506f32e7eSjoerg     IRBuilder<> IRB(&I);
316606f32e7eSjoerg     Type *ShadowTy = getShadowTy(&I);
316706f32e7eSjoerg 
316806f32e7eSjoerg     // If any bit of the mask operand is poisoned, then the whole thing is.
316906f32e7eSjoerg     Value *SMask = getShadow(&I, 1);
317006f32e7eSjoerg     SMask = IRB.CreateSExt(IRB.CreateICmpNE(SMask, getCleanShadow(ShadowTy)),
317106f32e7eSjoerg                            ShadowTy);
317206f32e7eSjoerg     // Apply the same intrinsic to the shadow of the first operand.
317306f32e7eSjoerg     Value *S = IRB.CreateCall(I.getCalledFunction(),
317406f32e7eSjoerg                               {getShadow(&I, 0), I.getOperand(1)});
317506f32e7eSjoerg     S = IRB.CreateOr(SMask, S);
317606f32e7eSjoerg     setShadow(&I, S);
317706f32e7eSjoerg     setOriginForNaryOp(I);
317806f32e7eSjoerg   }
317906f32e7eSjoerg 
getPclmulMask__anonb9e144640811::MemorySanitizerVisitor3180*da58b97aSjoerg   SmallVector<int, 8> getPclmulMask(unsigned Width, bool OddElements) {
3181*da58b97aSjoerg     SmallVector<int, 8> Mask;
3182*da58b97aSjoerg     for (unsigned X = OddElements ? 1 : 0; X < Width; X += 2) {
3183*da58b97aSjoerg       Mask.append(2, X);
3184*da58b97aSjoerg     }
3185*da58b97aSjoerg     return Mask;
3186*da58b97aSjoerg   }
3187*da58b97aSjoerg 
3188*da58b97aSjoerg   // Instrument pclmul intrinsics.
3189*da58b97aSjoerg   // These intrinsics operate either on odd or on even elements of the input
3190*da58b97aSjoerg   // vectors, depending on the constant in the 3rd argument, ignoring the rest.
3191*da58b97aSjoerg   // Replace the unused elements with copies of the used ones, ex:
3192*da58b97aSjoerg   //   (0, 1, 2, 3) -> (0, 0, 2, 2) (even case)
3193*da58b97aSjoerg   // or
3194*da58b97aSjoerg   //   (0, 1, 2, 3) -> (1, 1, 3, 3) (odd case)
3195*da58b97aSjoerg   // and then apply the usual shadow combining logic.
handlePclmulIntrinsic__anonb9e144640811::MemorySanitizerVisitor3196*da58b97aSjoerg   void handlePclmulIntrinsic(IntrinsicInst &I) {
3197*da58b97aSjoerg     IRBuilder<> IRB(&I);
3198*da58b97aSjoerg     unsigned Width =
3199*da58b97aSjoerg         cast<FixedVectorType>(I.getArgOperand(0)->getType())->getNumElements();
3200*da58b97aSjoerg     assert(isa<ConstantInt>(I.getArgOperand(2)) &&
3201*da58b97aSjoerg            "pclmul 3rd operand must be a constant");
3202*da58b97aSjoerg     unsigned Imm = cast<ConstantInt>(I.getArgOperand(2))->getZExtValue();
3203*da58b97aSjoerg     Value *Shuf0 = IRB.CreateShuffleVector(getShadow(&I, 0),
3204*da58b97aSjoerg                                            getPclmulMask(Width, Imm & 0x01));
3205*da58b97aSjoerg     Value *Shuf1 = IRB.CreateShuffleVector(getShadow(&I, 1),
3206*da58b97aSjoerg                                            getPclmulMask(Width, Imm & 0x10));
3207*da58b97aSjoerg     ShadowAndOriginCombiner SOC(this, IRB);
3208*da58b97aSjoerg     SOC.Add(Shuf0, getOrigin(&I, 0));
3209*da58b97aSjoerg     SOC.Add(Shuf1, getOrigin(&I, 1));
3210*da58b97aSjoerg     SOC.Done(&I);
3211*da58b97aSjoerg   }
3212*da58b97aSjoerg 
3213*da58b97aSjoerg   // Instrument _mm_*_sd intrinsics
handleUnarySdIntrinsic__anonb9e144640811::MemorySanitizerVisitor3214*da58b97aSjoerg   void handleUnarySdIntrinsic(IntrinsicInst &I) {
3215*da58b97aSjoerg     IRBuilder<> IRB(&I);
3216*da58b97aSjoerg     Value *First = getShadow(&I, 0);
3217*da58b97aSjoerg     Value *Second = getShadow(&I, 1);
3218*da58b97aSjoerg     // High word of first operand, low word of second
3219*da58b97aSjoerg     Value *Shadow =
3220*da58b97aSjoerg         IRB.CreateShuffleVector(First, Second, llvm::makeArrayRef<int>({2, 1}));
3221*da58b97aSjoerg 
3222*da58b97aSjoerg     setShadow(&I, Shadow);
3223*da58b97aSjoerg     setOriginForNaryOp(I);
3224*da58b97aSjoerg   }
3225*da58b97aSjoerg 
handleBinarySdIntrinsic__anonb9e144640811::MemorySanitizerVisitor3226*da58b97aSjoerg   void handleBinarySdIntrinsic(IntrinsicInst &I) {
3227*da58b97aSjoerg     IRBuilder<> IRB(&I);
3228*da58b97aSjoerg     Value *First = getShadow(&I, 0);
3229*da58b97aSjoerg     Value *Second = getShadow(&I, 1);
3230*da58b97aSjoerg     Value *OrShadow = IRB.CreateOr(First, Second);
3231*da58b97aSjoerg     // High word of first operand, low word of both OR'd together
3232*da58b97aSjoerg     Value *Shadow = IRB.CreateShuffleVector(First, OrShadow,
3233*da58b97aSjoerg                                             llvm::makeArrayRef<int>({2, 1}));
3234*da58b97aSjoerg 
3235*da58b97aSjoerg     setShadow(&I, Shadow);
3236*da58b97aSjoerg     setOriginForNaryOp(I);
3237*da58b97aSjoerg   }
3238*da58b97aSjoerg 
3239*da58b97aSjoerg   // Instrument abs intrinsic.
3240*da58b97aSjoerg   // handleUnknownIntrinsic can't handle it because of the last
3241*da58b97aSjoerg   // is_int_min_poison argument which does not match the result type.
handleAbsIntrinsic__anonb9e144640811::MemorySanitizerVisitor3242*da58b97aSjoerg   void handleAbsIntrinsic(IntrinsicInst &I) {
3243*da58b97aSjoerg     assert(I.getType()->isIntOrIntVectorTy());
3244*da58b97aSjoerg     assert(I.getArgOperand(0)->getType() == I.getType());
3245*da58b97aSjoerg 
3246*da58b97aSjoerg     // FIXME: Handle is_int_min_poison.
3247*da58b97aSjoerg     IRBuilder<> IRB(&I);
3248*da58b97aSjoerg     setShadow(&I, getShadow(&I, 0));
3249*da58b97aSjoerg     setOrigin(&I, getOrigin(&I, 0));
3250*da58b97aSjoerg   }
3251*da58b97aSjoerg 
visitIntrinsicInst__anonb9e144640811::MemorySanitizerVisitor325206f32e7eSjoerg   void visitIntrinsicInst(IntrinsicInst &I) {
325306f32e7eSjoerg     switch (I.getIntrinsicID()) {
3254*da58b97aSjoerg     case Intrinsic::abs:
3255*da58b97aSjoerg       handleAbsIntrinsic(I);
3256*da58b97aSjoerg       break;
325706f32e7eSjoerg     case Intrinsic::lifetime_start:
325806f32e7eSjoerg       handleLifetimeStart(I);
325906f32e7eSjoerg       break;
326006f32e7eSjoerg     case Intrinsic::launder_invariant_group:
326106f32e7eSjoerg     case Intrinsic::strip_invariant_group:
326206f32e7eSjoerg       handleInvariantGroup(I);
326306f32e7eSjoerg       break;
326406f32e7eSjoerg     case Intrinsic::bswap:
326506f32e7eSjoerg       handleBswap(I);
326606f32e7eSjoerg       break;
326706f32e7eSjoerg     case Intrinsic::masked_store:
326806f32e7eSjoerg       handleMaskedStore(I);
326906f32e7eSjoerg       break;
327006f32e7eSjoerg     case Intrinsic::masked_load:
327106f32e7eSjoerg       handleMaskedLoad(I);
327206f32e7eSjoerg       break;
3273*da58b97aSjoerg     case Intrinsic::vector_reduce_and:
3274*da58b97aSjoerg       handleVectorReduceAndIntrinsic(I);
3275*da58b97aSjoerg       break;
3276*da58b97aSjoerg     case Intrinsic::vector_reduce_or:
3277*da58b97aSjoerg       handleVectorReduceOrIntrinsic(I);
3278*da58b97aSjoerg       break;
3279*da58b97aSjoerg     case Intrinsic::vector_reduce_add:
3280*da58b97aSjoerg     case Intrinsic::vector_reduce_xor:
3281*da58b97aSjoerg     case Intrinsic::vector_reduce_mul:
3282*da58b97aSjoerg       handleVectorReduceIntrinsic(I);
3283*da58b97aSjoerg       break;
328406f32e7eSjoerg     case Intrinsic::x86_sse_stmxcsr:
328506f32e7eSjoerg       handleStmxcsr(I);
328606f32e7eSjoerg       break;
328706f32e7eSjoerg     case Intrinsic::x86_sse_ldmxcsr:
328806f32e7eSjoerg       handleLdmxcsr(I);
328906f32e7eSjoerg       break;
329006f32e7eSjoerg     case Intrinsic::x86_avx512_vcvtsd2usi64:
329106f32e7eSjoerg     case Intrinsic::x86_avx512_vcvtsd2usi32:
329206f32e7eSjoerg     case Intrinsic::x86_avx512_vcvtss2usi64:
329306f32e7eSjoerg     case Intrinsic::x86_avx512_vcvtss2usi32:
329406f32e7eSjoerg     case Intrinsic::x86_avx512_cvttss2usi64:
329506f32e7eSjoerg     case Intrinsic::x86_avx512_cvttss2usi:
329606f32e7eSjoerg     case Intrinsic::x86_avx512_cvttsd2usi64:
329706f32e7eSjoerg     case Intrinsic::x86_avx512_cvttsd2usi:
329806f32e7eSjoerg     case Intrinsic::x86_avx512_cvtusi2ss:
329906f32e7eSjoerg     case Intrinsic::x86_avx512_cvtusi642sd:
330006f32e7eSjoerg     case Intrinsic::x86_avx512_cvtusi642ss:
3301*da58b97aSjoerg       handleVectorConvertIntrinsic(I, 1, true);
3302*da58b97aSjoerg       break;
330306f32e7eSjoerg     case Intrinsic::x86_sse2_cvtsd2si64:
330406f32e7eSjoerg     case Intrinsic::x86_sse2_cvtsd2si:
330506f32e7eSjoerg     case Intrinsic::x86_sse2_cvtsd2ss:
330606f32e7eSjoerg     case Intrinsic::x86_sse2_cvttsd2si64:
330706f32e7eSjoerg     case Intrinsic::x86_sse2_cvttsd2si:
330806f32e7eSjoerg     case Intrinsic::x86_sse_cvtss2si64:
330906f32e7eSjoerg     case Intrinsic::x86_sse_cvtss2si:
331006f32e7eSjoerg     case Intrinsic::x86_sse_cvttss2si64:
331106f32e7eSjoerg     case Intrinsic::x86_sse_cvttss2si:
331206f32e7eSjoerg       handleVectorConvertIntrinsic(I, 1);
331306f32e7eSjoerg       break;
331406f32e7eSjoerg     case Intrinsic::x86_sse_cvtps2pi:
331506f32e7eSjoerg     case Intrinsic::x86_sse_cvttps2pi:
331606f32e7eSjoerg       handleVectorConvertIntrinsic(I, 2);
331706f32e7eSjoerg       break;
331806f32e7eSjoerg 
331906f32e7eSjoerg     case Intrinsic::x86_avx512_psll_w_512:
332006f32e7eSjoerg     case Intrinsic::x86_avx512_psll_d_512:
332106f32e7eSjoerg     case Intrinsic::x86_avx512_psll_q_512:
332206f32e7eSjoerg     case Intrinsic::x86_avx512_pslli_w_512:
332306f32e7eSjoerg     case Intrinsic::x86_avx512_pslli_d_512:
332406f32e7eSjoerg     case Intrinsic::x86_avx512_pslli_q_512:
332506f32e7eSjoerg     case Intrinsic::x86_avx512_psrl_w_512:
332606f32e7eSjoerg     case Intrinsic::x86_avx512_psrl_d_512:
332706f32e7eSjoerg     case Intrinsic::x86_avx512_psrl_q_512:
332806f32e7eSjoerg     case Intrinsic::x86_avx512_psra_w_512:
332906f32e7eSjoerg     case Intrinsic::x86_avx512_psra_d_512:
333006f32e7eSjoerg     case Intrinsic::x86_avx512_psra_q_512:
333106f32e7eSjoerg     case Intrinsic::x86_avx512_psrli_w_512:
333206f32e7eSjoerg     case Intrinsic::x86_avx512_psrli_d_512:
333306f32e7eSjoerg     case Intrinsic::x86_avx512_psrli_q_512:
333406f32e7eSjoerg     case Intrinsic::x86_avx512_psrai_w_512:
333506f32e7eSjoerg     case Intrinsic::x86_avx512_psrai_d_512:
333606f32e7eSjoerg     case Intrinsic::x86_avx512_psrai_q_512:
333706f32e7eSjoerg     case Intrinsic::x86_avx512_psra_q_256:
333806f32e7eSjoerg     case Intrinsic::x86_avx512_psra_q_128:
333906f32e7eSjoerg     case Intrinsic::x86_avx512_psrai_q_256:
334006f32e7eSjoerg     case Intrinsic::x86_avx512_psrai_q_128:
334106f32e7eSjoerg     case Intrinsic::x86_avx2_psll_w:
334206f32e7eSjoerg     case Intrinsic::x86_avx2_psll_d:
334306f32e7eSjoerg     case Intrinsic::x86_avx2_psll_q:
334406f32e7eSjoerg     case Intrinsic::x86_avx2_pslli_w:
334506f32e7eSjoerg     case Intrinsic::x86_avx2_pslli_d:
334606f32e7eSjoerg     case Intrinsic::x86_avx2_pslli_q:
334706f32e7eSjoerg     case Intrinsic::x86_avx2_psrl_w:
334806f32e7eSjoerg     case Intrinsic::x86_avx2_psrl_d:
334906f32e7eSjoerg     case Intrinsic::x86_avx2_psrl_q:
335006f32e7eSjoerg     case Intrinsic::x86_avx2_psra_w:
335106f32e7eSjoerg     case Intrinsic::x86_avx2_psra_d:
335206f32e7eSjoerg     case Intrinsic::x86_avx2_psrli_w:
335306f32e7eSjoerg     case Intrinsic::x86_avx2_psrli_d:
335406f32e7eSjoerg     case Intrinsic::x86_avx2_psrli_q:
335506f32e7eSjoerg     case Intrinsic::x86_avx2_psrai_w:
335606f32e7eSjoerg     case Intrinsic::x86_avx2_psrai_d:
335706f32e7eSjoerg     case Intrinsic::x86_sse2_psll_w:
335806f32e7eSjoerg     case Intrinsic::x86_sse2_psll_d:
335906f32e7eSjoerg     case Intrinsic::x86_sse2_psll_q:
336006f32e7eSjoerg     case Intrinsic::x86_sse2_pslli_w:
336106f32e7eSjoerg     case Intrinsic::x86_sse2_pslli_d:
336206f32e7eSjoerg     case Intrinsic::x86_sse2_pslli_q:
336306f32e7eSjoerg     case Intrinsic::x86_sse2_psrl_w:
336406f32e7eSjoerg     case Intrinsic::x86_sse2_psrl_d:
336506f32e7eSjoerg     case Intrinsic::x86_sse2_psrl_q:
336606f32e7eSjoerg     case Intrinsic::x86_sse2_psra_w:
336706f32e7eSjoerg     case Intrinsic::x86_sse2_psra_d:
336806f32e7eSjoerg     case Intrinsic::x86_sse2_psrli_w:
336906f32e7eSjoerg     case Intrinsic::x86_sse2_psrli_d:
337006f32e7eSjoerg     case Intrinsic::x86_sse2_psrli_q:
337106f32e7eSjoerg     case Intrinsic::x86_sse2_psrai_w:
337206f32e7eSjoerg     case Intrinsic::x86_sse2_psrai_d:
337306f32e7eSjoerg     case Intrinsic::x86_mmx_psll_w:
337406f32e7eSjoerg     case Intrinsic::x86_mmx_psll_d:
337506f32e7eSjoerg     case Intrinsic::x86_mmx_psll_q:
337606f32e7eSjoerg     case Intrinsic::x86_mmx_pslli_w:
337706f32e7eSjoerg     case Intrinsic::x86_mmx_pslli_d:
337806f32e7eSjoerg     case Intrinsic::x86_mmx_pslli_q:
337906f32e7eSjoerg     case Intrinsic::x86_mmx_psrl_w:
338006f32e7eSjoerg     case Intrinsic::x86_mmx_psrl_d:
338106f32e7eSjoerg     case Intrinsic::x86_mmx_psrl_q:
338206f32e7eSjoerg     case Intrinsic::x86_mmx_psra_w:
338306f32e7eSjoerg     case Intrinsic::x86_mmx_psra_d:
338406f32e7eSjoerg     case Intrinsic::x86_mmx_psrli_w:
338506f32e7eSjoerg     case Intrinsic::x86_mmx_psrli_d:
338606f32e7eSjoerg     case Intrinsic::x86_mmx_psrli_q:
338706f32e7eSjoerg     case Intrinsic::x86_mmx_psrai_w:
338806f32e7eSjoerg     case Intrinsic::x86_mmx_psrai_d:
338906f32e7eSjoerg       handleVectorShiftIntrinsic(I, /* Variable */ false);
339006f32e7eSjoerg       break;
339106f32e7eSjoerg     case Intrinsic::x86_avx2_psllv_d:
339206f32e7eSjoerg     case Intrinsic::x86_avx2_psllv_d_256:
339306f32e7eSjoerg     case Intrinsic::x86_avx512_psllv_d_512:
339406f32e7eSjoerg     case Intrinsic::x86_avx2_psllv_q:
339506f32e7eSjoerg     case Intrinsic::x86_avx2_psllv_q_256:
339606f32e7eSjoerg     case Intrinsic::x86_avx512_psllv_q_512:
339706f32e7eSjoerg     case Intrinsic::x86_avx2_psrlv_d:
339806f32e7eSjoerg     case Intrinsic::x86_avx2_psrlv_d_256:
339906f32e7eSjoerg     case Intrinsic::x86_avx512_psrlv_d_512:
340006f32e7eSjoerg     case Intrinsic::x86_avx2_psrlv_q:
340106f32e7eSjoerg     case Intrinsic::x86_avx2_psrlv_q_256:
340206f32e7eSjoerg     case Intrinsic::x86_avx512_psrlv_q_512:
340306f32e7eSjoerg     case Intrinsic::x86_avx2_psrav_d:
340406f32e7eSjoerg     case Intrinsic::x86_avx2_psrav_d_256:
340506f32e7eSjoerg     case Intrinsic::x86_avx512_psrav_d_512:
340606f32e7eSjoerg     case Intrinsic::x86_avx512_psrav_q_128:
340706f32e7eSjoerg     case Intrinsic::x86_avx512_psrav_q_256:
340806f32e7eSjoerg     case Intrinsic::x86_avx512_psrav_q_512:
340906f32e7eSjoerg       handleVectorShiftIntrinsic(I, /* Variable */ true);
341006f32e7eSjoerg       break;
341106f32e7eSjoerg 
341206f32e7eSjoerg     case Intrinsic::x86_sse2_packsswb_128:
341306f32e7eSjoerg     case Intrinsic::x86_sse2_packssdw_128:
341406f32e7eSjoerg     case Intrinsic::x86_sse2_packuswb_128:
341506f32e7eSjoerg     case Intrinsic::x86_sse41_packusdw:
341606f32e7eSjoerg     case Intrinsic::x86_avx2_packsswb:
341706f32e7eSjoerg     case Intrinsic::x86_avx2_packssdw:
341806f32e7eSjoerg     case Intrinsic::x86_avx2_packuswb:
341906f32e7eSjoerg     case Intrinsic::x86_avx2_packusdw:
342006f32e7eSjoerg       handleVectorPackIntrinsic(I);
342106f32e7eSjoerg       break;
342206f32e7eSjoerg 
342306f32e7eSjoerg     case Intrinsic::x86_mmx_packsswb:
342406f32e7eSjoerg     case Intrinsic::x86_mmx_packuswb:
342506f32e7eSjoerg       handleVectorPackIntrinsic(I, 16);
342606f32e7eSjoerg       break;
342706f32e7eSjoerg 
342806f32e7eSjoerg     case Intrinsic::x86_mmx_packssdw:
342906f32e7eSjoerg       handleVectorPackIntrinsic(I, 32);
343006f32e7eSjoerg       break;
343106f32e7eSjoerg 
343206f32e7eSjoerg     case Intrinsic::x86_mmx_psad_bw:
343306f32e7eSjoerg     case Intrinsic::x86_sse2_psad_bw:
343406f32e7eSjoerg     case Intrinsic::x86_avx2_psad_bw:
343506f32e7eSjoerg       handleVectorSadIntrinsic(I);
343606f32e7eSjoerg       break;
343706f32e7eSjoerg 
343806f32e7eSjoerg     case Intrinsic::x86_sse2_pmadd_wd:
343906f32e7eSjoerg     case Intrinsic::x86_avx2_pmadd_wd:
344006f32e7eSjoerg     case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
344106f32e7eSjoerg     case Intrinsic::x86_avx2_pmadd_ub_sw:
344206f32e7eSjoerg       handleVectorPmaddIntrinsic(I);
344306f32e7eSjoerg       break;
344406f32e7eSjoerg 
344506f32e7eSjoerg     case Intrinsic::x86_ssse3_pmadd_ub_sw:
344606f32e7eSjoerg       handleVectorPmaddIntrinsic(I, 8);
344706f32e7eSjoerg       break;
344806f32e7eSjoerg 
344906f32e7eSjoerg     case Intrinsic::x86_mmx_pmadd_wd:
345006f32e7eSjoerg       handleVectorPmaddIntrinsic(I, 16);
345106f32e7eSjoerg       break;
345206f32e7eSjoerg 
345306f32e7eSjoerg     case Intrinsic::x86_sse_cmp_ss:
345406f32e7eSjoerg     case Intrinsic::x86_sse2_cmp_sd:
345506f32e7eSjoerg     case Intrinsic::x86_sse_comieq_ss:
345606f32e7eSjoerg     case Intrinsic::x86_sse_comilt_ss:
345706f32e7eSjoerg     case Intrinsic::x86_sse_comile_ss:
345806f32e7eSjoerg     case Intrinsic::x86_sse_comigt_ss:
345906f32e7eSjoerg     case Intrinsic::x86_sse_comige_ss:
346006f32e7eSjoerg     case Intrinsic::x86_sse_comineq_ss:
346106f32e7eSjoerg     case Intrinsic::x86_sse_ucomieq_ss:
346206f32e7eSjoerg     case Intrinsic::x86_sse_ucomilt_ss:
346306f32e7eSjoerg     case Intrinsic::x86_sse_ucomile_ss:
346406f32e7eSjoerg     case Intrinsic::x86_sse_ucomigt_ss:
346506f32e7eSjoerg     case Intrinsic::x86_sse_ucomige_ss:
346606f32e7eSjoerg     case Intrinsic::x86_sse_ucomineq_ss:
346706f32e7eSjoerg     case Intrinsic::x86_sse2_comieq_sd:
346806f32e7eSjoerg     case Intrinsic::x86_sse2_comilt_sd:
346906f32e7eSjoerg     case Intrinsic::x86_sse2_comile_sd:
347006f32e7eSjoerg     case Intrinsic::x86_sse2_comigt_sd:
347106f32e7eSjoerg     case Intrinsic::x86_sse2_comige_sd:
347206f32e7eSjoerg     case Intrinsic::x86_sse2_comineq_sd:
347306f32e7eSjoerg     case Intrinsic::x86_sse2_ucomieq_sd:
347406f32e7eSjoerg     case Intrinsic::x86_sse2_ucomilt_sd:
347506f32e7eSjoerg     case Intrinsic::x86_sse2_ucomile_sd:
347606f32e7eSjoerg     case Intrinsic::x86_sse2_ucomigt_sd:
347706f32e7eSjoerg     case Intrinsic::x86_sse2_ucomige_sd:
347806f32e7eSjoerg     case Intrinsic::x86_sse2_ucomineq_sd:
347906f32e7eSjoerg       handleVectorCompareScalarIntrinsic(I);
348006f32e7eSjoerg       break;
348106f32e7eSjoerg 
348206f32e7eSjoerg     case Intrinsic::x86_sse_cmp_ps:
348306f32e7eSjoerg     case Intrinsic::x86_sse2_cmp_pd:
348406f32e7eSjoerg       // FIXME: For x86_avx_cmp_pd_256 and x86_avx_cmp_ps_256 this function
348506f32e7eSjoerg       // generates reasonably looking IR that fails in the backend with "Do not
348606f32e7eSjoerg       // know how to split the result of this operator!".
348706f32e7eSjoerg       handleVectorComparePackedIntrinsic(I);
348806f32e7eSjoerg       break;
348906f32e7eSjoerg 
349006f32e7eSjoerg     case Intrinsic::x86_bmi_bextr_32:
349106f32e7eSjoerg     case Intrinsic::x86_bmi_bextr_64:
349206f32e7eSjoerg     case Intrinsic::x86_bmi_bzhi_32:
349306f32e7eSjoerg     case Intrinsic::x86_bmi_bzhi_64:
349406f32e7eSjoerg     case Intrinsic::x86_bmi_pdep_32:
349506f32e7eSjoerg     case Intrinsic::x86_bmi_pdep_64:
349606f32e7eSjoerg     case Intrinsic::x86_bmi_pext_32:
349706f32e7eSjoerg     case Intrinsic::x86_bmi_pext_64:
349806f32e7eSjoerg       handleBmiIntrinsic(I);
349906f32e7eSjoerg       break;
350006f32e7eSjoerg 
3501*da58b97aSjoerg     case Intrinsic::x86_pclmulqdq:
3502*da58b97aSjoerg     case Intrinsic::x86_pclmulqdq_256:
3503*da58b97aSjoerg     case Intrinsic::x86_pclmulqdq_512:
3504*da58b97aSjoerg       handlePclmulIntrinsic(I);
3505*da58b97aSjoerg       break;
3506*da58b97aSjoerg 
3507*da58b97aSjoerg     case Intrinsic::x86_sse41_round_sd:
3508*da58b97aSjoerg       handleUnarySdIntrinsic(I);
3509*da58b97aSjoerg       break;
3510*da58b97aSjoerg     case Intrinsic::x86_sse2_max_sd:
3511*da58b97aSjoerg     case Intrinsic::x86_sse2_min_sd:
3512*da58b97aSjoerg       handleBinarySdIntrinsic(I);
3513*da58b97aSjoerg       break;
3514*da58b97aSjoerg 
351506f32e7eSjoerg     case Intrinsic::is_constant:
351606f32e7eSjoerg       // The result of llvm.is.constant() is always defined.
351706f32e7eSjoerg       setShadow(&I, getCleanShadow(&I));
351806f32e7eSjoerg       setOrigin(&I, getCleanOrigin());
351906f32e7eSjoerg       break;
352006f32e7eSjoerg 
352106f32e7eSjoerg     default:
352206f32e7eSjoerg       if (!handleUnknownIntrinsic(I))
352306f32e7eSjoerg         visitInstruction(I);
352406f32e7eSjoerg       break;
352506f32e7eSjoerg     }
352606f32e7eSjoerg   }
352706f32e7eSjoerg 
visitLibAtomicLoad__anonb9e144640811::MemorySanitizerVisitor3528*da58b97aSjoerg   void visitLibAtomicLoad(CallBase &CB) {
3529*da58b97aSjoerg     // Since we use getNextNode here, we can't have CB terminate the BB.
3530*da58b97aSjoerg     assert(isa<CallInst>(CB));
3531*da58b97aSjoerg 
3532*da58b97aSjoerg     IRBuilder<> IRB(&CB);
3533*da58b97aSjoerg     Value *Size = CB.getArgOperand(0);
3534*da58b97aSjoerg     Value *SrcPtr = CB.getArgOperand(1);
3535*da58b97aSjoerg     Value *DstPtr = CB.getArgOperand(2);
3536*da58b97aSjoerg     Value *Ordering = CB.getArgOperand(3);
3537*da58b97aSjoerg     // Convert the call to have at least Acquire ordering to make sure
3538*da58b97aSjoerg     // the shadow operations aren't reordered before it.
3539*da58b97aSjoerg     Value *NewOrdering =
3540*da58b97aSjoerg         IRB.CreateExtractElement(makeAddAcquireOrderingTable(IRB), Ordering);
3541*da58b97aSjoerg     CB.setArgOperand(3, NewOrdering);
3542*da58b97aSjoerg 
3543*da58b97aSjoerg     IRBuilder<> NextIRB(CB.getNextNode());
3544*da58b97aSjoerg     NextIRB.SetCurrentDebugLocation(CB.getDebugLoc());
3545*da58b97aSjoerg 
3546*da58b97aSjoerg     Value *SrcShadowPtr, *SrcOriginPtr;
3547*da58b97aSjoerg     std::tie(SrcShadowPtr, SrcOriginPtr) =
3548*da58b97aSjoerg         getShadowOriginPtr(SrcPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
3549*da58b97aSjoerg                            /*isStore*/ false);
3550*da58b97aSjoerg     Value *DstShadowPtr =
3551*da58b97aSjoerg         getShadowOriginPtr(DstPtr, NextIRB, NextIRB.getInt8Ty(), Align(1),
3552*da58b97aSjoerg                            /*isStore*/ true)
3553*da58b97aSjoerg             .first;
3554*da58b97aSjoerg 
3555*da58b97aSjoerg     NextIRB.CreateMemCpy(DstShadowPtr, Align(1), SrcShadowPtr, Align(1), Size);
3556*da58b97aSjoerg     if (MS.TrackOrigins) {
3557*da58b97aSjoerg       Value *SrcOrigin = NextIRB.CreateAlignedLoad(MS.OriginTy, SrcOriginPtr,
3558*da58b97aSjoerg                                                    kMinOriginAlignment);
3559*da58b97aSjoerg       Value *NewOrigin = updateOrigin(SrcOrigin, NextIRB);
3560*da58b97aSjoerg       NextIRB.CreateCall(MS.MsanSetOriginFn, {DstPtr, Size, NewOrigin});
3561*da58b97aSjoerg     }
3562*da58b97aSjoerg   }
3563*da58b97aSjoerg 
visitLibAtomicStore__anonb9e144640811::MemorySanitizerVisitor3564*da58b97aSjoerg   void visitLibAtomicStore(CallBase &CB) {
3565*da58b97aSjoerg     IRBuilder<> IRB(&CB);
3566*da58b97aSjoerg     Value *Size = CB.getArgOperand(0);
3567*da58b97aSjoerg     Value *DstPtr = CB.getArgOperand(2);
3568*da58b97aSjoerg     Value *Ordering = CB.getArgOperand(3);
3569*da58b97aSjoerg     // Convert the call to have at least Release ordering to make sure
3570*da58b97aSjoerg     // the shadow operations aren't reordered after it.
3571*da58b97aSjoerg     Value *NewOrdering =
3572*da58b97aSjoerg         IRB.CreateExtractElement(makeAddReleaseOrderingTable(IRB), Ordering);
3573*da58b97aSjoerg     CB.setArgOperand(3, NewOrdering);
3574*da58b97aSjoerg 
3575*da58b97aSjoerg     Value *DstShadowPtr =
3576*da58b97aSjoerg         getShadowOriginPtr(DstPtr, IRB, IRB.getInt8Ty(), Align(1),
3577*da58b97aSjoerg                            /*isStore*/ true)
3578*da58b97aSjoerg             .first;
3579*da58b97aSjoerg 
3580*da58b97aSjoerg     // Atomic store always paints clean shadow/origin. See file header.
3581*da58b97aSjoerg     IRB.CreateMemSet(DstShadowPtr, getCleanShadow(IRB.getInt8Ty()), Size,
3582*da58b97aSjoerg                      Align(1));
3583*da58b97aSjoerg   }
3584*da58b97aSjoerg 
visitCallBase__anonb9e144640811::MemorySanitizerVisitor3585*da58b97aSjoerg   void visitCallBase(CallBase &CB) {
3586*da58b97aSjoerg     assert(!CB.getMetadata("nosanitize"));
3587*da58b97aSjoerg     if (CB.isInlineAsm()) {
358806f32e7eSjoerg       // For inline asm (either a call to asm function, or callbr instruction),
358906f32e7eSjoerg       // do the usual thing: check argument shadow and mark all outputs as
359006f32e7eSjoerg       // clean. Note that any side effects of the inline asm that are not
359106f32e7eSjoerg       // immediately visible in its constraints are not handled.
359206f32e7eSjoerg       if (ClHandleAsmConservative && MS.CompileKernel)
3593*da58b97aSjoerg         visitAsmInstruction(CB);
359406f32e7eSjoerg       else
3595*da58b97aSjoerg         visitInstruction(CB);
359606f32e7eSjoerg       return;
359706f32e7eSjoerg     }
3598*da58b97aSjoerg     LibFunc LF;
3599*da58b97aSjoerg     if (TLI->getLibFunc(CB, LF)) {
3600*da58b97aSjoerg       // libatomic.a functions need to have special handling because there isn't
3601*da58b97aSjoerg       // a good way to intercept them or compile the library with
3602*da58b97aSjoerg       // instrumentation.
3603*da58b97aSjoerg       switch (LF) {
3604*da58b97aSjoerg       case LibFunc_atomic_load:
3605*da58b97aSjoerg         if (!isa<CallInst>(CB)) {
3606*da58b97aSjoerg           llvm::errs() << "MSAN -- cannot instrument invoke of libatomic load."
3607*da58b97aSjoerg                           "Ignoring!\n";
3608*da58b97aSjoerg           break;
3609*da58b97aSjoerg         }
3610*da58b97aSjoerg         visitLibAtomicLoad(CB);
3611*da58b97aSjoerg         return;
3612*da58b97aSjoerg       case LibFunc_atomic_store:
3613*da58b97aSjoerg         visitLibAtomicStore(CB);
3614*da58b97aSjoerg         return;
3615*da58b97aSjoerg       default:
3616*da58b97aSjoerg         break;
3617*da58b97aSjoerg       }
3618*da58b97aSjoerg     }
3619*da58b97aSjoerg 
3620*da58b97aSjoerg     if (auto *Call = dyn_cast<CallInst>(&CB)) {
3621*da58b97aSjoerg       assert(!isa<IntrinsicInst>(Call) && "intrinsics are handled elsewhere");
362206f32e7eSjoerg 
362306f32e7eSjoerg       // We are going to insert code that relies on the fact that the callee
362406f32e7eSjoerg       // will become a non-readonly function after it is instrumented by us. To
362506f32e7eSjoerg       // prevent this code from being optimized out, mark that function
362606f32e7eSjoerg       // non-readonly in advance.
362706f32e7eSjoerg       AttrBuilder B;
362806f32e7eSjoerg       B.addAttribute(Attribute::ReadOnly)
3629*da58b97aSjoerg           .addAttribute(Attribute::ReadNone)
3630*da58b97aSjoerg           .addAttribute(Attribute::WriteOnly)
3631*da58b97aSjoerg           .addAttribute(Attribute::ArgMemOnly)
3632*da58b97aSjoerg           .addAttribute(Attribute::Speculatable);
3633*da58b97aSjoerg 
3634*da58b97aSjoerg       Call->removeAttributes(AttributeList::FunctionIndex, B);
3635*da58b97aSjoerg       if (Function *Func = Call->getCalledFunction()) {
363606f32e7eSjoerg         Func->removeAttributes(AttributeList::FunctionIndex, B);
363706f32e7eSjoerg       }
363806f32e7eSjoerg 
363906f32e7eSjoerg       maybeMarkSanitizerLibraryCallNoBuiltin(Call, TLI);
364006f32e7eSjoerg     }
3641*da58b97aSjoerg     IRBuilder<> IRB(&CB);
3642*da58b97aSjoerg     bool MayCheckCall = ClEagerChecks;
3643*da58b97aSjoerg     if (Function *Func = CB.getCalledFunction()) {
3644*da58b97aSjoerg       // __sanitizer_unaligned_{load,store} functions may be called by users
3645*da58b97aSjoerg       // and always expects shadows in the TLS. So don't check them.
3646*da58b97aSjoerg       MayCheckCall &= !Func->getName().startswith("__sanitizer_unaligned_");
3647*da58b97aSjoerg     }
364806f32e7eSjoerg 
364906f32e7eSjoerg     unsigned ArgOffset = 0;
3650*da58b97aSjoerg     LLVM_DEBUG(dbgs() << "  CallSite: " << CB << "\n");
3651*da58b97aSjoerg     for (auto ArgIt = CB.arg_begin(), End = CB.arg_end(); ArgIt != End;
3652*da58b97aSjoerg          ++ArgIt) {
365306f32e7eSjoerg       Value *A = *ArgIt;
3654*da58b97aSjoerg       unsigned i = ArgIt - CB.arg_begin();
365506f32e7eSjoerg       if (!A->getType()->isSized()) {
3656*da58b97aSjoerg         LLVM_DEBUG(dbgs() << "Arg " << i << " is not sized: " << CB << "\n");
365706f32e7eSjoerg         continue;
365806f32e7eSjoerg       }
365906f32e7eSjoerg       unsigned Size = 0;
366006f32e7eSjoerg       Value *Store = nullptr;
366106f32e7eSjoerg       // Compute the Shadow for arg even if it is ByVal, because
366206f32e7eSjoerg       // in that case getShadow() will copy the actual arg shadow to
366306f32e7eSjoerg       // __msan_param_tls.
366406f32e7eSjoerg       Value *ArgShadow = getShadow(A);
366506f32e7eSjoerg       Value *ArgShadowBase = getShadowPtrForArgument(A, IRB, ArgOffset);
366606f32e7eSjoerg       LLVM_DEBUG(dbgs() << "  Arg#" << i << ": " << *A
366706f32e7eSjoerg                         << " Shadow: " << *ArgShadow << "\n");
366806f32e7eSjoerg       bool ArgIsInitialized = false;
366906f32e7eSjoerg       const DataLayout &DL = F.getParent()->getDataLayout();
3670*da58b97aSjoerg 
3671*da58b97aSjoerg       bool ByVal = CB.paramHasAttr(i, Attribute::ByVal);
3672*da58b97aSjoerg       bool NoUndef = CB.paramHasAttr(i, Attribute::NoUndef);
3673*da58b97aSjoerg       bool EagerCheck = MayCheckCall && !ByVal && NoUndef;
3674*da58b97aSjoerg 
3675*da58b97aSjoerg       if (EagerCheck) {
3676*da58b97aSjoerg         insertShadowCheck(A, &CB);
3677*da58b97aSjoerg         continue;
3678*da58b97aSjoerg       }
3679*da58b97aSjoerg       if (ByVal) {
3680*da58b97aSjoerg         // ByVal requires some special handling as it's too big for a single
3681*da58b97aSjoerg         // load
368206f32e7eSjoerg         assert(A->getType()->isPointerTy() &&
368306f32e7eSjoerg                "ByVal argument is not a pointer!");
3684*da58b97aSjoerg         Size = DL.getTypeAllocSize(CB.getParamByValType(i));
368506f32e7eSjoerg         if (ArgOffset + Size > kParamTLSSize) break;
3686*da58b97aSjoerg         const MaybeAlign ParamAlignment(CB.getParamAlign(i));
3687*da58b97aSjoerg         MaybeAlign Alignment = llvm::None;
3688*da58b97aSjoerg         if (ParamAlignment)
3689*da58b97aSjoerg           Alignment = std::min(*ParamAlignment, kShadowTLSAlignment);
369006f32e7eSjoerg         Value *AShadowPtr =
369106f32e7eSjoerg             getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), Alignment,
369206f32e7eSjoerg                                /*isStore*/ false)
369306f32e7eSjoerg                 .first;
369406f32e7eSjoerg 
369506f32e7eSjoerg         Store = IRB.CreateMemCpy(ArgShadowBase, Alignment, AShadowPtr,
369606f32e7eSjoerg                                  Alignment, Size);
369706f32e7eSjoerg         // TODO(glider): need to copy origins.
369806f32e7eSjoerg       } else {
3699*da58b97aSjoerg         // Any other parameters mean we need bit-grained tracking of uninit data
370006f32e7eSjoerg         Size = DL.getTypeAllocSize(A->getType());
370106f32e7eSjoerg         if (ArgOffset + Size > kParamTLSSize) break;
370206f32e7eSjoerg         Store = IRB.CreateAlignedStore(ArgShadow, ArgShadowBase,
370306f32e7eSjoerg                                        kShadowTLSAlignment);
370406f32e7eSjoerg         Constant *Cst = dyn_cast<Constant>(ArgShadow);
370506f32e7eSjoerg         if (Cst && Cst->isNullValue()) ArgIsInitialized = true;
370606f32e7eSjoerg       }
370706f32e7eSjoerg       if (MS.TrackOrigins && !ArgIsInitialized)
370806f32e7eSjoerg         IRB.CreateStore(getOrigin(A),
370906f32e7eSjoerg                         getOriginPtrForArgument(A, IRB, ArgOffset));
371006f32e7eSjoerg       (void)Store;
371106f32e7eSjoerg       assert(Size != 0 && Store != nullptr);
371206f32e7eSjoerg       LLVM_DEBUG(dbgs() << "  Param:" << *Store << "\n");
3713*da58b97aSjoerg       ArgOffset += alignTo(Size, kShadowTLSAlignment);
371406f32e7eSjoerg     }
371506f32e7eSjoerg     LLVM_DEBUG(dbgs() << "  done with call args\n");
371606f32e7eSjoerg 
3717*da58b97aSjoerg     FunctionType *FT = CB.getFunctionType();
371806f32e7eSjoerg     if (FT->isVarArg()) {
3719*da58b97aSjoerg       VAHelper->visitCallBase(CB, IRB);
372006f32e7eSjoerg     }
372106f32e7eSjoerg 
372206f32e7eSjoerg     // Now, get the shadow for the RetVal.
3723*da58b97aSjoerg     if (!CB.getType()->isSized())
3724*da58b97aSjoerg       return;
372506f32e7eSjoerg     // Don't emit the epilogue for musttail call returns.
3726*da58b97aSjoerg     if (isa<CallInst>(CB) && cast<CallInst>(CB).isMustTailCall())
3727*da58b97aSjoerg       return;
3728*da58b97aSjoerg 
3729*da58b97aSjoerg     if (MayCheckCall && CB.hasRetAttr(Attribute::NoUndef)) {
3730*da58b97aSjoerg       setShadow(&CB, getCleanShadow(&CB));
3731*da58b97aSjoerg       setOrigin(&CB, getCleanOrigin());
3732*da58b97aSjoerg       return;
3733*da58b97aSjoerg     }
3734*da58b97aSjoerg 
3735*da58b97aSjoerg     IRBuilder<> IRBBefore(&CB);
373606f32e7eSjoerg     // Until we have full dynamic coverage, make sure the retval shadow is 0.
3737*da58b97aSjoerg     Value *Base = getShadowPtrForRetval(&CB, IRBBefore);
3738*da58b97aSjoerg     IRBBefore.CreateAlignedStore(getCleanShadow(&CB), Base,
3739*da58b97aSjoerg                                  kShadowTLSAlignment);
374006f32e7eSjoerg     BasicBlock::iterator NextInsn;
3741*da58b97aSjoerg     if (isa<CallInst>(CB)) {
3742*da58b97aSjoerg       NextInsn = ++CB.getIterator();
3743*da58b97aSjoerg       assert(NextInsn != CB.getParent()->end());
374406f32e7eSjoerg     } else {
3745*da58b97aSjoerg       BasicBlock *NormalDest = cast<InvokeInst>(CB).getNormalDest();
374606f32e7eSjoerg       if (!NormalDest->getSinglePredecessor()) {
374706f32e7eSjoerg         // FIXME: this case is tricky, so we are just conservative here.
374806f32e7eSjoerg         // Perhaps we need to split the edge between this BB and NormalDest,
374906f32e7eSjoerg         // but a naive attempt to use SplitEdge leads to a crash.
3750*da58b97aSjoerg         setShadow(&CB, getCleanShadow(&CB));
3751*da58b97aSjoerg         setOrigin(&CB, getCleanOrigin());
375206f32e7eSjoerg         return;
375306f32e7eSjoerg       }
375406f32e7eSjoerg       // FIXME: NextInsn is likely in a basic block that has not been visited yet.
375506f32e7eSjoerg       // Anything inserted there will be instrumented by MSan later!
375606f32e7eSjoerg       NextInsn = NormalDest->getFirstInsertionPt();
375706f32e7eSjoerg       assert(NextInsn != NormalDest->end() &&
375806f32e7eSjoerg              "Could not find insertion point for retval shadow load");
375906f32e7eSjoerg     }
376006f32e7eSjoerg     IRBuilder<> IRBAfter(&*NextInsn);
376106f32e7eSjoerg     Value *RetvalShadow = IRBAfter.CreateAlignedLoad(
3762*da58b97aSjoerg         getShadowTy(&CB), getShadowPtrForRetval(&CB, IRBAfter),
376306f32e7eSjoerg         kShadowTLSAlignment, "_msret");
3764*da58b97aSjoerg     setShadow(&CB, RetvalShadow);
376506f32e7eSjoerg     if (MS.TrackOrigins)
3766*da58b97aSjoerg       setOrigin(&CB, IRBAfter.CreateLoad(MS.OriginTy,
376706f32e7eSjoerg                                          getOriginPtrForRetval(IRBAfter)));
376806f32e7eSjoerg   }
376906f32e7eSjoerg 
isAMustTailRetVal__anonb9e144640811::MemorySanitizerVisitor377006f32e7eSjoerg   bool isAMustTailRetVal(Value *RetVal) {
377106f32e7eSjoerg     if (auto *I = dyn_cast<BitCastInst>(RetVal)) {
377206f32e7eSjoerg       RetVal = I->getOperand(0);
377306f32e7eSjoerg     }
377406f32e7eSjoerg     if (auto *I = dyn_cast<CallInst>(RetVal)) {
377506f32e7eSjoerg       return I->isMustTailCall();
377606f32e7eSjoerg     }
377706f32e7eSjoerg     return false;
377806f32e7eSjoerg   }
377906f32e7eSjoerg 
visitReturnInst__anonb9e144640811::MemorySanitizerVisitor378006f32e7eSjoerg   void visitReturnInst(ReturnInst &I) {
378106f32e7eSjoerg     IRBuilder<> IRB(&I);
378206f32e7eSjoerg     Value *RetVal = I.getReturnValue();
378306f32e7eSjoerg     if (!RetVal) return;
378406f32e7eSjoerg     // Don't emit the epilogue for musttail call returns.
378506f32e7eSjoerg     if (isAMustTailRetVal(RetVal)) return;
378606f32e7eSjoerg     Value *ShadowPtr = getShadowPtrForRetval(RetVal, IRB);
3787*da58b97aSjoerg     bool HasNoUndef =
3788*da58b97aSjoerg         F.hasAttribute(AttributeList::ReturnIndex, Attribute::NoUndef);
3789*da58b97aSjoerg     bool StoreShadow = !(ClEagerChecks && HasNoUndef);
3790*da58b97aSjoerg     // FIXME: Consider using SpecialCaseList to specify a list of functions that
3791*da58b97aSjoerg     // must always return fully initialized values. For now, we hardcode "main".
3792*da58b97aSjoerg     bool EagerCheck = (ClEagerChecks && HasNoUndef) || (F.getName() == "main");
3793*da58b97aSjoerg 
379406f32e7eSjoerg     Value *Shadow = getShadow(RetVal);
3795*da58b97aSjoerg     bool StoreOrigin = true;
3796*da58b97aSjoerg     if (EagerCheck) {
3797*da58b97aSjoerg       insertShadowCheck(RetVal, &I);
3798*da58b97aSjoerg       Shadow = getCleanShadow(RetVal);
3799*da58b97aSjoerg       StoreOrigin = false;
3800*da58b97aSjoerg     }
3801*da58b97aSjoerg 
3802*da58b97aSjoerg     // The caller may still expect information passed over TLS if we pass our
3803*da58b97aSjoerg     // check
3804*da58b97aSjoerg     if (StoreShadow) {
380506f32e7eSjoerg       IRB.CreateAlignedStore(Shadow, ShadowPtr, kShadowTLSAlignment);
3806*da58b97aSjoerg       if (MS.TrackOrigins && StoreOrigin)
380706f32e7eSjoerg         IRB.CreateStore(getOrigin(RetVal), getOriginPtrForRetval(IRB));
380806f32e7eSjoerg     }
380906f32e7eSjoerg   }
381006f32e7eSjoerg 
visitPHINode__anonb9e144640811::MemorySanitizerVisitor381106f32e7eSjoerg   void visitPHINode(PHINode &I) {
381206f32e7eSjoerg     IRBuilder<> IRB(&I);
381306f32e7eSjoerg     if (!PropagateShadow) {
381406f32e7eSjoerg       setShadow(&I, getCleanShadow(&I));
381506f32e7eSjoerg       setOrigin(&I, getCleanOrigin());
381606f32e7eSjoerg       return;
381706f32e7eSjoerg     }
381806f32e7eSjoerg 
381906f32e7eSjoerg     ShadowPHINodes.push_back(&I);
382006f32e7eSjoerg     setShadow(&I, IRB.CreatePHI(getShadowTy(&I), I.getNumIncomingValues(),
382106f32e7eSjoerg                                 "_msphi_s"));
382206f32e7eSjoerg     if (MS.TrackOrigins)
382306f32e7eSjoerg       setOrigin(&I, IRB.CreatePHI(MS.OriginTy, I.getNumIncomingValues(),
382406f32e7eSjoerg                                   "_msphi_o"));
382506f32e7eSjoerg   }
382606f32e7eSjoerg 
getLocalVarDescription__anonb9e144640811::MemorySanitizerVisitor382706f32e7eSjoerg   Value *getLocalVarDescription(AllocaInst &I) {
382806f32e7eSjoerg     SmallString<2048> StackDescriptionStorage;
382906f32e7eSjoerg     raw_svector_ostream StackDescription(StackDescriptionStorage);
383006f32e7eSjoerg     // We create a string with a description of the stack allocation and
383106f32e7eSjoerg     // pass it into __msan_set_alloca_origin.
383206f32e7eSjoerg     // It will be printed by the run-time if stack-originated UMR is found.
383306f32e7eSjoerg     // The first 4 bytes of the string are set to '----' and will be replaced
383406f32e7eSjoerg     // by __msan_va_arg_overflow_size_tls at the first call.
383506f32e7eSjoerg     StackDescription << "----" << I.getName() << "@" << F.getName();
383606f32e7eSjoerg     return createPrivateNonConstGlobalForString(*F.getParent(),
383706f32e7eSjoerg                                                 StackDescription.str());
383806f32e7eSjoerg   }
383906f32e7eSjoerg 
poisonAllocaUserspace__anonb9e144640811::MemorySanitizerVisitor384006f32e7eSjoerg   void poisonAllocaUserspace(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
384106f32e7eSjoerg     if (PoisonStack && ClPoisonStackWithCall) {
384206f32e7eSjoerg       IRB.CreateCall(MS.MsanPoisonStackFn,
384306f32e7eSjoerg                      {IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()), Len});
384406f32e7eSjoerg     } else {
384506f32e7eSjoerg       Value *ShadowBase, *OriginBase;
3846*da58b97aSjoerg       std::tie(ShadowBase, OriginBase) = getShadowOriginPtr(
3847*da58b97aSjoerg           &I, IRB, IRB.getInt8Ty(), Align(1), /*isStore*/ true);
384806f32e7eSjoerg 
384906f32e7eSjoerg       Value *PoisonValue = IRB.getInt8(PoisonStack ? ClPoisonStackPattern : 0);
3850*da58b97aSjoerg       IRB.CreateMemSet(ShadowBase, PoisonValue, Len,
3851*da58b97aSjoerg                        MaybeAlign(I.getAlignment()));
385206f32e7eSjoerg     }
385306f32e7eSjoerg 
385406f32e7eSjoerg     if (PoisonStack && MS.TrackOrigins) {
385506f32e7eSjoerg       Value *Descr = getLocalVarDescription(I);
385606f32e7eSjoerg       IRB.CreateCall(MS.MsanSetAllocaOrigin4Fn,
385706f32e7eSjoerg                      {IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()), Len,
385806f32e7eSjoerg                       IRB.CreatePointerCast(Descr, IRB.getInt8PtrTy()),
385906f32e7eSjoerg                       IRB.CreatePointerCast(&F, MS.IntptrTy)});
386006f32e7eSjoerg     }
386106f32e7eSjoerg   }
386206f32e7eSjoerg 
poisonAllocaKmsan__anonb9e144640811::MemorySanitizerVisitor386306f32e7eSjoerg   void poisonAllocaKmsan(AllocaInst &I, IRBuilder<> &IRB, Value *Len) {
386406f32e7eSjoerg     Value *Descr = getLocalVarDescription(I);
386506f32e7eSjoerg     if (PoisonStack) {
386606f32e7eSjoerg       IRB.CreateCall(MS.MsanPoisonAllocaFn,
386706f32e7eSjoerg                      {IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()), Len,
386806f32e7eSjoerg                       IRB.CreatePointerCast(Descr, IRB.getInt8PtrTy())});
386906f32e7eSjoerg     } else {
387006f32e7eSjoerg       IRB.CreateCall(MS.MsanUnpoisonAllocaFn,
387106f32e7eSjoerg                      {IRB.CreatePointerCast(&I, IRB.getInt8PtrTy()), Len});
387206f32e7eSjoerg     }
387306f32e7eSjoerg   }
387406f32e7eSjoerg 
instrumentAlloca__anonb9e144640811::MemorySanitizerVisitor387506f32e7eSjoerg   void instrumentAlloca(AllocaInst &I, Instruction *InsPoint = nullptr) {
387606f32e7eSjoerg     if (!InsPoint)
387706f32e7eSjoerg       InsPoint = &I;
387806f32e7eSjoerg     IRBuilder<> IRB(InsPoint->getNextNode());
387906f32e7eSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
388006f32e7eSjoerg     uint64_t TypeSize = DL.getTypeAllocSize(I.getAllocatedType());
388106f32e7eSjoerg     Value *Len = ConstantInt::get(MS.IntptrTy, TypeSize);
388206f32e7eSjoerg     if (I.isArrayAllocation())
388306f32e7eSjoerg       Len = IRB.CreateMul(Len, I.getArraySize());
388406f32e7eSjoerg 
388506f32e7eSjoerg     if (MS.CompileKernel)
388606f32e7eSjoerg       poisonAllocaKmsan(I, IRB, Len);
388706f32e7eSjoerg     else
388806f32e7eSjoerg       poisonAllocaUserspace(I, IRB, Len);
388906f32e7eSjoerg   }
389006f32e7eSjoerg 
visitAllocaInst__anonb9e144640811::MemorySanitizerVisitor389106f32e7eSjoerg   void visitAllocaInst(AllocaInst &I) {
389206f32e7eSjoerg     setShadow(&I, getCleanShadow(&I));
389306f32e7eSjoerg     setOrigin(&I, getCleanOrigin());
389406f32e7eSjoerg     // We'll get to this alloca later unless it's poisoned at the corresponding
389506f32e7eSjoerg     // llvm.lifetime.start.
389606f32e7eSjoerg     AllocaSet.insert(&I);
389706f32e7eSjoerg   }
389806f32e7eSjoerg 
visitSelectInst__anonb9e144640811::MemorySanitizerVisitor389906f32e7eSjoerg   void visitSelectInst(SelectInst& I) {
390006f32e7eSjoerg     IRBuilder<> IRB(&I);
390106f32e7eSjoerg     // a = select b, c, d
390206f32e7eSjoerg     Value *B = I.getCondition();
390306f32e7eSjoerg     Value *C = I.getTrueValue();
390406f32e7eSjoerg     Value *D = I.getFalseValue();
390506f32e7eSjoerg     Value *Sb = getShadow(B);
390606f32e7eSjoerg     Value *Sc = getShadow(C);
390706f32e7eSjoerg     Value *Sd = getShadow(D);
390806f32e7eSjoerg 
390906f32e7eSjoerg     // Result shadow if condition shadow is 0.
391006f32e7eSjoerg     Value *Sa0 = IRB.CreateSelect(B, Sc, Sd);
391106f32e7eSjoerg     Value *Sa1;
391206f32e7eSjoerg     if (I.getType()->isAggregateType()) {
391306f32e7eSjoerg       // To avoid "sign extending" i1 to an arbitrary aggregate type, we just do
391406f32e7eSjoerg       // an extra "select". This results in much more compact IR.
391506f32e7eSjoerg       // Sa = select Sb, poisoned, (select b, Sc, Sd)
391606f32e7eSjoerg       Sa1 = getPoisonedShadow(getShadowTy(I.getType()));
391706f32e7eSjoerg     } else {
391806f32e7eSjoerg       // Sa = select Sb, [ (c^d) | Sc | Sd ], [ b ? Sc : Sd ]
391906f32e7eSjoerg       // If Sb (condition is poisoned), look for bits in c and d that are equal
392006f32e7eSjoerg       // and both unpoisoned.
392106f32e7eSjoerg       // If !Sb (condition is unpoisoned), simply pick one of Sc and Sd.
392206f32e7eSjoerg 
392306f32e7eSjoerg       // Cast arguments to shadow-compatible type.
392406f32e7eSjoerg       C = CreateAppToShadowCast(IRB, C);
392506f32e7eSjoerg       D = CreateAppToShadowCast(IRB, D);
392606f32e7eSjoerg 
392706f32e7eSjoerg       // Result shadow if condition shadow is 1.
392806f32e7eSjoerg       Sa1 = IRB.CreateOr({IRB.CreateXor(C, D), Sc, Sd});
392906f32e7eSjoerg     }
393006f32e7eSjoerg     Value *Sa = IRB.CreateSelect(Sb, Sa1, Sa0, "_msprop_select");
393106f32e7eSjoerg     setShadow(&I, Sa);
393206f32e7eSjoerg     if (MS.TrackOrigins) {
393306f32e7eSjoerg       // Origins are always i32, so any vector conditions must be flattened.
393406f32e7eSjoerg       // FIXME: consider tracking vector origins for app vectors?
393506f32e7eSjoerg       if (B->getType()->isVectorTy()) {
393606f32e7eSjoerg         Type *FlatTy = getShadowTyNoVec(B->getType());
393706f32e7eSjoerg         B = IRB.CreateICmpNE(IRB.CreateBitCast(B, FlatTy),
393806f32e7eSjoerg                                 ConstantInt::getNullValue(FlatTy));
393906f32e7eSjoerg         Sb = IRB.CreateICmpNE(IRB.CreateBitCast(Sb, FlatTy),
394006f32e7eSjoerg                                       ConstantInt::getNullValue(FlatTy));
394106f32e7eSjoerg       }
394206f32e7eSjoerg       // a = select b, c, d
394306f32e7eSjoerg       // Oa = Sb ? Ob : (b ? Oc : Od)
394406f32e7eSjoerg       setOrigin(
394506f32e7eSjoerg           &I, IRB.CreateSelect(Sb, getOrigin(I.getCondition()),
394606f32e7eSjoerg                                IRB.CreateSelect(B, getOrigin(I.getTrueValue()),
394706f32e7eSjoerg                                                 getOrigin(I.getFalseValue()))));
394806f32e7eSjoerg     }
394906f32e7eSjoerg   }
395006f32e7eSjoerg 
visitLandingPadInst__anonb9e144640811::MemorySanitizerVisitor395106f32e7eSjoerg   void visitLandingPadInst(LandingPadInst &I) {
395206f32e7eSjoerg     // Do nothing.
395306f32e7eSjoerg     // See https://github.com/google/sanitizers/issues/504
395406f32e7eSjoerg     setShadow(&I, getCleanShadow(&I));
395506f32e7eSjoerg     setOrigin(&I, getCleanOrigin());
395606f32e7eSjoerg   }
395706f32e7eSjoerg 
visitCatchSwitchInst__anonb9e144640811::MemorySanitizerVisitor395806f32e7eSjoerg   void visitCatchSwitchInst(CatchSwitchInst &I) {
395906f32e7eSjoerg     setShadow(&I, getCleanShadow(&I));
396006f32e7eSjoerg     setOrigin(&I, getCleanOrigin());
396106f32e7eSjoerg   }
396206f32e7eSjoerg 
visitFuncletPadInst__anonb9e144640811::MemorySanitizerVisitor396306f32e7eSjoerg   void visitFuncletPadInst(FuncletPadInst &I) {
396406f32e7eSjoerg     setShadow(&I, getCleanShadow(&I));
396506f32e7eSjoerg     setOrigin(&I, getCleanOrigin());
396606f32e7eSjoerg   }
396706f32e7eSjoerg 
visitGetElementPtrInst__anonb9e144640811::MemorySanitizerVisitor396806f32e7eSjoerg   void visitGetElementPtrInst(GetElementPtrInst &I) {
396906f32e7eSjoerg     handleShadowOr(I);
397006f32e7eSjoerg   }
397106f32e7eSjoerg 
visitExtractValueInst__anonb9e144640811::MemorySanitizerVisitor397206f32e7eSjoerg   void visitExtractValueInst(ExtractValueInst &I) {
397306f32e7eSjoerg     IRBuilder<> IRB(&I);
397406f32e7eSjoerg     Value *Agg = I.getAggregateOperand();
397506f32e7eSjoerg     LLVM_DEBUG(dbgs() << "ExtractValue:  " << I << "\n");
397606f32e7eSjoerg     Value *AggShadow = getShadow(Agg);
397706f32e7eSjoerg     LLVM_DEBUG(dbgs() << "   AggShadow:  " << *AggShadow << "\n");
397806f32e7eSjoerg     Value *ResShadow = IRB.CreateExtractValue(AggShadow, I.getIndices());
397906f32e7eSjoerg     LLVM_DEBUG(dbgs() << "   ResShadow:  " << *ResShadow << "\n");
398006f32e7eSjoerg     setShadow(&I, ResShadow);
398106f32e7eSjoerg     setOriginForNaryOp(I);
398206f32e7eSjoerg   }
398306f32e7eSjoerg 
visitInsertValueInst__anonb9e144640811::MemorySanitizerVisitor398406f32e7eSjoerg   void visitInsertValueInst(InsertValueInst &I) {
398506f32e7eSjoerg     IRBuilder<> IRB(&I);
398606f32e7eSjoerg     LLVM_DEBUG(dbgs() << "InsertValue:  " << I << "\n");
398706f32e7eSjoerg     Value *AggShadow = getShadow(I.getAggregateOperand());
398806f32e7eSjoerg     Value *InsShadow = getShadow(I.getInsertedValueOperand());
398906f32e7eSjoerg     LLVM_DEBUG(dbgs() << "   AggShadow:  " << *AggShadow << "\n");
399006f32e7eSjoerg     LLVM_DEBUG(dbgs() << "   InsShadow:  " << *InsShadow << "\n");
399106f32e7eSjoerg     Value *Res = IRB.CreateInsertValue(AggShadow, InsShadow, I.getIndices());
399206f32e7eSjoerg     LLVM_DEBUG(dbgs() << "   Res:        " << *Res << "\n");
399306f32e7eSjoerg     setShadow(&I, Res);
399406f32e7eSjoerg     setOriginForNaryOp(I);
399506f32e7eSjoerg   }
399606f32e7eSjoerg 
dumpInst__anonb9e144640811::MemorySanitizerVisitor399706f32e7eSjoerg   void dumpInst(Instruction &I) {
399806f32e7eSjoerg     if (CallInst *CI = dyn_cast<CallInst>(&I)) {
399906f32e7eSjoerg       errs() << "ZZZ call " << CI->getCalledFunction()->getName() << "\n";
400006f32e7eSjoerg     } else {
400106f32e7eSjoerg       errs() << "ZZZ " << I.getOpcodeName() << "\n";
400206f32e7eSjoerg     }
400306f32e7eSjoerg     errs() << "QQQ " << I << "\n";
400406f32e7eSjoerg   }
400506f32e7eSjoerg 
visitResumeInst__anonb9e144640811::MemorySanitizerVisitor400606f32e7eSjoerg   void visitResumeInst(ResumeInst &I) {
400706f32e7eSjoerg     LLVM_DEBUG(dbgs() << "Resume: " << I << "\n");
400806f32e7eSjoerg     // Nothing to do here.
400906f32e7eSjoerg   }
401006f32e7eSjoerg 
visitCleanupReturnInst__anonb9e144640811::MemorySanitizerVisitor401106f32e7eSjoerg   void visitCleanupReturnInst(CleanupReturnInst &CRI) {
401206f32e7eSjoerg     LLVM_DEBUG(dbgs() << "CleanupReturn: " << CRI << "\n");
401306f32e7eSjoerg     // Nothing to do here.
401406f32e7eSjoerg   }
401506f32e7eSjoerg 
visitCatchReturnInst__anonb9e144640811::MemorySanitizerVisitor401606f32e7eSjoerg   void visitCatchReturnInst(CatchReturnInst &CRI) {
401706f32e7eSjoerg     LLVM_DEBUG(dbgs() << "CatchReturn: " << CRI << "\n");
401806f32e7eSjoerg     // Nothing to do here.
401906f32e7eSjoerg   }
402006f32e7eSjoerg 
instrumentAsmArgument__anonb9e144640811::MemorySanitizerVisitor402106f32e7eSjoerg   void instrumentAsmArgument(Value *Operand, Instruction &I, IRBuilder<> &IRB,
402206f32e7eSjoerg                              const DataLayout &DL, bool isOutput) {
402306f32e7eSjoerg     // For each assembly argument, we check its value for being initialized.
402406f32e7eSjoerg     // If the argument is a pointer, we assume it points to a single element
402506f32e7eSjoerg     // of the corresponding type (or to a 8-byte word, if the type is unsized).
402606f32e7eSjoerg     // Each such pointer is instrumented with a call to the runtime library.
402706f32e7eSjoerg     Type *OpType = Operand->getType();
402806f32e7eSjoerg     // Check the operand value itself.
402906f32e7eSjoerg     insertShadowCheck(Operand, &I);
403006f32e7eSjoerg     if (!OpType->isPointerTy() || !isOutput) {
403106f32e7eSjoerg       assert(!isOutput);
403206f32e7eSjoerg       return;
403306f32e7eSjoerg     }
403406f32e7eSjoerg     Type *ElType = OpType->getPointerElementType();
403506f32e7eSjoerg     if (!ElType->isSized())
403606f32e7eSjoerg       return;
403706f32e7eSjoerg     int Size = DL.getTypeStoreSize(ElType);
403806f32e7eSjoerg     Value *Ptr = IRB.CreatePointerCast(Operand, IRB.getInt8PtrTy());
403906f32e7eSjoerg     Value *SizeVal = ConstantInt::get(MS.IntptrTy, Size);
404006f32e7eSjoerg     IRB.CreateCall(MS.MsanInstrumentAsmStoreFn, {Ptr, SizeVal});
404106f32e7eSjoerg   }
404206f32e7eSjoerg 
404306f32e7eSjoerg   /// Get the number of output arguments returned by pointers.
getNumOutputArgs__anonb9e144640811::MemorySanitizerVisitor404406f32e7eSjoerg   int getNumOutputArgs(InlineAsm *IA, CallBase *CB) {
404506f32e7eSjoerg     int NumRetOutputs = 0;
404606f32e7eSjoerg     int NumOutputs = 0;
404706f32e7eSjoerg     Type *RetTy = cast<Value>(CB)->getType();
404806f32e7eSjoerg     if (!RetTy->isVoidTy()) {
404906f32e7eSjoerg       // Register outputs are returned via the CallInst return value.
405006f32e7eSjoerg       auto *ST = dyn_cast<StructType>(RetTy);
405106f32e7eSjoerg       if (ST)
405206f32e7eSjoerg         NumRetOutputs = ST->getNumElements();
405306f32e7eSjoerg       else
405406f32e7eSjoerg         NumRetOutputs = 1;
405506f32e7eSjoerg     }
405606f32e7eSjoerg     InlineAsm::ConstraintInfoVector Constraints = IA->ParseConstraints();
4057*da58b97aSjoerg     for (const InlineAsm::ConstraintInfo &Info : Constraints) {
405806f32e7eSjoerg       switch (Info.Type) {
405906f32e7eSjoerg       case InlineAsm::isOutput:
406006f32e7eSjoerg         NumOutputs++;
406106f32e7eSjoerg         break;
406206f32e7eSjoerg       default:
406306f32e7eSjoerg         break;
406406f32e7eSjoerg       }
406506f32e7eSjoerg     }
406606f32e7eSjoerg     return NumOutputs - NumRetOutputs;
406706f32e7eSjoerg   }
406806f32e7eSjoerg 
visitAsmInstruction__anonb9e144640811::MemorySanitizerVisitor406906f32e7eSjoerg   void visitAsmInstruction(Instruction &I) {
407006f32e7eSjoerg     // Conservative inline assembly handling: check for poisoned shadow of
407106f32e7eSjoerg     // asm() arguments, then unpoison the result and all the memory locations
407206f32e7eSjoerg     // pointed to by those arguments.
407306f32e7eSjoerg     // An inline asm() statement in C++ contains lists of input and output
407406f32e7eSjoerg     // arguments used by the assembly code. These are mapped to operands of the
407506f32e7eSjoerg     // CallInst as follows:
407606f32e7eSjoerg     //  - nR register outputs ("=r) are returned by value in a single structure
407706f32e7eSjoerg     //  (SSA value of the CallInst);
407806f32e7eSjoerg     //  - nO other outputs ("=m" and others) are returned by pointer as first
407906f32e7eSjoerg     // nO operands of the CallInst;
408006f32e7eSjoerg     //  - nI inputs ("r", "m" and others) are passed to CallInst as the
408106f32e7eSjoerg     // remaining nI operands.
408206f32e7eSjoerg     // The total number of asm() arguments in the source is nR+nO+nI, and the
408306f32e7eSjoerg     // corresponding CallInst has nO+nI+1 operands (the last operand is the
408406f32e7eSjoerg     // function to be called).
408506f32e7eSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
408606f32e7eSjoerg     CallBase *CB = cast<CallBase>(&I);
408706f32e7eSjoerg     IRBuilder<> IRB(&I);
4088*da58b97aSjoerg     InlineAsm *IA = cast<InlineAsm>(CB->getCalledOperand());
408906f32e7eSjoerg     int OutputArgs = getNumOutputArgs(IA, CB);
409006f32e7eSjoerg     // The last operand of a CallInst is the function itself.
409106f32e7eSjoerg     int NumOperands = CB->getNumOperands() - 1;
409206f32e7eSjoerg 
409306f32e7eSjoerg     // Check input arguments. Doing so before unpoisoning output arguments, so
409406f32e7eSjoerg     // that we won't overwrite uninit values before checking them.
409506f32e7eSjoerg     for (int i = OutputArgs; i < NumOperands; i++) {
409606f32e7eSjoerg       Value *Operand = CB->getOperand(i);
409706f32e7eSjoerg       instrumentAsmArgument(Operand, I, IRB, DL, /*isOutput*/ false);
409806f32e7eSjoerg     }
409906f32e7eSjoerg     // Unpoison output arguments. This must happen before the actual InlineAsm
410006f32e7eSjoerg     // call, so that the shadow for memory published in the asm() statement
410106f32e7eSjoerg     // remains valid.
410206f32e7eSjoerg     for (int i = 0; i < OutputArgs; i++) {
410306f32e7eSjoerg       Value *Operand = CB->getOperand(i);
410406f32e7eSjoerg       instrumentAsmArgument(Operand, I, IRB, DL, /*isOutput*/ true);
410506f32e7eSjoerg     }
410606f32e7eSjoerg 
410706f32e7eSjoerg     setShadow(&I, getCleanShadow(&I));
410806f32e7eSjoerg     setOrigin(&I, getCleanOrigin());
410906f32e7eSjoerg   }
411006f32e7eSjoerg 
visitFreezeInst__anonb9e144640811::MemorySanitizerVisitor4111*da58b97aSjoerg   void visitFreezeInst(FreezeInst &I) {
4112*da58b97aSjoerg     // Freeze always returns a fully defined value.
4113*da58b97aSjoerg     setShadow(&I, getCleanShadow(&I));
4114*da58b97aSjoerg     setOrigin(&I, getCleanOrigin());
4115*da58b97aSjoerg   }
4116*da58b97aSjoerg 
visitInstruction__anonb9e144640811::MemorySanitizerVisitor411706f32e7eSjoerg   void visitInstruction(Instruction &I) {
411806f32e7eSjoerg     // Everything else: stop propagating and check for poisoned shadow.
411906f32e7eSjoerg     if (ClDumpStrictInstructions)
412006f32e7eSjoerg       dumpInst(I);
412106f32e7eSjoerg     LLVM_DEBUG(dbgs() << "DEFAULT: " << I << "\n");
412206f32e7eSjoerg     for (size_t i = 0, n = I.getNumOperands(); i < n; i++) {
412306f32e7eSjoerg       Value *Operand = I.getOperand(i);
412406f32e7eSjoerg       if (Operand->getType()->isSized())
412506f32e7eSjoerg         insertShadowCheck(Operand, &I);
412606f32e7eSjoerg     }
412706f32e7eSjoerg     setShadow(&I, getCleanShadow(&I));
412806f32e7eSjoerg     setOrigin(&I, getCleanOrigin());
412906f32e7eSjoerg   }
413006f32e7eSjoerg };
413106f32e7eSjoerg 
413206f32e7eSjoerg /// AMD64-specific implementation of VarArgHelper.
413306f32e7eSjoerg struct VarArgAMD64Helper : public VarArgHelper {
413406f32e7eSjoerg   // An unfortunate workaround for asymmetric lowering of va_arg stuff.
4135*da58b97aSjoerg   // See a comment in visitCallBase for more details.
413606f32e7eSjoerg   static const unsigned AMD64GpEndOffset = 48;  // AMD64 ABI Draft 0.99.6 p3.5.7
413706f32e7eSjoerg   static const unsigned AMD64FpEndOffsetSSE = 176;
413806f32e7eSjoerg   // If SSE is disabled, fp_offset in va_list is zero.
413906f32e7eSjoerg   static const unsigned AMD64FpEndOffsetNoSSE = AMD64GpEndOffset;
414006f32e7eSjoerg 
414106f32e7eSjoerg   unsigned AMD64FpEndOffset;
414206f32e7eSjoerg   Function &F;
414306f32e7eSjoerg   MemorySanitizer &MS;
414406f32e7eSjoerg   MemorySanitizerVisitor &MSV;
414506f32e7eSjoerg   Value *VAArgTLSCopy = nullptr;
414606f32e7eSjoerg   Value *VAArgTLSOriginCopy = nullptr;
414706f32e7eSjoerg   Value *VAArgOverflowSize = nullptr;
414806f32e7eSjoerg 
414906f32e7eSjoerg   SmallVector<CallInst*, 16> VAStartInstrumentationList;
415006f32e7eSjoerg 
415106f32e7eSjoerg   enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
415206f32e7eSjoerg 
VarArgAMD64Helper__anonb9e144640811::VarArgAMD64Helper415306f32e7eSjoerg   VarArgAMD64Helper(Function &F, MemorySanitizer &MS,
415406f32e7eSjoerg                     MemorySanitizerVisitor &MSV)
415506f32e7eSjoerg       : F(F), MS(MS), MSV(MSV) {
415606f32e7eSjoerg     AMD64FpEndOffset = AMD64FpEndOffsetSSE;
415706f32e7eSjoerg     for (const auto &Attr : F.getAttributes().getFnAttributes()) {
415806f32e7eSjoerg       if (Attr.isStringAttribute() &&
415906f32e7eSjoerg           (Attr.getKindAsString() == "target-features")) {
416006f32e7eSjoerg         if (Attr.getValueAsString().contains("-sse"))
416106f32e7eSjoerg           AMD64FpEndOffset = AMD64FpEndOffsetNoSSE;
416206f32e7eSjoerg         break;
416306f32e7eSjoerg       }
416406f32e7eSjoerg     }
416506f32e7eSjoerg   }
416606f32e7eSjoerg 
classifyArgument__anonb9e144640811::VarArgAMD64Helper416706f32e7eSjoerg   ArgKind classifyArgument(Value* arg) {
416806f32e7eSjoerg     // A very rough approximation of X86_64 argument classification rules.
416906f32e7eSjoerg     Type *T = arg->getType();
417006f32e7eSjoerg     if (T->isFPOrFPVectorTy() || T->isX86_MMXTy())
417106f32e7eSjoerg       return AK_FloatingPoint;
417206f32e7eSjoerg     if (T->isIntegerTy() && T->getPrimitiveSizeInBits() <= 64)
417306f32e7eSjoerg       return AK_GeneralPurpose;
417406f32e7eSjoerg     if (T->isPointerTy())
417506f32e7eSjoerg       return AK_GeneralPurpose;
417606f32e7eSjoerg     return AK_Memory;
417706f32e7eSjoerg   }
417806f32e7eSjoerg 
417906f32e7eSjoerg   // For VarArg functions, store the argument shadow in an ABI-specific format
418006f32e7eSjoerg   // that corresponds to va_list layout.
418106f32e7eSjoerg   // We do this because Clang lowers va_arg in the frontend, and this pass
418206f32e7eSjoerg   // only sees the low level code that deals with va_list internals.
418306f32e7eSjoerg   // A much easier alternative (provided that Clang emits va_arg instructions)
418406f32e7eSjoerg   // would have been to associate each live instance of va_list with a copy of
418506f32e7eSjoerg   // MSanParamTLS, and extract shadow on va_arg() call in the argument list
418606f32e7eSjoerg   // order.
visitCallBase__anonb9e144640811::VarArgAMD64Helper4187*da58b97aSjoerg   void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
418806f32e7eSjoerg     unsigned GpOffset = 0;
418906f32e7eSjoerg     unsigned FpOffset = AMD64GpEndOffset;
419006f32e7eSjoerg     unsigned OverflowOffset = AMD64FpEndOffset;
419106f32e7eSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
4192*da58b97aSjoerg     for (auto ArgIt = CB.arg_begin(), End = CB.arg_end(); ArgIt != End;
4193*da58b97aSjoerg          ++ArgIt) {
419406f32e7eSjoerg       Value *A = *ArgIt;
4195*da58b97aSjoerg       unsigned ArgNo = CB.getArgOperandNo(ArgIt);
4196*da58b97aSjoerg       bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
4197*da58b97aSjoerg       bool IsByVal = CB.paramHasAttr(ArgNo, Attribute::ByVal);
419806f32e7eSjoerg       if (IsByVal) {
419906f32e7eSjoerg         // ByVal arguments always go to the overflow area.
420006f32e7eSjoerg         // Fixed arguments passed through the overflow area will be stepped
420106f32e7eSjoerg         // over by va_start, so don't count them towards the offset.
420206f32e7eSjoerg         if (IsFixed)
420306f32e7eSjoerg           continue;
420406f32e7eSjoerg         assert(A->getType()->isPointerTy());
4205*da58b97aSjoerg         Type *RealTy = CB.getParamByValType(ArgNo);
420606f32e7eSjoerg         uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
420706f32e7eSjoerg         Value *ShadowBase = getShadowPtrForVAArgument(
420806f32e7eSjoerg             RealTy, IRB, OverflowOffset, alignTo(ArgSize, 8));
420906f32e7eSjoerg         Value *OriginBase = nullptr;
421006f32e7eSjoerg         if (MS.TrackOrigins)
421106f32e7eSjoerg           OriginBase = getOriginPtrForVAArgument(RealTy, IRB, OverflowOffset);
421206f32e7eSjoerg         OverflowOffset += alignTo(ArgSize, 8);
421306f32e7eSjoerg         if (!ShadowBase)
421406f32e7eSjoerg           continue;
421506f32e7eSjoerg         Value *ShadowPtr, *OriginPtr;
421606f32e7eSjoerg         std::tie(ShadowPtr, OriginPtr) =
421706f32e7eSjoerg             MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(), kShadowTLSAlignment,
421806f32e7eSjoerg                                    /*isStore*/ false);
421906f32e7eSjoerg 
422006f32e7eSjoerg         IRB.CreateMemCpy(ShadowBase, kShadowTLSAlignment, ShadowPtr,
422106f32e7eSjoerg                          kShadowTLSAlignment, ArgSize);
422206f32e7eSjoerg         if (MS.TrackOrigins)
422306f32e7eSjoerg           IRB.CreateMemCpy(OriginBase, kShadowTLSAlignment, OriginPtr,
422406f32e7eSjoerg                            kShadowTLSAlignment, ArgSize);
422506f32e7eSjoerg       } else {
422606f32e7eSjoerg         ArgKind AK = classifyArgument(A);
422706f32e7eSjoerg         if (AK == AK_GeneralPurpose && GpOffset >= AMD64GpEndOffset)
422806f32e7eSjoerg           AK = AK_Memory;
422906f32e7eSjoerg         if (AK == AK_FloatingPoint && FpOffset >= AMD64FpEndOffset)
423006f32e7eSjoerg           AK = AK_Memory;
423106f32e7eSjoerg         Value *ShadowBase, *OriginBase = nullptr;
423206f32e7eSjoerg         switch (AK) {
423306f32e7eSjoerg           case AK_GeneralPurpose:
423406f32e7eSjoerg             ShadowBase =
423506f32e7eSjoerg                 getShadowPtrForVAArgument(A->getType(), IRB, GpOffset, 8);
423606f32e7eSjoerg             if (MS.TrackOrigins)
423706f32e7eSjoerg               OriginBase =
423806f32e7eSjoerg                   getOriginPtrForVAArgument(A->getType(), IRB, GpOffset);
423906f32e7eSjoerg             GpOffset += 8;
424006f32e7eSjoerg             break;
424106f32e7eSjoerg           case AK_FloatingPoint:
424206f32e7eSjoerg             ShadowBase =
424306f32e7eSjoerg                 getShadowPtrForVAArgument(A->getType(), IRB, FpOffset, 16);
424406f32e7eSjoerg             if (MS.TrackOrigins)
424506f32e7eSjoerg               OriginBase =
424606f32e7eSjoerg                   getOriginPtrForVAArgument(A->getType(), IRB, FpOffset);
424706f32e7eSjoerg             FpOffset += 16;
424806f32e7eSjoerg             break;
424906f32e7eSjoerg           case AK_Memory:
425006f32e7eSjoerg             if (IsFixed)
425106f32e7eSjoerg               continue;
425206f32e7eSjoerg             uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
425306f32e7eSjoerg             ShadowBase =
425406f32e7eSjoerg                 getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset, 8);
425506f32e7eSjoerg             if (MS.TrackOrigins)
425606f32e7eSjoerg               OriginBase =
425706f32e7eSjoerg                   getOriginPtrForVAArgument(A->getType(), IRB, OverflowOffset);
425806f32e7eSjoerg             OverflowOffset += alignTo(ArgSize, 8);
425906f32e7eSjoerg         }
426006f32e7eSjoerg         // Take fixed arguments into account for GpOffset and FpOffset,
426106f32e7eSjoerg         // but don't actually store shadows for them.
426206f32e7eSjoerg         // TODO(glider): don't call get*PtrForVAArgument() for them.
426306f32e7eSjoerg         if (IsFixed)
426406f32e7eSjoerg           continue;
426506f32e7eSjoerg         if (!ShadowBase)
426606f32e7eSjoerg           continue;
426706f32e7eSjoerg         Value *Shadow = MSV.getShadow(A);
426806f32e7eSjoerg         IRB.CreateAlignedStore(Shadow, ShadowBase, kShadowTLSAlignment);
426906f32e7eSjoerg         if (MS.TrackOrigins) {
427006f32e7eSjoerg           Value *Origin = MSV.getOrigin(A);
427106f32e7eSjoerg           unsigned StoreSize = DL.getTypeStoreSize(Shadow->getType());
427206f32e7eSjoerg           MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
427306f32e7eSjoerg                           std::max(kShadowTLSAlignment, kMinOriginAlignment));
427406f32e7eSjoerg         }
427506f32e7eSjoerg       }
427606f32e7eSjoerg     }
427706f32e7eSjoerg     Constant *OverflowSize =
427806f32e7eSjoerg       ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AMD64FpEndOffset);
427906f32e7eSjoerg     IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
428006f32e7eSjoerg   }
428106f32e7eSjoerg 
428206f32e7eSjoerg   /// Compute the shadow address for a given va_arg.
getShadowPtrForVAArgument__anonb9e144640811::VarArgAMD64Helper428306f32e7eSjoerg   Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB,
428406f32e7eSjoerg                                    unsigned ArgOffset, unsigned ArgSize) {
428506f32e7eSjoerg     // Make sure we don't overflow __msan_va_arg_tls.
428606f32e7eSjoerg     if (ArgOffset + ArgSize > kParamTLSSize)
428706f32e7eSjoerg       return nullptr;
428806f32e7eSjoerg     Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
428906f32e7eSjoerg     Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
429006f32e7eSjoerg     return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0),
429106f32e7eSjoerg                               "_msarg_va_s");
429206f32e7eSjoerg   }
429306f32e7eSjoerg 
429406f32e7eSjoerg   /// Compute the origin address for a given va_arg.
getOriginPtrForVAArgument__anonb9e144640811::VarArgAMD64Helper429506f32e7eSjoerg   Value *getOriginPtrForVAArgument(Type *Ty, IRBuilder<> &IRB, int ArgOffset) {
429606f32e7eSjoerg     Value *Base = IRB.CreatePointerCast(MS.VAArgOriginTLS, MS.IntptrTy);
429706f32e7eSjoerg     // getOriginPtrForVAArgument() is always called after
429806f32e7eSjoerg     // getShadowPtrForVAArgument(), so __msan_va_arg_origin_tls can never
429906f32e7eSjoerg     // overflow.
430006f32e7eSjoerg     Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
430106f32e7eSjoerg     return IRB.CreateIntToPtr(Base, PointerType::get(MS.OriginTy, 0),
430206f32e7eSjoerg                               "_msarg_va_o");
430306f32e7eSjoerg   }
430406f32e7eSjoerg 
unpoisonVAListTagForInst__anonb9e144640811::VarArgAMD64Helper430506f32e7eSjoerg   void unpoisonVAListTagForInst(IntrinsicInst &I) {
430606f32e7eSjoerg     IRBuilder<> IRB(&I);
430706f32e7eSjoerg     Value *VAListTag = I.getArgOperand(0);
430806f32e7eSjoerg     Value *ShadowPtr, *OriginPtr;
4309*da58b97aSjoerg     const Align Alignment = Align(8);
431006f32e7eSjoerg     std::tie(ShadowPtr, OriginPtr) =
431106f32e7eSjoerg         MSV.getShadowOriginPtr(VAListTag, IRB, IRB.getInt8Ty(), Alignment,
431206f32e7eSjoerg                                /*isStore*/ true);
431306f32e7eSjoerg 
431406f32e7eSjoerg     // Unpoison the whole __va_list_tag.
431506f32e7eSjoerg     // FIXME: magic ABI constants.
431606f32e7eSjoerg     IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
431706f32e7eSjoerg                      /* size */ 24, Alignment, false);
431806f32e7eSjoerg     // We shouldn't need to zero out the origins, as they're only checked for
431906f32e7eSjoerg     // nonzero shadow.
432006f32e7eSjoerg   }
432106f32e7eSjoerg 
visitVAStartInst__anonb9e144640811::VarArgAMD64Helper432206f32e7eSjoerg   void visitVAStartInst(VAStartInst &I) override {
432306f32e7eSjoerg     if (F.getCallingConv() == CallingConv::Win64)
432406f32e7eSjoerg       return;
432506f32e7eSjoerg     VAStartInstrumentationList.push_back(&I);
432606f32e7eSjoerg     unpoisonVAListTagForInst(I);
432706f32e7eSjoerg   }
432806f32e7eSjoerg 
visitVACopyInst__anonb9e144640811::VarArgAMD64Helper432906f32e7eSjoerg   void visitVACopyInst(VACopyInst &I) override {
433006f32e7eSjoerg     if (F.getCallingConv() == CallingConv::Win64) return;
433106f32e7eSjoerg     unpoisonVAListTagForInst(I);
433206f32e7eSjoerg   }
433306f32e7eSjoerg 
finalizeInstrumentation__anonb9e144640811::VarArgAMD64Helper433406f32e7eSjoerg   void finalizeInstrumentation() override {
433506f32e7eSjoerg     assert(!VAArgOverflowSize && !VAArgTLSCopy &&
433606f32e7eSjoerg            "finalizeInstrumentation called twice");
433706f32e7eSjoerg     if (!VAStartInstrumentationList.empty()) {
433806f32e7eSjoerg       // If there is a va_start in this function, make a backup copy of
433906f32e7eSjoerg       // va_arg_tls somewhere in the function entry block.
4340*da58b97aSjoerg       IRBuilder<> IRB(MSV.FnPrologueEnd);
434106f32e7eSjoerg       VAArgOverflowSize =
434206f32e7eSjoerg           IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
434306f32e7eSjoerg       Value *CopySize =
434406f32e7eSjoerg         IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AMD64FpEndOffset),
434506f32e7eSjoerg                       VAArgOverflowSize);
434606f32e7eSjoerg       VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
4347*da58b97aSjoerg       IRB.CreateMemCpy(VAArgTLSCopy, Align(8), MS.VAArgTLS, Align(8), CopySize);
434806f32e7eSjoerg       if (MS.TrackOrigins) {
434906f32e7eSjoerg         VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
4350*da58b97aSjoerg         IRB.CreateMemCpy(VAArgTLSOriginCopy, Align(8), MS.VAArgOriginTLS,
4351*da58b97aSjoerg                          Align(8), CopySize);
435206f32e7eSjoerg       }
435306f32e7eSjoerg     }
435406f32e7eSjoerg 
435506f32e7eSjoerg     // Instrument va_start.
435606f32e7eSjoerg     // Copy va_list shadow from the backup copy of the TLS contents.
435706f32e7eSjoerg     for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) {
435806f32e7eSjoerg       CallInst *OrigInst = VAStartInstrumentationList[i];
435906f32e7eSjoerg       IRBuilder<> IRB(OrigInst->getNextNode());
436006f32e7eSjoerg       Value *VAListTag = OrigInst->getArgOperand(0);
436106f32e7eSjoerg 
436206f32e7eSjoerg       Type *RegSaveAreaPtrTy = Type::getInt64PtrTy(*MS.C);
436306f32e7eSjoerg       Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr(
436406f32e7eSjoerg           IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
436506f32e7eSjoerg                         ConstantInt::get(MS.IntptrTy, 16)),
436606f32e7eSjoerg           PointerType::get(RegSaveAreaPtrTy, 0));
436706f32e7eSjoerg       Value *RegSaveAreaPtr =
436806f32e7eSjoerg           IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
436906f32e7eSjoerg       Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
4370*da58b97aSjoerg       const Align Alignment = Align(16);
437106f32e7eSjoerg       std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
437206f32e7eSjoerg           MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
437306f32e7eSjoerg                                  Alignment, /*isStore*/ true);
437406f32e7eSjoerg       IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
437506f32e7eSjoerg                        AMD64FpEndOffset);
437606f32e7eSjoerg       if (MS.TrackOrigins)
437706f32e7eSjoerg         IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
437806f32e7eSjoerg                          Alignment, AMD64FpEndOffset);
437906f32e7eSjoerg       Type *OverflowArgAreaPtrTy = Type::getInt64PtrTy(*MS.C);
438006f32e7eSjoerg       Value *OverflowArgAreaPtrPtr = IRB.CreateIntToPtr(
438106f32e7eSjoerg           IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
438206f32e7eSjoerg                         ConstantInt::get(MS.IntptrTy, 8)),
438306f32e7eSjoerg           PointerType::get(OverflowArgAreaPtrTy, 0));
438406f32e7eSjoerg       Value *OverflowArgAreaPtr =
438506f32e7eSjoerg           IRB.CreateLoad(OverflowArgAreaPtrTy, OverflowArgAreaPtrPtr);
438606f32e7eSjoerg       Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
438706f32e7eSjoerg       std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
438806f32e7eSjoerg           MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
438906f32e7eSjoerg                                  Alignment, /*isStore*/ true);
439006f32e7eSjoerg       Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
439106f32e7eSjoerg                                              AMD64FpEndOffset);
439206f32e7eSjoerg       IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
439306f32e7eSjoerg                        VAArgOverflowSize);
439406f32e7eSjoerg       if (MS.TrackOrigins) {
439506f32e7eSjoerg         SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
439606f32e7eSjoerg                                         AMD64FpEndOffset);
439706f32e7eSjoerg         IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
439806f32e7eSjoerg                          VAArgOverflowSize);
439906f32e7eSjoerg       }
440006f32e7eSjoerg     }
440106f32e7eSjoerg   }
440206f32e7eSjoerg };
440306f32e7eSjoerg 
440406f32e7eSjoerg /// MIPS64-specific implementation of VarArgHelper.
440506f32e7eSjoerg struct VarArgMIPS64Helper : public VarArgHelper {
440606f32e7eSjoerg   Function &F;
440706f32e7eSjoerg   MemorySanitizer &MS;
440806f32e7eSjoerg   MemorySanitizerVisitor &MSV;
440906f32e7eSjoerg   Value *VAArgTLSCopy = nullptr;
441006f32e7eSjoerg   Value *VAArgSize = nullptr;
441106f32e7eSjoerg 
441206f32e7eSjoerg   SmallVector<CallInst*, 16> VAStartInstrumentationList;
441306f32e7eSjoerg 
VarArgMIPS64Helper__anonb9e144640811::VarArgMIPS64Helper441406f32e7eSjoerg   VarArgMIPS64Helper(Function &F, MemorySanitizer &MS,
441506f32e7eSjoerg                     MemorySanitizerVisitor &MSV) : F(F), MS(MS), MSV(MSV) {}
441606f32e7eSjoerg 
visitCallBase__anonb9e144640811::VarArgMIPS64Helper4417*da58b97aSjoerg   void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
441806f32e7eSjoerg     unsigned VAArgOffset = 0;
441906f32e7eSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
4420*da58b97aSjoerg     for (auto ArgIt = CB.arg_begin() + CB.getFunctionType()->getNumParams(),
4421*da58b97aSjoerg               End = CB.arg_end();
442206f32e7eSjoerg          ArgIt != End; ++ArgIt) {
442306f32e7eSjoerg       Triple TargetTriple(F.getParent()->getTargetTriple());
442406f32e7eSjoerg       Value *A = *ArgIt;
442506f32e7eSjoerg       Value *Base;
442606f32e7eSjoerg       uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
442706f32e7eSjoerg       if (TargetTriple.getArch() == Triple::mips64) {
442806f32e7eSjoerg         // Adjusting the shadow for argument with size < 8 to match the placement
442906f32e7eSjoerg         // of bits in big endian system
443006f32e7eSjoerg         if (ArgSize < 8)
443106f32e7eSjoerg           VAArgOffset += (8 - ArgSize);
443206f32e7eSjoerg       }
443306f32e7eSjoerg       Base = getShadowPtrForVAArgument(A->getType(), IRB, VAArgOffset, ArgSize);
443406f32e7eSjoerg       VAArgOffset += ArgSize;
443506f32e7eSjoerg       VAArgOffset = alignTo(VAArgOffset, 8);
443606f32e7eSjoerg       if (!Base)
443706f32e7eSjoerg         continue;
443806f32e7eSjoerg       IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
443906f32e7eSjoerg     }
444006f32e7eSjoerg 
444106f32e7eSjoerg     Constant *TotalVAArgSize = ConstantInt::get(IRB.getInt64Ty(), VAArgOffset);
444206f32e7eSjoerg     // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
444306f32e7eSjoerg     // a new class member i.e. it is the total size of all VarArgs.
444406f32e7eSjoerg     IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
444506f32e7eSjoerg   }
444606f32e7eSjoerg 
444706f32e7eSjoerg   /// Compute the shadow address for a given va_arg.
getShadowPtrForVAArgument__anonb9e144640811::VarArgMIPS64Helper444806f32e7eSjoerg   Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB,
444906f32e7eSjoerg                                    unsigned ArgOffset, unsigned ArgSize) {
445006f32e7eSjoerg     // Make sure we don't overflow __msan_va_arg_tls.
445106f32e7eSjoerg     if (ArgOffset + ArgSize > kParamTLSSize)
445206f32e7eSjoerg       return nullptr;
445306f32e7eSjoerg     Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
445406f32e7eSjoerg     Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
445506f32e7eSjoerg     return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0),
445606f32e7eSjoerg                               "_msarg");
445706f32e7eSjoerg   }
445806f32e7eSjoerg 
visitVAStartInst__anonb9e144640811::VarArgMIPS64Helper445906f32e7eSjoerg   void visitVAStartInst(VAStartInst &I) override {
446006f32e7eSjoerg     IRBuilder<> IRB(&I);
446106f32e7eSjoerg     VAStartInstrumentationList.push_back(&I);
446206f32e7eSjoerg     Value *VAListTag = I.getArgOperand(0);
446306f32e7eSjoerg     Value *ShadowPtr, *OriginPtr;
4464*da58b97aSjoerg     const Align Alignment = Align(8);
446506f32e7eSjoerg     std::tie(ShadowPtr, OriginPtr) = MSV.getShadowOriginPtr(
446606f32e7eSjoerg         VAListTag, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ true);
446706f32e7eSjoerg     IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
446806f32e7eSjoerg                      /* size */ 8, Alignment, false);
446906f32e7eSjoerg   }
447006f32e7eSjoerg 
visitVACopyInst__anonb9e144640811::VarArgMIPS64Helper447106f32e7eSjoerg   void visitVACopyInst(VACopyInst &I) override {
447206f32e7eSjoerg     IRBuilder<> IRB(&I);
447306f32e7eSjoerg     VAStartInstrumentationList.push_back(&I);
447406f32e7eSjoerg     Value *VAListTag = I.getArgOperand(0);
447506f32e7eSjoerg     Value *ShadowPtr, *OriginPtr;
4476*da58b97aSjoerg     const Align Alignment = Align(8);
447706f32e7eSjoerg     std::tie(ShadowPtr, OriginPtr) = MSV.getShadowOriginPtr(
447806f32e7eSjoerg         VAListTag, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ true);
447906f32e7eSjoerg     IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
448006f32e7eSjoerg                      /* size */ 8, Alignment, false);
448106f32e7eSjoerg   }
448206f32e7eSjoerg 
finalizeInstrumentation__anonb9e144640811::VarArgMIPS64Helper448306f32e7eSjoerg   void finalizeInstrumentation() override {
448406f32e7eSjoerg     assert(!VAArgSize && !VAArgTLSCopy &&
448506f32e7eSjoerg            "finalizeInstrumentation called twice");
4486*da58b97aSjoerg     IRBuilder<> IRB(MSV.FnPrologueEnd);
448706f32e7eSjoerg     VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
448806f32e7eSjoerg     Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0),
448906f32e7eSjoerg                                     VAArgSize);
449006f32e7eSjoerg 
449106f32e7eSjoerg     if (!VAStartInstrumentationList.empty()) {
449206f32e7eSjoerg       // If there is a va_start in this function, make a backup copy of
449306f32e7eSjoerg       // va_arg_tls somewhere in the function entry block.
449406f32e7eSjoerg       VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
4495*da58b97aSjoerg       IRB.CreateMemCpy(VAArgTLSCopy, Align(8), MS.VAArgTLS, Align(8), CopySize);
449606f32e7eSjoerg     }
449706f32e7eSjoerg 
449806f32e7eSjoerg     // Instrument va_start.
449906f32e7eSjoerg     // Copy va_list shadow from the backup copy of the TLS contents.
450006f32e7eSjoerg     for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) {
450106f32e7eSjoerg       CallInst *OrigInst = VAStartInstrumentationList[i];
450206f32e7eSjoerg       IRBuilder<> IRB(OrigInst->getNextNode());
450306f32e7eSjoerg       Value *VAListTag = OrigInst->getArgOperand(0);
450406f32e7eSjoerg       Type *RegSaveAreaPtrTy = Type::getInt64PtrTy(*MS.C);
450506f32e7eSjoerg       Value *RegSaveAreaPtrPtr =
450606f32e7eSjoerg           IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
450706f32e7eSjoerg                              PointerType::get(RegSaveAreaPtrTy, 0));
450806f32e7eSjoerg       Value *RegSaveAreaPtr =
450906f32e7eSjoerg           IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
451006f32e7eSjoerg       Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
4511*da58b97aSjoerg       const Align Alignment = Align(8);
451206f32e7eSjoerg       std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
451306f32e7eSjoerg           MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
451406f32e7eSjoerg                                  Alignment, /*isStore*/ true);
451506f32e7eSjoerg       IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
451606f32e7eSjoerg                        CopySize);
451706f32e7eSjoerg     }
451806f32e7eSjoerg   }
451906f32e7eSjoerg };
452006f32e7eSjoerg 
452106f32e7eSjoerg /// AArch64-specific implementation of VarArgHelper.
452206f32e7eSjoerg struct VarArgAArch64Helper : public VarArgHelper {
452306f32e7eSjoerg   static const unsigned kAArch64GrArgSize = 64;
452406f32e7eSjoerg   static const unsigned kAArch64VrArgSize = 128;
452506f32e7eSjoerg 
452606f32e7eSjoerg   static const unsigned AArch64GrBegOffset = 0;
452706f32e7eSjoerg   static const unsigned AArch64GrEndOffset = kAArch64GrArgSize;
452806f32e7eSjoerg   // Make VR space aligned to 16 bytes.
452906f32e7eSjoerg   static const unsigned AArch64VrBegOffset = AArch64GrEndOffset;
453006f32e7eSjoerg   static const unsigned AArch64VrEndOffset = AArch64VrBegOffset
453106f32e7eSjoerg                                              + kAArch64VrArgSize;
453206f32e7eSjoerg   static const unsigned AArch64VAEndOffset = AArch64VrEndOffset;
453306f32e7eSjoerg 
453406f32e7eSjoerg   Function &F;
453506f32e7eSjoerg   MemorySanitizer &MS;
453606f32e7eSjoerg   MemorySanitizerVisitor &MSV;
453706f32e7eSjoerg   Value *VAArgTLSCopy = nullptr;
453806f32e7eSjoerg   Value *VAArgOverflowSize = nullptr;
453906f32e7eSjoerg 
454006f32e7eSjoerg   SmallVector<CallInst*, 16> VAStartInstrumentationList;
454106f32e7eSjoerg 
454206f32e7eSjoerg   enum ArgKind { AK_GeneralPurpose, AK_FloatingPoint, AK_Memory };
454306f32e7eSjoerg 
VarArgAArch64Helper__anonb9e144640811::VarArgAArch64Helper454406f32e7eSjoerg   VarArgAArch64Helper(Function &F, MemorySanitizer &MS,
454506f32e7eSjoerg                     MemorySanitizerVisitor &MSV) : F(F), MS(MS), MSV(MSV) {}
454606f32e7eSjoerg 
classifyArgument__anonb9e144640811::VarArgAArch64Helper454706f32e7eSjoerg   ArgKind classifyArgument(Value* arg) {
454806f32e7eSjoerg     Type *T = arg->getType();
454906f32e7eSjoerg     if (T->isFPOrFPVectorTy())
455006f32e7eSjoerg       return AK_FloatingPoint;
455106f32e7eSjoerg     if ((T->isIntegerTy() && T->getPrimitiveSizeInBits() <= 64)
455206f32e7eSjoerg         || (T->isPointerTy()))
455306f32e7eSjoerg       return AK_GeneralPurpose;
455406f32e7eSjoerg     return AK_Memory;
455506f32e7eSjoerg   }
455606f32e7eSjoerg 
455706f32e7eSjoerg   // The instrumentation stores the argument shadow in a non ABI-specific
455806f32e7eSjoerg   // format because it does not know which argument is named (since Clang,
455906f32e7eSjoerg   // like x86_64 case, lowers the va_args in the frontend and this pass only
456006f32e7eSjoerg   // sees the low level code that deals with va_list internals).
456106f32e7eSjoerg   // The first seven GR registers are saved in the first 56 bytes of the
456206f32e7eSjoerg   // va_arg tls arra, followers by the first 8 FP/SIMD registers, and then
456306f32e7eSjoerg   // the remaining arguments.
456406f32e7eSjoerg   // Using constant offset within the va_arg TLS array allows fast copy
456506f32e7eSjoerg   // in the finalize instrumentation.
visitCallBase__anonb9e144640811::VarArgAArch64Helper4566*da58b97aSjoerg   void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
456706f32e7eSjoerg     unsigned GrOffset = AArch64GrBegOffset;
456806f32e7eSjoerg     unsigned VrOffset = AArch64VrBegOffset;
456906f32e7eSjoerg     unsigned OverflowOffset = AArch64VAEndOffset;
457006f32e7eSjoerg 
457106f32e7eSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
4572*da58b97aSjoerg     for (auto ArgIt = CB.arg_begin(), End = CB.arg_end(); ArgIt != End;
4573*da58b97aSjoerg          ++ArgIt) {
457406f32e7eSjoerg       Value *A = *ArgIt;
4575*da58b97aSjoerg       unsigned ArgNo = CB.getArgOperandNo(ArgIt);
4576*da58b97aSjoerg       bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
457706f32e7eSjoerg       ArgKind AK = classifyArgument(A);
457806f32e7eSjoerg       if (AK == AK_GeneralPurpose && GrOffset >= AArch64GrEndOffset)
457906f32e7eSjoerg         AK = AK_Memory;
458006f32e7eSjoerg       if (AK == AK_FloatingPoint && VrOffset >= AArch64VrEndOffset)
458106f32e7eSjoerg         AK = AK_Memory;
458206f32e7eSjoerg       Value *Base;
458306f32e7eSjoerg       switch (AK) {
458406f32e7eSjoerg         case AK_GeneralPurpose:
458506f32e7eSjoerg           Base = getShadowPtrForVAArgument(A->getType(), IRB, GrOffset, 8);
458606f32e7eSjoerg           GrOffset += 8;
458706f32e7eSjoerg           break;
458806f32e7eSjoerg         case AK_FloatingPoint:
458906f32e7eSjoerg           Base = getShadowPtrForVAArgument(A->getType(), IRB, VrOffset, 8);
459006f32e7eSjoerg           VrOffset += 16;
459106f32e7eSjoerg           break;
459206f32e7eSjoerg         case AK_Memory:
459306f32e7eSjoerg           // Don't count fixed arguments in the overflow area - va_start will
459406f32e7eSjoerg           // skip right over them.
459506f32e7eSjoerg           if (IsFixed)
459606f32e7eSjoerg             continue;
459706f32e7eSjoerg           uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
459806f32e7eSjoerg           Base = getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset,
459906f32e7eSjoerg                                            alignTo(ArgSize, 8));
460006f32e7eSjoerg           OverflowOffset += alignTo(ArgSize, 8);
460106f32e7eSjoerg           break;
460206f32e7eSjoerg       }
460306f32e7eSjoerg       // Count Gp/Vr fixed arguments to their respective offsets, but don't
460406f32e7eSjoerg       // bother to actually store a shadow.
460506f32e7eSjoerg       if (IsFixed)
460606f32e7eSjoerg         continue;
460706f32e7eSjoerg       if (!Base)
460806f32e7eSjoerg         continue;
460906f32e7eSjoerg       IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
461006f32e7eSjoerg     }
461106f32e7eSjoerg     Constant *OverflowSize =
461206f32e7eSjoerg       ConstantInt::get(IRB.getInt64Ty(), OverflowOffset - AArch64VAEndOffset);
461306f32e7eSjoerg     IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
461406f32e7eSjoerg   }
461506f32e7eSjoerg 
461606f32e7eSjoerg   /// Compute the shadow address for a given va_arg.
getShadowPtrForVAArgument__anonb9e144640811::VarArgAArch64Helper461706f32e7eSjoerg   Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB,
461806f32e7eSjoerg                                    unsigned ArgOffset, unsigned ArgSize) {
461906f32e7eSjoerg     // Make sure we don't overflow __msan_va_arg_tls.
462006f32e7eSjoerg     if (ArgOffset + ArgSize > kParamTLSSize)
462106f32e7eSjoerg       return nullptr;
462206f32e7eSjoerg     Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
462306f32e7eSjoerg     Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
462406f32e7eSjoerg     return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0),
462506f32e7eSjoerg                               "_msarg");
462606f32e7eSjoerg   }
462706f32e7eSjoerg 
visitVAStartInst__anonb9e144640811::VarArgAArch64Helper462806f32e7eSjoerg   void visitVAStartInst(VAStartInst &I) override {
462906f32e7eSjoerg     IRBuilder<> IRB(&I);
463006f32e7eSjoerg     VAStartInstrumentationList.push_back(&I);
463106f32e7eSjoerg     Value *VAListTag = I.getArgOperand(0);
463206f32e7eSjoerg     Value *ShadowPtr, *OriginPtr;
4633*da58b97aSjoerg     const Align Alignment = Align(8);
463406f32e7eSjoerg     std::tie(ShadowPtr, OriginPtr) = MSV.getShadowOriginPtr(
463506f32e7eSjoerg         VAListTag, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ true);
463606f32e7eSjoerg     IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
463706f32e7eSjoerg                      /* size */ 32, Alignment, false);
463806f32e7eSjoerg   }
463906f32e7eSjoerg 
visitVACopyInst__anonb9e144640811::VarArgAArch64Helper464006f32e7eSjoerg   void visitVACopyInst(VACopyInst &I) override {
464106f32e7eSjoerg     IRBuilder<> IRB(&I);
464206f32e7eSjoerg     VAStartInstrumentationList.push_back(&I);
464306f32e7eSjoerg     Value *VAListTag = I.getArgOperand(0);
464406f32e7eSjoerg     Value *ShadowPtr, *OriginPtr;
4645*da58b97aSjoerg     const Align Alignment = Align(8);
464606f32e7eSjoerg     std::tie(ShadowPtr, OriginPtr) = MSV.getShadowOriginPtr(
464706f32e7eSjoerg         VAListTag, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ true);
464806f32e7eSjoerg     IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
464906f32e7eSjoerg                      /* size */ 32, Alignment, false);
465006f32e7eSjoerg   }
465106f32e7eSjoerg 
465206f32e7eSjoerg   // Retrieve a va_list field of 'void*' size.
getVAField64__anonb9e144640811::VarArgAArch64Helper465306f32e7eSjoerg   Value* getVAField64(IRBuilder<> &IRB, Value *VAListTag, int offset) {
465406f32e7eSjoerg     Value *SaveAreaPtrPtr =
465506f32e7eSjoerg       IRB.CreateIntToPtr(
465606f32e7eSjoerg         IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
465706f32e7eSjoerg                       ConstantInt::get(MS.IntptrTy, offset)),
465806f32e7eSjoerg         Type::getInt64PtrTy(*MS.C));
465906f32e7eSjoerg     return IRB.CreateLoad(Type::getInt64Ty(*MS.C), SaveAreaPtrPtr);
466006f32e7eSjoerg   }
466106f32e7eSjoerg 
466206f32e7eSjoerg   // Retrieve a va_list field of 'int' size.
getVAField32__anonb9e144640811::VarArgAArch64Helper466306f32e7eSjoerg   Value* getVAField32(IRBuilder<> &IRB, Value *VAListTag, int offset) {
466406f32e7eSjoerg     Value *SaveAreaPtr =
466506f32e7eSjoerg       IRB.CreateIntToPtr(
466606f32e7eSjoerg         IRB.CreateAdd(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
466706f32e7eSjoerg                       ConstantInt::get(MS.IntptrTy, offset)),
466806f32e7eSjoerg         Type::getInt32PtrTy(*MS.C));
466906f32e7eSjoerg     Value *SaveArea32 = IRB.CreateLoad(IRB.getInt32Ty(), SaveAreaPtr);
467006f32e7eSjoerg     return IRB.CreateSExt(SaveArea32, MS.IntptrTy);
467106f32e7eSjoerg   }
467206f32e7eSjoerg 
finalizeInstrumentation__anonb9e144640811::VarArgAArch64Helper467306f32e7eSjoerg   void finalizeInstrumentation() override {
467406f32e7eSjoerg     assert(!VAArgOverflowSize && !VAArgTLSCopy &&
467506f32e7eSjoerg            "finalizeInstrumentation called twice");
467606f32e7eSjoerg     if (!VAStartInstrumentationList.empty()) {
467706f32e7eSjoerg       // If there is a va_start in this function, make a backup copy of
467806f32e7eSjoerg       // va_arg_tls somewhere in the function entry block.
4679*da58b97aSjoerg       IRBuilder<> IRB(MSV.FnPrologueEnd);
468006f32e7eSjoerg       VAArgOverflowSize =
468106f32e7eSjoerg           IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
468206f32e7eSjoerg       Value *CopySize =
468306f32e7eSjoerg         IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, AArch64VAEndOffset),
468406f32e7eSjoerg                       VAArgOverflowSize);
468506f32e7eSjoerg       VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
4686*da58b97aSjoerg       IRB.CreateMemCpy(VAArgTLSCopy, Align(8), MS.VAArgTLS, Align(8), CopySize);
468706f32e7eSjoerg     }
468806f32e7eSjoerg 
468906f32e7eSjoerg     Value *GrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64GrArgSize);
469006f32e7eSjoerg     Value *VrArgSize = ConstantInt::get(MS.IntptrTy, kAArch64VrArgSize);
469106f32e7eSjoerg 
469206f32e7eSjoerg     // Instrument va_start, copy va_list shadow from the backup copy of
469306f32e7eSjoerg     // the TLS contents.
469406f32e7eSjoerg     for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) {
469506f32e7eSjoerg       CallInst *OrigInst = VAStartInstrumentationList[i];
469606f32e7eSjoerg       IRBuilder<> IRB(OrigInst->getNextNode());
469706f32e7eSjoerg 
469806f32e7eSjoerg       Value *VAListTag = OrigInst->getArgOperand(0);
469906f32e7eSjoerg 
470006f32e7eSjoerg       // The variadic ABI for AArch64 creates two areas to save the incoming
470106f32e7eSjoerg       // argument registers (one for 64-bit general register xn-x7 and another
470206f32e7eSjoerg       // for 128-bit FP/SIMD vn-v7).
470306f32e7eSjoerg       // We need then to propagate the shadow arguments on both regions
470406f32e7eSjoerg       // 'va::__gr_top + va::__gr_offs' and 'va::__vr_top + va::__vr_offs'.
4705*da58b97aSjoerg       // The remaining arguments are saved on shadow for 'va::stack'.
470606f32e7eSjoerg       // One caveat is it requires only to propagate the non-named arguments,
470706f32e7eSjoerg       // however on the call site instrumentation 'all' the arguments are
470806f32e7eSjoerg       // saved. So to copy the shadow values from the va_arg TLS array
470906f32e7eSjoerg       // we need to adjust the offset for both GR and VR fields based on
471006f32e7eSjoerg       // the __{gr,vr}_offs value (since they are stores based on incoming
471106f32e7eSjoerg       // named arguments).
471206f32e7eSjoerg 
471306f32e7eSjoerg       // Read the stack pointer from the va_list.
471406f32e7eSjoerg       Value *StackSaveAreaPtr = getVAField64(IRB, VAListTag, 0);
471506f32e7eSjoerg 
471606f32e7eSjoerg       // Read both the __gr_top and __gr_off and add them up.
471706f32e7eSjoerg       Value *GrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 8);
471806f32e7eSjoerg       Value *GrOffSaveArea = getVAField32(IRB, VAListTag, 24);
471906f32e7eSjoerg 
472006f32e7eSjoerg       Value *GrRegSaveAreaPtr = IRB.CreateAdd(GrTopSaveAreaPtr, GrOffSaveArea);
472106f32e7eSjoerg 
472206f32e7eSjoerg       // Read both the __vr_top and __vr_off and add them up.
472306f32e7eSjoerg       Value *VrTopSaveAreaPtr = getVAField64(IRB, VAListTag, 16);
472406f32e7eSjoerg       Value *VrOffSaveArea = getVAField32(IRB, VAListTag, 28);
472506f32e7eSjoerg 
472606f32e7eSjoerg       Value *VrRegSaveAreaPtr = IRB.CreateAdd(VrTopSaveAreaPtr, VrOffSaveArea);
472706f32e7eSjoerg 
472806f32e7eSjoerg       // It does not know how many named arguments is being used and, on the
472906f32e7eSjoerg       // callsite all the arguments were saved.  Since __gr_off is defined as
473006f32e7eSjoerg       // '0 - ((8 - named_gr) * 8)', the idea is to just propagate the variadic
473106f32e7eSjoerg       // argument by ignoring the bytes of shadow from named arguments.
473206f32e7eSjoerg       Value *GrRegSaveAreaShadowPtrOff =
473306f32e7eSjoerg         IRB.CreateAdd(GrArgSize, GrOffSaveArea);
473406f32e7eSjoerg 
473506f32e7eSjoerg       Value *GrRegSaveAreaShadowPtr =
473606f32e7eSjoerg           MSV.getShadowOriginPtr(GrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
4737*da58b97aSjoerg                                  Align(8), /*isStore*/ true)
473806f32e7eSjoerg               .first;
473906f32e7eSjoerg 
474006f32e7eSjoerg       Value *GrSrcPtr = IRB.CreateInBoundsGEP(IRB.getInt8Ty(), VAArgTLSCopy,
474106f32e7eSjoerg                                               GrRegSaveAreaShadowPtrOff);
474206f32e7eSjoerg       Value *GrCopySize = IRB.CreateSub(GrArgSize, GrRegSaveAreaShadowPtrOff);
474306f32e7eSjoerg 
4744*da58b97aSjoerg       IRB.CreateMemCpy(GrRegSaveAreaShadowPtr, Align(8), GrSrcPtr, Align(8),
4745*da58b97aSjoerg                        GrCopySize);
474606f32e7eSjoerg 
474706f32e7eSjoerg       // Again, but for FP/SIMD values.
474806f32e7eSjoerg       Value *VrRegSaveAreaShadowPtrOff =
474906f32e7eSjoerg           IRB.CreateAdd(VrArgSize, VrOffSaveArea);
475006f32e7eSjoerg 
475106f32e7eSjoerg       Value *VrRegSaveAreaShadowPtr =
475206f32e7eSjoerg           MSV.getShadowOriginPtr(VrRegSaveAreaPtr, IRB, IRB.getInt8Ty(),
4753*da58b97aSjoerg                                  Align(8), /*isStore*/ true)
475406f32e7eSjoerg               .first;
475506f32e7eSjoerg 
475606f32e7eSjoerg       Value *VrSrcPtr = IRB.CreateInBoundsGEP(
475706f32e7eSjoerg         IRB.getInt8Ty(),
475806f32e7eSjoerg         IRB.CreateInBoundsGEP(IRB.getInt8Ty(), VAArgTLSCopy,
475906f32e7eSjoerg                               IRB.getInt32(AArch64VrBegOffset)),
476006f32e7eSjoerg         VrRegSaveAreaShadowPtrOff);
476106f32e7eSjoerg       Value *VrCopySize = IRB.CreateSub(VrArgSize, VrRegSaveAreaShadowPtrOff);
476206f32e7eSjoerg 
4763*da58b97aSjoerg       IRB.CreateMemCpy(VrRegSaveAreaShadowPtr, Align(8), VrSrcPtr, Align(8),
4764*da58b97aSjoerg                        VrCopySize);
476506f32e7eSjoerg 
476606f32e7eSjoerg       // And finally for remaining arguments.
476706f32e7eSjoerg       Value *StackSaveAreaShadowPtr =
476806f32e7eSjoerg           MSV.getShadowOriginPtr(StackSaveAreaPtr, IRB, IRB.getInt8Ty(),
4769*da58b97aSjoerg                                  Align(16), /*isStore*/ true)
477006f32e7eSjoerg               .first;
477106f32e7eSjoerg 
477206f32e7eSjoerg       Value *StackSrcPtr =
477306f32e7eSjoerg         IRB.CreateInBoundsGEP(IRB.getInt8Ty(), VAArgTLSCopy,
477406f32e7eSjoerg                               IRB.getInt32(AArch64VAEndOffset));
477506f32e7eSjoerg 
4776*da58b97aSjoerg       IRB.CreateMemCpy(StackSaveAreaShadowPtr, Align(16), StackSrcPtr,
4777*da58b97aSjoerg                        Align(16), VAArgOverflowSize);
477806f32e7eSjoerg     }
477906f32e7eSjoerg   }
478006f32e7eSjoerg };
478106f32e7eSjoerg 
478206f32e7eSjoerg /// PowerPC64-specific implementation of VarArgHelper.
478306f32e7eSjoerg struct VarArgPowerPC64Helper : public VarArgHelper {
478406f32e7eSjoerg   Function &F;
478506f32e7eSjoerg   MemorySanitizer &MS;
478606f32e7eSjoerg   MemorySanitizerVisitor &MSV;
478706f32e7eSjoerg   Value *VAArgTLSCopy = nullptr;
478806f32e7eSjoerg   Value *VAArgSize = nullptr;
478906f32e7eSjoerg 
479006f32e7eSjoerg   SmallVector<CallInst*, 16> VAStartInstrumentationList;
479106f32e7eSjoerg 
VarArgPowerPC64Helper__anonb9e144640811::VarArgPowerPC64Helper479206f32e7eSjoerg   VarArgPowerPC64Helper(Function &F, MemorySanitizer &MS,
479306f32e7eSjoerg                     MemorySanitizerVisitor &MSV) : F(F), MS(MS), MSV(MSV) {}
479406f32e7eSjoerg 
visitCallBase__anonb9e144640811::VarArgPowerPC64Helper4795*da58b97aSjoerg   void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
479606f32e7eSjoerg     // For PowerPC, we need to deal with alignment of stack arguments -
479706f32e7eSjoerg     // they are mostly aligned to 8 bytes, but vectors and i128 arrays
479806f32e7eSjoerg     // are aligned to 16 bytes, byvals can be aligned to 8 or 16 bytes,
4799*da58b97aSjoerg     // For that reason, we compute current offset from stack pointer (which is
4800*da58b97aSjoerg     // always properly aligned), and offset for the first vararg, then subtract
4801*da58b97aSjoerg     // them.
480206f32e7eSjoerg     unsigned VAArgBase;
480306f32e7eSjoerg     Triple TargetTriple(F.getParent()->getTargetTriple());
480406f32e7eSjoerg     // Parameter save area starts at 48 bytes from frame pointer for ABIv1,
480506f32e7eSjoerg     // and 32 bytes for ABIv2.  This is usually determined by target
4806*da58b97aSjoerg     // endianness, but in theory could be overridden by function attribute.
480706f32e7eSjoerg     if (TargetTriple.getArch() == Triple::ppc64)
480806f32e7eSjoerg       VAArgBase = 48;
480906f32e7eSjoerg     else
481006f32e7eSjoerg       VAArgBase = 32;
481106f32e7eSjoerg     unsigned VAArgOffset = VAArgBase;
481206f32e7eSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
4813*da58b97aSjoerg     for (auto ArgIt = CB.arg_begin(), End = CB.arg_end(); ArgIt != End;
4814*da58b97aSjoerg          ++ArgIt) {
481506f32e7eSjoerg       Value *A = *ArgIt;
4816*da58b97aSjoerg       unsigned ArgNo = CB.getArgOperandNo(ArgIt);
4817*da58b97aSjoerg       bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
4818*da58b97aSjoerg       bool IsByVal = CB.paramHasAttr(ArgNo, Attribute::ByVal);
481906f32e7eSjoerg       if (IsByVal) {
482006f32e7eSjoerg         assert(A->getType()->isPointerTy());
4821*da58b97aSjoerg         Type *RealTy = CB.getParamByValType(ArgNo);
482206f32e7eSjoerg         uint64_t ArgSize = DL.getTypeAllocSize(RealTy);
4823*da58b97aSjoerg         MaybeAlign ArgAlign = CB.getParamAlign(ArgNo);
4824*da58b97aSjoerg         if (!ArgAlign || *ArgAlign < Align(8))
4825*da58b97aSjoerg           ArgAlign = Align(8);
482606f32e7eSjoerg         VAArgOffset = alignTo(VAArgOffset, ArgAlign);
482706f32e7eSjoerg         if (!IsFixed) {
482806f32e7eSjoerg           Value *Base = getShadowPtrForVAArgument(
482906f32e7eSjoerg               RealTy, IRB, VAArgOffset - VAArgBase, ArgSize);
483006f32e7eSjoerg           if (Base) {
483106f32e7eSjoerg             Value *AShadowPtr, *AOriginPtr;
483206f32e7eSjoerg             std::tie(AShadowPtr, AOriginPtr) =
483306f32e7eSjoerg                 MSV.getShadowOriginPtr(A, IRB, IRB.getInt8Ty(),
483406f32e7eSjoerg                                        kShadowTLSAlignment, /*isStore*/ false);
483506f32e7eSjoerg 
483606f32e7eSjoerg             IRB.CreateMemCpy(Base, kShadowTLSAlignment, AShadowPtr,
483706f32e7eSjoerg                              kShadowTLSAlignment, ArgSize);
483806f32e7eSjoerg           }
483906f32e7eSjoerg         }
484006f32e7eSjoerg         VAArgOffset += alignTo(ArgSize, 8);
484106f32e7eSjoerg       } else {
484206f32e7eSjoerg         Value *Base;
484306f32e7eSjoerg         uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
484406f32e7eSjoerg         uint64_t ArgAlign = 8;
484506f32e7eSjoerg         if (A->getType()->isArrayTy()) {
484606f32e7eSjoerg           // Arrays are aligned to element size, except for long double
484706f32e7eSjoerg           // arrays, which are aligned to 8 bytes.
484806f32e7eSjoerg           Type *ElementTy = A->getType()->getArrayElementType();
484906f32e7eSjoerg           if (!ElementTy->isPPC_FP128Ty())
485006f32e7eSjoerg             ArgAlign = DL.getTypeAllocSize(ElementTy);
485106f32e7eSjoerg         } else if (A->getType()->isVectorTy()) {
485206f32e7eSjoerg           // Vectors are naturally aligned.
485306f32e7eSjoerg           ArgAlign = DL.getTypeAllocSize(A->getType());
485406f32e7eSjoerg         }
485506f32e7eSjoerg         if (ArgAlign < 8)
485606f32e7eSjoerg           ArgAlign = 8;
485706f32e7eSjoerg         VAArgOffset = alignTo(VAArgOffset, ArgAlign);
485806f32e7eSjoerg         if (DL.isBigEndian()) {
485906f32e7eSjoerg           // Adjusting the shadow for argument with size < 8 to match the placement
486006f32e7eSjoerg           // of bits in big endian system
486106f32e7eSjoerg           if (ArgSize < 8)
486206f32e7eSjoerg             VAArgOffset += (8 - ArgSize);
486306f32e7eSjoerg         }
486406f32e7eSjoerg         if (!IsFixed) {
486506f32e7eSjoerg           Base = getShadowPtrForVAArgument(A->getType(), IRB,
486606f32e7eSjoerg                                            VAArgOffset - VAArgBase, ArgSize);
486706f32e7eSjoerg           if (Base)
486806f32e7eSjoerg             IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
486906f32e7eSjoerg         }
487006f32e7eSjoerg         VAArgOffset += ArgSize;
487106f32e7eSjoerg         VAArgOffset = alignTo(VAArgOffset, 8);
487206f32e7eSjoerg       }
487306f32e7eSjoerg       if (IsFixed)
487406f32e7eSjoerg         VAArgBase = VAArgOffset;
487506f32e7eSjoerg     }
487606f32e7eSjoerg 
487706f32e7eSjoerg     Constant *TotalVAArgSize = ConstantInt::get(IRB.getInt64Ty(),
487806f32e7eSjoerg                                                 VAArgOffset - VAArgBase);
487906f32e7eSjoerg     // Here using VAArgOverflowSizeTLS as VAArgSizeTLS to avoid creation of
488006f32e7eSjoerg     // a new class member i.e. it is the total size of all VarArgs.
488106f32e7eSjoerg     IRB.CreateStore(TotalVAArgSize, MS.VAArgOverflowSizeTLS);
488206f32e7eSjoerg   }
488306f32e7eSjoerg 
488406f32e7eSjoerg   /// Compute the shadow address for a given va_arg.
getShadowPtrForVAArgument__anonb9e144640811::VarArgPowerPC64Helper488506f32e7eSjoerg   Value *getShadowPtrForVAArgument(Type *Ty, IRBuilder<> &IRB,
488606f32e7eSjoerg                                    unsigned ArgOffset, unsigned ArgSize) {
488706f32e7eSjoerg     // Make sure we don't overflow __msan_va_arg_tls.
488806f32e7eSjoerg     if (ArgOffset + ArgSize > kParamTLSSize)
488906f32e7eSjoerg       return nullptr;
489006f32e7eSjoerg     Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
489106f32e7eSjoerg     Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
489206f32e7eSjoerg     return IRB.CreateIntToPtr(Base, PointerType::get(MSV.getShadowTy(Ty), 0),
489306f32e7eSjoerg                               "_msarg");
489406f32e7eSjoerg   }
489506f32e7eSjoerg 
visitVAStartInst__anonb9e144640811::VarArgPowerPC64Helper489606f32e7eSjoerg   void visitVAStartInst(VAStartInst &I) override {
489706f32e7eSjoerg     IRBuilder<> IRB(&I);
489806f32e7eSjoerg     VAStartInstrumentationList.push_back(&I);
489906f32e7eSjoerg     Value *VAListTag = I.getArgOperand(0);
490006f32e7eSjoerg     Value *ShadowPtr, *OriginPtr;
4901*da58b97aSjoerg     const Align Alignment = Align(8);
490206f32e7eSjoerg     std::tie(ShadowPtr, OriginPtr) = MSV.getShadowOriginPtr(
490306f32e7eSjoerg         VAListTag, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ true);
490406f32e7eSjoerg     IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
490506f32e7eSjoerg                      /* size */ 8, Alignment, false);
490606f32e7eSjoerg   }
490706f32e7eSjoerg 
visitVACopyInst__anonb9e144640811::VarArgPowerPC64Helper490806f32e7eSjoerg   void visitVACopyInst(VACopyInst &I) override {
490906f32e7eSjoerg     IRBuilder<> IRB(&I);
491006f32e7eSjoerg     Value *VAListTag = I.getArgOperand(0);
491106f32e7eSjoerg     Value *ShadowPtr, *OriginPtr;
4912*da58b97aSjoerg     const Align Alignment = Align(8);
491306f32e7eSjoerg     std::tie(ShadowPtr, OriginPtr) = MSV.getShadowOriginPtr(
491406f32e7eSjoerg         VAListTag, IRB, IRB.getInt8Ty(), Alignment, /*isStore*/ true);
491506f32e7eSjoerg     // Unpoison the whole __va_list_tag.
491606f32e7eSjoerg     // FIXME: magic ABI constants.
491706f32e7eSjoerg     IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
491806f32e7eSjoerg                      /* size */ 8, Alignment, false);
491906f32e7eSjoerg   }
492006f32e7eSjoerg 
finalizeInstrumentation__anonb9e144640811::VarArgPowerPC64Helper492106f32e7eSjoerg   void finalizeInstrumentation() override {
492206f32e7eSjoerg     assert(!VAArgSize && !VAArgTLSCopy &&
492306f32e7eSjoerg            "finalizeInstrumentation called twice");
4924*da58b97aSjoerg     IRBuilder<> IRB(MSV.FnPrologueEnd);
492506f32e7eSjoerg     VAArgSize = IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
492606f32e7eSjoerg     Value *CopySize = IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, 0),
492706f32e7eSjoerg                                     VAArgSize);
492806f32e7eSjoerg 
492906f32e7eSjoerg     if (!VAStartInstrumentationList.empty()) {
493006f32e7eSjoerg       // If there is a va_start in this function, make a backup copy of
493106f32e7eSjoerg       // va_arg_tls somewhere in the function entry block.
493206f32e7eSjoerg       VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
4933*da58b97aSjoerg       IRB.CreateMemCpy(VAArgTLSCopy, Align(8), MS.VAArgTLS, Align(8), CopySize);
493406f32e7eSjoerg     }
493506f32e7eSjoerg 
493606f32e7eSjoerg     // Instrument va_start.
493706f32e7eSjoerg     // Copy va_list shadow from the backup copy of the TLS contents.
493806f32e7eSjoerg     for (size_t i = 0, n = VAStartInstrumentationList.size(); i < n; i++) {
493906f32e7eSjoerg       CallInst *OrigInst = VAStartInstrumentationList[i];
494006f32e7eSjoerg       IRBuilder<> IRB(OrigInst->getNextNode());
494106f32e7eSjoerg       Value *VAListTag = OrigInst->getArgOperand(0);
494206f32e7eSjoerg       Type *RegSaveAreaPtrTy = Type::getInt64PtrTy(*MS.C);
494306f32e7eSjoerg       Value *RegSaveAreaPtrPtr =
494406f32e7eSjoerg           IRB.CreateIntToPtr(IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
494506f32e7eSjoerg                              PointerType::get(RegSaveAreaPtrTy, 0));
494606f32e7eSjoerg       Value *RegSaveAreaPtr =
494706f32e7eSjoerg           IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
494806f32e7eSjoerg       Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
4949*da58b97aSjoerg       const Align Alignment = Align(8);
495006f32e7eSjoerg       std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
495106f32e7eSjoerg           MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(),
495206f32e7eSjoerg                                  Alignment, /*isStore*/ true);
495306f32e7eSjoerg       IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
495406f32e7eSjoerg                        CopySize);
495506f32e7eSjoerg     }
495606f32e7eSjoerg   }
495706f32e7eSjoerg };
495806f32e7eSjoerg 
4959*da58b97aSjoerg /// SystemZ-specific implementation of VarArgHelper.
4960*da58b97aSjoerg struct VarArgSystemZHelper : public VarArgHelper {
4961*da58b97aSjoerg   static const unsigned SystemZGpOffset = 16;
4962*da58b97aSjoerg   static const unsigned SystemZGpEndOffset = 56;
4963*da58b97aSjoerg   static const unsigned SystemZFpOffset = 128;
4964*da58b97aSjoerg   static const unsigned SystemZFpEndOffset = 160;
4965*da58b97aSjoerg   static const unsigned SystemZMaxVrArgs = 8;
4966*da58b97aSjoerg   static const unsigned SystemZRegSaveAreaSize = 160;
4967*da58b97aSjoerg   static const unsigned SystemZOverflowOffset = 160;
4968*da58b97aSjoerg   static const unsigned SystemZVAListTagSize = 32;
4969*da58b97aSjoerg   static const unsigned SystemZOverflowArgAreaPtrOffset = 16;
4970*da58b97aSjoerg   static const unsigned SystemZRegSaveAreaPtrOffset = 24;
4971*da58b97aSjoerg 
4972*da58b97aSjoerg   Function &F;
4973*da58b97aSjoerg   MemorySanitizer &MS;
4974*da58b97aSjoerg   MemorySanitizerVisitor &MSV;
4975*da58b97aSjoerg   Value *VAArgTLSCopy = nullptr;
4976*da58b97aSjoerg   Value *VAArgTLSOriginCopy = nullptr;
4977*da58b97aSjoerg   Value *VAArgOverflowSize = nullptr;
4978*da58b97aSjoerg 
4979*da58b97aSjoerg   SmallVector<CallInst *, 16> VAStartInstrumentationList;
4980*da58b97aSjoerg 
4981*da58b97aSjoerg   enum class ArgKind {
4982*da58b97aSjoerg     GeneralPurpose,
4983*da58b97aSjoerg     FloatingPoint,
4984*da58b97aSjoerg     Vector,
4985*da58b97aSjoerg     Memory,
4986*da58b97aSjoerg     Indirect,
4987*da58b97aSjoerg   };
4988*da58b97aSjoerg 
4989*da58b97aSjoerg   enum class ShadowExtension { None, Zero, Sign };
4990*da58b97aSjoerg 
VarArgSystemZHelper__anonb9e144640811::VarArgSystemZHelper4991*da58b97aSjoerg   VarArgSystemZHelper(Function &F, MemorySanitizer &MS,
4992*da58b97aSjoerg                       MemorySanitizerVisitor &MSV)
4993*da58b97aSjoerg       : F(F), MS(MS), MSV(MSV) {}
4994*da58b97aSjoerg 
classifyArgument__anonb9e144640811::VarArgSystemZHelper4995*da58b97aSjoerg   ArgKind classifyArgument(Type *T, bool IsSoftFloatABI) {
4996*da58b97aSjoerg     // T is a SystemZABIInfo::classifyArgumentType() output, and there are
4997*da58b97aSjoerg     // only a few possibilities of what it can be. In particular, enums, single
4998*da58b97aSjoerg     // element structs and large types have already been taken care of.
4999*da58b97aSjoerg 
5000*da58b97aSjoerg     // Some i128 and fp128 arguments are converted to pointers only in the
5001*da58b97aSjoerg     // back end.
5002*da58b97aSjoerg     if (T->isIntegerTy(128) || T->isFP128Ty())
5003*da58b97aSjoerg       return ArgKind::Indirect;
5004*da58b97aSjoerg     if (T->isFloatingPointTy())
5005*da58b97aSjoerg       return IsSoftFloatABI ? ArgKind::GeneralPurpose : ArgKind::FloatingPoint;
5006*da58b97aSjoerg     if (T->isIntegerTy() || T->isPointerTy())
5007*da58b97aSjoerg       return ArgKind::GeneralPurpose;
5008*da58b97aSjoerg     if (T->isVectorTy())
5009*da58b97aSjoerg       return ArgKind::Vector;
5010*da58b97aSjoerg     return ArgKind::Memory;
5011*da58b97aSjoerg   }
5012*da58b97aSjoerg 
getShadowExtension__anonb9e144640811::VarArgSystemZHelper5013*da58b97aSjoerg   ShadowExtension getShadowExtension(const CallBase &CB, unsigned ArgNo) {
5014*da58b97aSjoerg     // ABI says: "One of the simple integer types no more than 64 bits wide.
5015*da58b97aSjoerg     // ... If such an argument is shorter than 64 bits, replace it by a full
5016*da58b97aSjoerg     // 64-bit integer representing the same number, using sign or zero
5017*da58b97aSjoerg     // extension". Shadow for an integer argument has the same type as the
5018*da58b97aSjoerg     // argument itself, so it can be sign or zero extended as well.
5019*da58b97aSjoerg     bool ZExt = CB.paramHasAttr(ArgNo, Attribute::ZExt);
5020*da58b97aSjoerg     bool SExt = CB.paramHasAttr(ArgNo, Attribute::SExt);
5021*da58b97aSjoerg     if (ZExt) {
5022*da58b97aSjoerg       assert(!SExt);
5023*da58b97aSjoerg       return ShadowExtension::Zero;
5024*da58b97aSjoerg     }
5025*da58b97aSjoerg     if (SExt) {
5026*da58b97aSjoerg       assert(!ZExt);
5027*da58b97aSjoerg       return ShadowExtension::Sign;
5028*da58b97aSjoerg     }
5029*da58b97aSjoerg     return ShadowExtension::None;
5030*da58b97aSjoerg   }
5031*da58b97aSjoerg 
visitCallBase__anonb9e144640811::VarArgSystemZHelper5032*da58b97aSjoerg   void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {
5033*da58b97aSjoerg     bool IsSoftFloatABI = CB.getCalledFunction()
5034*da58b97aSjoerg                               ->getFnAttribute("use-soft-float")
5035*da58b97aSjoerg                               .getValueAsBool();
5036*da58b97aSjoerg     unsigned GpOffset = SystemZGpOffset;
5037*da58b97aSjoerg     unsigned FpOffset = SystemZFpOffset;
5038*da58b97aSjoerg     unsigned VrIndex = 0;
5039*da58b97aSjoerg     unsigned OverflowOffset = SystemZOverflowOffset;
5040*da58b97aSjoerg     const DataLayout &DL = F.getParent()->getDataLayout();
5041*da58b97aSjoerg     for (auto ArgIt = CB.arg_begin(), End = CB.arg_end(); ArgIt != End;
5042*da58b97aSjoerg          ++ArgIt) {
5043*da58b97aSjoerg       Value *A = *ArgIt;
5044*da58b97aSjoerg       unsigned ArgNo = CB.getArgOperandNo(ArgIt);
5045*da58b97aSjoerg       bool IsFixed = ArgNo < CB.getFunctionType()->getNumParams();
5046*da58b97aSjoerg       // SystemZABIInfo does not produce ByVal parameters.
5047*da58b97aSjoerg       assert(!CB.paramHasAttr(ArgNo, Attribute::ByVal));
5048*da58b97aSjoerg       Type *T = A->getType();
5049*da58b97aSjoerg       ArgKind AK = classifyArgument(T, IsSoftFloatABI);
5050*da58b97aSjoerg       if (AK == ArgKind::Indirect) {
5051*da58b97aSjoerg         T = PointerType::get(T, 0);
5052*da58b97aSjoerg         AK = ArgKind::GeneralPurpose;
5053*da58b97aSjoerg       }
5054*da58b97aSjoerg       if (AK == ArgKind::GeneralPurpose && GpOffset >= SystemZGpEndOffset)
5055*da58b97aSjoerg         AK = ArgKind::Memory;
5056*da58b97aSjoerg       if (AK == ArgKind::FloatingPoint && FpOffset >= SystemZFpEndOffset)
5057*da58b97aSjoerg         AK = ArgKind::Memory;
5058*da58b97aSjoerg       if (AK == ArgKind::Vector && (VrIndex >= SystemZMaxVrArgs || !IsFixed))
5059*da58b97aSjoerg         AK = ArgKind::Memory;
5060*da58b97aSjoerg       Value *ShadowBase = nullptr;
5061*da58b97aSjoerg       Value *OriginBase = nullptr;
5062*da58b97aSjoerg       ShadowExtension SE = ShadowExtension::None;
5063*da58b97aSjoerg       switch (AK) {
5064*da58b97aSjoerg       case ArgKind::GeneralPurpose: {
5065*da58b97aSjoerg         // Always keep track of GpOffset, but store shadow only for varargs.
5066*da58b97aSjoerg         uint64_t ArgSize = 8;
5067*da58b97aSjoerg         if (GpOffset + ArgSize <= kParamTLSSize) {
5068*da58b97aSjoerg           if (!IsFixed) {
5069*da58b97aSjoerg             SE = getShadowExtension(CB, ArgNo);
5070*da58b97aSjoerg             uint64_t GapSize = 0;
5071*da58b97aSjoerg             if (SE == ShadowExtension::None) {
5072*da58b97aSjoerg               uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
5073*da58b97aSjoerg               assert(ArgAllocSize <= ArgSize);
5074*da58b97aSjoerg               GapSize = ArgSize - ArgAllocSize;
5075*da58b97aSjoerg             }
5076*da58b97aSjoerg             ShadowBase = getShadowAddrForVAArgument(IRB, GpOffset + GapSize);
5077*da58b97aSjoerg             if (MS.TrackOrigins)
5078*da58b97aSjoerg               OriginBase = getOriginPtrForVAArgument(IRB, GpOffset + GapSize);
5079*da58b97aSjoerg           }
5080*da58b97aSjoerg           GpOffset += ArgSize;
5081*da58b97aSjoerg         } else {
5082*da58b97aSjoerg           GpOffset = kParamTLSSize;
5083*da58b97aSjoerg         }
5084*da58b97aSjoerg         break;
5085*da58b97aSjoerg       }
5086*da58b97aSjoerg       case ArgKind::FloatingPoint: {
5087*da58b97aSjoerg         // Always keep track of FpOffset, but store shadow only for varargs.
5088*da58b97aSjoerg         uint64_t ArgSize = 8;
5089*da58b97aSjoerg         if (FpOffset + ArgSize <= kParamTLSSize) {
5090*da58b97aSjoerg           if (!IsFixed) {
5091*da58b97aSjoerg             // PoP says: "A short floating-point datum requires only the
5092*da58b97aSjoerg             // left-most 32 bit positions of a floating-point register".
5093*da58b97aSjoerg             // Therefore, in contrast to AK_GeneralPurpose and AK_Memory,
5094*da58b97aSjoerg             // don't extend shadow and don't mind the gap.
5095*da58b97aSjoerg             ShadowBase = getShadowAddrForVAArgument(IRB, FpOffset);
5096*da58b97aSjoerg             if (MS.TrackOrigins)
5097*da58b97aSjoerg               OriginBase = getOriginPtrForVAArgument(IRB, FpOffset);
5098*da58b97aSjoerg           }
5099*da58b97aSjoerg           FpOffset += ArgSize;
5100*da58b97aSjoerg         } else {
5101*da58b97aSjoerg           FpOffset = kParamTLSSize;
5102*da58b97aSjoerg         }
5103*da58b97aSjoerg         break;
5104*da58b97aSjoerg       }
5105*da58b97aSjoerg       case ArgKind::Vector: {
5106*da58b97aSjoerg         // Keep track of VrIndex. No need to store shadow, since vector varargs
5107*da58b97aSjoerg         // go through AK_Memory.
5108*da58b97aSjoerg         assert(IsFixed);
5109*da58b97aSjoerg         VrIndex++;
5110*da58b97aSjoerg         break;
5111*da58b97aSjoerg       }
5112*da58b97aSjoerg       case ArgKind::Memory: {
5113*da58b97aSjoerg         // Keep track of OverflowOffset and store shadow only for varargs.
5114*da58b97aSjoerg         // Ignore fixed args, since we need to copy only the vararg portion of
5115*da58b97aSjoerg         // the overflow area shadow.
5116*da58b97aSjoerg         if (!IsFixed) {
5117*da58b97aSjoerg           uint64_t ArgAllocSize = DL.getTypeAllocSize(T);
5118*da58b97aSjoerg           uint64_t ArgSize = alignTo(ArgAllocSize, 8);
5119*da58b97aSjoerg           if (OverflowOffset + ArgSize <= kParamTLSSize) {
5120*da58b97aSjoerg             SE = getShadowExtension(CB, ArgNo);
5121*da58b97aSjoerg             uint64_t GapSize =
5122*da58b97aSjoerg                 SE == ShadowExtension::None ? ArgSize - ArgAllocSize : 0;
5123*da58b97aSjoerg             ShadowBase =
5124*da58b97aSjoerg                 getShadowAddrForVAArgument(IRB, OverflowOffset + GapSize);
5125*da58b97aSjoerg             if (MS.TrackOrigins)
5126*da58b97aSjoerg               OriginBase =
5127*da58b97aSjoerg                   getOriginPtrForVAArgument(IRB, OverflowOffset + GapSize);
5128*da58b97aSjoerg             OverflowOffset += ArgSize;
5129*da58b97aSjoerg           } else {
5130*da58b97aSjoerg             OverflowOffset = kParamTLSSize;
5131*da58b97aSjoerg           }
5132*da58b97aSjoerg         }
5133*da58b97aSjoerg         break;
5134*da58b97aSjoerg       }
5135*da58b97aSjoerg       case ArgKind::Indirect:
5136*da58b97aSjoerg         llvm_unreachable("Indirect must be converted to GeneralPurpose");
5137*da58b97aSjoerg       }
5138*da58b97aSjoerg       if (ShadowBase == nullptr)
5139*da58b97aSjoerg         continue;
5140*da58b97aSjoerg       Value *Shadow = MSV.getShadow(A);
5141*da58b97aSjoerg       if (SE != ShadowExtension::None)
5142*da58b97aSjoerg         Shadow = MSV.CreateShadowCast(IRB, Shadow, IRB.getInt64Ty(),
5143*da58b97aSjoerg                                       /*Signed*/ SE == ShadowExtension::Sign);
5144*da58b97aSjoerg       ShadowBase = IRB.CreateIntToPtr(
5145*da58b97aSjoerg           ShadowBase, PointerType::get(Shadow->getType(), 0), "_msarg_va_s");
5146*da58b97aSjoerg       IRB.CreateStore(Shadow, ShadowBase);
5147*da58b97aSjoerg       if (MS.TrackOrigins) {
5148*da58b97aSjoerg         Value *Origin = MSV.getOrigin(A);
5149*da58b97aSjoerg         unsigned StoreSize = DL.getTypeStoreSize(Shadow->getType());
5150*da58b97aSjoerg         MSV.paintOrigin(IRB, Origin, OriginBase, StoreSize,
5151*da58b97aSjoerg                         kMinOriginAlignment);
5152*da58b97aSjoerg       }
5153*da58b97aSjoerg     }
5154*da58b97aSjoerg     Constant *OverflowSize = ConstantInt::get(
5155*da58b97aSjoerg         IRB.getInt64Ty(), OverflowOffset - SystemZOverflowOffset);
5156*da58b97aSjoerg     IRB.CreateStore(OverflowSize, MS.VAArgOverflowSizeTLS);
5157*da58b97aSjoerg   }
5158*da58b97aSjoerg 
getShadowAddrForVAArgument__anonb9e144640811::VarArgSystemZHelper5159*da58b97aSjoerg   Value *getShadowAddrForVAArgument(IRBuilder<> &IRB, unsigned ArgOffset) {
5160*da58b97aSjoerg     Value *Base = IRB.CreatePointerCast(MS.VAArgTLS, MS.IntptrTy);
5161*da58b97aSjoerg     return IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
5162*da58b97aSjoerg   }
5163*da58b97aSjoerg 
getOriginPtrForVAArgument__anonb9e144640811::VarArgSystemZHelper5164*da58b97aSjoerg   Value *getOriginPtrForVAArgument(IRBuilder<> &IRB, int ArgOffset) {
5165*da58b97aSjoerg     Value *Base = IRB.CreatePointerCast(MS.VAArgOriginTLS, MS.IntptrTy);
5166*da58b97aSjoerg     Base = IRB.CreateAdd(Base, ConstantInt::get(MS.IntptrTy, ArgOffset));
5167*da58b97aSjoerg     return IRB.CreateIntToPtr(Base, PointerType::get(MS.OriginTy, 0),
5168*da58b97aSjoerg                               "_msarg_va_o");
5169*da58b97aSjoerg   }
5170*da58b97aSjoerg 
unpoisonVAListTagForInst__anonb9e144640811::VarArgSystemZHelper5171*da58b97aSjoerg   void unpoisonVAListTagForInst(IntrinsicInst &I) {
5172*da58b97aSjoerg     IRBuilder<> IRB(&I);
5173*da58b97aSjoerg     Value *VAListTag = I.getArgOperand(0);
5174*da58b97aSjoerg     Value *ShadowPtr, *OriginPtr;
5175*da58b97aSjoerg     const Align Alignment = Align(8);
5176*da58b97aSjoerg     std::tie(ShadowPtr, OriginPtr) =
5177*da58b97aSjoerg         MSV.getShadowOriginPtr(VAListTag, IRB, IRB.getInt8Ty(), Alignment,
5178*da58b97aSjoerg                                /*isStore*/ true);
5179*da58b97aSjoerg     IRB.CreateMemSet(ShadowPtr, Constant::getNullValue(IRB.getInt8Ty()),
5180*da58b97aSjoerg                      SystemZVAListTagSize, Alignment, false);
5181*da58b97aSjoerg   }
5182*da58b97aSjoerg 
visitVAStartInst__anonb9e144640811::VarArgSystemZHelper5183*da58b97aSjoerg   void visitVAStartInst(VAStartInst &I) override {
5184*da58b97aSjoerg     VAStartInstrumentationList.push_back(&I);
5185*da58b97aSjoerg     unpoisonVAListTagForInst(I);
5186*da58b97aSjoerg   }
5187*da58b97aSjoerg 
visitVACopyInst__anonb9e144640811::VarArgSystemZHelper5188*da58b97aSjoerg   void visitVACopyInst(VACopyInst &I) override { unpoisonVAListTagForInst(I); }
5189*da58b97aSjoerg 
copyRegSaveArea__anonb9e144640811::VarArgSystemZHelper5190*da58b97aSjoerg   void copyRegSaveArea(IRBuilder<> &IRB, Value *VAListTag) {
5191*da58b97aSjoerg     Type *RegSaveAreaPtrTy = Type::getInt64PtrTy(*MS.C);
5192*da58b97aSjoerg     Value *RegSaveAreaPtrPtr = IRB.CreateIntToPtr(
5193*da58b97aSjoerg         IRB.CreateAdd(
5194*da58b97aSjoerg             IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5195*da58b97aSjoerg             ConstantInt::get(MS.IntptrTy, SystemZRegSaveAreaPtrOffset)),
5196*da58b97aSjoerg         PointerType::get(RegSaveAreaPtrTy, 0));
5197*da58b97aSjoerg     Value *RegSaveAreaPtr = IRB.CreateLoad(RegSaveAreaPtrTy, RegSaveAreaPtrPtr);
5198*da58b97aSjoerg     Value *RegSaveAreaShadowPtr, *RegSaveAreaOriginPtr;
5199*da58b97aSjoerg     const Align Alignment = Align(8);
5200*da58b97aSjoerg     std::tie(RegSaveAreaShadowPtr, RegSaveAreaOriginPtr) =
5201*da58b97aSjoerg         MSV.getShadowOriginPtr(RegSaveAreaPtr, IRB, IRB.getInt8Ty(), Alignment,
5202*da58b97aSjoerg                                /*isStore*/ true);
5203*da58b97aSjoerg     // TODO(iii): copy only fragments filled by visitCallBase()
5204*da58b97aSjoerg     IRB.CreateMemCpy(RegSaveAreaShadowPtr, Alignment, VAArgTLSCopy, Alignment,
5205*da58b97aSjoerg                      SystemZRegSaveAreaSize);
5206*da58b97aSjoerg     if (MS.TrackOrigins)
5207*da58b97aSjoerg       IRB.CreateMemCpy(RegSaveAreaOriginPtr, Alignment, VAArgTLSOriginCopy,
5208*da58b97aSjoerg                        Alignment, SystemZRegSaveAreaSize);
5209*da58b97aSjoerg   }
5210*da58b97aSjoerg 
copyOverflowArea__anonb9e144640811::VarArgSystemZHelper5211*da58b97aSjoerg   void copyOverflowArea(IRBuilder<> &IRB, Value *VAListTag) {
5212*da58b97aSjoerg     Type *OverflowArgAreaPtrTy = Type::getInt64PtrTy(*MS.C);
5213*da58b97aSjoerg     Value *OverflowArgAreaPtrPtr = IRB.CreateIntToPtr(
5214*da58b97aSjoerg         IRB.CreateAdd(
5215*da58b97aSjoerg             IRB.CreatePtrToInt(VAListTag, MS.IntptrTy),
5216*da58b97aSjoerg             ConstantInt::get(MS.IntptrTy, SystemZOverflowArgAreaPtrOffset)),
5217*da58b97aSjoerg         PointerType::get(OverflowArgAreaPtrTy, 0));
5218*da58b97aSjoerg     Value *OverflowArgAreaPtr =
5219*da58b97aSjoerg         IRB.CreateLoad(OverflowArgAreaPtrTy, OverflowArgAreaPtrPtr);
5220*da58b97aSjoerg     Value *OverflowArgAreaShadowPtr, *OverflowArgAreaOriginPtr;
5221*da58b97aSjoerg     const Align Alignment = Align(8);
5222*da58b97aSjoerg     std::tie(OverflowArgAreaShadowPtr, OverflowArgAreaOriginPtr) =
5223*da58b97aSjoerg         MSV.getShadowOriginPtr(OverflowArgAreaPtr, IRB, IRB.getInt8Ty(),
5224*da58b97aSjoerg                                Alignment, /*isStore*/ true);
5225*da58b97aSjoerg     Value *SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSCopy,
5226*da58b97aSjoerg                                            SystemZOverflowOffset);
5227*da58b97aSjoerg     IRB.CreateMemCpy(OverflowArgAreaShadowPtr, Alignment, SrcPtr, Alignment,
5228*da58b97aSjoerg                      VAArgOverflowSize);
5229*da58b97aSjoerg     if (MS.TrackOrigins) {
5230*da58b97aSjoerg       SrcPtr = IRB.CreateConstGEP1_32(IRB.getInt8Ty(), VAArgTLSOriginCopy,
5231*da58b97aSjoerg                                       SystemZOverflowOffset);
5232*da58b97aSjoerg       IRB.CreateMemCpy(OverflowArgAreaOriginPtr, Alignment, SrcPtr, Alignment,
5233*da58b97aSjoerg                        VAArgOverflowSize);
5234*da58b97aSjoerg     }
5235*da58b97aSjoerg   }
5236*da58b97aSjoerg 
finalizeInstrumentation__anonb9e144640811::VarArgSystemZHelper5237*da58b97aSjoerg   void finalizeInstrumentation() override {
5238*da58b97aSjoerg     assert(!VAArgOverflowSize && !VAArgTLSCopy &&
5239*da58b97aSjoerg            "finalizeInstrumentation called twice");
5240*da58b97aSjoerg     if (!VAStartInstrumentationList.empty()) {
5241*da58b97aSjoerg       // If there is a va_start in this function, make a backup copy of
5242*da58b97aSjoerg       // va_arg_tls somewhere in the function entry block.
5243*da58b97aSjoerg       IRBuilder<> IRB(MSV.FnPrologueEnd);
5244*da58b97aSjoerg       VAArgOverflowSize =
5245*da58b97aSjoerg           IRB.CreateLoad(IRB.getInt64Ty(), MS.VAArgOverflowSizeTLS);
5246*da58b97aSjoerg       Value *CopySize =
5247*da58b97aSjoerg           IRB.CreateAdd(ConstantInt::get(MS.IntptrTy, SystemZOverflowOffset),
5248*da58b97aSjoerg                         VAArgOverflowSize);
5249*da58b97aSjoerg       VAArgTLSCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5250*da58b97aSjoerg       IRB.CreateMemCpy(VAArgTLSCopy, Align(8), MS.VAArgTLS, Align(8), CopySize);
5251*da58b97aSjoerg       if (MS.TrackOrigins) {
5252*da58b97aSjoerg         VAArgTLSOriginCopy = IRB.CreateAlloca(Type::getInt8Ty(*MS.C), CopySize);
5253*da58b97aSjoerg         IRB.CreateMemCpy(VAArgTLSOriginCopy, Align(8), MS.VAArgOriginTLS,
5254*da58b97aSjoerg                          Align(8), CopySize);
5255*da58b97aSjoerg       }
5256*da58b97aSjoerg     }
5257*da58b97aSjoerg 
5258*da58b97aSjoerg     // Instrument va_start.
5259*da58b97aSjoerg     // Copy va_list shadow from the backup copy of the TLS contents.
5260*da58b97aSjoerg     for (size_t VaStartNo = 0, VaStartNum = VAStartInstrumentationList.size();
5261*da58b97aSjoerg          VaStartNo < VaStartNum; VaStartNo++) {
5262*da58b97aSjoerg       CallInst *OrigInst = VAStartInstrumentationList[VaStartNo];
5263*da58b97aSjoerg       IRBuilder<> IRB(OrigInst->getNextNode());
5264*da58b97aSjoerg       Value *VAListTag = OrigInst->getArgOperand(0);
5265*da58b97aSjoerg       copyRegSaveArea(IRB, VAListTag);
5266*da58b97aSjoerg       copyOverflowArea(IRB, VAListTag);
5267*da58b97aSjoerg     }
5268*da58b97aSjoerg   }
5269*da58b97aSjoerg };
5270*da58b97aSjoerg 
527106f32e7eSjoerg /// A no-op implementation of VarArgHelper.
527206f32e7eSjoerg struct VarArgNoOpHelper : public VarArgHelper {
VarArgNoOpHelper__anonb9e144640811::VarArgNoOpHelper527306f32e7eSjoerg   VarArgNoOpHelper(Function &F, MemorySanitizer &MS,
527406f32e7eSjoerg                    MemorySanitizerVisitor &MSV) {}
527506f32e7eSjoerg 
visitCallBase__anonb9e144640811::VarArgNoOpHelper5276*da58b97aSjoerg   void visitCallBase(CallBase &CB, IRBuilder<> &IRB) override {}
527706f32e7eSjoerg 
visitVAStartInst__anonb9e144640811::VarArgNoOpHelper527806f32e7eSjoerg   void visitVAStartInst(VAStartInst &I) override {}
527906f32e7eSjoerg 
visitVACopyInst__anonb9e144640811::VarArgNoOpHelper528006f32e7eSjoerg   void visitVACopyInst(VACopyInst &I) override {}
528106f32e7eSjoerg 
finalizeInstrumentation__anonb9e144640811::VarArgNoOpHelper528206f32e7eSjoerg   void finalizeInstrumentation() override {}
528306f32e7eSjoerg };
528406f32e7eSjoerg 
528506f32e7eSjoerg } // end anonymous namespace
528606f32e7eSjoerg 
CreateVarArgHelper(Function & Func,MemorySanitizer & Msan,MemorySanitizerVisitor & Visitor)528706f32e7eSjoerg static VarArgHelper *CreateVarArgHelper(Function &Func, MemorySanitizer &Msan,
528806f32e7eSjoerg                                         MemorySanitizerVisitor &Visitor) {
528906f32e7eSjoerg   // VarArg handling is only implemented on AMD64. False positives are possible
529006f32e7eSjoerg   // on other platforms.
529106f32e7eSjoerg   Triple TargetTriple(Func.getParent()->getTargetTriple());
529206f32e7eSjoerg   if (TargetTriple.getArch() == Triple::x86_64)
529306f32e7eSjoerg     return new VarArgAMD64Helper(Func, Msan, Visitor);
529406f32e7eSjoerg   else if (TargetTriple.isMIPS64())
529506f32e7eSjoerg     return new VarArgMIPS64Helper(Func, Msan, Visitor);
529606f32e7eSjoerg   else if (TargetTriple.getArch() == Triple::aarch64)
529706f32e7eSjoerg     return new VarArgAArch64Helper(Func, Msan, Visitor);
529806f32e7eSjoerg   else if (TargetTriple.getArch() == Triple::ppc64 ||
529906f32e7eSjoerg            TargetTriple.getArch() == Triple::ppc64le)
530006f32e7eSjoerg     return new VarArgPowerPC64Helper(Func, Msan, Visitor);
5301*da58b97aSjoerg   else if (TargetTriple.getArch() == Triple::systemz)
5302*da58b97aSjoerg     return new VarArgSystemZHelper(Func, Msan, Visitor);
530306f32e7eSjoerg   else
530406f32e7eSjoerg     return new VarArgNoOpHelper(Func, Msan, Visitor);
530506f32e7eSjoerg }
530606f32e7eSjoerg 
sanitizeFunction(Function & F,TargetLibraryInfo & TLI)530706f32e7eSjoerg bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
530806f32e7eSjoerg   if (!CompileKernel && F.getName() == kMsanModuleCtorName)
530906f32e7eSjoerg     return false;
531006f32e7eSjoerg 
531106f32e7eSjoerg   MemorySanitizerVisitor Visitor(F, *this, TLI);
531206f32e7eSjoerg 
531306f32e7eSjoerg   // Clear out readonly/readnone attributes.
531406f32e7eSjoerg   AttrBuilder B;
531506f32e7eSjoerg   B.addAttribute(Attribute::ReadOnly)
5316*da58b97aSjoerg       .addAttribute(Attribute::ReadNone)
5317*da58b97aSjoerg       .addAttribute(Attribute::WriteOnly)
5318*da58b97aSjoerg       .addAttribute(Attribute::ArgMemOnly)
5319*da58b97aSjoerg       .addAttribute(Attribute::Speculatable);
532006f32e7eSjoerg   F.removeAttributes(AttributeList::FunctionIndex, B);
532106f32e7eSjoerg 
532206f32e7eSjoerg   return Visitor.runOnFunction();
532306f32e7eSjoerg }
5324