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