LLVM  8.0.1
HWAddressSanitizer.cpp
Go to the documentation of this file.
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"
41 #include "llvm/Support/Debug.h"
47 #include <sstream>
48 
49 using namespace llvm;
50 
51 #define DEBUG_TYPE "hwasan"
52 
53 static const char *const kHwasanModuleCtorName = "hwasan.module_ctor";
54 static const char *const kHwasanInitName = "__hwasan_init";
55 
56 static const char *const kHwasanShadowMemoryDynamicAddress =
57  "__hwasan_shadow_memory_dynamic_address";
58 
59 // Accesses sizes are powers of two: 1, 2, 4, 8, 16.
60 static const size_t kNumberOfAccessSizes = 5;
61 
62 static const size_t kDefaultShadowScale = 4;
63 static const uint64_t kDynamicShadowSentinel =
65 static const unsigned kPointerTagShift = 56;
66 
67 static const unsigned kShadowBaseAlignment = 32;
68 
70  "hwasan-memory-access-callback-prefix",
71  cl::desc("Prefix for memory access callbacks"), cl::Hidden,
72  cl::init("__hwasan_"));
73 
74 static cl::opt<bool>
75  ClInstrumentWithCalls("hwasan-instrument-with-calls",
76  cl::desc("instrument reads and writes with callbacks"),
77  cl::Hidden, cl::init(false));
78 
79 static cl::opt<bool> ClInstrumentReads("hwasan-instrument-reads",
80  cl::desc("instrument read instructions"),
81  cl::Hidden, cl::init(true));
82 
84  "hwasan-instrument-writes", cl::desc("instrument write instructions"),
85  cl::Hidden, cl::init(true));
86 
88  "hwasan-instrument-atomics",
89  cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
90  cl::init(true));
91 
93  "hwasan-recover",
94  cl::desc("Enable recovery mode (continue-after-error)."),
95  cl::Hidden, cl::init(false));
96 
97 static cl::opt<bool> ClInstrumentStack("hwasan-instrument-stack",
98  cl::desc("instrument stack (allocas)"),
99  cl::Hidden, cl::init(true));
100 
102  "hwasan-uar-retag-to-zero",
103  cl::desc("Clear alloca tags before returning from the function to allow "
104  "non-instrumented and instrumented function calls mix. When set "
105  "to false, allocas are retagged before returning from the "
106  "function to detect use after return."),
107  cl::Hidden, cl::init(true));
108 
110  "hwasan-generate-tags-with-calls",
111  cl::desc("generate new tags with runtime library calls"), cl::Hidden,
112  cl::init(false));
113 
115  "hwasan-match-all-tag",
116  cl::desc("don't report bad accesses via pointers with this tag"),
117  cl::Hidden, cl::init(-1));
118 
120  "hwasan-kernel",
121  cl::desc("Enable KernelHWAddressSanitizer instrumentation"),
122  cl::Hidden, cl::init(false));
123 
124 // These flags allow to change the shadow mapping and control how shadow memory
125 // is accessed. The shadow mapping looks like:
126 // Shadow = (Mem >> scale) + offset
127 
129  "hwasan-mapping-offset",
130  cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"), cl::Hidden,
131  cl::init(0));
132 
133 static cl::opt<bool>
134  ClWithIfunc("hwasan-with-ifunc",
135  cl::desc("Access dynamic shadow through an ifunc global on "
136  "platforms that support this"),
137  cl::Hidden, cl::init(false));
138 
139 static cl::opt<bool> ClWithTls(
140  "hwasan-with-tls",
141  cl::desc("Access dynamic shadow through an thread-local pointer on "
142  "platforms that support this"),
143  cl::Hidden, cl::init(true));
144 
145 static cl::opt<bool>
146  ClRecordStackHistory("hwasan-record-stack-history",
147  cl::desc("Record stack frames with tagged allocations "
148  "in a thread-local ring buffer"),
149  cl::Hidden, cl::init(true));
150 static cl::opt<bool>
151  ClCreateFrameDescriptions("hwasan-create-frame-descriptions",
152  cl::desc("create static frame descriptions"),
153  cl::Hidden, cl::init(true));
154 
155 static cl::opt<bool>
156  ClInstrumentMemIntrinsics("hwasan-instrument-mem-intrinsics",
157  cl::desc("instrument memory intrinsics"),
158  cl::Hidden, cl::init(true));
159 namespace {
160 
161 /// An instrumentation pass implementing detection of addressability bugs
162 /// using tagged pointers.
163 class HWAddressSanitizer : public FunctionPass {
164 public:
165  // Pass identification, replacement for typeid.
166  static char ID;
167 
168  explicit HWAddressSanitizer(bool CompileKernel = false, bool Recover = false)
169  : FunctionPass(ID) {
170  this->Recover = ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover;
171  this->CompileKernel = ClEnableKhwasan.getNumOccurrences() > 0 ?
172  ClEnableKhwasan : CompileKernel;
173  }
174 
175  StringRef getPassName() const override { return "HWAddressSanitizer"; }
176 
177  bool runOnFunction(Function &F) override;
178  bool doInitialization(Module &M) override;
179 
180  void initializeCallbacks(Module &M);
181 
182  Value *getDynamicShadowNonTls(IRBuilder<> &IRB);
183 
184  void untagPointerOperand(Instruction *I, Value *Addr);
185  Value *memToShadow(Value *Shadow, Type *Ty, IRBuilder<> &IRB);
186  void instrumentMemAccessInline(Value *PtrLong, bool IsWrite,
187  unsigned AccessSizeIndex,
188  Instruction *InsertBefore);
189  void instrumentMemIntrinsic(MemIntrinsic *MI);
190  bool instrumentMemAccess(Instruction *I);
191  Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite,
192  uint64_t *TypeSize, unsigned *Alignment,
193  Value **MaybeMask);
194 
195  bool isInterestingAlloca(const AllocaInst &AI);
196  bool tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag);
197  Value *tagPointer(IRBuilder<> &IRB, Type *Ty, Value *PtrLong, Value *Tag);
198  Value *untagPointer(IRBuilder<> &IRB, Value *PtrLong);
199  bool instrumentStack(SmallVectorImpl<AllocaInst *> &Allocas,
200  SmallVectorImpl<Instruction *> &RetVec, Value *StackTag);
201  Value *getNextTagWithCall(IRBuilder<> &IRB);
202  Value *getStackBaseTag(IRBuilder<> &IRB);
203  Value *getAllocaTag(IRBuilder<> &IRB, Value *StackTag, AllocaInst *AI,
204  unsigned AllocaNo);
205  Value *getUARTag(IRBuilder<> &IRB, Value *StackTag);
206 
207  Value *getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty);
208  Value *emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord);
209 
210 private:
211  LLVMContext *C;
212  std::string CurModuleUniqueId;
213  Triple TargetTriple;
214  Function *HWAsanMemmove, *HWAsanMemcpy, *HWAsanMemset;
215 
216  // Frame description is a way to pass names/sizes of local variables
217  // to the run-time w/o adding extra executable code in every function.
218  // We do this by creating a separate section with {PC,Descr} pairs and passing
219  // the section beg/end to __hwasan_init_frames() at module init time.
220  std::string createFrameString(ArrayRef<AllocaInst*> Allocas);
221  void createFrameGlobal(Function &F, const std::string &FrameString);
222  // Get the section name for frame descriptions. Currently ELF-only.
223  const char *getFrameSection() { return "__hwasan_frames"; }
224  const char *getFrameSectionBeg() { return "__start___hwasan_frames"; }
225  const char *getFrameSectionEnd() { return "__stop___hwasan_frames"; }
226  GlobalVariable *createFrameSectionBound(Module &M, Type *Ty,
227  const char *Name) {
228  auto GV = new GlobalVariable(M, Ty, false, GlobalVariable::ExternalLinkage,
229  nullptr, Name);
230  GV->setVisibility(GlobalValue::HiddenVisibility);
231  return GV;
232  }
233 
234  /// This struct defines the shadow mapping using the rule:
235  /// shadow = (mem >> Scale) + Offset.
236  /// If InGlobal is true, then
237  /// extern char __hwasan_shadow[];
238  /// shadow = (mem >> Scale) + &__hwasan_shadow
239  /// If InTls is true, then
240  /// extern char *__hwasan_tls;
241  /// shadow = (mem>>Scale) + align_up(__hwasan_shadow, kShadowBaseAlignment)
242  struct ShadowMapping {
243  int Scale;
244  uint64_t Offset;
245  bool InGlobal;
246  bool InTls;
247 
248  void init(Triple &TargetTriple);
249  unsigned getAllocaAlignment() const { return 1U << Scale; }
250  };
251  ShadowMapping Mapping;
252 
253  Type *IntptrTy;
254  Type *Int8PtrTy;
255  Type *Int8Ty;
256 
257  bool CompileKernel;
258  bool Recover;
259 
260  Function *HwasanCtorFunction;
261 
262  Function *HwasanMemoryAccessCallback[2][kNumberOfAccessSizes];
263  Function *HwasanMemoryAccessCallbackSized[2];
264 
265  Function *HwasanTagMemoryFunc;
266  Function *HwasanGenerateTagFunc;
267  Function *HwasanThreadEnterFunc;
268 
269  Constant *ShadowGlobal;
270 
271  Value *LocalDynamicShadow = nullptr;
272  GlobalValue *ThreadPtrGlobal = nullptr;
273 };
274 
275 } // end anonymous namespace
276 
277 char HWAddressSanitizer::ID = 0;
278 
280  HWAddressSanitizer, "hwasan",
281  "HWAddressSanitizer: detect memory bugs using tagged addressing.", false,
282  false)
284  HWAddressSanitizer, "hwasan",
285  "HWAddressSanitizer: detect memory bugs using tagged addressing.", false,
286  false)
287 
289  bool Recover) {
290  assert(!CompileKernel || Recover);
291  return new HWAddressSanitizer(CompileKernel, Recover);
292 }
293 
294 /// Module-level initialization.
295 ///
296 /// inserts a call to __hwasan_init to the module's constructor list.
297 bool HWAddressSanitizer::doInitialization(Module &M) {
298  LLVM_DEBUG(dbgs() << "Init " << M.getName() << "\n");
299  auto &DL = M.getDataLayout();
300 
301  TargetTriple = Triple(M.getTargetTriple());
302 
303  Mapping.init(TargetTriple);
304 
305  C = &(M.getContext());
306  CurModuleUniqueId = getUniqueModuleId(&M);
307  IRBuilder<> IRB(*C);
308  IntptrTy = IRB.getIntPtrTy(DL);
309  Int8PtrTy = IRB.getInt8PtrTy();
310  Int8Ty = IRB.getInt8Ty();
311 
312  HwasanCtorFunction = nullptr;
313  if (!CompileKernel) {
314  std::tie(HwasanCtorFunction, std::ignore) =
315  createSanitizerCtorAndInitFunctions(M, kHwasanModuleCtorName,
316  kHwasanInitName,
317  /*InitArgTypes=*/{},
318  /*InitArgs=*/{});
319  Comdat *CtorComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
320  HwasanCtorFunction->setComdat(CtorComdat);
321  appendToGlobalCtors(M, HwasanCtorFunction, 0, HwasanCtorFunction);
322 
323  // Create a zero-length global in __hwasan_frame so that the linker will
324  // always create start and stop symbols.
325  //
326  // N.B. If we ever start creating associated metadata in this pass this
327  // global will need to be associated with the ctor.
328  Type *Int8Arr0Ty = ArrayType::get(Int8Ty, 0);
329  auto GV =
330  new GlobalVariable(M, Int8Arr0Ty, /*isConstantGlobal*/ true,
332  Constant::getNullValue(Int8Arr0Ty), "__hwasan");
333  GV->setSection(getFrameSection());
334  GV->setComdat(CtorComdat);
335  appendToCompilerUsed(M, GV);
336 
337  IRBuilder<> IRBCtor(HwasanCtorFunction->getEntryBlock().getTerminator());
338  IRBCtor.CreateCall(
339  declareSanitizerInitFunction(M, "__hwasan_init_frames",
340  {Int8PtrTy, Int8PtrTy}),
341  {createFrameSectionBound(M, Int8Ty, getFrameSectionBeg()),
342  createFrameSectionBound(M, Int8Ty, getFrameSectionEnd())});
343  }
344 
345  if (!TargetTriple.isAndroid())
347  M, ThreadPtrGlobal = new GlobalVariable(
348  M, IntptrTy, false, GlobalVariable::ExternalLinkage, nullptr,
349  "__hwasan_tls", nullptr, GlobalVariable::InitialExecTLSModel));
350 
351  return true;
352 }
353 
354 void HWAddressSanitizer::initializeCallbacks(Module &M) {
355  IRBuilder<> IRB(*C);
356  for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
357  const std::string TypeStr = AccessIsWrite ? "store" : "load";
358  const std::string EndingStr = Recover ? "_noabort" : "";
359 
360  HwasanMemoryAccessCallbackSized[AccessIsWrite] =
362  ClMemoryAccessCallbackPrefix + TypeStr + "N" + EndingStr,
363  FunctionType::get(IRB.getVoidTy(), {IntptrTy, IntptrTy}, false)));
364 
365  for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
366  AccessSizeIndex++) {
367  HwasanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] =
369  ClMemoryAccessCallbackPrefix + TypeStr +
370  itostr(1ULL << AccessSizeIndex) + EndingStr,
371  FunctionType::get(IRB.getVoidTy(), {IntptrTy}, false)));
372  }
373  }
374 
376  "__hwasan_tag_memory", IRB.getVoidTy(), Int8PtrTy, Int8Ty, IntptrTy));
377  HwasanGenerateTagFunc = checkSanitizerInterfaceFunction(
378  M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty));
379 
380  if (Mapping.InGlobal)
381  ShadowGlobal = M.getOrInsertGlobal("__hwasan_shadow",
382  ArrayType::get(IRB.getInt8Ty(), 0));
383 
384  const std::string MemIntrinCallbackPrefix =
385  CompileKernel ? std::string("") : ClMemoryAccessCallbackPrefix;
387  MemIntrinCallbackPrefix + "memmove", IRB.getInt8PtrTy(),
388  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy));
390  MemIntrinCallbackPrefix + "memcpy", IRB.getInt8PtrTy(),
391  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(), IntptrTy));
393  MemIntrinCallbackPrefix + "memset", IRB.getInt8PtrTy(),
394  IRB.getInt8PtrTy(), IRB.getInt32Ty(), IntptrTy));
395 
396  HwasanThreadEnterFunc = checkSanitizerInterfaceFunction(
397  M.getOrInsertFunction("__hwasan_thread_enter", IRB.getVoidTy()));
398 }
399 
400 Value *HWAddressSanitizer::getDynamicShadowNonTls(IRBuilder<> &IRB) {
401  // Generate code only when dynamic addressing is needed.
402  if (Mapping.Offset != kDynamicShadowSentinel)
403  return nullptr;
404 
405  if (Mapping.InGlobal) {
406  // An empty inline asm with input reg == output reg.
407  // An opaque pointer-to-int cast, basically.
409  FunctionType::get(IntptrTy, {ShadowGlobal->getType()}, false),
410  StringRef(""), StringRef("=r,0"),
411  /*hasSideEffects=*/false);
412  return IRB.CreateCall(Asm, {ShadowGlobal}, ".hwasan.shadow");
413  } else {
414  Value *GlobalDynamicAddress =
416  kHwasanShadowMemoryDynamicAddress, IntptrTy);
417  return IRB.CreateLoad(GlobalDynamicAddress);
418  }
419 }
420 
421 Value *HWAddressSanitizer::isInterestingMemoryAccess(Instruction *I,
422  bool *IsWrite,
423  uint64_t *TypeSize,
424  unsigned *Alignment,
425  Value **MaybeMask) {
426  // Skip memory accesses inserted by another instrumentation.
427  if (I->getMetadata("nosanitize")) return nullptr;
428 
429  // Do not instrument the load fetching the dynamic shadow address.
430  if (LocalDynamicShadow == I)
431  return nullptr;
432 
433  Value *PtrOperand = nullptr;
434  const DataLayout &DL = I->getModule()->getDataLayout();
435  if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
436  if (!ClInstrumentReads) return nullptr;
437  *IsWrite = false;
438  *TypeSize = DL.getTypeStoreSizeInBits(LI->getType());
439  *Alignment = LI->getAlignment();
440  PtrOperand = LI->getPointerOperand();
441  } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
442  if (!ClInstrumentWrites) return nullptr;
443  *IsWrite = true;
444  *TypeSize = DL.getTypeStoreSizeInBits(SI->getValueOperand()->getType());
445  *Alignment = SI->getAlignment();
446  PtrOperand = SI->getPointerOperand();
447  } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
448  if (!ClInstrumentAtomics) return nullptr;
449  *IsWrite = true;
450  *TypeSize = DL.getTypeStoreSizeInBits(RMW->getValOperand()->getType());
451  *Alignment = 0;
452  PtrOperand = RMW->getPointerOperand();
453  } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
454  if (!ClInstrumentAtomics) return nullptr;
455  *IsWrite = true;
456  *TypeSize = DL.getTypeStoreSizeInBits(XCHG->getCompareOperand()->getType());
457  *Alignment = 0;
458  PtrOperand = XCHG->getPointerOperand();
459  }
460 
461  if (PtrOperand) {
462  // Do not instrument accesses from different address spaces; we cannot deal
463  // with them.
464  Type *PtrTy = cast<PointerType>(PtrOperand->getType()->getScalarType());
465  if (PtrTy->getPointerAddressSpace() != 0)
466  return nullptr;
467 
468  // Ignore swifterror addresses.
469  // swifterror memory addresses are mem2reg promoted by instruction
470  // selection. As such they cannot have regular uses like an instrumentation
471  // function and it makes no sense to track them as memory.
472  if (PtrOperand->isSwiftError())
473  return nullptr;
474  }
475 
476  return PtrOperand;
477 }
478 
479 static unsigned getPointerOperandIndex(Instruction *I) {
480  if (LoadInst *LI = dyn_cast<LoadInst>(I))
481  return LI->getPointerOperandIndex();
482  if (StoreInst *SI = dyn_cast<StoreInst>(I))
483  return SI->getPointerOperandIndex();
484  if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I))
485  return RMW->getPointerOperandIndex();
486  if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I))
487  return XCHG->getPointerOperandIndex();
488  report_fatal_error("Unexpected instruction");
489  return -1;
490 }
491 
492 static size_t TypeSizeToSizeIndex(uint32_t TypeSize) {
493  size_t Res = countTrailingZeros(TypeSize / 8);
495  return Res;
496 }
497 
498 void HWAddressSanitizer::untagPointerOperand(Instruction *I, Value *Addr) {
499  if (TargetTriple.isAArch64())
500  return;
501 
502  IRBuilder<> IRB(I);
503  Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
504  Value *UntaggedPtr =
505  IRB.CreateIntToPtr(untagPointer(IRB, AddrLong), Addr->getType());
506  I->setOperand(getPointerOperandIndex(I), UntaggedPtr);
507 }
508 
509 Value *HWAddressSanitizer::memToShadow(Value *Mem, Type *Ty, IRBuilder<> &IRB) {
510  // Mem >> Scale
511  Value *Shadow = IRB.CreateLShr(Mem, Mapping.Scale);
512  if (Mapping.Offset == 0)
513  return Shadow;
514  // (Mem >> Scale) + Offset
515  Value *ShadowBase;
516  if (LocalDynamicShadow)
517  ShadowBase = LocalDynamicShadow;
518  else
519  ShadowBase = ConstantInt::get(Ty, Mapping.Offset);
520  return IRB.CreateAdd(Shadow, ShadowBase);
521 }
522 
523 void HWAddressSanitizer::instrumentMemAccessInline(Value *PtrLong, bool IsWrite,
524  unsigned AccessSizeIndex,
525  Instruction *InsertBefore) {
526  IRBuilder<> IRB(InsertBefore);
527  Value *PtrTag = IRB.CreateTrunc(IRB.CreateLShr(PtrLong, kPointerTagShift),
528  IRB.getInt8Ty());
529  Value *AddrLong = untagPointer(IRB, PtrLong);
530  Value *ShadowLong = memToShadow(AddrLong, PtrLong->getType(), IRB);
531  Value *MemTag = IRB.CreateLoad(IRB.CreateIntToPtr(ShadowLong, Int8PtrTy));
532  Value *TagMismatch = IRB.CreateICmpNE(PtrTag, MemTag);
533 
534  int matchAllTag = ClMatchAllTag.getNumOccurrences() > 0 ?
535  ClMatchAllTag : (CompileKernel ? 0xFF : -1);
536  if (matchAllTag != -1) {
537  Value *TagNotIgnored = IRB.CreateICmpNE(PtrTag,
538  ConstantInt::get(PtrTag->getType(), matchAllTag));
539  TagMismatch = IRB.CreateAnd(TagMismatch, TagNotIgnored);
540  }
541 
542  Instruction *CheckTerm =
543  SplitBlockAndInsertIfThen(TagMismatch, InsertBefore, !Recover,
544  MDBuilder(*C).createBranchWeights(1, 100000));
545 
546  IRB.SetInsertPoint(CheckTerm);
547  const int64_t AccessInfo = Recover * 0x20 + IsWrite * 0x10 + AccessSizeIndex;
548  InlineAsm *Asm;
549  switch (TargetTriple.getArch()) {
550  case Triple::x86_64:
551  // The signal handler will find the data address in rdi.
552  Asm = InlineAsm::get(
553  FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
554  "int3\nnopl " + itostr(0x40 + AccessInfo) + "(%rax)",
555  "{rdi}",
556  /*hasSideEffects=*/true);
557  break;
558  case Triple::aarch64:
559  case Triple::aarch64_be:
560  // The signal handler will find the data address in x0.
561  Asm = InlineAsm::get(
562  FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
563  "brk #" + itostr(0x900 + AccessInfo),
564  "{x0}",
565  /*hasSideEffects=*/true);
566  break;
567  default:
568  report_fatal_error("unsupported architecture");
569  }
570  IRB.CreateCall(Asm, PtrLong);
571 }
572 
573 void HWAddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
574  IRBuilder<> IRB(MI);
575  if (isa<MemTransferInst>(MI)) {
576  IRB.CreateCall(
577  isa<MemMoveInst>(MI) ? HWAsanMemmove : HWAsanMemcpy,
578  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
579  IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()),
580  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
581  } else if (isa<MemSetInst>(MI)) {
582  IRB.CreateCall(
583  HWAsanMemset,
584  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
585  IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
586  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
587  }
588  MI->eraseFromParent();
589 }
590 
591 bool HWAddressSanitizer::instrumentMemAccess(Instruction *I) {
592  LLVM_DEBUG(dbgs() << "Instrumenting: " << *I << "\n");
593  bool IsWrite = false;
594  unsigned Alignment = 0;
595  uint64_t TypeSize = 0;
596  Value *MaybeMask = nullptr;
597 
598  if (ClInstrumentMemIntrinsics && isa<MemIntrinsic>(I)) {
599  instrumentMemIntrinsic(cast<MemIntrinsic>(I));
600  return true;
601  }
602 
603  Value *Addr =
604  isInterestingMemoryAccess(I, &IsWrite, &TypeSize, &Alignment, &MaybeMask);
605 
606  if (!Addr)
607  return false;
608 
609  if (MaybeMask)
610  return false; //FIXME
611 
612  IRBuilder<> IRB(I);
613  Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
614  if (isPowerOf2_64(TypeSize) &&
615  (TypeSize / 8 <= (1UL << (kNumberOfAccessSizes - 1))) &&
616  (Alignment >= (1UL << Mapping.Scale) || Alignment == 0 ||
617  Alignment >= TypeSize / 8)) {
618  size_t AccessSizeIndex = TypeSizeToSizeIndex(TypeSize);
619  if (ClInstrumentWithCalls) {
620  IRB.CreateCall(HwasanMemoryAccessCallback[IsWrite][AccessSizeIndex],
621  AddrLong);
622  } else {
623  instrumentMemAccessInline(AddrLong, IsWrite, AccessSizeIndex, I);
624  }
625  } else {
626  IRB.CreateCall(HwasanMemoryAccessCallbackSized[IsWrite],
627  {AddrLong, ConstantInt::get(IntptrTy, TypeSize / 8)});
628  }
629  untagPointerOperand(I, Addr);
630 
631  return true;
632 }
633 
634 static uint64_t getAllocaSizeInBytes(const AllocaInst &AI) {
635  uint64_t ArraySize = 1;
636  if (AI.isArrayAllocation()) {
637  const ConstantInt *CI = dyn_cast<ConstantInt>(AI.getArraySize());
638  assert(CI && "non-constant array size");
639  ArraySize = CI->getZExtValue();
640  }
641  Type *Ty = AI.getAllocatedType();
642  uint64_t SizeInBytes = AI.getModule()->getDataLayout().getTypeAllocSize(Ty);
643  return SizeInBytes * ArraySize;
644 }
645 
646 bool HWAddressSanitizer::tagAlloca(IRBuilder<> &IRB, AllocaInst *AI,
647  Value *Tag) {
648  size_t Size = (getAllocaSizeInBytes(*AI) + Mapping.getAllocaAlignment() - 1) &
649  ~(Mapping.getAllocaAlignment() - 1);
650 
651  Value *JustTag = IRB.CreateTrunc(Tag, IRB.getInt8Ty());
652  if (ClInstrumentWithCalls) {
653  IRB.CreateCall(HwasanTagMemoryFunc,
654  {IRB.CreatePointerCast(AI, Int8PtrTy), JustTag,
655  ConstantInt::get(IntptrTy, Size)});
656  } else {
657  size_t ShadowSize = Size >> Mapping.Scale;
658  Value *ShadowPtr = IRB.CreateIntToPtr(
659  memToShadow(IRB.CreatePointerCast(AI, IntptrTy), AI->getType(), IRB),
660  Int8PtrTy);
661  // If this memset is not inlined, it will be intercepted in the hwasan
662  // runtime library. That's OK, because the interceptor skips the checks if
663  // the address is in the shadow region.
664  // FIXME: the interceptor is not as fast as real memset. Consider lowering
665  // llvm.memset right here into either a sequence of stores, or a call to
666  // hwasan_tag_memory.
667  IRB.CreateMemSet(ShadowPtr, JustTag, ShadowSize, /*Align=*/1);
668  }
669  return true;
670 }
671 
672 static unsigned RetagMask(unsigned AllocaNo) {
673  // A list of 8-bit numbers that have at most one run of non-zero bits.
674  // x = x ^ (mask << 56) can be encoded as a single armv8 instruction for these
675  // masks.
676  // The list does not include the value 255, which is used for UAR.
677  static unsigned FastMasks[] = {
678  0, 1, 2, 3, 4, 6, 7, 8, 12, 14, 15, 16, 24,
679  28, 30, 31, 32, 48, 56, 60, 62, 63, 64, 96, 112, 120,
680  124, 126, 127, 128, 192, 224, 240, 248, 252, 254};
681  return FastMasks[AllocaNo % (sizeof(FastMasks) / sizeof(FastMasks[0]))];
682 }
683 
684 Value *HWAddressSanitizer::getNextTagWithCall(IRBuilder<> &IRB) {
685  return IRB.CreateZExt(IRB.CreateCall(HwasanGenerateTagFunc), IntptrTy);
686 }
687 
688 Value *HWAddressSanitizer::getStackBaseTag(IRBuilder<> &IRB) {
690  return getNextTagWithCall(IRB);
691  // FIXME: use addressofreturnaddress (but implement it in aarch64 backend
692  // first).
693  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
694  auto GetStackPointerFn =
696  Value *StackPointer = IRB.CreateCall(
697  GetStackPointerFn, {Constant::getNullValue(IRB.getInt32Ty())});
698 
699  // Extract some entropy from the stack pointer for the tags.
700  // Take bits 20..28 (ASLR entropy) and xor with bits 0..8 (these differ
701  // between functions).
702  Value *StackPointerLong = IRB.CreatePointerCast(StackPointer, IntptrTy);
703  Value *StackTag =
704  IRB.CreateXor(StackPointerLong, IRB.CreateLShr(StackPointerLong, 20),
705  "hwasan.stack.base.tag");
706  return StackTag;
707 }
708 
709 Value *HWAddressSanitizer::getAllocaTag(IRBuilder<> &IRB, Value *StackTag,
710  AllocaInst *AI, unsigned AllocaNo) {
712  return getNextTagWithCall(IRB);
713  return IRB.CreateXor(StackTag,
714  ConstantInt::get(IntptrTy, RetagMask(AllocaNo)));
715 }
716 
717 Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB, Value *StackTag) {
718  if (ClUARRetagToZero)
719  return ConstantInt::get(IntptrTy, 0);
721  return getNextTagWithCall(IRB);
722  return IRB.CreateXor(StackTag, ConstantInt::get(IntptrTy, 0xFFU));
723 }
724 
725 // Add a tag to an address.
726 Value *HWAddressSanitizer::tagPointer(IRBuilder<> &IRB, Type *Ty,
727  Value *PtrLong, Value *Tag) {
728  Value *TaggedPtrLong;
729  if (CompileKernel) {
730  // Kernel addresses have 0xFF in the most significant byte.
731  Value *ShiftedTag = IRB.CreateOr(
732  IRB.CreateShl(Tag, kPointerTagShift),
733  ConstantInt::get(IntptrTy, (1ULL << kPointerTagShift) - 1));
734  TaggedPtrLong = IRB.CreateAnd(PtrLong, ShiftedTag);
735  } else {
736  // Userspace can simply do OR (tag << 56);
737  Value *ShiftedTag = IRB.CreateShl(Tag, kPointerTagShift);
738  TaggedPtrLong = IRB.CreateOr(PtrLong, ShiftedTag);
739  }
740  return IRB.CreateIntToPtr(TaggedPtrLong, Ty);
741 }
742 
743 // Remove tag from an address.
744 Value *HWAddressSanitizer::untagPointer(IRBuilder<> &IRB, Value *PtrLong) {
745  Value *UntaggedPtrLong;
746  if (CompileKernel) {
747  // Kernel addresses have 0xFF in the most significant byte.
748  UntaggedPtrLong = IRB.CreateOr(PtrLong,
749  ConstantInt::get(PtrLong->getType(), 0xFFULL << kPointerTagShift));
750  } else {
751  // Userspace addresses have 0x00.
752  UntaggedPtrLong = IRB.CreateAnd(PtrLong,
753  ConstantInt::get(PtrLong->getType(), ~(0xFFULL << kPointerTagShift)));
754  }
755  return UntaggedPtrLong;
756 }
757 
758 Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty) {
759  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
760  if (TargetTriple.isAArch64() && TargetTriple.isAndroid()) {
761  // Android provides a fixed TLS slot for sanitizers. See TLS_SLOT_SANITIZER
762  // in Bionic's libc/private/bionic_tls.h.
763  Function *ThreadPointerFunc =
765  Value *SlotPtr = IRB.CreatePointerCast(
766  IRB.CreateConstGEP1_32(IRB.CreateCall(ThreadPointerFunc), 0x30),
767  Ty->getPointerTo(0));
768  return SlotPtr;
769  }
770  if (ThreadPtrGlobal)
771  return ThreadPtrGlobal;
772 
773 
774  return nullptr;
775 }
776 
777 // Creates a string with a description of the stack frame (set of Allocas).
778 // The string is intended to be human readable.
779 // The current form is: Size1 Name1; Size2 Name2; ...
780 std::string
781 HWAddressSanitizer::createFrameString(ArrayRef<AllocaInst *> Allocas) {
782  std::ostringstream Descr;
783  for (auto AI : Allocas)
784  Descr << getAllocaSizeInBytes(*AI) << " " << AI->getName().str() << "; ";
785  return Descr.str();
786 }
787 
788 // Creates a global in the frame section which consists of two pointers:
789 // the function PC and the frame string constant.
790 void HWAddressSanitizer::createFrameGlobal(Function &F,
791  const std::string &FrameString) {
792  Module &M = *F.getParent();
793  auto DescrGV = createPrivateGlobalForString(M, FrameString, true);
794  auto PtrPairTy = StructType::get(F.getType(), DescrGV->getType());
795  auto GV = new GlobalVariable(
796  M, PtrPairTy, /*isConstantGlobal*/ true, GlobalVariable::PrivateLinkage,
797  ConstantStruct::get(PtrPairTy, (Constant *)&F, (Constant *)DescrGV),
798  "__hwasan");
799  GV->setSection(getFrameSection());
800  appendToCompilerUsed(M, GV);
801  // Put GV into the F's Comadat so that if F is deleted GV can be deleted too.
802  if (auto Comdat =
803  GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
804  GV->setComdat(Comdat);
805 }
806 
807 Value *HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB,
808  bool WithFrameRecord) {
809  if (!Mapping.InTls)
810  return getDynamicShadowNonTls(IRB);
811 
812  Value *SlotPtr = getHwasanThreadSlotPtr(IRB, IntptrTy);
813  assert(SlotPtr);
814 
815  Instruction *ThreadLong = IRB.CreateLoad(SlotPtr);
816 
817  Function *F = IRB.GetInsertBlock()->getParent();
818  if (F->getFnAttribute("hwasan-abi").getValueAsString() == "interceptor") {
819  Value *ThreadLongEqZero =
820  IRB.CreateICmpEQ(ThreadLong, ConstantInt::get(IntptrTy, 0));
821  auto *Br = cast<BranchInst>(SplitBlockAndInsertIfThen(
822  ThreadLongEqZero, cast<Instruction>(ThreadLongEqZero)->getNextNode(),
823  false, MDBuilder(*C).createBranchWeights(1, 100000)));
824 
825  IRB.SetInsertPoint(Br);
826  // FIXME: This should call a new runtime function with a custom calling
827  // convention to avoid needing to spill all arguments here.
828  IRB.CreateCall(HwasanThreadEnterFunc);
829  LoadInst *ReloadThreadLong = IRB.CreateLoad(SlotPtr);
830 
831  IRB.SetInsertPoint(&*Br->getSuccessor(0)->begin());
832  PHINode *ThreadLongPhi = IRB.CreatePHI(IntptrTy, 2);
833  ThreadLongPhi->addIncoming(ThreadLong, ThreadLong->getParent());
834  ThreadLongPhi->addIncoming(ReloadThreadLong, ReloadThreadLong->getParent());
835  ThreadLong = ThreadLongPhi;
836  }
837 
838  // Extract the address field from ThreadLong. Unnecessary on AArch64 with TBI.
839  Value *ThreadLongMaybeUntagged =
840  TargetTriple.isAArch64() ? ThreadLong : untagPointer(IRB, ThreadLong);
841 
842  if (WithFrameRecord) {
843  // Prepare ring buffer data.
844  auto PC = IRB.CreatePtrToInt(F, IntptrTy);
845  auto GetStackPointerFn =
847  Value *SP = IRB.CreatePtrToInt(
848  IRB.CreateCall(GetStackPointerFn,
849  {Constant::getNullValue(IRB.getInt32Ty())}),
850  IntptrTy);
851  // Mix SP and PC. TODO: also add the tag to the mix.
852  // Assumptions:
853  // PC is 0x0000PPPPPPPPPPPP (48 bits are meaningful, others are zero)
854  // SP is 0xsssssssssssSSSS0 (4 lower bits are zero)
855  // We only really need ~20 lower non-zero bits (SSSS), so we mix like this:
856  // 0xSSSSPPPPPPPPPPPP
857  SP = IRB.CreateShl(SP, 44);
858 
859  // Store data to ring buffer.
860  Value *RecordPtr =
861  IRB.CreateIntToPtr(ThreadLongMaybeUntagged, IntptrTy->getPointerTo(0));
862  IRB.CreateStore(IRB.CreateOr(PC, SP), RecordPtr);
863 
864  // Update the ring buffer. Top byte of ThreadLong defines the size of the
865  // buffer in pages, it must be a power of two, and the start of the buffer
866  // must be aligned by twice that much. Therefore wrap around of the ring
867  // buffer is simply Addr &= ~((ThreadLong >> 56) << 12).
868  // The use of AShr instead of LShr is due to
869  // https://bugs.llvm.org/show_bug.cgi?id=39030
870  // Runtime library makes sure not to use the highest bit.
871  Value *WrapMask = IRB.CreateXor(
872  IRB.CreateShl(IRB.CreateAShr(ThreadLong, 56), 12, "", true, true),
873  ConstantInt::get(IntptrTy, (uint64_t)-1));
874  Value *ThreadLongNew = IRB.CreateAnd(
875  IRB.CreateAdd(ThreadLong, ConstantInt::get(IntptrTy, 8)), WrapMask);
876  IRB.CreateStore(ThreadLongNew, SlotPtr);
877  }
878 
879  // Get shadow base address by aligning RecordPtr up.
880  // Note: this is not correct if the pointer is already aligned.
881  // Runtime library will make sure this never happens.
882  Value *ShadowBase = IRB.CreateAdd(
883  IRB.CreateOr(
884  ThreadLongMaybeUntagged,
885  ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
886  ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
887  return ShadowBase;
888 }
889 
890 bool HWAddressSanitizer::instrumentStack(
892  SmallVectorImpl<Instruction *> &RetVec, Value *StackTag) {
893  // Ideally, we want to calculate tagged stack base pointer, and rewrite all
894  // alloca addresses using that. Unfortunately, offsets are not known yet
895  // (unless we use ASan-style mega-alloca). Instead we keep the base tag in a
896  // temp, shift-OR it into each alloca address and xor with the retag mask.
897  // This generates one extra instruction per alloca use.
898  for (unsigned N = 0; N < Allocas.size(); ++N) {
899  auto *AI = Allocas[N];
900  IRBuilder<> IRB(AI->getNextNode());
901 
902  // Replace uses of the alloca with tagged address.
903  Value *Tag = getAllocaTag(IRB, StackTag, AI, N);
904  Value *AILong = IRB.CreatePointerCast(AI, IntptrTy);
905  Value *Replacement = tagPointer(IRB, AI->getType(), AILong, Tag);
906  std::string Name =
907  AI->hasName() ? AI->getName().str() : "alloca." + itostr(N);
908  Replacement->setName(Name + ".hwasan");
909 
910  for (auto UI = AI->use_begin(), UE = AI->use_end(); UI != UE;) {
911  Use &U = *UI++;
912  if (U.getUser() != AILong)
913  U.set(Replacement);
914  }
915 
916  tagAlloca(IRB, AI, Tag);
917 
918  for (auto RI : RetVec) {
919  IRB.SetInsertPoint(RI);
920 
921  // Re-tag alloca memory with the special UAR tag.
922  Value *Tag = getUARTag(IRB, StackTag);
923  tagAlloca(IRB, AI, Tag);
924  }
925  }
926 
927  return true;
928 }
929 
930 bool HWAddressSanitizer::isInterestingAlloca(const AllocaInst &AI) {
931  return (AI.getAllocatedType()->isSized() &&
932  // FIXME: instrument dynamic allocas, too
933  AI.isStaticAlloca() &&
934  // alloca() may be called with 0 size, ignore it.
935  getAllocaSizeInBytes(AI) > 0 &&
936  // We are only interested in allocas not promotable to registers.
937  // Promotable allocas are common under -O0.
938  !isAllocaPromotable(&AI) &&
939  // inalloca allocas are not treated as static, and we don't want
940  // dynamic alloca instrumentation for them as well.
941  !AI.isUsedWithInAlloca() &&
942  // swifterror allocas are register promoted by ISel
943  !AI.isSwiftError());
944 }
945 
947  if (&F == HwasanCtorFunction)
948  return false;
949 
951  return false;
952 
953  LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n");
954 
955  SmallVector<Instruction*, 16> ToInstrument;
956  SmallVector<AllocaInst*, 8> AllocasToInstrument;
958  for (auto &BB : F) {
959  for (auto &Inst : BB) {
960  if (ClInstrumentStack)
961  if (AllocaInst *AI = dyn_cast<AllocaInst>(&Inst)) {
962  // Realign all allocas. We don't want small uninteresting allocas to
963  // hide in instrumented alloca's padding.
964  if (AI->getAlignment() < Mapping.getAllocaAlignment())
965  AI->setAlignment(Mapping.getAllocaAlignment());
966  // Instrument some of them.
967  if (isInterestingAlloca(*AI))
968  AllocasToInstrument.push_back(AI);
969  continue;
970  }
971 
972  if (isa<ReturnInst>(Inst) || isa<ResumeInst>(Inst) ||
973  isa<CleanupReturnInst>(Inst))
974  RetVec.push_back(&Inst);
975 
976  Value *MaybeMask = nullptr;
977  bool IsWrite;
978  unsigned Alignment;
979  uint64_t TypeSize;
980  Value *Addr = isInterestingMemoryAccess(&Inst, &IsWrite, &TypeSize,
981  &Alignment, &MaybeMask);
982  if (Addr || isa<MemIntrinsic>(Inst))
983  ToInstrument.push_back(&Inst);
984  }
985  }
986 
987  if (AllocasToInstrument.empty() && ToInstrument.empty())
988  return false;
989 
990  if (ClCreateFrameDescriptions && !AllocasToInstrument.empty())
991  createFrameGlobal(F, createFrameString(AllocasToInstrument));
992 
993  initializeCallbacks(*F.getParent());
994 
995  assert(!LocalDynamicShadow);
996 
997  Instruction *InsertPt = &*F.getEntryBlock().begin();
998  IRBuilder<> EntryIRB(InsertPt);
999  LocalDynamicShadow = emitPrologue(EntryIRB,
1000  /*WithFrameRecord*/ ClRecordStackHistory &&
1001  !AllocasToInstrument.empty());
1002 
1003  bool Changed = false;
1004  if (!AllocasToInstrument.empty()) {
1005  Value *StackTag =
1006  ClGenerateTagsWithCalls ? nullptr : getStackBaseTag(EntryIRB);
1007  Changed |= instrumentStack(AllocasToInstrument, RetVec, StackTag);
1008  }
1009 
1010  for (auto Inst : ToInstrument)
1011  Changed |= instrumentMemAccess(Inst);
1012 
1013  LocalDynamicShadow = nullptr;
1014 
1015  return Changed;
1016 }
1017 
1018 void HWAddressSanitizer::ShadowMapping::init(Triple &TargetTriple) {
1019  Scale = kDefaultShadowScale;
1020  if (ClMappingOffset.getNumOccurrences() > 0) {
1021  InGlobal = false;
1022  InTls = false;
1024  } else if (ClEnableKhwasan || ClInstrumentWithCalls) {
1025  InGlobal = false;
1026  InTls = false;
1027  Offset = 0;
1028  } else if (ClWithIfunc) {
1029  InGlobal = true;
1030  InTls = false;
1032  } else if (ClWithTls) {
1033  InGlobal = false;
1034  InTls = true;
1036  } else {
1037  InGlobal = false;
1038  InTls = false;
1040  }
1041 }
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:68
use_iterator use_end()
Definition: Value.h:347
A parsed version of the target data layout string in and methods for querying it. ...
Definition: DataLayout.h:111
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:427
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
Definition: Module.h:240
Value * CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const Twine &Name="")
Definition: IRBuilder.h:1516
Function * declareSanitizerInitFunction(Module &M, StringRef InitName, ArrayRef< Type *> InitArgTypes)
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:228
Function * checkSanitizerInterfaceFunction(Constant *FuncOrBitcast)
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1843
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:289
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:140
This class represents lattice values for constants.
Definition: AllocatorList.h:24
Constant * getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
Definition: Module.cpp:144
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:1357
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1200
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:265
void setAlignment(unsigned Align)
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:529
static cl::opt< bool > ClRecover("hwasan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
Definition: Instructions.h:136
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:57
Externally visible function.
Definition: GlobalValue.h:49
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:321
StringRef getName() const
Get a short "name" for the module.
Definition: Module.h:227
F(f)
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Definition: DerivedTypes.h:503
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:404
An instruction for reading from memory.
Definition: Instructions.h:168
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
Definition: Instructions.h:692
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:265
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition: IRBuilder.h:347
amdgpu Simplify well known AMD library false Value Value const Twine & Name
static const char *const kHwasanShadowMemoryDynamicAddress
const DataLayout & getDataLayout() const
Get the data layout for the module&#39;s target platform.
Definition: Module.cpp:371
unsigned getAlignment() const
Return the alignment of the memory that is being allocated by the instruction.
Definition: Instructions.h:113
PointerType * getType() const
Overload to return most specific pointer type.
Definition: Instructions.h:97
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:56
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
Definition: Type.cpp:652
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:743
IntegerType * getIntPtrTy(const DataLayout &DL, unsigned AddrSpace=0)
Fetch the type representing a pointer to an integer value.
Definition: IRBuilder.h:390
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:1014
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:342
Type * getVoidTy()
Fetch the type representing void.
Definition: IRBuilder.h:380
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1386
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1727
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
Definition: Use.cpp:41
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:245
std::string itostr(int64_t X)
Definition: StringExtras.h:239
bool isSwiftError() const
Return true if this value is a swifterror value.
Definition: Value.cpp:726
BasicBlock * GetInsertBlock() const
Definition: IRBuilder.h:121
static const unsigned kShadowBaseAlignment
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
Definition: Instructions.h:125
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:221
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
static const unsigned kPointerTagShift
An instruction for storing to memory.
Definition: Instructions.h:321
static cl::opt< bool > ClInstrumentMemIntrinsics("hwasan-instrument-mem-intrinsics", cl::desc("instrument memory intrinsics"), cl::Hidden, cl::init(true))
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1659
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:1020
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Definition: IRBuilder.h:127
Value * getOperand(unsigned i) const
Definition: User.h:170
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:1182
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return &#39;this&#39;.
Definition: Type.h:304
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:423
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:149
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1144
std::size_t 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:120
void set(Value *Val)
Definition: Value.h:671
bool hasName() const
Definition: Value.h:251
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
std::pair< Function *, Function * > createSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type *> InitArgTypes, ArrayRef< Value *> InitArgs, StringRef VersionCheckName=StringRef())
Creates sanitizer constructor function, and calls sanitizer&#39;s init function from it.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
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:42
INITIALIZE_PASS_BEGIN(HWAddressSanitizer, "hwasan", "HWAddressSanitizer: detect memory bugs using tagged addressing.", false, false) INITIALIZE_PASS_END(HWAddressSanitizer
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:434
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
static FunctionType * get(Type *Result, ArrayRef< Type *> Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:297
static Constant * get(StructType *T, ArrayRef< Constant *> V)
Definition: Constants.cpp:1044
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1839
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:484
const Value * getArraySize() const
Get the number of elements allocated.
Definition: Instructions.h:93
size_t size() const
Definition: SmallVector.h:53
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
Definition: IRBuilder.h:385
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
Definition: MDBuilder.cpp:38
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:1655
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
Definition: Instructions.h:106
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Definition: IRBuilder.h:1969
This is the common base class for memset/memcpy/memmove.
This is the shared class of boolean and integer constants.
Definition: Constants.h:84
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition: IRBuilder.h:1801
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
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:622
GlobalVariable * createPrivateGlobalForString(Module &M, StringRef Str, bool AllowMerging, const char *NamePrefix="")
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:84
void setOperand(unsigned i, Value *Val)
Definition: User.h:175
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
Definition: Instruction.cpp:56
Comdat * GetOrCreateFunctionComdat(Function &F, Triple &T, const std::string &ModuleId)
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition: IRBuilder.h:337
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1103
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1778
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
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:436
static cl::opt< bool > ClEnableKhwasan("hwasan-kernel", cl::desc("Enable KernelHWAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
use_iterator use_begin()
Definition: Value.h:339
Constant * getOrInsertGlobal(StringRef Name, Type *Ty, function_ref< GlobalVariable *()> CreateGlobalCallback)
Look up the specified global in the module symbol table.
Definition: Module.cpp:206
LLVM_NODISCARD bool empty() const
Definition: SmallVector.h:56
StringRef getValueAsString() const
Return the attribute&#39;s value as a string.
Definition: Attributes.cpp:195
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:107
#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:581
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:323
uint32_t Size
Definition: Profile.cpp:47
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value *> Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:1974
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:43
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))
FunctionPass * createHWAddressSanitizerPass(bool CompileKernel=false, bool Recover=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1164
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1722
static cl::opt< bool > ClCreateFrameDescriptions("hwasan-create-frame-descriptions", cl::desc("create static frame descriptions"), cl::Hidden, cl::init(true))
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:566
LLVM Value Representation.
Definition: Value.h:73
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:331
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1124
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size...
static cl::opt< unsigned long long > ClMappingOffset("hwasan-mapping-offset", cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
static const char *const kHwasanModuleCtorName
#define LLVM_DEBUG(X)
Definition: Debug.h:123
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:274
const BasicBlock * getParent() const
Definition: Instruction.h:67
an instruction to allocate memory on the stack
Definition: Instructions.h:60
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))