1 //===- HWAddressSanitizer.cpp - detector of uninitialized reads -------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 /// \file
11 /// This file is a part of HWAddressSanitizer, an address sanity checker
12 /// based on tagged addressing.
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/StringExtras.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/Triple.h"
19 #include "llvm/IR/Attributes.h"
20 #include "llvm/IR/BasicBlock.h"
21 #include "llvm/IR/Constant.h"
22 #include "llvm/IR/Constants.h"
23 #include "llvm/IR/DataLayout.h"
24 #include "llvm/IR/DerivedTypes.h"
25 #include "llvm/IR/Function.h"
26 #include "llvm/IR/IRBuilder.h"
27 #include "llvm/IR/InlineAsm.h"
28 #include "llvm/IR/InstVisitor.h"
29 #include "llvm/IR/Instruction.h"
30 #include "llvm/IR/Instructions.h"
31 #include "llvm/IR/IntrinsicInst.h"
32 #include "llvm/IR/Intrinsics.h"
33 #include "llvm/IR/LLVMContext.h"
34 #include "llvm/IR/MDBuilder.h"
35 #include "llvm/IR/Module.h"
36 #include "llvm/IR/Type.h"
37 #include "llvm/IR/Value.h"
38 #include "llvm/Pass.h"
39 #include "llvm/Support/Casting.h"
40 #include "llvm/Support/CommandLine.h"
41 #include "llvm/Support/Debug.h"
42 #include "llvm/Support/raw_ostream.h"
43 #include "llvm/Transforms/Instrumentation.h"
44 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
45 #include "llvm/Transforms/Utils/ModuleUtils.h"
46 #include "llvm/Transforms/Utils/PromoteMemToReg.h"
47 
48 using namespace llvm;
49 
50 #define DEBUG_TYPE "hwasan"
51 
52 static const char *const kHwasanModuleCtorName = "hwasan.module_ctor";
53 static const char *const kHwasanInitName = "__hwasan_init";
54 
55 // Accesses sizes are powers of two: 1, 2, 4, 8, 16.
56 static const size_t kNumberOfAccessSizes = 5;
57 
58 static const size_t kShadowScale = 4;
59 static const unsigned kAllocaAlignment = 1U << kShadowScale;
60 static const unsigned kPointerTagShift = 56;
61 
62 static cl::opt<std::string> ClMemoryAccessCallbackPrefix(
63     "hwasan-memory-access-callback-prefix",
64     cl::desc("Prefix for memory access callbacks"), cl::Hidden,
65     cl::init("__hwasan_"));
66 
67 static cl::opt<bool>
68     ClInstrumentWithCalls("hwasan-instrument-with-calls",
69                 cl::desc("instrument reads and writes with callbacks"),
70                 cl::Hidden, cl::init(false));
71 
72 static cl::opt<bool> ClInstrumentReads("hwasan-instrument-reads",
73                                        cl::desc("instrument read instructions"),
74                                        cl::Hidden, cl::init(true));
75 
76 static cl::opt<bool> ClInstrumentWrites(
77     "hwasan-instrument-writes", cl::desc("instrument write instructions"),
78     cl::Hidden, cl::init(true));
79 
80 static cl::opt<bool> ClInstrumentAtomics(
81     "hwasan-instrument-atomics",
82     cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
83     cl::init(true));
84 
85 static cl::opt<bool> ClRecover(
86     "hwasan-recover",
87     cl::desc("Enable recovery mode (continue-after-error)."),
88     cl::Hidden, cl::init(false));
89 
90 static cl::opt<bool> ClInstrumentStack("hwasan-instrument-stack",
91                                        cl::desc("instrument stack (allocas)"),
92                                        cl::Hidden, cl::init(true));
93 
94 static cl::opt<bool> ClGenerateTagsWithCalls(
95     "hwasan-generate-tags-with-calls",
96     cl::desc("generate new tags with runtime library calls"), cl::Hidden,
97     cl::init(false));
98 
99 static cl::opt<unsigned long long> ClMappingOffset(
100     "hwasan-mapping-offset",
101     cl::desc("offset of hwasan shadow mapping [EXPERIMENTAL]"), cl::Hidden,
102     cl::init(0));
103 
104 static cl::opt<bool> ClEnableKhwasan(
105     "hwasan-kernel", cl::desc("Enable KernelHWAddressSanitizer instrumentation"),
106     cl::Hidden, cl::init(false));
107 
108 namespace {
109 
110 /// \brief An instrumentation pass implementing detection of addressability bugs
111 /// using tagged pointers.
112 class HWAddressSanitizer : public FunctionPass {
113 public:
114   // Pass identification, replacement for typeid.
115   static char ID;
116 
117   HWAddressSanitizer(bool Recover = false)
118       : FunctionPass(ID), Recover(Recover || ClRecover) {}
119 
120   StringRef getPassName() const override { return "HWAddressSanitizer"; }
121 
122   bool runOnFunction(Function &F) override;
123   bool doInitialization(Module &M) override;
124 
125   void initializeCallbacks(Module &M);
126   void instrumentMemAccessInline(Value *PtrLong, bool IsWrite,
127                                  unsigned AccessSizeIndex,
128                                  Instruction *InsertBefore);
129   bool instrumentMemAccess(Instruction *I);
130   Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite,
131                                    uint64_t *TypeSize, unsigned *Alignment,
132                                    Value **MaybeMask);
133 
134   bool isInterestingAlloca(const AllocaInst &AI);
135   bool tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag);
136   bool instrumentStack(SmallVectorImpl<AllocaInst *> &Allocas,
137                        SmallVectorImpl<Instruction *> &RetVec);
138   Value *getNextTagWithCall(IRBuilder<> &IRB);
139   Value *getStackBaseTag(IRBuilder<> &IRB);
140   Value *getAllocaTag(IRBuilder<> &IRB, Value *StackTag, AllocaInst *AI,
141                      unsigned AllocaNo);
142   Value *getUARTag(IRBuilder<> &IRB, Value *StackTag);
143 
144 private:
145   LLVMContext *C;
146   Type *IntptrTy;
147   Type *Int8Ty;
148 
149   bool Recover;
150 
151   Function *HwasanCtorFunction;
152 
153   Function *HwasanMemoryAccessCallback[2][kNumberOfAccessSizes];
154   Function *HwasanMemoryAccessCallbackSized[2];
155 
156   Function *HwasanTagMemoryFunc;
157   Function *HwasanGenerateTagFunc;
158 };
159 
160 } // end anonymous namespace
161 
162 char HWAddressSanitizer::ID = 0;
163 
164 INITIALIZE_PASS_BEGIN(
165     HWAddressSanitizer, "hwasan",
166     "HWAddressSanitizer: detect memory bugs using tagged addressing.", false, false)
167 INITIALIZE_PASS_END(
168     HWAddressSanitizer, "hwasan",
169     "HWAddressSanitizer: detect memory bugs using tagged addressing.", false, false)
170 
171 FunctionPass *llvm::createHWAddressSanitizerPass(bool Recover) {
172   return new HWAddressSanitizer(Recover);
173 }
174 
175 /// \brief Module-level initialization.
176 ///
177 /// inserts a call to __hwasan_init to the module's constructor list.
178 bool HWAddressSanitizer::doInitialization(Module &M) {
179   DEBUG(dbgs() << "Init " << M.getName() << "\n");
180   auto &DL = M.getDataLayout();
181 
182   Triple TargetTriple(M.getTargetTriple());
183 
184   C = &(M.getContext());
185   IRBuilder<> IRB(*C);
186   IntptrTy = IRB.getIntPtrTy(DL);
187   Int8Ty = IRB.getInt8Ty();
188 
189   if (!ClEnableKhwasan) {
190     std::tie(HwasanCtorFunction, std::ignore) =
191         createSanitizerCtorAndInitFunctions(M, kHwasanModuleCtorName,
192                                             kHwasanInitName,
193                                             /*InitArgTypes=*/{},
194                                             /*InitArgs=*/{});
195     appendToGlobalCtors(M, HwasanCtorFunction, 0);
196   }
197   return true;
198 }
199 
200 void HWAddressSanitizer::initializeCallbacks(Module &M) {
201   IRBuilder<> IRB(*C);
202   for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
203     const std::string TypeStr = AccessIsWrite ? "store" : "load";
204     const std::string EndingStr = Recover ? "_noabort" : "";
205 
206     HwasanMemoryAccessCallbackSized[AccessIsWrite] =
207         checkSanitizerInterfaceFunction(M.getOrInsertFunction(
208             ClMemoryAccessCallbackPrefix + TypeStr + "N" + EndingStr,
209             FunctionType::get(IRB.getVoidTy(), {IntptrTy, IntptrTy}, false)));
210 
211     for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
212          AccessSizeIndex++) {
213       HwasanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] =
214           checkSanitizerInterfaceFunction(M.getOrInsertFunction(
215               ClMemoryAccessCallbackPrefix + TypeStr +
216                   itostr(1ULL << AccessSizeIndex) + EndingStr,
217               FunctionType::get(IRB.getVoidTy(), {IntptrTy}, false)));
218     }
219   }
220 
221   HwasanTagMemoryFunc = checkSanitizerInterfaceFunction(M.getOrInsertFunction(
222       "__hwasan_tag_memory", IRB.getVoidTy(), IntptrTy, Int8Ty, IntptrTy));
223   HwasanGenerateTagFunc = checkSanitizerInterfaceFunction(
224       M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty));
225 }
226 
227 Value *HWAddressSanitizer::isInterestingMemoryAccess(Instruction *I,
228                                                    bool *IsWrite,
229                                                    uint64_t *TypeSize,
230                                                    unsigned *Alignment,
231                                                    Value **MaybeMask) {
232   // Skip memory accesses inserted by another instrumentation.
233   if (I->getMetadata("nosanitize")) return nullptr;
234 
235   Value *PtrOperand = nullptr;
236   const DataLayout &DL = I->getModule()->getDataLayout();
237   if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
238     if (!ClInstrumentReads) return nullptr;
239     *IsWrite = false;
240     *TypeSize = DL.getTypeStoreSizeInBits(LI->getType());
241     *Alignment = LI->getAlignment();
242     PtrOperand = LI->getPointerOperand();
243   } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
244     if (!ClInstrumentWrites) return nullptr;
245     *IsWrite = true;
246     *TypeSize = DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType());
247     *Alignment = SI->getAlignment();
248     PtrOperand = SI->getPointerOperand();
249   } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
250     if (!ClInstrumentAtomics) return nullptr;
251     *IsWrite = true;
252     *TypeSize = DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType());
253     *Alignment = 0;
254     PtrOperand = RMW->getPointerOperand();
255   } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
256     if (!ClInstrumentAtomics) return nullptr;
257     *IsWrite = true;
258     *TypeSize = DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType());
259     *Alignment = 0;
260     PtrOperand = XCHG->getPointerOperand();
261   }
262 
263   if (PtrOperand) {
264     // Do not instrument acesses from different address spaces; we cannot deal
265     // with them.
266     Type *PtrTy = cast<PointerType>(PtrOperand->getType()->getScalarType());
267     if (PtrTy->getPointerAddressSpace() != 0)
268       return nullptr;
269 
270     // Ignore swifterror addresses.
271     // swifterror memory addresses are mem2reg promoted by instruction
272     // selection. As such they cannot have regular uses like an instrumentation
273     // function and it makes no sense to track them as memory.
274     if (PtrOperand->isSwiftError())
275       return nullptr;
276   }
277 
278   return PtrOperand;
279 }
280 
281 static size_t TypeSizeToSizeIndex(uint32_t TypeSize) {
282   size_t Res = countTrailingZeros(TypeSize / 8);
283   assert(Res < kNumberOfAccessSizes);
284   return Res;
285 }
286 
287 void HWAddressSanitizer::instrumentMemAccessInline(Value *PtrLong, bool IsWrite,
288                                                    unsigned AccessSizeIndex,
289                                                    Instruction *InsertBefore) {
290   IRBuilder<> IRB(InsertBefore);
291   Value *PtrTag = IRB.CreateTrunc(IRB.CreateLShr(PtrLong, kPointerTagShift), IRB.getInt8Ty());
292   Value *AddrLong =
293       IRB.CreateAnd(PtrLong, ConstantInt::get(PtrLong->getType(),
294                                               ~(0xFFULL << kPointerTagShift)));
295   Value *ShadowLong = IRB.CreateLShr(AddrLong, kShadowScale);
296   if (ClMappingOffset)
297     ShadowLong = IRB.CreateAdd(
298         ShadowLong, ConstantInt::get(PtrLong->getType(), ClMappingOffset,
299                                      /*isSigned=*/false));
300   Value *MemTag =
301       IRB.CreateLoad(IRB.CreateIntToPtr(ShadowLong, IRB.getInt8PtrTy()));
302   Value *TagMismatch = IRB.CreateICmpNE(PtrTag, MemTag);
303 
304   TerminatorInst *CheckTerm =
305       SplitBlockAndInsertIfThen(TagMismatch, InsertBefore, !Recover,
306                                 MDBuilder(*C).createBranchWeights(1, 100000));
307 
308   IRB.SetInsertPoint(CheckTerm);
309   // The signal handler will find the data address in x0.
310   InlineAsm *Asm = InlineAsm::get(
311       FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
312       "hlt #" +
313           itostr(0x100 + Recover * 0x20 + IsWrite * 0x10 + AccessSizeIndex),
314       "{x0}",
315       /*hasSideEffects=*/true);
316   IRB.CreateCall(Asm, PtrLong);
317 }
318 
319 bool HWAddressSanitizer::instrumentMemAccess(Instruction *I) {
320   DEBUG(dbgs() << "Instrumenting: " << *I << "\n");
321   bool IsWrite = false;
322   unsigned Alignment = 0;
323   uint64_t TypeSize = 0;
324   Value *MaybeMask = nullptr;
325   Value *Addr =
326       isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask);
327 
328   if (!Addr)
329     return false;
330 
331   if (MaybeMask)
332     return false; //FIXME
333 
334   IRBuilder<> IRB(I);
335   Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
336   if (isPowerOf2_64(TypeSize) &&
337       (TypeSize / 8 <= (1UL << (kNumberOfAccessSizes - 1))) &&
338       (Alignment >= (1UL << kShadowScale) || Alignment == 0 ||
339        Alignment >= TypeSize / 8)) {
340     size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize);
341     if (ClInstrumentWithCalls) {
342       IRB.CreateCall(HwasanMemoryAccessCallback[IsWrite][AccessSizeIndex],
343                      AddrLong);
344     } else {
345       instrumentMemAccessInline(AddrLong, IsWrite, AccessSizeIndex, I);
346     }
347   } else {
348     IRB.CreateCall(HwasanMemoryAccessCallbackSized[IsWrite],
349                    {AddrLong, ConstantInt::get(IntptrTy, TypeSize / 8)});
350   }
351 
352   return true;
353 }
354 
355 static uint64_t getAllocaSizeInBytes(const AllocaInst &AI) {
356   uint64_t ArraySize = 1;
357   if (AI.isArrayAllocation()) {
358     const ConstantInt *CI = dyn_cast<ConstantInt>(AI.getArraySize());
359     assert(CI && "non-constant array size");
360     ArraySize = CI->getZExtValue();
361   }
362   Type *Ty = AI.getAllocatedType();
363   uint64_t SizeInBytes = AI.getModule()->getDataLayout().getTypeAllocSize(Ty);
364   return SizeInBytes * ArraySize;
365 }
366 
367 bool HWAddressSanitizer::tagAlloca(IRBuilder<> &IRB, AllocaInst *AI,
368                                    Value *Tag) {
369   size_t Size = (getAllocaSizeInBytes(*AI) + kAllocaAlignment - 1) &
370                 ~(kAllocaAlignment - 1);
371 
372   Value *JustTag = IRB.CreateTrunc(Tag, IRB.getInt8Ty());
373   if (ClInstrumentWithCalls) {
374     IRB.CreateCall(HwasanTagMemoryFunc,
375                    {IRB.CreatePointerCast(AI, IntptrTy), JustTag,
376                     ConstantInt::get(IntptrTy, Size)});
377   } else {
378     size_t ShadowSize = Size >> kShadowScale;
379     Value *ShadowPtr = IRB.CreateIntToPtr(
380         IRB.CreateLShr(IRB.CreatePointerCast(AI, IntptrTy), kShadowScale),
381         IRB.getInt8PtrTy());
382     // If this memset is not inlined, it will be intercepted in the hwasan
383     // runtime library. That's OK, because the interceptor skips the checks if
384     // the address is in the shadow region.
385     // FIXME: the interceptor is not as fast as real memset. Consider lowering
386     // llvm.memset right here into either a sequence of stores, or a call to
387     // hwasan_tag_memory.
388     IRB.CreateMemSet(ShadowPtr, JustTag, ShadowSize, /*Align=*/1);
389   }
390   return true;
391 }
392 
393 static unsigned RetagMask(unsigned AllocaNo) {
394   // A list of 8-bit numbers that have at most one run of non-zero bits.
395   // x = x ^ (mask << 56) can be encoded as a single armv8 instruction for these
396   // masks.
397   // The list does not include the value 255, which is used for UAR.
398   static unsigned FastMasks[] = {
399       0,   1,   2,   3,   4,   6,   7,   8,   12,  14,  15, 16,  24,
400       28,  30,  31,  32,  48,  56,  60,  62,  63,  64,  96, 112, 120,
401       124, 126, 127, 128, 192, 224, 240, 248, 252, 254};
402   return FastMasks[AllocaNo % (sizeof(FastMasks) / sizeof(FastMasks[0]))];
403 }
404 
405 Value *HWAddressSanitizer::getNextTagWithCall(IRBuilder<> &IRB) {
406   return IRB.CreateZExt(IRB.CreateCall(HwasanGenerateTagFunc), IntptrTy);
407 }
408 
409 Value *HWAddressSanitizer::getStackBaseTag(IRBuilder<> &IRB) {
410   if (ClGenerateTagsWithCalls)
411     return nullptr;
412   // FIXME: use addressofreturnaddress (but implement it in aarch64 backend
413   // first).
414   Module *M = IRB.GetInsertBlock()->getParent()->getParent();
415   auto GetStackPointerFn =
416       Intrinsic::getDeclaration(M, Intrinsic::frameaddress);
417   Value *StackPointer = IRB.CreateCall(
418       GetStackPointerFn, {Constant::getNullValue(IRB.getInt32Ty())});
419 
420   // Extract some entropy from the stack pointer for the tags.
421   // Take bits 20..28 (ASLR entropy) and xor with bits 0..8 (these differ
422   // between functions).
423   Value *StackPointerLong = IRB.CreatePointerCast(StackPointer, IntptrTy);
424   Value *StackTag =
425       IRB.CreateXor(StackPointerLong, IRB.CreateLShr(StackPointerLong, 20),
426                     "hwasan.stack.base.tag");
427   return StackTag;
428 }
429 
430 Value *HWAddressSanitizer::getAllocaTag(IRBuilder<> &IRB, Value *StackTag,
431                                         AllocaInst *AI, unsigned AllocaNo) {
432   if (ClGenerateTagsWithCalls)
433     return getNextTagWithCall(IRB);
434   return IRB.CreateXor(StackTag,
435                        ConstantInt::get(IntptrTy, RetagMask(AllocaNo)));
436 }
437 
438 Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB, Value *StackTag) {
439   if (ClGenerateTagsWithCalls)
440     return getNextTagWithCall(IRB);
441   return IRB.CreateXor(StackTag, ConstantInt::get(IntptrTy, 0xFFU));
442 }
443 
444 bool HWAddressSanitizer::instrumentStack(
445     SmallVectorImpl<AllocaInst *> &Allocas,
446     SmallVectorImpl<Instruction *> &RetVec) {
447   Function *F = Allocas[0]->getParent()->getParent();
448   Instruction *InsertPt = &*F->getEntryBlock().begin();
449   IRBuilder<> IRB(InsertPt);
450 
451   Value *StackTag = getStackBaseTag(IRB);
452 
453   // Ideally, we want to calculate tagged stack base pointer, and rewrite all
454   // alloca addresses using that. Unfortunately, offsets are not known yet
455   // (unless we use ASan-style mega-alloca). Instead we keep the base tag in a
456   // temp, shift-OR it into each alloca address and xor with the retag mask.
457   // This generates one extra instruction per alloca use.
458   for (unsigned N = 0; N < Allocas.size(); ++N) {
459     auto *AI = Allocas[N];
460     IRB.SetInsertPoint(AI->getNextNode());
461 
462     // Replace uses of the alloca with tagged address.
463     Value *Tag = getAllocaTag(IRB, StackTag, AI, N);
464     Value *AILong = IRB.CreatePointerCast(AI, IntptrTy);
465     std::string Name =
466         AI->hasName() ? AI->getName().str() : "alloca." + itostr(N);
467     Value *Replacement = IRB.CreateIntToPtr(
468         IRB.CreateOr(AILong, IRB.CreateShl(Tag, kPointerTagShift)),
469         AI->getType(), Name + ".hwasan");
470 
471     for (auto UI = AI->use_begin(), UE = AI->use_end(); UI != UE;) {
472       Use &U = *UI++;
473       if (U.getUser() != AILong)
474         U.set(Replacement);
475     }
476 
477     tagAlloca(IRB, AI, Tag);
478 
479     for (auto RI : RetVec) {
480       IRB.SetInsertPoint(RI);
481 
482       // Re-tag alloca memory with the special UAR tag.
483       Value *Tag = getUARTag(IRB, StackTag);
484       tagAlloca(IRB, AI, Tag);
485     }
486   }
487 
488   return true;
489 }
490 
491 bool HWAddressSanitizer::isInterestingAlloca(const AllocaInst &AI) {
492   return (AI.getAllocatedType()->isSized() &&
493           // FIXME: instrument dynamic allocas, too
494           AI.isStaticAlloca() &&
495           // alloca() may be called with 0 size, ignore it.
496           getAllocaSizeInBytes(AI) > 0 &&
497           // We are only interested in allocas not promotable to registers.
498           // Promotable allocas are common under -O0.
499           !isAllocaPromotable(&AI) &&
500           // inalloca allocas are not treated as static, and we don't want
501           // dynamic alloca instrumentation for them as well.
502           !AI.isUsedWithInAlloca() &&
503           // swifterror allocas are register promoted by ISel
504           !AI.isSwiftError());
505 }
506 
507 bool HWAddressSanitizer::runOnFunction(Function &F) {
508   if (&F == HwasanCtorFunction)
509     return false;
510 
511   if (!F.hasFnAttribute(Attribute::SanitizeHWAddress))
512     return false;
513 
514   DEBUG(dbgs() << "Function: " << F.getName() << "\n");
515 
516   initializeCallbacks(*F.getParent());
517 
518   bool Changed = false;
519   SmallVector<Instruction*, 16> ToInstrument;
520   SmallVector<AllocaInst*, 8> AllocasToInstrument;
521   SmallVector<Instruction*, 8> RetVec;
522   for (auto &BB : F) {
523     for (auto &Inst : BB) {
524       if (ClInstrumentStack)
525         if (AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) {
526           // Realign all allocas. We don't want small uninteresting allocas to
527           // hide in instrumented alloca's padding.
528           if (AI->getAlignment() < kAllocaAlignment)
529             AI->setAlignment(kAllocaAlignment);
530           // Instrument some of them.
531           if (isInterestingAlloca(*AI))
532             AllocasToInstrument.push_back(AI);
533           continue;
534         }
535 
536       if (isa<ReturnInst>(Inst) || isa<ResumeInst>(Inst) || isa<CleanupReturnInst>(Inst))
537         RetVec.push_back(&Inst);
538 
539       Value *MaybeMask = nullptr;
540       bool IsWrite;
541       unsigned Alignment;
542       uint64_t TypeSize;
543       Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize,
544                                               &Alignment, &MaybeMask);
545       if (Addr || isa<MemIntrinsic>(Inst))
546         ToInstrument.push_back(&Inst);
547     }
548   }
549 
550   if (!AllocasToInstrument.empty())
551     Changed |= instrumentStack(AllocasToInstrument, RetVec);
552 
553   for (auto Inst : ToInstrument)
554     Changed |= instrumentMemAccess(Inst);
555 
556   return Changed;
557 }
558