LLVM  9.0.0svn
HWAddressSanitizer.cpp
Go to the documentation of this file.
1 //===- HWAddressSanitizer.cpp - detector of uninitialized reads -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// This file is a part of HWAddressSanitizer, an address sanity checker
11 /// based on tagged addressing.
12 //===----------------------------------------------------------------------===//
13 
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"
25 #include "llvm/IR/DerivedTypes.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/IR/IRBuilder.h"
28 #include "llvm/IR/InlineAsm.h"
29 #include "llvm/IR/InstVisitor.h"
30 #include "llvm/IR/Instruction.h"
31 #include "llvm/IR/Instructions.h"
32 #include "llvm/IR/IntrinsicInst.h"
33 #include "llvm/IR/Intrinsics.h"
34 #include "llvm/IR/LLVMContext.h"
35 #include "llvm/IR/MDBuilder.h"
36 #include "llvm/IR/Module.h"
37 #include "llvm/IR/Type.h"
38 #include "llvm/IR/Value.h"
39 #include "llvm/Pass.h"
40 #include "llvm/Support/Casting.h"
42 #include "llvm/Support/Debug.h"
48 #include <sstream>
49 
50 using namespace llvm;
51 
52 #define DEBUG_TYPE "hwasan"
53 
54 static const char *const kHwasanModuleCtorName = "hwasan.module_ctor";
55 static const char *const kHwasanInitName = "__hwasan_init";
56 
57 static const char *const kHwasanShadowMemoryDynamicAddress =
58  "__hwasan_shadow_memory_dynamic_address";
59 
60 // Accesses sizes are powers of two: 1, 2, 4, 8, 16.
61 static const size_t kNumberOfAccessSizes = 5;
62 
63 static const size_t kDefaultShadowScale = 4;
64 static const uint64_t kDynamicShadowSentinel =
66 static const unsigned kPointerTagShift = 56;
67 
68 static const unsigned kShadowBaseAlignment = 32;
69 
71  "hwasan-memory-access-callback-prefix",
72  cl::desc("Prefix for memory access callbacks"), cl::Hidden,
73  cl::init("__hwasan_"));
74 
75 static cl::opt<bool>
76  ClInstrumentWithCalls("hwasan-instrument-with-calls",
77  cl::desc("instrument reads and writes with callbacks"),
78  cl::Hidden, cl::init(false));
79 
80 static cl::opt<bool> ClInstrumentReads("hwasan-instrument-reads",
81  cl::desc("instrument read instructions"),
82  cl::Hidden, cl::init(true));
83 
85  "hwasan-instrument-writes", cl::desc("instrument write instructions"),
86  cl::Hidden, cl::init(true));
87 
89  "hwasan-instrument-atomics",
90  cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
91  cl::init(true));
92 
94  "hwasan-recover",
95  cl::desc("Enable recovery mode (continue-after-error)."),
96  cl::Hidden, cl::init(false));
97 
98 static cl::opt<bool> ClInstrumentStack("hwasan-instrument-stack",
99  cl::desc("instrument stack (allocas)"),
100  cl::Hidden, cl::init(true));
101 
103  "hwasan-uar-retag-to-zero",
104  cl::desc("Clear alloca tags before returning from the function to allow "
105  "non-instrumented and instrumented function calls mix. When set "
106  "to false, allocas are retagged before returning from the "
107  "function to detect use after return."),
108  cl::Hidden, cl::init(true));
109 
111  "hwasan-generate-tags-with-calls",
112  cl::desc("generate new tags with runtime library calls"), cl::Hidden,
113  cl::init(false));
114 
116  "hwasan-match-all-tag",
117  cl::desc("don't report bad accesses via pointers with this tag"),
118  cl::Hidden, cl::init(-1));
119 
121  "hwasan-kernel",
122  cl::desc("Enable KernelHWAddressSanitizer instrumentation"),
123  cl::Hidden, cl::init(false));
124 
125 // These flags allow to change the shadow mapping and control how shadow memory
126 // is accessed. The shadow mapping looks like:
127 // Shadow = (Mem >> scale) + offset
128 
129 static cl::opt<uint64_t>
130  ClMappingOffset("hwasan-mapping-offset",
131  cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"),
132  cl::Hidden, cl::init(0));
133 
134 static cl::opt<bool>
135  ClWithIfunc("hwasan-with-ifunc",
136  cl::desc("Access dynamic shadow through an ifunc global on "
137  "platforms that support this"),
138  cl::Hidden, cl::init(false));
139 
140 static cl::opt<bool> ClWithTls(
141  "hwasan-with-tls",
142  cl::desc("Access dynamic shadow through an thread-local pointer on "
143  "platforms that support this"),
144  cl::Hidden, cl::init(true));
145 
146 static cl::opt<bool>
147  ClRecordStackHistory("hwasan-record-stack-history",
148  cl::desc("Record stack frames with tagged allocations "
149  "in a thread-local ring buffer"),
150  cl::Hidden, cl::init(true));
151 static cl::opt<bool>
152  ClInstrumentMemIntrinsics("hwasan-instrument-mem-intrinsics",
153  cl::desc("instrument memory intrinsics"),
154  cl::Hidden, cl::init(true));
155 
156 static cl::opt<bool>
157  ClInstrumentLandingPads("hwasan-instrument-landing-pads",
158  cl::desc("instrument landing pads"), cl::Hidden,
159  cl::init(true));
160 
161 static cl::opt<bool> ClInlineAllChecks("hwasan-inline-all-checks",
162  cl::desc("inline all checks"),
163  cl::Hidden, cl::init(false));
164 
165 namespace {
166 
167 /// An instrumentation pass implementing detection of addressability bugs
168 /// using tagged pointers.
169 class HWAddressSanitizer {
170 public:
171  explicit HWAddressSanitizer(Module &M, bool CompileKernel = false,
172  bool Recover = false) {
173  this->Recover = ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover;
174  this->CompileKernel = ClEnableKhwasan.getNumOccurrences() > 0 ?
175  ClEnableKhwasan : CompileKernel;
176 
177  initializeModule(M);
178  }
179 
180  bool sanitizeFunction(Function &F);
181  void initializeModule(Module &M);
182 
183  void initializeCallbacks(Module &M);
184 
185  Value *getDynamicShadowIfunc(IRBuilder<> &IRB);
186  Value *getDynamicShadowNonTls(IRBuilder<> &IRB);
187 
188  void untagPointerOperand(Instruction *I, Value *Addr);
189  Value *shadowBase();
190  Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
191  void instrumentMemAccessInline(Value *Ptr, bool IsWrite,
192  unsigned AccessSizeIndex,
193  Instruction *InsertBefore);
194  void instrumentMemIntrinsic(MemIntrinsic *MI);
195  bool instrumentMemAccess(Instruction *I);
196  Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite,
197  uint64_t *TypeSize, unsigned *Alignment,
198  Value **MaybeMask);
199 
200  bool isInterestingAlloca(const AllocaInst &AI);
201  bool tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag, size_t Size);
202  Value *tagPointer(IRBuilder<> &IRB, Type *Ty, Value *PtrLong, Value *Tag);
203  Value *untagPointer(IRBuilder<> &IRB, Value *PtrLong);
204  bool instrumentStack(
206  DenseMap<AllocaInst *, std::vector<DbgDeclareInst *>> &AllocaDeclareMap,
207  SmallVectorImpl<Instruction *> &RetVec, Value *StackTag);
208  Value *readRegister(IRBuilder<> &IRB, StringRef Name);
209  bool instrumentLandingPads(SmallVectorImpl<Instruction *> &RetVec);
210  Value *getNextTagWithCall(IRBuilder<> &IRB);
211  Value *getStackBaseTag(IRBuilder<> &IRB);
212  Value *getAllocaTag(IRBuilder<> &IRB, Value *StackTag, AllocaInst *AI,
213  unsigned AllocaNo);
214  Value *getUARTag(IRBuilder<> &IRB, Value *StackTag);
215 
216  Value *getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty);
217  void emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord);
218 
219 private:
220  LLVMContext *C;
221  std::string CurModuleUniqueId;
222  Triple TargetTriple;
223  FunctionCallee HWAsanMemmove, HWAsanMemcpy, HWAsanMemset;
224  FunctionCallee HWAsanHandleVfork;
225 
226  /// This struct defines the shadow mapping using the rule:
227  /// shadow = (mem >> Scale) + Offset.
228  /// If InGlobal is true, then
229  /// extern char __hwasan_shadow[];
230  /// shadow = (mem >> Scale) + &__hwasan_shadow
231  /// If InTls is true, then
232  /// extern char *__hwasan_tls;
233  /// shadow = (mem>>Scale) + align_up(__hwasan_shadow, kShadowBaseAlignment)
234  struct ShadowMapping {
235  int Scale;
236  uint64_t Offset;
237  bool InGlobal;
238  bool InTls;
239 
240  void init(Triple &TargetTriple);
241  unsigned getAllocaAlignment() const { return 1U << Scale; }
242  };
243  ShadowMapping Mapping;
244 
245  Type *IntptrTy;
246  Type *Int8PtrTy;
247  Type *Int8Ty;
248  Type *Int32Ty;
249 
250  bool CompileKernel;
251  bool Recover;
252 
253  Function *HwasanCtorFunction;
254 
255  FunctionCallee HwasanMemoryAccessCallback[2][kNumberOfAccessSizes];
256  FunctionCallee HwasanMemoryAccessCallbackSized[2];
257 
258  FunctionCallee HwasanTagMemoryFunc;
259  FunctionCallee HwasanGenerateTagFunc;
260  FunctionCallee HwasanThreadEnterFunc;
261 
262  Constant *ShadowGlobal;
263 
264  Value *LocalDynamicShadow = nullptr;
265  Value *StackBaseTag = nullptr;
266  GlobalValue *ThreadPtrGlobal = nullptr;
267 };
268 
269 class HWAddressSanitizerLegacyPass : public FunctionPass {
270 public:
271  // Pass identification, replacement for typeid.
272  static char ID;
273 
274  explicit HWAddressSanitizerLegacyPass(bool CompileKernel = false,
275  bool Recover = false)
276  : FunctionPass(ID), CompileKernel(CompileKernel), Recover(Recover) {}
277 
278  StringRef getPassName() const override { return "HWAddressSanitizer"; }
279 
280  bool runOnFunction(Function &F) override {
281  HWAddressSanitizer HWASan(*F.getParent(), CompileKernel, Recover);
282  return HWASan.sanitizeFunction(F);
283  }
284 
285 private:
286  bool CompileKernel;
287  bool Recover;
288 };
289 
290 } // end anonymous namespace
291 
293 
295  HWAddressSanitizerLegacyPass, "hwasan",
296  "HWAddressSanitizer: detect memory bugs using tagged addressing.", false,
297  false)
299  HWAddressSanitizerLegacyPass, "hwasan",
300  "HWAddressSanitizer: detect memory bugs using tagged addressing.", false,
301  false)
302 
304  bool Recover) {
305  assert(!CompileKernel || Recover);
306  return new HWAddressSanitizerLegacyPass(CompileKernel, Recover);
307 }
308 
309 HWAddressSanitizerPass::HWAddressSanitizerPass(bool CompileKernel, bool Recover)
310  : CompileKernel(CompileKernel), Recover(Recover) {}
311 
314  HWAddressSanitizer HWASan(*F.getParent(), CompileKernel, Recover);
315  if (HWASan.sanitizeFunction(F))
316  return PreservedAnalyses::none();
317  return PreservedAnalyses::all();
318 }
319 
320 /// Module-level initialization.
321 ///
322 /// inserts a call to __hwasan_init to the module's constructor list.
323 void HWAddressSanitizer::initializeModule(Module &M) {
324  LLVM_DEBUG(dbgs() << "Init " << M.getName() << "\n");
325  auto &DL = M.getDataLayout();
326 
327  TargetTriple = Triple(M.getTargetTriple());
328 
329  Mapping.init(TargetTriple);
330 
331  C = &(M.getContext());
332  CurModuleUniqueId = getUniqueModuleId(&M);
333  IRBuilder<> IRB(*C);
334  IntptrTy = IRB.getIntPtrTy(DL);
335  Int8PtrTy = IRB.getInt8PtrTy();
336  Int8Ty = IRB.getInt8Ty();
337  Int32Ty = IRB.getInt32Ty();
338 
339  HwasanCtorFunction = nullptr;
340  if (!CompileKernel) {
341  std::tie(HwasanCtorFunction, std::ignore) =
343  M, kHwasanModuleCtorName, kHwasanInitName,
344  /*InitArgTypes=*/{},
345  /*InitArgs=*/{},
346  // This callback is invoked when the functions are created the first
347  // time. Hook them into the global ctors list in that case:
348  [&](Function *Ctor, FunctionCallee) {
349  Comdat *CtorComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
350  Ctor->setComdat(CtorComdat);
351  appendToGlobalCtors(M, Ctor, 0, Ctor);
352  });
353  }
354 
355  if (!TargetTriple.isAndroid()) {
356  Constant *C = M.getOrInsertGlobal("__hwasan_tls", IntptrTy, [&] {
357  auto *GV = new GlobalVariable(M, IntptrTy, /*isConstant=*/false,
359  "__hwasan_tls", nullptr,
361  appendToCompilerUsed(M, GV);
362  return GV;
363  });
364  ThreadPtrGlobal = cast<GlobalVariable>(C);
365  }
366 }
367 
368 void HWAddressSanitizer::initializeCallbacks(Module &M) {
369  IRBuilder<> IRB(*C);
370  for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
371  const std::string TypeStr = AccessIsWrite ? "store" : "load";
372  const std::string EndingStr = Recover ? "_noabort" : "";
373 
374  HwasanMemoryAccessCallbackSized[AccessIsWrite] = M.getOrInsertFunction(
375  ClMemoryAccessCallbackPrefix + TypeStr + "N" + EndingStr,
376  FunctionType::get(IRB.getVoidTy(), {IntptrTy, IntptrTy}, false));
377 
378  for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
379  AccessSizeIndex++) {
380  HwasanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] =
382  ClMemoryAccessCallbackPrefix + TypeStr +
383  itostr(1ULL << AccessSizeIndex) + EndingStr,
384  FunctionType::get(IRB.getVoidTy(), {IntptrTy}, false));
385  }
386  }
387 
388  HwasanTagMemoryFunc = M.getOrInsertFunction(
389  "__hwasan_tag_memory", IRB.getVoidTy(), Int8PtrTy, Int8Ty, IntptrTy);
390  HwasanGenerateTagFunc =
391  M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty);
392 
393  ShadowGlobal = M.getOrInsertGlobal("__hwasan_shadow",
394  ArrayType::get(IRB.getInt8Ty(), 0));
395 
396  const std::string MemIntrinCallbackPrefix =
397  CompileKernel ? std::string("") : ClMemoryAccessCallbackPrefix;
398  HWAsanMemmove = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memmove",
399  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
400  IRB.getInt8PtrTy(), IntptrTy);
401  HWAsanMemcpy = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memcpy",
402  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
403  IRB.getInt8PtrTy(), IntptrTy);
404  HWAsanMemset = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memset",
405  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
406  IRB.getInt32Ty(), IntptrTy);
407 
408  HWAsanHandleVfork =
409  M.getOrInsertFunction("__hwasan_handle_vfork", IRB.getVoidTy(), IntptrTy);
410 
411  HwasanThreadEnterFunc =
412  M.getOrInsertFunction("__hwasan_thread_enter", IRB.getVoidTy());
413 }
414 
415 Value *HWAddressSanitizer::getDynamicShadowIfunc(IRBuilder<> &IRB) {
416  // An empty inline asm with input reg == output reg.
417  // An opaque no-op cast, basically.
419  FunctionType::get(Int8PtrTy, {ShadowGlobal->getType()}, false),
420  StringRef(""), StringRef("=r,0"),
421  /*hasSideEffects=*/false);
422  return IRB.CreateCall(Asm, {ShadowGlobal}, ".hwasan.shadow");
423 }
424 
425 Value *HWAddressSanitizer::getDynamicShadowNonTls(IRBuilder<> &IRB) {
426  // Generate code only when dynamic addressing is needed.
427  if (Mapping.Offset != kDynamicShadowSentinel)
428  return nullptr;
429 
430  if (Mapping.InGlobal) {
431  return getDynamicShadowIfunc(IRB);
432  } else {
433  Value *GlobalDynamicAddress =
435  kHwasanShadowMemoryDynamicAddress, Int8PtrTy);
436  return IRB.CreateLoad(Int8PtrTy, GlobalDynamicAddress);
437  }
438 }
439 
440 Value *HWAddressSanitizer::isInterestingMemoryAccess(Instruction *I,
441  bool *IsWrite,
442  uint64_t *TypeSize,
443  unsigned *Alignment,
444  Value **MaybeMask) {
445  // Skip memory accesses inserted by another instrumentation.
446  if (I->getMetadata("nosanitize")) return nullptr;
447 
448  // Do not instrument the load fetching the dynamic shadow address.
449  if (LocalDynamicShadow == I)
450  return nullptr;
451 
452  Value *PtrOperand = nullptr;
453  const DataLayout &DL = I->getModule()->getDataLayout();
454  if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
455  if (!ClInstrumentReads) return nullptr;
456  *IsWrite = false;
457  *TypeSize = DL.getTypeStoreSizeInBits(LI->getType());
458  *Alignment = LI->getAlignment();
459  PtrOperand = LI->getPointerOperand();
460  } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
461  if (!ClInstrumentWrites) return nullptr;
462  *IsWrite = true;
463  *TypeSize = DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType());
464  *Alignment = SI->getAlignment();
465  PtrOperand = SI->getPointerOperand();
466  } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
467  if (!ClInstrumentAtomics) return nullptr;
468  *IsWrite = true;
469  *TypeSize = DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType());
470  *Alignment = 0;
471  PtrOperand = RMW->getPointerOperand();
472  } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
473  if (!ClInstrumentAtomics) return nullptr;
474  *IsWrite = true;
475  *TypeSize = DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType());
476  *Alignment = 0;
477  PtrOperand = XCHG->getPointerOperand();
478  }
479 
480  if (PtrOperand) {
481  // Do not instrument accesses from different address spaces; we cannot deal
482  // with them.
483  Type *PtrTy = cast<PointerType>(PtrOperand->getType()->getScalarType());
484  if (PtrTy->getPointerAddressSpace() != 0)
485  return nullptr;
486 
487  // Ignore swifterror addresses.
488  // swifterror memory addresses are mem2reg promoted by instruction
489  // selection. As such they cannot have regular uses like an instrumentation
490  // function and it makes no sense to track them as memory.
491  if (PtrOperand->isSwiftError())
492  return nullptr;
493  }
494 
495  return PtrOperand;
496 }
497 
498 static unsigned getPointerOperandIndex(Instruction *I) {
499  if (LoadInst *LI = dyn_cast<LoadInst>(I))
500  return LI->getPointerOperandIndex();
501  if (StoreInst *SI = dyn_cast<StoreInst>(I))
502  return SI->getPointerOperandIndex();
503  if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I))
504  return RMW->getPointerOperandIndex();
505  if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I))
506  return XCHG->getPointerOperandIndex();
507  report_fatal_error("Unexpected instruction");
508  return -1;
509 }
510 
511 static size_t TypeSizeToSizeIndex(uint32_t TypeSize) {
512  size_t Res = countTrailingZeros(TypeSize / 8);
514  return Res;
515 }
516 
517 void HWAddressSanitizer::untagPointerOperand(Instruction *I, Value *Addr) {
518  if (TargetTriple.isAArch64())
519  return;
520 
521  IRBuilder<> IRB(I);
522  Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
523  Value *UntaggedPtr =
524  IRB.CreateIntToPtr(untagPointer(IRB, AddrLong), Addr->getType());
525  I->setOperand(getPointerOperandIndex(I), UntaggedPtr);
526 }
527 
528 Value *HWAddressSanitizer::shadowBase() {
529  if (LocalDynamicShadow)
530  return LocalDynamicShadow;
531  return ConstantExpr::getIntToPtr(ConstantInt::get(IntptrTy, Mapping.Offset),
532  Int8PtrTy);
533 }
534 
535 Value *HWAddressSanitizer::memToShadow(Value *Mem, IRBuilder<> &IRB) {
536  // Mem >> Scale
537  Value *Shadow = IRB.CreateLShr(Mem, Mapping.Scale);
538  if (Mapping.Offset == 0)
539  return IRB.CreateIntToPtr(Shadow, Int8PtrTy);
540  // (Mem >> Scale) + Offset
541  return IRB.CreateGEP(Int8Ty, shadowBase(), Shadow);
542 }
543 
544 void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
545  unsigned AccessSizeIndex,
546  Instruction *InsertBefore) {
547  const int64_t AccessInfo = Recover * 0x20 + IsWrite * 0x10 + AccessSizeIndex;
548  IRBuilder<> IRB(InsertBefore);
549 
550  if (!ClInlineAllChecks && TargetTriple.isAArch64() &&
551  TargetTriple.isOSBinFormatELF() && !Recover) {
552  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
553  Ptr = IRB.CreateBitCast(Ptr, Int8PtrTy);
554  IRB.CreateCall(
555  Intrinsic::getDeclaration(M, Intrinsic::hwasan_check_memaccess),
556  {shadowBase(), Ptr, ConstantInt::get(Int32Ty, AccessInfo)});
557  return;
558  }
559 
560  Value *PtrLong = IRB.CreatePointerCast(Ptr, IntptrTy);
561  Value *PtrTag = IRB.CreateTrunc(IRB.CreateLShr(PtrLong, kPointerTagShift),
562  IRB.getInt8Ty());
563  Value *AddrLong = untagPointer(IRB, PtrLong);
564  Value *Shadow = memToShadow(AddrLong, IRB);
565  Value *MemTag = IRB.CreateLoad(Int8Ty, Shadow);
566  Value *TagMismatch = IRB.CreateICmpNE(PtrTag, MemTag);
567 
568  int matchAllTag = ClMatchAllTag.getNumOccurrences() > 0 ?
569  ClMatchAllTag : (CompileKernel ? 0xFF : -1);
570  if (matchAllTag != -1) {
571  Value *TagNotIgnored = IRB.CreateICmpNE(PtrTag,
572  ConstantInt::get(PtrTag->getType(), matchAllTag));
573  TagMismatch = IRB.CreateAnd(TagMismatch, TagNotIgnored);
574  }
575 
576  Instruction *CheckTerm =
577  SplitBlockAndInsertIfThen(TagMismatch, InsertBefore, false,
578  MDBuilder(*C).createBranchWeights(1, 100000));
579 
580  IRB.SetInsertPoint(CheckTerm);
581  Value *OutOfShortGranuleTagRange =
582  IRB.CreateICmpUGT(MemTag, ConstantInt::get(Int8Ty, 15));
583  Instruction *CheckFailTerm =
584  SplitBlockAndInsertIfThen(OutOfShortGranuleTagRange, CheckTerm, !Recover,
585  MDBuilder(*C).createBranchWeights(1, 100000));
586 
587  IRB.SetInsertPoint(CheckTerm);
588  Value *PtrLowBits = IRB.CreateTrunc(IRB.CreateAnd(PtrLong, 15), Int8Ty);
589  PtrLowBits = IRB.CreateAdd(
590  PtrLowBits, ConstantInt::get(Int8Ty, (1 << AccessSizeIndex) - 1));
591  Value *PtrLowBitsOOB = IRB.CreateICmpUGE(PtrLowBits, MemTag);
592  SplitBlockAndInsertIfThen(PtrLowBitsOOB, CheckTerm, false,
593  MDBuilder(*C).createBranchWeights(1, 100000),
594  nullptr, nullptr, CheckFailTerm->getParent());
595 
596  IRB.SetInsertPoint(CheckTerm);
597  Value *InlineTagAddr = IRB.CreateOr(AddrLong, 15);
598  InlineTagAddr = IRB.CreateIntToPtr(InlineTagAddr, Int8PtrTy);
599  Value *InlineTag = IRB.CreateLoad(Int8Ty, InlineTagAddr);
600  Value *InlineTagMismatch = IRB.CreateICmpNE(PtrTag, InlineTag);
601  SplitBlockAndInsertIfThen(InlineTagMismatch, CheckTerm, false,
602  MDBuilder(*C).createBranchWeights(1, 100000),
603  nullptr, nullptr, CheckFailTerm->getParent());
604 
605  IRB.SetInsertPoint(CheckFailTerm);
606  InlineAsm *Asm;
607  switch (TargetTriple.getArch()) {
608  case Triple::x86_64:
609  // The signal handler will find the data address in rdi.
610  Asm = InlineAsm::get(
611  FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
612  "int3\nnopl " + itostr(0x40 + AccessInfo) + "(%rax)",
613  "{rdi}",
614  /*hasSideEffects=*/true);
615  break;
616  case Triple::aarch64:
617  case Triple::aarch64_be:
618  // The signal handler will find the data address in x0.
619  Asm = InlineAsm::get(
620  FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
621  "brk #" + itostr(0x900 + AccessInfo),
622  "{x0}",
623  /*hasSideEffects=*/true);
624  break;
625  default:
626  report_fatal_error("unsupported architecture");
627  }
628  IRB.CreateCall(Asm, PtrLong);
629  if (Recover)
630  cast<BranchInst>(CheckFailTerm)->setSuccessor(0, CheckTerm->getParent());
631 }
632 
633 void HWAddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
634  IRBuilder<> IRB(MI);
635  if (isa<MemTransferInst>(MI)) {
636  IRB.CreateCall(
637  isa<MemMoveInst>(MI) ? HWAsanMemmove : HWAsanMemcpy,
638  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
639  IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()),
640  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
641  } else if (isa<MemSetInst>(MI)) {
642  IRB.CreateCall(
643  HWAsanMemset,
644  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
645  IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
646  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
647  }
648  MI->eraseFromParent();
649 }
650 
651 bool HWAddressSanitizer::instrumentMemAccess(Instruction *I) {
652  LLVM_DEBUG(dbgs() << "Instrumenting: " << *I << "\n");
653  bool IsWrite = false;
654  unsigned Alignment = 0;
655  uint64_t TypeSize = 0;
656  Value *MaybeMask = nullptr;
657 
658  if (ClInstrumentMemIntrinsics && isa<MemIntrinsic>(I)) {
659  instrumentMemIntrinsic(cast<MemIntrinsic>(I));
660  return true;
661  }
662 
663  Value *Addr =
664  isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask);
665 
666  if (!Addr)
667  return false;
668 
669  if (MaybeMask)
670  return false; //FIXME
671 
672  IRBuilder<> IRB(I);
673  if (isPowerOf2_64(TypeSize) &&
674  (TypeSize / 8 <= (1UL << (kNumberOfAccessSizes - 1))) &&
675  (Alignment >= (1UL << Mapping.Scale) || Alignment == 0 ||
676  Alignment >= TypeSize / 8)) {
677  size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize);
678  if (ClInstrumentWithCalls) {
679  IRB.CreateCall(HwasanMemoryAccessCallback[IsWrite][AccessSizeIndex],
680  IRB.CreatePointerCast(Addr, IntptrTy));
681  } else {
682  instrumentMemAccessInline(Addr, IsWrite, AccessSizeIndex, I);
683  }
684  } else {
685  IRB.CreateCall(HwasanMemoryAccessCallbackSized[IsWrite],
686  {IRB.CreatePointerCast(Addr, IntptrTy),
687  ConstantInt::get(IntptrTy, TypeSize / 8)});
688  }
689  untagPointerOperand(I, Addr);
690 
691  return true;
692 }
693 
694 static uint64_t getAllocaSizeInBytes(const AllocaInst &AI) {
695  uint64_t ArraySize = 1;
696  if (AI.isArrayAllocation()) {
697  const ConstantInt *CI = dyn_cast<ConstantInt>(AI.getArraySize());
698  assert(CI && "non-constant array size");
699  ArraySize = CI->getZExtValue();
700  }
701  Type *Ty = AI.getAllocatedType();
702  uint64_t SizeInBytes = AI.getModule()->getDataLayout().getTypeAllocSize(Ty);
703  return SizeInBytes * ArraySize;
704 }
705 
706 bool HWAddressSanitizer::tagAlloca(IRBuilder<> &IRB, AllocaInst *AI,
707  Value *Tag, size_t Size) {
708  size_t AlignedSize = alignTo(Size, Mapping.getAllocaAlignment());
709 
710  Value *JustTag = IRB.CreateTrunc(Tag, IRB.getInt8Ty());
711  if (ClInstrumentWithCalls) {
712  IRB.CreateCall(HwasanTagMemoryFunc,
713  {IRB.CreatePointerCast(AI, Int8PtrTy), JustTag,
714  ConstantInt::get(IntptrTy, AlignedSize)});
715  } else {
716  size_t ShadowSize = Size >> Mapping.Scale;
717  Value *ShadowPtr = memToShadow(IRB.CreatePointerCast(AI, IntptrTy), IRB);
718  // If this memset is not inlined, it will be intercepted in the hwasan
719  // runtime library. That's OK, because the interceptor skips the checks if
720  // the address is in the shadow region.
721  // FIXME: the interceptor is not as fast as real memset. Consider lowering
722  // llvm.memset right here into either a sequence of stores, or a call to
723  // hwasan_tag_memory.
724  if (ShadowSize)
725  IRB.CreateMemSet(ShadowPtr, JustTag, ShadowSize, /*Align=*/1);
726  if (Size != AlignedSize) {
727  IRB.CreateStore(
728  ConstantInt::get(Int8Ty, Size % Mapping.getAllocaAlignment()),
729  IRB.CreateConstGEP1_32(Int8Ty, ShadowPtr, ShadowSize));
730  IRB.CreateStore(JustTag, IRB.CreateConstGEP1_32(
731  Int8Ty, IRB.CreateBitCast(AI, Int8PtrTy),
732  AlignedSize - 1));
733  }
734  }
735  return true;
736 }
737 
738 static unsigned RetagMask(unsigned AllocaNo) {
739  // A list of 8-bit numbers that have at most one run of non-zero bits.
740  // x = x ^ (mask << 56) can be encoded as a single armv8 instruction for these
741  // masks.
742  // The list does not include the value 255, which is used for UAR.
743  //
744  // Because we are more likely to use earlier elements of this list than later
745  // ones, it is sorted in increasing order of probability of collision with a
746  // mask allocated (temporally) nearby. The program that generated this list
747  // can be found at:
748  // https://github.com/google/sanitizers/blob/master/hwaddress-sanitizer/sort_masks.py
749  static unsigned FastMasks[] = {0, 128, 64, 192, 32, 96, 224, 112, 240,
750  48, 16, 120, 248, 56, 24, 8, 124, 252,
751  60, 28, 12, 4, 126, 254, 62, 30, 14,
752  6, 2, 127, 63, 31, 15, 7, 3, 1};
753  return FastMasks[AllocaNo % (sizeof(FastMasks) / sizeof(FastMasks[0]))];
754 }
755 
756 Value *HWAddressSanitizer::getNextTagWithCall(IRBuilder<> &IRB) {
757  return IRB.CreateZExt(IRB.CreateCall(HwasanGenerateTagFunc), IntptrTy);
758 }
759 
760 Value *HWAddressSanitizer::getStackBaseTag(IRBuilder<> &IRB) {
762  return getNextTagWithCall(IRB);
763  if (StackBaseTag)
764  return StackBaseTag;
765  // FIXME: use addressofreturnaddress (but implement it in aarch64 backend
766  // first).
767  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
768  auto GetStackPointerFn =
769  Intrinsic::getDeclaration(M, Intrinsic::frameaddress);
770  Value *StackPointer = IRB.CreateCall(
771  GetStackPointerFn, {Constant::getNullValue(IRB.getInt32Ty())});
772 
773  // Extract some entropy from the stack pointer for the tags.
774  // Take bits 20..28 (ASLR entropy) and xor with bits 0..8 (these differ
775  // between functions).
776  Value *StackPointerLong = IRB.CreatePointerCast(StackPointer, IntptrTy);
777  Value *StackTag =
778  IRB.CreateXor(StackPointerLong, IRB.CreateLShr(StackPointerLong, 20),
779  "hwasan.stack.base.tag");
780  return StackTag;
781 }
782 
783 Value *HWAddressSanitizer::getAllocaTag(IRBuilder<> &IRB, Value *StackTag,
784  AllocaInst *AI, unsigned AllocaNo) {
786  return getNextTagWithCall(IRB);
787  return IRB.CreateXor(StackTag,
788  ConstantInt::get(IntptrTy, RetagMask(AllocaNo)));
789 }
790 
791 Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB, Value *StackTag) {
792  if (ClUARRetagToZero)
793  return ConstantInt::get(IntptrTy, 0);
795  return getNextTagWithCall(IRB);
796  return IRB.CreateXor(StackTag, ConstantInt::get(IntptrTy, 0xFFU));
797 }
798 
799 // Add a tag to an address.
800 Value *HWAddressSanitizer::tagPointer(IRBuilder<> &IRB, Type *Ty,
801  Value *PtrLong, Value *Tag) {
802  Value *TaggedPtrLong;
803  if (CompileKernel) {
804  // Kernel addresses have 0xFF in the most significant byte.
805  Value *ShiftedTag = IRB.CreateOr(
806  IRB.CreateShl(Tag, kPointerTagShift),
807  ConstantInt::get(IntptrTy, (1ULL << kPointerTagShift) - 1));
808  TaggedPtrLong = IRB.CreateAnd(PtrLong, ShiftedTag);
809  } else {
810  // Userspace can simply do OR (tag << 56);
811  Value *ShiftedTag = IRB.CreateShl(Tag, kPointerTagShift);
812  TaggedPtrLong = IRB.CreateOr(PtrLong, ShiftedTag);
813  }
814  return IRB.CreateIntToPtr(TaggedPtrLong, Ty);
815 }
816 
817 // Remove tag from an address.
818 Value *HWAddressSanitizer::untagPointer(IRBuilder<> &IRB, Value *PtrLong) {
819  Value *UntaggedPtrLong;
820  if (CompileKernel) {
821  // Kernel addresses have 0xFF in the most significant byte.
822  UntaggedPtrLong = IRB.CreateOr(PtrLong,
823  ConstantInt::get(PtrLong->getType(), 0xFFULL << kPointerTagShift));
824  } else {
825  // Userspace addresses have 0x00.
826  UntaggedPtrLong = IRB.CreateAnd(PtrLong,
827  ConstantInt::get(PtrLong->getType(), ~(0xFFULL << kPointerTagShift)));
828  }
829  return UntaggedPtrLong;
830 }
831 
832 Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty) {
833  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
834  if (TargetTriple.isAArch64() && TargetTriple.isAndroid()) {
835  // Android provides a fixed TLS slot for sanitizers. See TLS_SLOT_SANITIZER
836  // in Bionic's libc/private/bionic_tls.h.
837  Function *ThreadPointerFunc =
838  Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
839  Value *SlotPtr = IRB.CreatePointerCast(
840  IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
841  IRB.CreateCall(ThreadPointerFunc), 0x30),
842  Ty->getPointerTo(0));
843  return SlotPtr;
844  }
845  if (ThreadPtrGlobal)
846  return ThreadPtrGlobal;
847 
848 
849  return nullptr;
850 }
851 
852 void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
853  if (!Mapping.InTls) {
854  LocalDynamicShadow = getDynamicShadowNonTls(IRB);
855  return;
856  }
857 
858  if (!WithFrameRecord && TargetTriple.isAndroid()) {
859  LocalDynamicShadow = getDynamicShadowIfunc(IRB);
860  return;
861  }
862 
863  Value *SlotPtr = getHwasanThreadSlotPtr(IRB, IntptrTy);
864  assert(SlotPtr);
865 
866  Instruction *ThreadLong = IRB.CreateLoad(IntptrTy, SlotPtr);
867 
868  Function *F = IRB.GetInsertBlock()->getParent();
869  if (F->getFnAttribute("hwasan-abi").getValueAsString() == "interceptor") {
870  Value *ThreadLongEqZero =
871  IRB.CreateICmpEQ(ThreadLong, ConstantInt::get(IntptrTy, 0));
872  auto *Br = cast<BranchInst>(SplitBlockAndInsertIfThen(
873  ThreadLongEqZero, cast<Instruction>(ThreadLongEqZero)->getNextNode(),
874  false, MDBuilder(*C).createBranchWeights(1, 100000)));
875 
876  IRB.SetInsertPoint(Br);
877  // FIXME: This should call a new runtime function with a custom calling
878  // convention to avoid needing to spill all arguments here.
879  IRB.CreateCall(HwasanThreadEnterFunc);
880  LoadInst *ReloadThreadLong = IRB.CreateLoad(IntptrTy, SlotPtr);
881 
882  IRB.SetInsertPoint(&*Br->getSuccessor(0)->begin());
883  PHINode *ThreadLongPhi = IRB.CreatePHI(IntptrTy, 2);
884  ThreadLongPhi->addIncoming(ThreadLong, ThreadLong->getParent());
885  ThreadLongPhi->addIncoming(ReloadThreadLong, ReloadThreadLong->getParent());
886  ThreadLong = ThreadLongPhi;
887  }
888 
889  // Extract the address field from ThreadLong. Unnecessary on AArch64 with TBI.
890  Value *ThreadLongMaybeUntagged =
891  TargetTriple.isAArch64() ? ThreadLong : untagPointer(IRB, ThreadLong);
892 
893  if (WithFrameRecord) {
894  StackBaseTag = IRB.CreateAShr(ThreadLong, 3);
895 
896  // Prepare ring buffer data.
897  Value *PC;
898  if (TargetTriple.getArch() == Triple::aarch64)
899  PC = readRegister(IRB, "pc");
900  else
901  PC = IRB.CreatePtrToInt(F, IntptrTy);
902  auto GetStackPointerFn =
903  Intrinsic::getDeclaration(F->getParent(), Intrinsic::frameaddress);
904  Value *SP = IRB.CreatePtrToInt(
905  IRB.CreateCall(GetStackPointerFn,
906  {Constant::getNullValue(IRB.getInt32Ty())}),
907  IntptrTy);
908  // Mix SP and PC.
909  // Assumptions:
910  // PC is 0x0000PPPPPPPPPPPP (48 bits are meaningful, others are zero)
911  // SP is 0xsssssssssssSSSS0 (4 lower bits are zero)
912  // We only really need ~20 lower non-zero bits (SSSS), so we mix like this:
913  // 0xSSSSPPPPPPPPPPPP
914  SP = IRB.CreateShl(SP, 44);
915 
916  // Store data to ring buffer.
917  Value *RecordPtr =
918  IRB.CreateIntToPtr(ThreadLongMaybeUntagged, IntptrTy->getPointerTo(0));
919  IRB.CreateStore(IRB.CreateOr(PC, SP), RecordPtr);
920 
921  // Update the ring buffer. Top byte of ThreadLong defines the size of the
922  // buffer in pages, it must be a power of two, and the start of the buffer
923  // must be aligned by twice that much. Therefore wrap around of the ring
924  // buffer is simply Addr &= ~((ThreadLong >> 56) << 12).
925  // The use of AShr instead of LShr is due to
926  // https://bugs.llvm.org/show_bug.cgi?id=39030
927  // Runtime library makes sure not to use the highest bit.
928  Value *WrapMask = IRB.CreateXor(
929  IRB.CreateShl(IRB.CreateAShr(ThreadLong, 56), 12, "", true, true),
930  ConstantInt::get(IntptrTy, (uint64_t)-1));
931  Value *ThreadLongNew = IRB.CreateAnd(
932  IRB.CreateAdd(ThreadLong, ConstantInt::get(IntptrTy, 8)), WrapMask);
933  IRB.CreateStore(ThreadLongNew, SlotPtr);
934  }
935 
936  // Get shadow base address by aligning RecordPtr up.
937  // Note: this is not correct if the pointer is already aligned.
938  // Runtime library will make sure this never happens.
939  LocalDynamicShadow = IRB.CreateAdd(
940  IRB.CreateOr(
941  ThreadLongMaybeUntagged,
942  ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
943  ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
944  LocalDynamicShadow = IRB.CreateIntToPtr(LocalDynamicShadow, Int8PtrTy);
945 }
946 
947 Value *HWAddressSanitizer::readRegister(IRBuilder<> &IRB, StringRef Name) {
948  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
949  Function *ReadRegister =
950  Intrinsic::getDeclaration(M, Intrinsic::read_register, IntptrTy);
951  MDNode *MD = MDNode::get(*C, {MDString::get(*C, Name)});
952  Value *Args[] = {MetadataAsValue::get(*C, MD)};
953  return IRB.CreateCall(ReadRegister, Args);
954 }
955 
956 bool HWAddressSanitizer::instrumentLandingPads(
957  SmallVectorImpl<Instruction *> &LandingPadVec) {
958  for (auto *LP : LandingPadVec) {
959  IRBuilder<> IRB(LP->getNextNode());
960  IRB.CreateCall(
961  HWAsanHandleVfork,
962  {readRegister(IRB, (TargetTriple.getArch() == Triple::x86_64) ? "rsp"
963  : "sp")});
964  }
965  return true;
966 }
967 
968 bool HWAddressSanitizer::instrumentStack(
970  DenseMap<AllocaInst *, std::vector<DbgDeclareInst *>> &AllocaDeclareMap,
971  SmallVectorImpl<Instruction *> &RetVec, Value *StackTag) {
972  // Ideally, we want to calculate tagged stack base pointer, and rewrite all
973  // alloca addresses using that. Unfortunately, offsets are not known yet
974  // (unless we use ASan-style mega-alloca). Instead we keep the base tag in a
975  // temp, shift-OR it into each alloca address and xor with the retag mask.
976  // This generates one extra instruction per alloca use.
977  for (unsigned N = 0; N < Allocas.size(); ++N) {
978  auto *AI = Allocas[N];
979  IRBuilder<> IRB(AI->getNextNode());
980 
981  // Replace uses of the alloca with tagged address.
982  Value *Tag = getAllocaTag(IRB, StackTag, AI, N);
983  Value *AILong = IRB.CreatePointerCast(AI, IntptrTy);
984  Value *Replacement = tagPointer(IRB, AI->getType(), AILong, Tag);
985  std::string Name =
986  AI->hasName() ? AI->getName().str() : "alloca." + itostr(N);
987  Replacement->setName(Name + ".hwasan");
988 
989  for (auto UI = AI->use_begin(), UE = AI->use_end(); UI != UE;) {
990  Use &U = *UI++;
991  if (U.getUser() != AILong)
992  U.set(Replacement);
993  }
994 
995  for (auto *DDI : AllocaDeclareMap.lookup(AI)) {
996  DIExpression *OldExpr = DDI->getExpression();
999  DDI->setArgOperand(2, MetadataAsValue::get(*C, NewExpr));
1000  }
1001 
1002  size_t Size = getAllocaSizeInBytes(*AI);
1003  tagAlloca(IRB, AI, Tag, Size);
1004 
1005  for (auto RI : RetVec) {
1006  IRB.SetInsertPoint(RI);
1007 
1008  // Re-tag alloca memory with the special UAR tag.
1009  Value *Tag = getUARTag(IRB, StackTag);
1010  tagAlloca(IRB, AI, Tag, alignTo(Size, Mapping.getAllocaAlignment()));
1011  }
1012  }
1013 
1014  return true;
1015 }
1016 
1017 bool HWAddressSanitizer::isInterestingAlloca(const AllocaInst &AI) {
1018  return (AI.getAllocatedType()->isSized() &&
1019  // FIXME: instrument dynamic allocas, too
1020  AI.isStaticAlloca() &&
1021  // alloca() may be called with 0 size, ignore it.
1022  getAllocaSizeInBytes(AI) > 0 &&
1023  // We are only interested in allocas not promotable to registers.
1024  // Promotable allocas are common under -O0.
1025  !isAllocaPromotable(&AI) &&
1026  // inalloca allocas are not treated as static, and we don't want
1027  // dynamic alloca instrumentation for them as well.
1028  !AI.isUsedWithInAlloca() &&
1029  // swifterror allocas are register promoted by ISel
1030  !AI.isSwiftError());
1031 }
1032 
1033 bool HWAddressSanitizer::sanitizeFunction(Function &F) {
1034  if (&F == HwasanCtorFunction)
1035  return false;
1036 
1037  if (!F.hasFnAttribute(Attribute::SanitizeHWAddress))
1038  return false;
1039 
1040  LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n");
1041 
1042  SmallVector<Instruction*, 16> ToInstrument;
1043  SmallVector<AllocaInst*, 8> AllocasToInstrument;
1045  SmallVector<Instruction*, 8> LandingPadVec;
1047  for (auto &BB : F) {
1048  for (auto &Inst : BB) {
1049  if (ClInstrumentStack)
1050  if (AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) {
1051  if (isInterestingAlloca(*AI))
1052  AllocasToInstrument.push_back(AI);
1053  continue;
1054  }
1055 
1056  if (isa<ReturnInst>(Inst) || isa<ResumeInst>(Inst) ||
1057  isa<CleanupReturnInst>(Inst))
1058  RetVec.push_back(&Inst);
1059 
1060  if (auto *DDI = dyn_cast<DbgDeclareInst>(&Inst))
1061  if (auto *Alloca = dyn_cast_or_null<AllocaInst>(DDI->getAddress()))
1062  AllocaDeclareMap[Alloca].push_back(DDI);
1063 
1064  if (ClInstrumentLandingPads && isa<LandingPadInst>(Inst))
1065  LandingPadVec.push_back(&Inst);
1066 
1067  Value *MaybeMask = nullptr;
1068  bool IsWrite;
1069  unsigned Alignment;
1070  uint64_t TypeSize;
1071  Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize,
1072  &Alignment, &MaybeMask);
1073  if (Addr || isa<MemIntrinsic>(Inst))
1074  ToInstrument.push_back(&Inst);
1075  }
1076  }
1077 
1078  initializeCallbacks(*F.getParent());
1079 
1080  if (!LandingPadVec.empty())
1081  instrumentLandingPads(LandingPadVec);
1082 
1083  if (AllocasToInstrument.empty() && ToInstrument.empty())
1084  return false;
1085 
1086  assert(!LocalDynamicShadow);
1087 
1088  Instruction *InsertPt = &*F.getEntryBlock().begin();
1089  IRBuilder<> EntryIRB(InsertPt);
1090  emitPrologue(EntryIRB,
1091  /*WithFrameRecord*/ ClRecordStackHistory &&
1092  !AllocasToInstrument.empty());
1093 
1094  bool Changed = false;
1095  if (!AllocasToInstrument.empty()) {
1096  Value *StackTag =
1097  ClGenerateTagsWithCalls ? nullptr : getStackBaseTag(EntryIRB);
1098  Changed |= instrumentStack(AllocasToInstrument, AllocaDeclareMap, RetVec,
1099  StackTag);
1100  }
1101 
1102  // Pad and align each of the allocas that we instrumented to stop small
1103  // uninteresting allocas from hiding in instrumented alloca's padding and so
1104  // that we have enough space to store real tags for short granules.
1105  DenseMap<AllocaInst *, AllocaInst *> AllocaToPaddedAllocaMap;
1106  for (AllocaInst *AI : AllocasToInstrument) {
1107  uint64_t Size = getAllocaSizeInBytes(*AI);
1108  uint64_t AlignedSize = alignTo(Size, Mapping.getAllocaAlignment());
1109  AI->setAlignment(std::max(AI->getAlignment(), 16u));
1110  if (Size != AlignedSize) {
1111  Type *AllocatedType = AI->getAllocatedType();
1112  if (AI->isArrayAllocation()) {
1113  uint64_t ArraySize =
1114  cast<ConstantInt>(AI->getArraySize())->getZExtValue();
1115  AllocatedType = ArrayType::get(AllocatedType, ArraySize);
1116  }
1117  Type *TypeWithPadding = StructType::get(
1118  AllocatedType, ArrayType::get(Int8Ty, AlignedSize - Size));
1119  auto *NewAI = new AllocaInst(
1120  TypeWithPadding, AI->getType()->getAddressSpace(), nullptr, "", AI);
1121  NewAI->takeName(AI);
1122  NewAI->setAlignment(AI->getAlignment());
1123  NewAI->setUsedWithInAlloca(AI->isUsedWithInAlloca());
1124  NewAI->setSwiftError(AI->isSwiftError());
1125  NewAI->copyMetadata(*AI);
1126  auto *Bitcast = new BitCastInst(NewAI, AI->getType(), "", AI);
1128  AllocaToPaddedAllocaMap[AI] = NewAI;
1129  }
1130  }
1131 
1132  if (!AllocaToPaddedAllocaMap.empty()) {
1133  for (auto &BB : F)
1134  for (auto &Inst : BB)
1135  if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&Inst))
1136  if (auto *AI =
1137  dyn_cast_or_null<AllocaInst>(DVI->getVariableLocation()))
1138  if (auto *NewAI = AllocaToPaddedAllocaMap.lookup(AI))
1139  DVI->setArgOperand(
1141  for (auto &P : AllocaToPaddedAllocaMap)
1142  P.first->eraseFromParent();
1143  }
1144 
1145  // If we split the entry block, move any allocas that were originally in the
1146  // entry block back into the entry block so that they aren't treated as
1147  // dynamic allocas.
1148  if (EntryIRB.GetInsertBlock() != &F.getEntryBlock()) {
1149  InsertPt = &*F.getEntryBlock().begin();
1150  for (auto II = EntryIRB.GetInsertBlock()->begin(),
1151  IE = EntryIRB.GetInsertBlock()->end();
1152  II != IE;) {
1153  Instruction *I = &*II++;
1154  if (auto *AI = dyn_cast<AllocaInst>(I))
1155  if (isa<ConstantInt>(AI->getArraySize()))
1156  I->moveBefore(InsertPt);
1157  }
1158  }
1159 
1160  for (auto Inst : ToInstrument)
1161  Changed |= instrumentMemAccess(Inst);
1162 
1163  LocalDynamicShadow = nullptr;
1164  StackBaseTag = nullptr;
1165 
1166  return Changed;
1167 }
1168 
1169 void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple) {
1170  Scale = kDefaultShadowScale;
1171  if (ClMappingOffset.getNumOccurrences() > 0) {
1172  InGlobal = false;
1173  InTls = false;
1175  } else if (ClEnableKhwasan || ClInstrumentWithCalls) {
1176  InGlobal = false;
1177  InTls = false;
1178  Offset = 0;
1179  } else if (ClWithIfunc) {
1180  InGlobal = true;
1181  InTls = false;
1183  } else if (ClWithTls) {
1184  InGlobal = false;
1185  InTls = true;
1187  } else {
1188  InGlobal = false;
1189  InTls = false;
1191  }
1192 }
static cl::opt< int > ClMatchAllTag("hwasan-match-all-tag", cl::desc("don't report bad accesses via pointers with this tag"), cl::Hidden, cl::init(-1))
uint64_t CallInst * C
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue *> Values)
Adds global values to the llvm.compiler.used list.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks &#39;this&#39; from the containing basic block and deletes it.
Definition: Instruction.cpp:67
use_iterator use_end()
Definition: Value.h:346
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:110
uint64_t getTypeStoreSizeInBits(Type *Ty) const
Returns the maximum number of bits that may be overwritten by storing the specified type; always a mu...
Definition: DataLayout.h:452
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition: Module.h:240
FunctionPass * createHWAddressSanitizerLegacyPassPass(bool CompileKernel=false, bool Recover=false)
Value * CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name="")
Definition: IRBuilder.h:1735
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:218
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2062
static cl::opt< uint64_t > ClMappingOffset("hwasan-mapping-offset", cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:288
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:139
This class represents lattice values for constants.
Definition: AllocatorList.h:23
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve &#39;CreateLoad(Ty, Ptr, "...")&#39; correctly, instead of converting the string to &#39;bool...
Definition: IRBuilder.h:1576
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1320
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
bool isSized(SmallPtrSetImpl< Type *> *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:264
void setAlignment(unsigned Align)
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
An instruction that atomically checks whether a specified value is in a memory location, and, if it is, stores a new value there.
Definition: Instructions.h:530
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:453
static cl::opt< bool > ClRecover("hwasan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:1769
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
Definition: Instructions.h:135
Externally visible function.
Definition: GlobalValue.h:48
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:323
Metadata node.
Definition: Metadata.h:863
StringRef getName() const
Get a short "name" for the module.
Definition: Module.h:227
F(f)
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
Definition: MathExtras.h:684
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Definition: DerivedTypes.h:580
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, unsigned Align, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memset to the specified pointer and the specified value.
Definition: IRBuilder.h:440
An instruction for reading from memory.
Definition: Instructions.h:167
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
Definition: Instructions.h:693
static const char *const kHwasanInitName
static unsigned getPointerOperandIndex(Instruction *I)
static const size_t kDefaultShadowScale
bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
static Constant * getNullValue(Type *Ty)
Constructor to create a &#39;0&#39; constant of arbitrary type.
Definition: Constants.cpp:274
iterator begin()
Instruction iterator methods.
Definition: BasicBlock.h:268
static cl::opt< bool > ClInlineAllChecks("hwasan-inline-all-checks", cl::desc("inline all checks"), cl::Hidden, cl::init(false))
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition: IRBuilder.h:383
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0&#39;s from the least significant bit to the most stopping at the first 1...
Definition: MathExtras.h:119
static const char *const kHwasanShadowMemoryDynamicAddress
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:369
unsigned getAlignment() const
Return the alignment of the memory that is being allocated by the instruction.
Definition: Instructions.h:112
PointerType * getType() const
Overload to return most specific pointer type.
Definition: Instructions.h:96
LLVMContext & getContext() const
Get the global data context.
Definition: Module.h:244
static cl::opt< bool > ClInstrumentWrites("hwasan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
A Use represents the edge between a Value definition and its users.
Definition: Use.h:55
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
Definition: Type.cpp:654
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:779
IntegerType * getIntPtrTy(const DataLayout &DL, unsigned AddrSpace=0)
Fetch the type representing a pointer to an integer value.
Definition: IRBuilder.h:426
This file contains the simple types necessary to represent the attributes associated with functions a...
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1118
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:285
static StructType * get(LLVMContext &Context, ArrayRef< Type *> Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
Definition: Type.cpp:341
Type * getVoidTy()
Fetch the type representing void.
Definition: IRBuilder.h:416
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1605
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1946
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
Definition: Use.cpp:40
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1951
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:244
Value * CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2066
std::string itostr(int64_t X)
Definition: StringExtras.h:238
bool isSwiftError() const
Return true if this value is a swifterror value.
Definition: Value.cpp:753
static DIExpression * append(const DIExpression *Expr, ArrayRef< uint64_t > Ops)
Append the opcodes Ops to DIExpr.
BasicBlock * GetInsertBlock() const
Definition: IRBuilder.h:126
static const unsigned kShadowBaseAlignment
std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type *> InitArgTypes, ArrayRef< Value *> InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef())
Creates sanitizer constructor function lazily.
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
Definition: Instructions.h:124
void setComdat(Comdat *C)
Definition: GlobalObject.h:102
This class represents a no-op cast from one type to another.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:234
static const unsigned kPointerTagShift
An instruction for storing to memory.
Definition: Instructions.h:320
static cl::opt< bool > ClInstrumentMemIntrinsics("hwasan-instrument-mem-intrinsics", cl::desc("instrument memory intrinsics"), cl::Hidden, cl::init(true))
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:429
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1878
void takeName(Value *V)
Transfer the name from V to this value.
Definition: Value.cpp:291
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1043
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Definition: IRBuilder.h:132
Value * getOperand(unsigned i) const
Definition: User.h:169
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:156
static cl::opt< bool > ClInstrumentStack("hwasan-instrument-stack", cl::desc("instrument stack (allocas)"), cl::Hidden, cl::init(true))
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1294
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return &#39;this&#39;.
Definition: Type.h:303
static MetadataAsValue * get(LLVMContext &Context, Metadata *MD)
Definition: Metadata.cpp:105
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata *> MDs)
Definition: Metadata.h:1165
static bool runOnFunction(Function &F, bool PostInlining)
#define P(N)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
Definition: Constants.h:148
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:153
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1248
void set(Value *Val)
Definition: Value.h:710
bool hasName() const
Definition: Value.h:250
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:64
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("hwasan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__hwasan_"))
This is an important base class in LLVM.
Definition: Constant.h:41
Only used in LLVM metadata.
Definition: Dwarf.h:134
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< bool > ClGenerateTagsWithCalls("hwasan-generate-tags-with-calls", cl::desc("generate new tags with runtime library calls"), cl::Hidden, cl::init(false))
static const size_t kNumberOfAccessSizes
static cl::opt< bool > ClInstrumentAtomics("hwasan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:433
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:296
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Definition: DerivedTypes.h:572
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2058
static cl::opt< bool > ClInstrumentLandingPads("hwasan-instrument-landing-pads", cl::desc("instrument landing pads"), cl::Hidden, cl::init(true))
static LocalAsMetadata * get(Value *Local)
Definition: Metadata.h:435
std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module&#39;s strong...
Comdat * getOrInsertComdat(StringRef Name)
Return the Comdat in the module with the specified name.
Definition: Module.cpp:482
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:159
const Value * getArraySize() const
Get the number of elements allocated.
Definition: Instructions.h:92
size_t size() const
Definition: SmallVector.h:52
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
Definition: IRBuilder.h:421
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
Definition: MDBuilder.cpp:37
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1874
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
Definition: Instructions.h:105
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:43
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition: IRBuilder.h:2188
Value * CreateGEP(Value *Ptr, ArrayRef< Value *> IdxList, const Twine &Name="")
Definition: IRBuilder.h:1677
This is the common base class for memset/memcpy/memmove.
This is the shared class of boolean and integer constants.
Definition: Constants.h:83
iterator end()
Definition: BasicBlock.h:270
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition: IRBuilder.h:2020
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2070
Module.h This file contains the declarations for the Module class.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition: Constants.cpp:631
void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
Definition: ModuleUtils.cpp:63
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
Definition: Module.cpp:143
DWARF expression.
void setOperand(unsigned i, Value *Val)
Definition: User.h:174
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Definition: Instruction.cpp:55
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition: IRBuilder.h:373
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1207
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1997
static cl::opt< bool > ClWithTls("hwasan-with-tls", cl::desc("Access dynamic shadow through an thread-local pointer on " "platforms that support this"), cl::Hidden, cl::init(true))
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
Definition: DataLayout.h:469
static cl::opt< bool > ClEnableKhwasan("hwasan-kernel", cl::desc("Enable KernelHWAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
use_iterator use_begin()
Definition: Value.h:338
Constant * getOrInsertGlobal(StringRef Name, Type *Ty, function_ref< GlobalVariable *()> CreateGlobalCallback)
Look up the specified global in the module symbol table.
Definition: Module.cpp:204
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:55
StringRef getValueAsString() const
Return the attribute&#39;s value as a string.
Definition: Attributes.cpp:223
static const uint64_t kDynamicShadowSentinel
StringRef getName() const
Return a constant reference to the value&#39;s name.
Definition: Value.cpp:214
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:106
#define I(x, y, z)
Definition: MD5.cpp:58
#define N
static unsigned RetagMask(unsigned AllocaNo)
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Definition: Type.cpp:582
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:332
uint32_t Size
Definition: Profile.cpp:46
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value *> Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2193
static cl::opt< bool > ClRecordStackHistory("hwasan-record-stack-history", cl::desc("Record stack frames with tagged allocations " "in a thread-local ring buffer"), cl::Hidden, cl::init(true))
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT)
InlineAsm::get - Return the specified uniqued inline asm string.
Definition: InlineAsm.cpp:42
static cl::opt< bool > ClWithIfunc("hwasan-with-ifunc", cl::desc("Access dynamic shadow through an ifunc global on " "platforms that support this"), cl::Hidden, cl::init(false))
static cl::opt< bool > ClInstrumentWithCalls("hwasan-instrument-with-calls", cl::desc("instrument reads and writes with callbacks"), cl::Hidden, cl::init(false))
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition: DenseMap.h:211
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1268
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1941
static uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
bool isArrayAllocation() const
Return true if there is an allocation size parameter to the allocation instruction that is not 1...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:575
LLVM Value Representation.
Definition: Value.h:72
void moveBefore(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
Definition: Instruction.cpp:86
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:333
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1228
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:48
A container for analyses that lazily runs them and caches their results.
HWAddressSanitizerPass(bool CompileKernel=false, bool Recover=false)
INITIALIZE_PASS_BEGIN(HWAddressSanitizerLegacyPass, "hwasan", "HWAddressSanitizer: detect memory bugs using tagged addressing.", false, false) INITIALIZE_PASS_END(HWAddressSanitizerLegacyPass
bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
static const char *const kHwasanModuleCtorName
#define LLVM_DEBUG(X)
Definition: Debug.h:122
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
IntegerType * Int32Ty
const BasicBlock * getParent() const
Definition: Instruction.h:66
an instruction to allocate memory on the stack
Definition: Instructions.h:59
static cl::opt< bool > ClUARRetagToZero("hwasan-uar-retag-to-zero", cl::desc("Clear alloca tags before returning from the function to allow " "non-instrumented and instrumented function calls mix. When set " "to false, allocas are retagged before returning from the " "function to detect use after return."), cl::Hidden, cl::init(true))
static cl::opt< bool > ClInstrumentReads("hwasan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))