LLVM  15.0.0git
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 basic correctness
11 /// checker based on tagged addressing.
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/MapVector.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/ADT/Triple.h"
25 #include "llvm/BinaryFormat/ELF.h"
26 #include "llvm/IR/Attributes.h"
27 #include "llvm/IR/BasicBlock.h"
28 #include "llvm/IR/Constant.h"
29 #include "llvm/IR/Constants.h"
30 #include "llvm/IR/DataLayout.h"
32 #include "llvm/IR/DerivedTypes.h"
33 #include "llvm/IR/Dominators.h"
34 #include "llvm/IR/Function.h"
35 #include "llvm/IR/IRBuilder.h"
36 #include "llvm/IR/InlineAsm.h"
37 #include "llvm/IR/InstIterator.h"
38 #include "llvm/IR/Instruction.h"
39 #include "llvm/IR/Instructions.h"
40 #include "llvm/IR/IntrinsicInst.h"
41 #include "llvm/IR/Intrinsics.h"
42 #include "llvm/IR/LLVMContext.h"
43 #include "llvm/IR/MDBuilder.h"
44 #include "llvm/IR/Module.h"
45 #include "llvm/IR/Type.h"
46 #include "llvm/IR/Value.h"
47 #include "llvm/Support/Casting.h"
49 #include "llvm/Support/Debug.h"
56 
57 using namespace llvm;
58 
59 #define DEBUG_TYPE "hwasan"
60 
61 const char kHwasanModuleCtorName[] = "hwasan.module_ctor";
62 const char kHwasanNoteName[] = "hwasan.note";
63 const char kHwasanInitName[] = "__hwasan_init";
64 const char kHwasanPersonalityThunkName[] = "__hwasan_personality_thunk";
65 
67  "__hwasan_shadow_memory_dynamic_address";
68 
69 // Accesses sizes are powers of two: 1, 2, 4, 8, 16.
70 static const size_t kNumberOfAccessSizes = 5;
71 
72 static const size_t kDefaultShadowScale = 4;
75 
76 static const unsigned kShadowBaseAlignment = 32;
77 
79  ClMemoryAccessCallbackPrefix("hwasan-memory-access-callback-prefix",
80  cl::desc("Prefix for memory access callbacks"),
81  cl::Hidden, cl::init("__hwasan_"));
82 
84  "hwasan-kernel-mem-intrinsic-prefix",
85  cl::desc("Use prefix for memory intrinsics in KASAN mode"), cl::Hidden,
86  cl::init(false));
87 
89  "hwasan-instrument-with-calls",
90  cl::desc("instrument reads and writes with callbacks"), cl::Hidden,
91  cl::init(false));
92 
93 static cl::opt<bool> ClInstrumentReads("hwasan-instrument-reads",
94  cl::desc("instrument read instructions"),
95  cl::Hidden, cl::init(true));
96 
97 static cl::opt<bool>
98  ClInstrumentWrites("hwasan-instrument-writes",
99  cl::desc("instrument write instructions"), cl::Hidden,
100  cl::init(true));
101 
103  "hwasan-instrument-atomics",
104  cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden,
105  cl::init(true));
106 
107 static cl::opt<bool> ClInstrumentByval("hwasan-instrument-byval",
108  cl::desc("instrument byval arguments"),
109  cl::Hidden, cl::init(true));
110 
111 static cl::opt<bool>
112  ClRecover("hwasan-recover",
113  cl::desc("Enable recovery mode (continue-after-error)."),
114  cl::Hidden, cl::init(false));
115 
116 static cl::opt<bool> ClInstrumentStack("hwasan-instrument-stack",
117  cl::desc("instrument stack (allocas)"),
118  cl::Hidden, cl::init(true));
119 
120 static cl::opt<bool>
121  ClUseStackSafety("hwasan-use-stack-safety", cl::Hidden, cl::init(true),
122  cl::Hidden, cl::desc("Use Stack Safety analysis results"),
123  cl::Optional);
124 
126  "hwasan-max-lifetimes-for-alloca", cl::Hidden, cl::init(3),
128  cl::desc("How many lifetime ends to handle for a single alloca."),
129  cl::Optional);
130 
131 static cl::opt<bool>
132  ClUseAfterScope("hwasan-use-after-scope",
133  cl::desc("detect use after scope within function"),
134  cl::Hidden, cl::init(false));
135 
137  "hwasan-uar-retag-to-zero",
138  cl::desc("Clear alloca tags before returning from the function to allow "
139  "non-instrumented and instrumented function calls mix. When set "
140  "to false, allocas are retagged before returning from the "
141  "function to detect use after return."),
142  cl::Hidden, cl::init(true));
143 
145  "hwasan-generate-tags-with-calls",
146  cl::desc("generate new tags with runtime library calls"), cl::Hidden,
147  cl::init(false));
148 
149 static cl::opt<bool> ClGlobals("hwasan-globals", cl::desc("Instrument globals"),
151 
153  "hwasan-match-all-tag",
154  cl::desc("don't report bad accesses via pointers with this tag"),
155  cl::Hidden, cl::init(-1));
156 
157 static cl::opt<bool>
158  ClEnableKhwasan("hwasan-kernel",
159  cl::desc("Enable KernelHWAddressSanitizer instrumentation"),
160  cl::Hidden, cl::init(false));
161 
162 // These flags allow to change the shadow mapping and control how shadow memory
163 // is accessed. The shadow mapping looks like:
164 // Shadow = (Mem >> scale) + offset
165 
166 static cl::opt<uint64_t>
167  ClMappingOffset("hwasan-mapping-offset",
168  cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"),
169  cl::Hidden, cl::init(0));
170 
171 static cl::opt<bool>
172  ClWithIfunc("hwasan-with-ifunc",
173  cl::desc("Access dynamic shadow through an ifunc global on "
174  "platforms that support this"),
175  cl::Hidden, cl::init(false));
176 
177 static cl::opt<bool> ClWithTls(
178  "hwasan-with-tls",
179  cl::desc("Access dynamic shadow through an thread-local pointer on "
180  "platforms that support this"),
181  cl::Hidden, cl::init(true));
182 
183 static cl::opt<bool>
184  ClRecordStackHistory("hwasan-record-stack-history",
185  cl::desc("Record stack frames with tagged allocations "
186  "in a thread-local ring buffer"),
187  cl::Hidden, cl::init(true));
188 static cl::opt<bool>
189  ClInstrumentMemIntrinsics("hwasan-instrument-mem-intrinsics",
190  cl::desc("instrument memory intrinsics"),
191  cl::Hidden, cl::init(true));
192 
193 static cl::opt<bool>
194  ClInstrumentLandingPads("hwasan-instrument-landing-pads",
195  cl::desc("instrument landing pads"), cl::Hidden,
196  cl::init(false), cl::ZeroOrMore);
197 
199  "hwasan-use-short-granules",
200  cl::desc("use short granules in allocas and outlined checks"), cl::Hidden,
201  cl::init(false), cl::ZeroOrMore);
202 
204  "hwasan-instrument-personality-functions",
205  cl::desc("instrument personality functions"), cl::Hidden, cl::init(false),
207 
208 static cl::opt<bool> ClInlineAllChecks("hwasan-inline-all-checks",
209  cl::desc("inline all checks"),
210  cl::Hidden, cl::init(false));
211 
212 // Enabled from clang by "-fsanitize-hwaddress-experimental-aliasing".
213 static cl::opt<bool> ClUsePageAliases("hwasan-experimental-use-page-aliases",
214  cl::desc("Use page aliasing in HWASan"),
215  cl::Hidden, cl::init(false));
216 
217 namespace {
218 
219 bool shouldUsePageAliases(const Triple &TargetTriple) {
220  return ClUsePageAliases && TargetTriple.getArch() == Triple::x86_64;
221 }
222 
223 bool shouldInstrumentStack(const Triple &TargetTriple) {
224  return !shouldUsePageAliases(TargetTriple) && ClInstrumentStack;
225 }
226 
227 bool shouldInstrumentWithCalls(const Triple &TargetTriple) {
228  return ClInstrumentWithCalls || TargetTriple.getArch() == Triple::x86_64;
229 }
230 
231 bool mightUseStackSafetyAnalysis(bool DisableOptimization) {
233  : !DisableOptimization;
234 }
235 
236 bool shouldUseStackSafetyAnalysis(const Triple &TargetTriple,
237  bool DisableOptimization) {
238  return shouldInstrumentStack(TargetTriple) &&
239  mightUseStackSafetyAnalysis(DisableOptimization);
240 }
241 
242 bool shouldDetectUseAfterScope(const Triple &TargetTriple) {
243  return ClUseAfterScope && shouldInstrumentStack(TargetTriple);
244 }
245 
246 /// An instrumentation pass implementing detection of addressability bugs
247 /// using tagged pointers.
248 class HWAddressSanitizer {
249 public:
250  HWAddressSanitizer(Module &M, bool CompileKernel, bool Recover,
251  const StackSafetyGlobalInfo *SSI)
252  : M(M), SSI(SSI) {
253  this->Recover = ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover;
254  this->CompileKernel = ClEnableKhwasan.getNumOccurrences() > 0
256  : CompileKernel;
257 
258  initializeModule();
259  }
260 
261  void setSSI(const StackSafetyGlobalInfo *S) { SSI = S; }
262 
263  bool sanitizeFunction(Function &F,
264  llvm::function_ref<const DominatorTree &()> GetDT,
265  llvm::function_ref<const PostDominatorTree &()> GetPDT);
266  void initializeModule();
267  void createHwasanCtorComdat();
268 
269  void initializeCallbacks(Module &M);
270 
271  Value *getOpaqueNoopCast(IRBuilder<> &IRB, Value *Val);
272 
273  Value *getDynamicShadowIfunc(IRBuilder<> &IRB);
274  Value *getShadowNonTls(IRBuilder<> &IRB);
275 
276  void untagPointerOperand(Instruction *I, Value *Addr);
277  Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
278 
279  int64_t getAccessInfo(bool IsWrite, unsigned AccessSizeIndex);
280  void instrumentMemAccessOutline(Value *Ptr, bool IsWrite,
281  unsigned AccessSizeIndex,
282  Instruction *InsertBefore);
283  void instrumentMemAccessInline(Value *Ptr, bool IsWrite,
284  unsigned AccessSizeIndex,
285  Instruction *InsertBefore);
286  bool ignoreMemIntrinsic(MemIntrinsic *MI);
287  void instrumentMemIntrinsic(MemIntrinsic *MI);
288  bool instrumentMemAccess(InterestingMemoryOperand &O);
289  bool ignoreAccess(Instruction *Inst, Value *Ptr);
290  void getInterestingMemoryOperands(
292 
293  bool isInterestingAlloca(const AllocaInst &AI);
294  void tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag, size_t Size);
295  Value *tagPointer(IRBuilder<> &IRB, Type *Ty, Value *PtrLong, Value *Tag);
296  Value *untagPointer(IRBuilder<> &IRB, Value *PtrLong);
297  bool instrumentStack(memtag::StackInfo &Info, Value *StackTag,
298  llvm::function_ref<const DominatorTree &()> GetDT,
299  llvm::function_ref<const PostDominatorTree &()> GetPDT);
300  Value *readRegister(IRBuilder<> &IRB, StringRef Name);
301  bool instrumentLandingPads(SmallVectorImpl<Instruction *> &RetVec);
302  Value *getNextTagWithCall(IRBuilder<> &IRB);
303  Value *getStackBaseTag(IRBuilder<> &IRB);
304  Value *getAllocaTag(IRBuilder<> &IRB, Value *StackTag, AllocaInst *AI,
305  unsigned AllocaNo);
306  Value *getUARTag(IRBuilder<> &IRB, Value *StackTag);
307 
308  Value *getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty);
309  Value *applyTagMask(IRBuilder<> &IRB, Value *OldTag);
310  unsigned retagMask(unsigned AllocaNo);
311 
312  void emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord);
313 
314  void instrumentGlobal(GlobalVariable *GV, uint8_t Tag);
315  void instrumentGlobals();
316 
317  void instrumentPersonalityFunctions();
318 
319 private:
320  LLVMContext *C;
321  Module &M;
322  const StackSafetyGlobalInfo *SSI;
323  Triple TargetTriple;
324  FunctionCallee HWAsanMemmove, HWAsanMemcpy, HWAsanMemset;
325  FunctionCallee HWAsanHandleVfork;
326 
327  /// This struct defines the shadow mapping using the rule:
328  /// shadow = (mem >> Scale) + Offset.
329  /// If InGlobal is true, then
330  /// extern char __hwasan_shadow[];
331  /// shadow = (mem >> Scale) + &__hwasan_shadow
332  /// If InTls is true, then
333  /// extern char *__hwasan_tls;
334  /// shadow = (mem>>Scale) + align_up(__hwasan_shadow, kShadowBaseAlignment)
335  ///
336  /// If WithFrameRecord is true, then __hwasan_tls will be used to access the
337  /// ring buffer for storing stack allocations on targets that support it.
338  struct ShadowMapping {
339  int Scale;
341  bool InGlobal;
342  bool InTls;
343  bool WithFrameRecord;
344 
345  void init(Triple &TargetTriple, bool InstrumentWithCalls);
346  uint64_t getObjectAlignment() const { return 1ULL << Scale; }
347  };
348 
349  ShadowMapping Mapping;
350 
351  Type *VoidTy = Type::getVoidTy(M.getContext());
352  Type *IntptrTy;
353  Type *Int8PtrTy;
354  Type *Int8Ty;
355  Type *Int32Ty;
356  Type *Int64Ty = Type::getInt64Ty(M.getContext());
357 
358  bool CompileKernel;
359  bool Recover;
360  bool OutlinedChecks;
361  bool UseShortGranules;
362  bool InstrumentLandingPads;
363  bool InstrumentWithCalls;
364  bool InstrumentStack;
365  bool DetectUseAfterScope;
366  bool UsePageAliases;
367 
368  bool HasMatchAllTag = false;
369  uint8_t MatchAllTag = 0;
370 
371  unsigned PointerTagShift;
372  uint64_t TagMaskByte;
373 
374  Function *HwasanCtorFunction;
375 
376  FunctionCallee HwasanMemoryAccessCallback[2][kNumberOfAccessSizes];
377  FunctionCallee HwasanMemoryAccessCallbackSized[2];
378 
379  FunctionCallee HwasanTagMemoryFunc;
380  FunctionCallee HwasanGenerateTagFunc;
381 
382  Constant *ShadowGlobal;
383 
384  Value *ShadowBase = nullptr;
385  Value *StackBaseTag = nullptr;
386  GlobalValue *ThreadPtrGlobal = nullptr;
387 };
388 
389 } // end anonymous namespace
390 
393  const StackSafetyGlobalInfo *SSI = nullptr;
394  auto TargetTriple = llvm::Triple(M.getTargetTriple());
395  if (shouldUseStackSafetyAnalysis(TargetTriple, Options.DisableOptimization))
397 
398  HWAddressSanitizer HWASan(M, Options.CompileKernel, Options.Recover, SSI);
399  bool Modified = false;
400  auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
401  for (Function &F : M) {
402  Modified |= HWASan.sanitizeFunction(
403  F,
404  [&]() -> const DominatorTree & {
406  },
407  [&]() -> const PostDominatorTree & {
409  });
410  }
411  if (Modified)
412  return PreservedAnalyses::none();
413  return PreservedAnalyses::all();
414 }
416  raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
418  OS, MapClassName2PassName);
419  OS << "<";
420  if (Options.CompileKernel)
421  OS << "kernel;";
422  if (Options.Recover)
423  OS << "recover";
424  OS << ">";
425 }
426 
427 void HWAddressSanitizer::createHwasanCtorComdat() {
428  std::tie(HwasanCtorFunction, std::ignore) =
431  /*InitArgTypes=*/{},
432  /*InitArgs=*/{},
433  // This callback is invoked when the functions are created the first
434  // time. Hook them into the global ctors list in that case:
435  [&](Function *Ctor, FunctionCallee) {
436  Comdat *CtorComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
437  Ctor->setComdat(CtorComdat);
438  appendToGlobalCtors(M, Ctor, 0, Ctor);
439  });
440 
441  // Create a note that contains pointers to the list of global
442  // descriptors. Adding a note to the output file will cause the linker to
443  // create a PT_NOTE program header pointing to the note that we can use to
444  // find the descriptor list starting from the program headers. A function
445  // provided by the runtime initializes the shadow memory for the globals by
446  // accessing the descriptor list via the note. The dynamic loader needs to
447  // call this function whenever a library is loaded.
448  //
449  // The reason why we use a note for this instead of a more conventional
450  // approach of having a global constructor pass a descriptor list pointer to
451  // the runtime is because of an order of initialization problem. With
452  // constructors we can encounter the following problematic scenario:
453  //
454  // 1) library A depends on library B and also interposes one of B's symbols
455  // 2) B's constructors are called before A's (as required for correctness)
456  // 3) during construction, B accesses one of its "own" globals (actually
457  // interposed by A) and triggers a HWASAN failure due to the initialization
458  // for A not having happened yet
459  //
460  // Even without interposition it is possible to run into similar situations in
461  // cases where two libraries mutually depend on each other.
462  //
463  // We only need one note per binary, so put everything for the note in a
464  // comdat. This needs to be a comdat with an .init_array section to prevent
465  // newer versions of lld from discarding the note.
466  //
467  // Create the note even if we aren't instrumenting globals. This ensures that
468  // binaries linked from object files with both instrumented and
469  // non-instrumented globals will end up with a note, even if a comdat from an
470  // object file with non-instrumented globals is selected. The note is harmless
471  // if the runtime doesn't support it, since it will just be ignored.
472  Comdat *NoteComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
473 
474  Type *Int8Arr0Ty = ArrayType::get(Int8Ty, 0);
475  auto Start =
476  new GlobalVariable(M, Int8Arr0Ty, true, GlobalVariable::ExternalLinkage,
477  nullptr, "__start_hwasan_globals");
478  Start->setVisibility(GlobalValue::HiddenVisibility);
479  Start->setDSOLocal(true);
480  auto Stop =
481  new GlobalVariable(M, Int8Arr0Ty, true, GlobalVariable::ExternalLinkage,
482  nullptr, "__stop_hwasan_globals");
483  Stop->setVisibility(GlobalValue::HiddenVisibility);
484  Stop->setDSOLocal(true);
485 
486  // Null-terminated so actually 8 bytes, which are required in order to align
487  // the note properly.
488  auto *Name = ConstantDataArray::get(*C, "LLVM\0\0\0");
489 
490  auto *NoteTy = StructType::get(Int32Ty, Int32Ty, Int32Ty, Name->getType(),
491  Int32Ty, Int32Ty);
492  auto *Note =
493  new GlobalVariable(M, NoteTy, /*isConstant=*/true,
495  Note->setSection(".note.hwasan.globals");
496  Note->setComdat(NoteComdat);
497  Note->setAlignment(Align(4));
498  Note->setDSOLocal(true);
499 
500  // The pointers in the note need to be relative so that the note ends up being
501  // placed in rodata, which is the standard location for notes.
502  auto CreateRelPtr = [&](Constant *Ptr) {
503  return ConstantExpr::getTrunc(
505  ConstantExpr::getPtrToInt(Note, Int64Ty)),
506  Int32Ty);
507  };
508  Note->setInitializer(ConstantStruct::getAnon(
509  {ConstantInt::get(Int32Ty, 8), // n_namesz
510  ConstantInt::get(Int32Ty, 8), // n_descsz
512  Name, CreateRelPtr(Start), CreateRelPtr(Stop)}));
513  appendToCompilerUsed(M, Note);
514 
515  // Create a zero-length global in hwasan_globals so that the linker will
516  // always create start and stop symbols.
517  auto Dummy = new GlobalVariable(
518  M, Int8Arr0Ty, /*isConstantGlobal*/ true, GlobalVariable::PrivateLinkage,
519  Constant::getNullValue(Int8Arr0Ty), "hwasan.dummy.global");
520  Dummy->setSection("hwasan_globals");
521  Dummy->setComdat(NoteComdat);
522  Dummy->setMetadata(LLVMContext::MD_associated,
525 }
526 
527 /// Module-level initialization.
528 ///
529 /// inserts a call to __hwasan_init to the module's constructor list.
530 void HWAddressSanitizer::initializeModule() {
531  LLVM_DEBUG(dbgs() << "Init " << M.getName() << "\n");
532  auto &DL = M.getDataLayout();
533 
534  TargetTriple = Triple(M.getTargetTriple());
535 
536  // x86_64 currently has two modes:
537  // - Intel LAM (default)
538  // - pointer aliasing (heap only)
539  bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64;
540  UsePageAliases = shouldUsePageAliases(TargetTriple);
541  InstrumentWithCalls = shouldInstrumentWithCalls(TargetTriple);
542  InstrumentStack = shouldInstrumentStack(TargetTriple);
543  DetectUseAfterScope = shouldDetectUseAfterScope(TargetTriple);
544  PointerTagShift = IsX86_64 ? 57 : 56;
545  TagMaskByte = IsX86_64 ? 0x3F : 0xFF;
546 
547  Mapping.init(TargetTriple, InstrumentWithCalls);
548 
549  C = &(M.getContext());
550  IRBuilder<> IRB(*C);
551  IntptrTy = IRB.getIntPtrTy(DL);
552  Int8PtrTy = IRB.getInt8PtrTy();
553  Int8Ty = IRB.getInt8Ty();
554  Int32Ty = IRB.getInt32Ty();
555 
556  HwasanCtorFunction = nullptr;
557 
558  // Older versions of Android do not have the required runtime support for
559  // short granules, global or personality function instrumentation. On other
560  // platforms we currently require using the latest version of the runtime.
561  bool NewRuntime =
562  !TargetTriple.isAndroid() || !TargetTriple.isAndroidVersionLT(30);
563 
564  UseShortGranules =
566  OutlinedChecks =
567  TargetTriple.isAArch64() && TargetTriple.isOSBinFormatELF() &&
569 
570  if (ClMatchAllTag.getNumOccurrences()) {
571  if (ClMatchAllTag != -1) {
572  HasMatchAllTag = true;
573  MatchAllTag = ClMatchAllTag & 0xFF;
574  }
575  } else if (CompileKernel) {
576  HasMatchAllTag = true;
577  MatchAllTag = 0xFF;
578  }
579 
580  // If we don't have personality function support, fall back to landing pads.
581  InstrumentLandingPads = ClInstrumentLandingPads.getNumOccurrences()
583  : !NewRuntime;
584 
585  if (!CompileKernel) {
586  createHwasanCtorComdat();
587  bool InstrumentGlobals =
588  ClGlobals.getNumOccurrences() ? ClGlobals : NewRuntime;
589 
590  if (InstrumentGlobals && !UsePageAliases)
591  instrumentGlobals();
592 
593  bool InstrumentPersonalityFunctions =
596  : NewRuntime;
597  if (InstrumentPersonalityFunctions)
598  instrumentPersonalityFunctions();
599  }
600 
601  if (!TargetTriple.isAndroid()) {
602  Constant *C = M.getOrInsertGlobal("__hwasan_tls", IntptrTy, [&] {
603  auto *GV = new GlobalVariable(M, IntptrTy, /*isConstant=*/false,
605  "__hwasan_tls", nullptr,
607  appendToCompilerUsed(M, GV);
608  return GV;
609  });
610  ThreadPtrGlobal = cast<GlobalVariable>(C);
611  }
612 }
613 
614 void HWAddressSanitizer::initializeCallbacks(Module &M) {
615  IRBuilder<> IRB(*C);
616  for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
617  const std::string TypeStr = AccessIsWrite ? "store" : "load";
618  const std::string EndingStr = Recover ? "_noabort" : "";
619 
620  HwasanMemoryAccessCallbackSized[AccessIsWrite] = M.getOrInsertFunction(
621  ClMemoryAccessCallbackPrefix + TypeStr + "N" + EndingStr,
622  FunctionType::get(IRB.getVoidTy(), {IntptrTy, IntptrTy}, false));
623 
624  for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
625  AccessSizeIndex++) {
626  HwasanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] =
627  M.getOrInsertFunction(
628  ClMemoryAccessCallbackPrefix + TypeStr +
629  itostr(1ULL << AccessSizeIndex) + EndingStr,
630  FunctionType::get(IRB.getVoidTy(), {IntptrTy}, false));
631  }
632  }
633 
634  HwasanTagMemoryFunc = M.getOrInsertFunction(
635  "__hwasan_tag_memory", IRB.getVoidTy(), Int8PtrTy, Int8Ty, IntptrTy);
636  HwasanGenerateTagFunc =
637  M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty);
638 
639  ShadowGlobal = M.getOrInsertGlobal("__hwasan_shadow",
640  ArrayType::get(IRB.getInt8Ty(), 0));
641 
642  const std::string MemIntrinCallbackPrefix =
643  (CompileKernel && !ClKasanMemIntrinCallbackPrefix)
644  ? std::string("")
646  HWAsanMemmove = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memmove",
647  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
648  IRB.getInt8PtrTy(), IntptrTy);
649  HWAsanMemcpy = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memcpy",
650  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
651  IRB.getInt8PtrTy(), IntptrTy);
652  HWAsanMemset = M.getOrInsertFunction(MemIntrinCallbackPrefix + "memset",
653  IRB.getInt8PtrTy(), IRB.getInt8PtrTy(),
654  IRB.getInt32Ty(), IntptrTy);
655 
656  HWAsanHandleVfork =
657  M.getOrInsertFunction("__hwasan_handle_vfork", IRB.getVoidTy(), IntptrTy);
658 }
659 
660 Value *HWAddressSanitizer::getOpaqueNoopCast(IRBuilder<> &IRB, Value *Val) {
661  // An empty inline asm with input reg == output reg.
662  // An opaque no-op cast, basically.
663  // This prevents code bloat as a result of rematerializing trivial definitions
664  // such as constants or global addresses at every load and store.
665  InlineAsm *Asm =
666  InlineAsm::get(FunctionType::get(Int8PtrTy, {Val->getType()}, false),
667  StringRef(""), StringRef("=r,0"),
668  /*hasSideEffects=*/false);
669  return IRB.CreateCall(Asm, {Val}, ".hwasan.shadow");
670 }
671 
672 Value *HWAddressSanitizer::getDynamicShadowIfunc(IRBuilder<> &IRB) {
673  return getOpaqueNoopCast(IRB, ShadowGlobal);
674 }
675 
676 Value *HWAddressSanitizer::getShadowNonTls(IRBuilder<> &IRB) {
677  if (Mapping.Offset != kDynamicShadowSentinel)
678  return getOpaqueNoopCast(
680  ConstantInt::get(IntptrTy, Mapping.Offset), Int8PtrTy));
681 
682  if (Mapping.InGlobal) {
683  return getDynamicShadowIfunc(IRB);
684  } else {
685  Value *GlobalDynamicAddress =
688  return IRB.CreateLoad(Int8PtrTy, GlobalDynamicAddress);
689  }
690 }
691 
692 bool HWAddressSanitizer::ignoreAccess(Instruction *Inst, Value *Ptr) {
693  // Do not instrument acesses from different address spaces; we cannot deal
694  // with them.
695  Type *PtrTy = cast<PointerType>(Ptr->getType()->getScalarType());
696  if (PtrTy->getPointerAddressSpace() != 0)
697  return true;
698 
699  // Ignore swifterror addresses.
700  // swifterror memory addresses are mem2reg promoted by instruction
701  // selection. As such they cannot have regular uses like an instrumentation
702  // function and it makes no sense to track them as memory.
703  if (Ptr->isSwiftError())
704  return true;
705 
706  if (findAllocaForValue(Ptr)) {
707  if (!InstrumentStack)
708  return true;
709  if (SSI && SSI->stackAccessIsSafe(*Inst))
710  return true;
711  }
712  return false;
713 }
714 
715 void HWAddressSanitizer::getInterestingMemoryOperands(
717  // Skip memory accesses inserted by another instrumentation.
718  if (I->hasMetadata("nosanitize"))
719  return;
720 
721  // Do not instrument the load fetching the dynamic shadow address.
722  if (ShadowBase == I)
723  return;
724 
725  if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
726  if (!ClInstrumentReads || ignoreAccess(I, LI->getPointerOperand()))
727  return;
728  Interesting.emplace_back(I, LI->getPointerOperandIndex(), false,
729  LI->getType(), LI->getAlign());
730  } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
731  if (!ClInstrumentWrites || ignoreAccess(I, SI->getPointerOperand()))
732  return;
733  Interesting.emplace_back(I, SI->getPointerOperandIndex(), true,
734  SI->getValueOperand()->getType(), SI->getAlign());
735  } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
736  if (!ClInstrumentAtomics || ignoreAccess(I, RMW->getPointerOperand()))
737  return;
738  Interesting.emplace_back(I, RMW->getPointerOperandIndex(), true,
739  RMW->getValOperand()->getType(), None);
740  } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
741  if (!ClInstrumentAtomics || ignoreAccess(I, XCHG->getPointerOperand()))
742  return;
743  Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true,
744  XCHG->getCompareOperand()->getType(), None);
745  } else if (auto CI = dyn_cast<CallInst>(I)) {
746  for (unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
747  if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) ||
748  ignoreAccess(I, CI->getArgOperand(ArgNo)))
749  continue;
750  Type *Ty = CI->getParamByValType(ArgNo);
751  Interesting.emplace_back(I, ArgNo, false, Ty, Align(1));
752  }
753  }
754 }
755 
757  if (LoadInst *LI = dyn_cast<LoadInst>(I))
758  return LI->getPointerOperandIndex();
759  if (StoreInst *SI = dyn_cast<StoreInst>(I))
760  return SI->getPointerOperandIndex();
761  if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I))
762  return RMW->getPointerOperandIndex();
763  if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I))
764  return XCHG->getPointerOperandIndex();
765  report_fatal_error("Unexpected instruction");
766  return -1;
767 }
768 
770  size_t Res = countTrailingZeros(TypeSize / 8);
772  return Res;
773 }
774 
775 void HWAddressSanitizer::untagPointerOperand(Instruction *I, Value *Addr) {
776  if (TargetTriple.isAArch64() || TargetTriple.getArch() == Triple::x86_64)
777  return;
778 
779  IRBuilder<> IRB(I);
780  Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
781  Value *UntaggedPtr =
782  IRB.CreateIntToPtr(untagPointer(IRB, AddrLong), Addr->getType());
783  I->setOperand(getPointerOperandIndex(I), UntaggedPtr);
784 }
785 
786 Value *HWAddressSanitizer::memToShadow(Value *Mem, IRBuilder<> &IRB) {
787  // Mem >> Scale
788  Value *Shadow = IRB.CreateLShr(Mem, Mapping.Scale);
789  if (Mapping.Offset == 0)
790  return IRB.CreateIntToPtr(Shadow, Int8PtrTy);
791  // (Mem >> Scale) + Offset
792  return IRB.CreateGEP(Int8Ty, ShadowBase, Shadow);
793 }
794 
795 int64_t HWAddressSanitizer::getAccessInfo(bool IsWrite,
796  unsigned AccessSizeIndex) {
797  return (CompileKernel << HWASanAccessInfo::CompileKernelShift) +
798  (HasMatchAllTag << HWASanAccessInfo::HasMatchAllShift) +
799  (MatchAllTag << HWASanAccessInfo::MatchAllShift) +
800  (Recover << HWASanAccessInfo::RecoverShift) +
801  (IsWrite << HWASanAccessInfo::IsWriteShift) +
802  (AccessSizeIndex << HWASanAccessInfo::AccessSizeShift);
803 }
804 
805 void HWAddressSanitizer::instrumentMemAccessOutline(Value *Ptr, bool IsWrite,
806  unsigned AccessSizeIndex,
807  Instruction *InsertBefore) {
808  assert(!UsePageAliases);
809  const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
810  IRBuilder<> IRB(InsertBefore);
811  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
812  Ptr = IRB.CreateBitCast(Ptr, Int8PtrTy);
814  M, UseShortGranules
815  ? Intrinsic::hwasan_check_memaccess_shortgranules
816  : Intrinsic::hwasan_check_memaccess),
817  {ShadowBase, Ptr, ConstantInt::get(Int32Ty, AccessInfo)});
818 }
819 
820 void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
821  unsigned AccessSizeIndex,
822  Instruction *InsertBefore) {
823  assert(!UsePageAliases);
824  const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
825  IRBuilder<> IRB(InsertBefore);
826 
827  Value *PtrLong = IRB.CreatePointerCast(Ptr, IntptrTy);
828  Value *PtrTag = IRB.CreateTrunc(IRB.CreateLShr(PtrLong, PointerTagShift),
829  IRB.getInt8Ty());
830  Value *AddrLong = untagPointer(IRB, PtrLong);
831  Value *Shadow = memToShadow(AddrLong, IRB);
832  Value *MemTag = IRB.CreateLoad(Int8Ty, Shadow);
833  Value *TagMismatch = IRB.CreateICmpNE(PtrTag, MemTag);
834 
835  if (HasMatchAllTag) {
836  Value *TagNotIgnored = IRB.CreateICmpNE(
837  PtrTag, ConstantInt::get(PtrTag->getType(), MatchAllTag));
838  TagMismatch = IRB.CreateAnd(TagMismatch, TagNotIgnored);
839  }
840 
841  Instruction *CheckTerm =
842  SplitBlockAndInsertIfThen(TagMismatch, InsertBefore, false,
843  MDBuilder(*C).createBranchWeights(1, 100000));
844 
845  IRB.SetInsertPoint(CheckTerm);
846  Value *OutOfShortGranuleTagRange =
847  IRB.CreateICmpUGT(MemTag, ConstantInt::get(Int8Ty, 15));
848  Instruction *CheckFailTerm =
849  SplitBlockAndInsertIfThen(OutOfShortGranuleTagRange, CheckTerm, !Recover,
850  MDBuilder(*C).createBranchWeights(1, 100000));
851 
852  IRB.SetInsertPoint(CheckTerm);
853  Value *PtrLowBits = IRB.CreateTrunc(IRB.CreateAnd(PtrLong, 15), Int8Ty);
854  PtrLowBits = IRB.CreateAdd(
855  PtrLowBits, ConstantInt::get(Int8Ty, (1 << AccessSizeIndex) - 1));
856  Value *PtrLowBitsOOB = IRB.CreateICmpUGE(PtrLowBits, MemTag);
857  SplitBlockAndInsertIfThen(PtrLowBitsOOB, CheckTerm, false,
858  MDBuilder(*C).createBranchWeights(1, 100000),
859  (DomTreeUpdater *)nullptr, nullptr,
860  CheckFailTerm->getParent());
861 
862  IRB.SetInsertPoint(CheckTerm);
863  Value *InlineTagAddr = IRB.CreateOr(AddrLong, 15);
864  InlineTagAddr = IRB.CreateIntToPtr(InlineTagAddr, Int8PtrTy);
865  Value *InlineTag = IRB.CreateLoad(Int8Ty, InlineTagAddr);
866  Value *InlineTagMismatch = IRB.CreateICmpNE(PtrTag, InlineTag);
867  SplitBlockAndInsertIfThen(InlineTagMismatch, CheckTerm, false,
868  MDBuilder(*C).createBranchWeights(1, 100000),
869  (DomTreeUpdater *)nullptr, nullptr,
870  CheckFailTerm->getParent());
871 
872  IRB.SetInsertPoint(CheckFailTerm);
873  InlineAsm *Asm;
874  switch (TargetTriple.getArch()) {
875  case Triple::x86_64:
876  // The signal handler will find the data address in rdi.
878  FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
879  "int3\nnopl " +
880  itostr(0x40 + (AccessInfo & HWASanAccessInfo::RuntimeMask)) +
881  "(%rax)",
882  "{rdi}",
883  /*hasSideEffects=*/true);
884  break;
885  case Triple::aarch64:
886  case Triple::aarch64_be:
887  // The signal handler will find the data address in x0.
889  FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
890  "brk #" + itostr(0x900 + (AccessInfo & HWASanAccessInfo::RuntimeMask)),
891  "{x0}",
892  /*hasSideEffects=*/true);
893  break;
894  default:
895  report_fatal_error("unsupported architecture");
896  }
897  IRB.CreateCall(Asm, PtrLong);
898  if (Recover)
899  cast<BranchInst>(CheckFailTerm)->setSuccessor(0, CheckTerm->getParent());
900 }
901 
902 bool HWAddressSanitizer::ignoreMemIntrinsic(MemIntrinsic *MI) {
903  if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) {
904  return (!ClInstrumentWrites || ignoreAccess(MTI, MTI->getDest())) &&
905  (!ClInstrumentReads || ignoreAccess(MTI, MTI->getSource()));
906  }
907  if (isa<MemSetInst>(MI))
908  return !ClInstrumentWrites || ignoreAccess(MI, MI->getDest());
909  return false;
910 }
911 
912 void HWAddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
913  IRBuilder<> IRB(MI);
914  if (isa<MemTransferInst>(MI)) {
915  IRB.CreateCall(
916  isa<MemMoveInst>(MI) ? HWAsanMemmove : HWAsanMemcpy,
917  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
918  IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()),
919  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
920  } else if (isa<MemSetInst>(MI)) {
921  IRB.CreateCall(
922  HWAsanMemset,
923  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
924  IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
925  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
926  }
927  MI->eraseFromParent();
928 }
929 
930 bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O) {
931  Value *Addr = O.getPtr();
932 
933  LLVM_DEBUG(dbgs() << "Instrumenting: " << O.getInsn() << "\n");
934 
935  if (O.MaybeMask)
936  return false; // FIXME
937 
938  IRBuilder<> IRB(O.getInsn());
939  if (isPowerOf2_64(O.TypeSize) &&
940  (O.TypeSize / 8 <= (1ULL << (kNumberOfAccessSizes - 1))) &&
941  (!O.Alignment || *O.Alignment >= (1ULL << Mapping.Scale) ||
942  *O.Alignment >= O.TypeSize / 8)) {
943  size_t AccessSizeIndex = TypeSizeToSizeIndex(O.TypeSize);
944  if (InstrumentWithCalls) {
945  IRB.CreateCall(HwasanMemoryAccessCallback[O.IsWrite][AccessSizeIndex],
946  IRB.CreatePointerCast(Addr, IntptrTy));
947  } else if (OutlinedChecks) {
948  instrumentMemAccessOutline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn());
949  } else {
950  instrumentMemAccessInline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn());
951  }
952  } else {
953  IRB.CreateCall(HwasanMemoryAccessCallbackSized[O.IsWrite],
954  {IRB.CreatePointerCast(Addr, IntptrTy),
955  ConstantInt::get(IntptrTy, O.TypeSize / 8)});
956  }
957  untagPointerOperand(O.getInsn(), Addr);
958 
959  return true;
960 }
961 
962 void HWAddressSanitizer::tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag,
963  size_t Size) {
964  size_t AlignedSize = alignTo(Size, Mapping.getObjectAlignment());
965  if (!UseShortGranules)
966  Size = AlignedSize;
967 
968  Value *JustTag = IRB.CreateTrunc(Tag, IRB.getInt8Ty());
969  if (InstrumentWithCalls) {
970  IRB.CreateCall(HwasanTagMemoryFunc,
971  {IRB.CreatePointerCast(AI, Int8PtrTy), JustTag,
972  ConstantInt::get(IntptrTy, AlignedSize)});
973  } else {
974  size_t ShadowSize = Size >> Mapping.Scale;
975  Value *ShadowPtr = memToShadow(IRB.CreatePointerCast(AI, IntptrTy), IRB);
976  // If this memset is not inlined, it will be intercepted in the hwasan
977  // runtime library. That's OK, because the interceptor skips the checks if
978  // the address is in the shadow region.
979  // FIXME: the interceptor is not as fast as real memset. Consider lowering
980  // llvm.memset right here into either a sequence of stores, or a call to
981  // hwasan_tag_memory.
982  if (ShadowSize)
983  IRB.CreateMemSet(ShadowPtr, JustTag, ShadowSize, Align(1));
984  if (Size != AlignedSize) {
985  IRB.CreateStore(
986  ConstantInt::get(Int8Ty, Size % Mapping.getObjectAlignment()),
987  IRB.CreateConstGEP1_32(Int8Ty, ShadowPtr, ShadowSize));
988  IRB.CreateStore(JustTag, IRB.CreateConstGEP1_32(
989  Int8Ty, IRB.CreateBitCast(AI, Int8PtrTy),
990  AlignedSize - 1));
991  }
992  }
993 }
994 
995 unsigned HWAddressSanitizer::retagMask(unsigned AllocaNo) {
996  if (TargetTriple.getArch() == Triple::x86_64)
997  return AllocaNo & TagMaskByte;
998 
999  // A list of 8-bit numbers that have at most one run of non-zero bits.
1000  // x = x ^ (mask << 56) can be encoded as a single armv8 instruction for these
1001  // masks.
1002  // The list does not include the value 255, which is used for UAR.
1003  //
1004  // Because we are more likely to use earlier elements of this list than later
1005  // ones, it is sorted in increasing order of probability of collision with a
1006  // mask allocated (temporally) nearby. The program that generated this list
1007  // can be found at:
1008  // https://github.com/google/sanitizers/blob/master/hwaddress-sanitizer/sort_masks.py
1009  static unsigned FastMasks[] = {0, 128, 64, 192, 32, 96, 224, 112, 240,
1010  48, 16, 120, 248, 56, 24, 8, 124, 252,
1011  60, 28, 12, 4, 126, 254, 62, 30, 14,
1012  6, 2, 127, 63, 31, 15, 7, 3, 1};
1013  return FastMasks[AllocaNo % (sizeof(FastMasks) / sizeof(FastMasks[0]))];
1014 }
1015 
1016 Value *HWAddressSanitizer::applyTagMask(IRBuilder<> &IRB, Value *OldTag) {
1017  if (TargetTriple.getArch() == Triple::x86_64) {
1018  Constant *TagMask = ConstantInt::get(IntptrTy, TagMaskByte);
1019  Value *NewTag = IRB.CreateAnd(OldTag, TagMask);
1020  return NewTag;
1021  }
1022  // aarch64 uses 8-bit tags, so no mask is needed.
1023  return OldTag;
1024 }
1025 
1026 Value *HWAddressSanitizer::getNextTagWithCall(IRBuilder<> &IRB) {
1027  return IRB.CreateZExt(IRB.CreateCall(HwasanGenerateTagFunc), IntptrTy);
1028 }
1029 
1030 Value *HWAddressSanitizer::getStackBaseTag(IRBuilder<> &IRB) {
1032  return getNextTagWithCall(IRB);
1033  if (StackBaseTag)
1034  return StackBaseTag;
1035  // FIXME: use addressofreturnaddress (but implement it in aarch64 backend
1036  // first).
1037  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
1038  auto GetStackPointerFn = Intrinsic::getDeclaration(
1039  M, Intrinsic::frameaddress,
1040  IRB.getInt8PtrTy(M->getDataLayout().getAllocaAddrSpace()));
1041  Value *StackPointer = IRB.CreateCall(
1042  GetStackPointerFn, {Constant::getNullValue(IRB.getInt32Ty())});
1043 
1044  // Extract some entropy from the stack pointer for the tags.
1045  // Take bits 20..28 (ASLR entropy) and xor with bits 0..8 (these differ
1046  // between functions).
1047  Value *StackPointerLong = IRB.CreatePointerCast(StackPointer, IntptrTy);
1048  Value *StackTag =
1049  applyTagMask(IRB, IRB.CreateXor(StackPointerLong,
1050  IRB.CreateLShr(StackPointerLong, 20)));
1051  StackTag->setName("hwasan.stack.base.tag");
1052  return StackTag;
1053 }
1054 
1055 Value *HWAddressSanitizer::getAllocaTag(IRBuilder<> &IRB, Value *StackTag,
1056  AllocaInst *AI, unsigned AllocaNo) {
1058  return getNextTagWithCall(IRB);
1059  return IRB.CreateXor(StackTag,
1060  ConstantInt::get(IntptrTy, retagMask(AllocaNo)));
1061 }
1062 
1063 Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB, Value *StackTag) {
1064  if (ClUARRetagToZero)
1065  return ConstantInt::get(IntptrTy, 0);
1067  return getNextTagWithCall(IRB);
1068  return IRB.CreateXor(StackTag, ConstantInt::get(IntptrTy, TagMaskByte));
1069 }
1070 
1071 // Add a tag to an address.
1072 Value *HWAddressSanitizer::tagPointer(IRBuilder<> &IRB, Type *Ty,
1073  Value *PtrLong, Value *Tag) {
1074  assert(!UsePageAliases);
1075  Value *TaggedPtrLong;
1076  if (CompileKernel) {
1077  // Kernel addresses have 0xFF in the most significant byte.
1078  Value *ShiftedTag =
1079  IRB.CreateOr(IRB.CreateShl(Tag, PointerTagShift),
1080  ConstantInt::get(IntptrTy, (1ULL << PointerTagShift) - 1));
1081  TaggedPtrLong = IRB.CreateAnd(PtrLong, ShiftedTag);
1082  } else {
1083  // Userspace can simply do OR (tag << PointerTagShift);
1084  Value *ShiftedTag = IRB.CreateShl(Tag, PointerTagShift);
1085  TaggedPtrLong = IRB.CreateOr(PtrLong, ShiftedTag);
1086  }
1087  return IRB.CreateIntToPtr(TaggedPtrLong, Ty);
1088 }
1089 
1090 // Remove tag from an address.
1091 Value *HWAddressSanitizer::untagPointer(IRBuilder<> &IRB, Value *PtrLong) {
1092  assert(!UsePageAliases);
1093  Value *UntaggedPtrLong;
1094  if (CompileKernel) {
1095  // Kernel addresses have 0xFF in the most significant byte.
1096  UntaggedPtrLong =
1097  IRB.CreateOr(PtrLong, ConstantInt::get(PtrLong->getType(),
1098  0xFFULL << PointerTagShift));
1099  } else {
1100  // Userspace addresses have 0x00.
1101  UntaggedPtrLong =
1102  IRB.CreateAnd(PtrLong, ConstantInt::get(PtrLong->getType(),
1103  ~(0xFFULL << PointerTagShift)));
1104  }
1105  return UntaggedPtrLong;
1106 }
1107 
1108 Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty) {
1109  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
1110  if (TargetTriple.isAArch64() && TargetTriple.isAndroid()) {
1111  // Android provides a fixed TLS slot for sanitizers. See TLS_SLOT_SANITIZER
1112  // in Bionic's libc/private/bionic_tls.h.
1113  Function *ThreadPointerFunc =
1114  Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
1115  Value *SlotPtr = IRB.CreatePointerCast(
1116  IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
1117  IRB.CreateCall(ThreadPointerFunc), 0x30),
1118  Ty->getPointerTo(0));
1119  return SlotPtr;
1120  }
1121  if (ThreadPtrGlobal)
1122  return ThreadPtrGlobal;
1123 
1124  return nullptr;
1125 }
1126 
1127 void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
1128  if (!Mapping.InTls)
1129  ShadowBase = getShadowNonTls(IRB);
1130  else if (!WithFrameRecord && TargetTriple.isAndroid())
1131  ShadowBase = getDynamicShadowIfunc(IRB);
1132 
1133  if (!WithFrameRecord && ShadowBase)
1134  return;
1135 
1136  Value *SlotPtr = getHwasanThreadSlotPtr(IRB, IntptrTy);
1137  assert(SlotPtr);
1138 
1139  Value *ThreadLong = IRB.CreateLoad(IntptrTy, SlotPtr);
1140  // Extract the address field from ThreadLong. Unnecessary on AArch64 with TBI.
1141  Value *ThreadLongMaybeUntagged =
1142  TargetTriple.isAArch64() ? ThreadLong : untagPointer(IRB, ThreadLong);
1143 
1144  if (WithFrameRecord) {
1145  Function *F = IRB.GetInsertBlock()->getParent();
1146  StackBaseTag = IRB.CreateAShr(ThreadLong, 3);
1147 
1148  // Prepare ring buffer data.
1149  Value *PC;
1150  if (TargetTriple.getArch() == Triple::aarch64)
1151  PC = readRegister(IRB, "pc");
1152  else
1153  PC = IRB.CreatePtrToInt(F, IntptrTy);
1154  Module *M = F->getParent();
1155  auto GetStackPointerFn = Intrinsic::getDeclaration(
1156  M, Intrinsic::frameaddress,
1157  IRB.getInt8PtrTy(M->getDataLayout().getAllocaAddrSpace()));
1158  Value *SP = IRB.CreatePtrToInt(
1159  IRB.CreateCall(GetStackPointerFn,
1160  {Constant::getNullValue(IRB.getInt32Ty())}),
1161  IntptrTy);
1162  // Mix SP and PC.
1163  // Assumptions:
1164  // PC is 0x0000PPPPPPPPPPPP (48 bits are meaningful, others are zero)
1165  // SP is 0xsssssssssssSSSS0 (4 lower bits are zero)
1166  // We only really need ~20 lower non-zero bits (SSSS), so we mix like this:
1167  // 0xSSSSPPPPPPPPPPPP
1168  SP = IRB.CreateShl(SP, 44);
1169 
1170  // Store data to ring buffer.
1171  Value *RecordPtr =
1172  IRB.CreateIntToPtr(ThreadLongMaybeUntagged, IntptrTy->getPointerTo(0));
1173  IRB.CreateStore(IRB.CreateOr(PC, SP), RecordPtr);
1174 
1175  // Update the ring buffer. Top byte of ThreadLong defines the size of the
1176  // buffer in pages, it must be a power of two, and the start of the buffer
1177  // must be aligned by twice that much. Therefore wrap around of the ring
1178  // buffer is simply Addr &= ~((ThreadLong >> 56) << 12).
1179  // The use of AShr instead of LShr is due to
1180  // https://bugs.llvm.org/show_bug.cgi?id=39030
1181  // Runtime library makes sure not to use the highest bit.
1182  Value *WrapMask = IRB.CreateXor(
1183  IRB.CreateShl(IRB.CreateAShr(ThreadLong, 56), 12, "", true, true),
1184  ConstantInt::get(IntptrTy, (uint64_t)-1));
1185  Value *ThreadLongNew = IRB.CreateAnd(
1186  IRB.CreateAdd(ThreadLong, ConstantInt::get(IntptrTy, 8)), WrapMask);
1187  IRB.CreateStore(ThreadLongNew, SlotPtr);
1188  }
1189 
1190  if (!ShadowBase) {
1191  // Get shadow base address by aligning RecordPtr up.
1192  // Note: this is not correct if the pointer is already aligned.
1193  // Runtime library will make sure this never happens.
1194  ShadowBase = IRB.CreateAdd(
1195  IRB.CreateOr(
1196  ThreadLongMaybeUntagged,
1197  ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
1198  ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
1199  ShadowBase = IRB.CreateIntToPtr(ShadowBase, Int8PtrTy);
1200  }
1201 }
1202 
1203 Value *HWAddressSanitizer::readRegister(IRBuilder<> &IRB, StringRef Name) {
1204  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
1205  Function *ReadRegister =
1206  Intrinsic::getDeclaration(M, Intrinsic::read_register, IntptrTy);
1207  MDNode *MD = MDNode::get(*C, {MDString::get(*C, Name)});
1208  Value *Args[] = {MetadataAsValue::get(*C, MD)};
1209  return IRB.CreateCall(ReadRegister, Args);
1210 }
1211 
1212 bool HWAddressSanitizer::instrumentLandingPads(
1213  SmallVectorImpl<Instruction *> &LandingPadVec) {
1214  for (auto *LP : LandingPadVec) {
1215  IRBuilder<> IRB(LP->getNextNode());
1216  IRB.CreateCall(
1217  HWAsanHandleVfork,
1218  {readRegister(IRB, (TargetTriple.getArch() == Triple::x86_64) ? "rsp"
1219  : "sp")});
1220  }
1221  return true;
1222 }
1223 
1224 static bool isLifetimeIntrinsic(Value *V) {
1225  auto *II = dyn_cast<IntrinsicInst>(V);
1226  return II && II->isLifetimeStartOrEnd();
1227 }
1228 
1229 bool HWAddressSanitizer::instrumentStack(
1230  memtag::StackInfo &SInfo, Value *StackTag,
1231  llvm::function_ref<const DominatorTree &()> GetDT,
1232  llvm::function_ref<const PostDominatorTree &()> GetPDT) {
1233  // Ideally, we want to calculate tagged stack base pointer, and rewrite all
1234  // alloca addresses using that. Unfortunately, offsets are not known yet
1235  // (unless we use ASan-style mega-alloca). Instead we keep the base tag in a
1236  // temp, shift-OR it into each alloca address and xor with the retag mask.
1237  // This generates one extra instruction per alloca use.
1238  unsigned int I = 0;
1239 
1240  for (auto &KV : SInfo.AllocasToInstrument) {
1241  auto N = I++;
1242  auto *AI = KV.first;
1243  memtag::AllocaInfo &Info = KV.second;
1244  IRBuilder<> IRB(AI->getNextNode());
1245 
1246  // Replace uses of the alloca with tagged address.
1247  Value *Tag = getAllocaTag(IRB, StackTag, AI, N);
1248  Value *AILong = IRB.CreatePointerCast(AI, IntptrTy);
1249  Value *Replacement = tagPointer(IRB, AI->getType(), AILong, Tag);
1250  std::string Name =
1251  AI->hasName() ? AI->getName().str() : "alloca." + itostr(N);
1252  Replacement->setName(Name + ".hwasan");
1253 
1254  size_t Size = memtag::getAllocaSizeInBytes(*AI);
1255  size_t AlignedSize = alignTo(Size, Mapping.getObjectAlignment());
1256 
1257  Value *AICast = IRB.CreatePointerCast(AI, Int8PtrTy);
1258 
1259  auto HandleLifetime = [&](IntrinsicInst *II) {
1260  // Set the lifetime intrinsic to cover the whole alloca. This reduces the
1261  // set of assumptions we need to make about the lifetime. Without this we
1262  // would need to ensure that we can track the lifetime pointer to a
1263  // constant offset from the alloca, and would still need to change the
1264  // size to include the extra alignment we use for the untagging to make
1265  // the size consistent.
1266  //
1267  // The check for standard lifetime below makes sure that we have exactly
1268  // one set of start / end in any execution (i.e. the ends are not
1269  // reachable from each other), so this will not cause any problems.
1270  II->setArgOperand(0, ConstantInt::get(Int64Ty, AlignedSize));
1271  II->setArgOperand(1, AICast);
1272  };
1273  llvm::for_each(Info.LifetimeStart, HandleLifetime);
1274  llvm::for_each(Info.LifetimeEnd, HandleLifetime);
1275 
1276  AI->replaceUsesWithIf(Replacement, [AICast, AILong](Use &U) {
1277  auto *User = U.getUser();
1278  return User != AILong && User != AICast && !isLifetimeIntrinsic(User);
1279  });
1280 
1281  for (auto *DDI : Info.DbgVariableIntrinsics) {
1282  // Prepend "tag_offset, N" to the dwarf expression.
1283  // Tag offset logically applies to the alloca pointer, and it makes sense
1284  // to put it at the beginning of the expression.
1286  retagMask(N)};
1287  for (size_t LocNo = 0; LocNo < DDI->getNumVariableLocationOps(); ++LocNo)
1288  if (DDI->getVariableLocationOp(LocNo) == AI)
1289  DDI->setExpression(DIExpression::appendOpsToArg(DDI->getExpression(),
1290  NewOps, LocNo));
1291  }
1292 
1293  auto TagEnd = [&](Instruction *Node) {
1294  IRB.SetInsertPoint(Node);
1295  Value *UARTag = getUARTag(IRB, StackTag);
1296  // When untagging, use the `AlignedSize` because we need to set the tags
1297  // for the entire alloca to zero. If we used `Size` here, we would
1298  // keep the last granule tagged, and store zero in the last byte of the
1299  // last granule, due to how short granules are implemented.
1300  tagAlloca(IRB, AI, UARTag, AlignedSize);
1301  };
1302  // Calls to functions that may return twice (e.g. setjmp) confuse the
1303  // postdominator analysis, and will leave us to keep memory tagged after
1304  // function return. Work around this by always untagging at every return
1305  // statement if return_twice functions are called.
1306  bool StandardLifetime =
1307  SInfo.UnrecognizedLifetimes.empty() &&
1308  memtag::isStandardLifetime(Info.LifetimeStart, Info.LifetimeEnd,
1309  &GetDT(), ClMaxLifetimes) &&
1310  !SInfo.CallsReturnTwice;
1311  if (DetectUseAfterScope && StandardLifetime) {
1312  IntrinsicInst *Start = Info.LifetimeStart[0];
1313  IRB.SetInsertPoint(Start->getNextNode());
1314  tagAlloca(IRB, AI, Tag, Size);
1315  if (!memtag::forAllReachableExits(GetDT(), GetPDT(), Start,
1316  Info.LifetimeEnd, SInfo.RetVec,
1317  TagEnd)) {
1318  for (auto *End : Info.LifetimeEnd)
1319  End->eraseFromParent();
1320  }
1321  } else {
1322  tagAlloca(IRB, AI, Tag, Size);
1323  for (auto *RI : SInfo.RetVec)
1324  TagEnd(RI);
1325  // We inserted tagging outside of the lifetimes, so we have to remove
1326  // them.
1327  for (auto &II : Info.LifetimeStart)
1328  II->eraseFromParent();
1329  for (auto &II : Info.LifetimeEnd)
1330  II->eraseFromParent();
1331  }
1332  memtag::alignAndPadAlloca(Info, Align(Mapping.getObjectAlignment()));
1333  }
1334  for (auto &I : SInfo.UnrecognizedLifetimes)
1335  I->eraseFromParent();
1336  return true;
1337 }
1338 
1339 bool HWAddressSanitizer::isInterestingAlloca(const AllocaInst &AI) {
1340  return (AI.getAllocatedType()->isSized() &&
1341  // FIXME: instrument dynamic allocas, too
1342  AI.isStaticAlloca() &&
1343  // alloca() may be called with 0 size, ignore it.
1344  memtag::getAllocaSizeInBytes(AI) > 0 &&
1345  // We are only interested in allocas not promotable to registers.
1346  // Promotable allocas are common under -O0.
1347  !isAllocaPromotable(&AI) &&
1348  // inalloca allocas are not treated as static, and we don't want
1349  // dynamic alloca instrumentation for them as well.
1350  !AI.isUsedWithInAlloca() &&
1351  // swifterror allocas are register promoted by ISel
1352  !AI.isSwiftError()) &&
1353  // safe allocas are not interesting
1354  !(SSI && SSI->isSafe(AI));
1355 }
1356 
1357 bool HWAddressSanitizer::sanitizeFunction(
1358  Function &F, llvm::function_ref<const DominatorTree &()> GetDT,
1359  llvm::function_ref<const PostDominatorTree &()> GetPDT) {
1360  if (&F == HwasanCtorFunction)
1361  return false;
1362 
1363  if (!F.hasFnAttribute(Attribute::SanitizeHWAddress))
1364  return false;
1365 
1366  LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n");
1367 
1368  SmallVector<InterestingMemoryOperand, 16> OperandsToInstrument;
1369  SmallVector<MemIntrinsic *, 16> IntrinToInstrument;
1370  SmallVector<Instruction *, 8> LandingPadVec;
1371 
1373  [this](const AllocaInst &AI) { return isInterestingAlloca(AI); });
1374  for (auto &Inst : instructions(F)) {
1375  if (InstrumentStack) {
1376  SIB.visit(Inst);
1377  }
1378 
1379  if (InstrumentLandingPads && isa<LandingPadInst>(Inst))
1380  LandingPadVec.push_back(&Inst);
1381 
1382  getInterestingMemoryOperands(&Inst, OperandsToInstrument);
1383 
1384  if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&Inst))
1385  if (!ignoreMemIntrinsic(MI))
1386  IntrinToInstrument.push_back(MI);
1387  }
1388 
1389  memtag::StackInfo &SInfo = SIB.get();
1390 
1391  initializeCallbacks(*F.getParent());
1392 
1393  bool Changed = false;
1394 
1395  if (!LandingPadVec.empty())
1396  Changed |= instrumentLandingPads(LandingPadVec);
1397 
1398  if (SInfo.AllocasToInstrument.empty() && F.hasPersonalityFn() &&
1399  F.getPersonalityFn()->getName() == kHwasanPersonalityThunkName) {
1400  // __hwasan_personality_thunk is a no-op for functions without an
1401  // instrumented stack, so we can drop it.
1402  F.setPersonalityFn(nullptr);
1403  Changed = true;
1404  }
1405 
1406  if (SInfo.AllocasToInstrument.empty() && OperandsToInstrument.empty() &&
1407  IntrinToInstrument.empty())
1408  return Changed;
1409 
1410  assert(!ShadowBase);
1411 
1412  Instruction *InsertPt = &*F.getEntryBlock().begin();
1413  IRBuilder<> EntryIRB(InsertPt);
1414  emitPrologue(EntryIRB,
1415  /*WithFrameRecord*/ ClRecordStackHistory &&
1416  Mapping.WithFrameRecord &&
1417  !SInfo.AllocasToInstrument.empty());
1418 
1419  if (!SInfo.AllocasToInstrument.empty()) {
1420  Value *StackTag =
1421  ClGenerateTagsWithCalls ? nullptr : getStackBaseTag(EntryIRB);
1422  instrumentStack(SInfo, StackTag, GetDT, GetPDT);
1423  }
1424 
1425  // If we split the entry block, move any allocas that were originally in the
1426  // entry block back into the entry block so that they aren't treated as
1427  // dynamic allocas.
1428  if (EntryIRB.GetInsertBlock() != &F.getEntryBlock()) {
1429  InsertPt = &*F.getEntryBlock().begin();
1430  for (Instruction &I :
1431  llvm::make_early_inc_range(*EntryIRB.GetInsertBlock())) {
1432  if (auto *AI = dyn_cast<AllocaInst>(&I))
1433  if (isa<ConstantInt>(AI->getArraySize()))
1434  I.moveBefore(InsertPt);
1435  }
1436  }
1437 
1438  for (auto &Operand : OperandsToInstrument)
1439  instrumentMemAccess(Operand);
1440 
1441  if (ClInstrumentMemIntrinsics && !IntrinToInstrument.empty()) {
1442  for (auto Inst : IntrinToInstrument)
1443  instrumentMemIntrinsic(cast<MemIntrinsic>(Inst));
1444  }
1445 
1446  ShadowBase = nullptr;
1447  StackBaseTag = nullptr;
1448 
1449  return true;
1450 }
1451 
1452 void HWAddressSanitizer::instrumentGlobal(GlobalVariable *GV, uint8_t Tag) {
1453  assert(!UsePageAliases);
1455  uint64_t SizeInBytes =
1456  M.getDataLayout().getTypeAllocSize(Initializer->getType());
1457  uint64_t NewSize = alignTo(SizeInBytes, Mapping.getObjectAlignment());
1458  if (SizeInBytes != NewSize) {
1459  // Pad the initializer out to the next multiple of 16 bytes and add the
1460  // required short granule tag.
1461  std::vector<uint8_t> Init(NewSize - SizeInBytes, 0);
1462  Init.back() = Tag;
1465  }
1466 
1467  auto *NewGV = new GlobalVariable(M, Initializer->getType(), GV->isConstant(),
1468  GlobalValue::ExternalLinkage, Initializer,
1469  GV->getName() + ".hwasan");
1470  NewGV->copyAttributesFrom(GV);
1471  NewGV->setLinkage(GlobalValue::PrivateLinkage);
1472  NewGV->copyMetadata(GV, 0);
1473  NewGV->setAlignment(
1474  MaybeAlign(std::max(GV->getAlignment(), Mapping.getObjectAlignment())));
1475 
1476  // It is invalid to ICF two globals that have different tags. In the case
1477  // where the size of the global is a multiple of the tag granularity the
1478  // contents of the globals may be the same but the tags (i.e. symbol values)
1479  // may be different, and the symbols are not considered during ICF. In the
1480  // case where the size is not a multiple of the granularity, the short granule
1481  // tags would discriminate two globals with different tags, but there would
1482  // otherwise be nothing stopping such a global from being incorrectly ICF'd
1483  // with an uninstrumented (i.e. tag 0) global that happened to have the short
1484  // granule tag in the last byte.
1485  NewGV->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
1486 
1487  // Descriptor format (assuming little-endian):
1488  // bytes 0-3: relative address of global
1489  // bytes 4-6: size of global (16MB ought to be enough for anyone, but in case
1490  // it isn't, we create multiple descriptors)
1491  // byte 7: tag
1492  auto *DescriptorTy = StructType::get(Int32Ty, Int32Ty);
1493  const uint64_t MaxDescriptorSize = 0xfffff0;
1494  for (uint64_t DescriptorPos = 0; DescriptorPos < SizeInBytes;
1495  DescriptorPos += MaxDescriptorSize) {
1496  auto *Descriptor =
1497  new GlobalVariable(M, DescriptorTy, true, GlobalValue::PrivateLinkage,
1498  nullptr, GV->getName() + ".hwasan.descriptor");
1499  auto *GVRelPtr = ConstantExpr::getTrunc(
1502  ConstantExpr::getPtrToInt(NewGV, Int64Ty),
1503  ConstantExpr::getPtrToInt(Descriptor, Int64Ty)),
1504  ConstantInt::get(Int64Ty, DescriptorPos)),
1505  Int32Ty);
1506  uint32_t Size = std::min(SizeInBytes - DescriptorPos, MaxDescriptorSize);
1507  auto *SizeAndTag = ConstantInt::get(Int32Ty, Size | (uint32_t(Tag) << 24));
1508  Descriptor->setComdat(NewGV->getComdat());
1509  Descriptor->setInitializer(ConstantStruct::getAnon({GVRelPtr, SizeAndTag}));
1510  Descriptor->setSection("hwasan_globals");
1511  Descriptor->setMetadata(LLVMContext::MD_associated,
1512  MDNode::get(*C, ValueAsMetadata::get(NewGV)));
1513  appendToCompilerUsed(M, Descriptor);
1514  }
1515 
1518  ConstantExpr::getPtrToInt(NewGV, Int64Ty),
1519  ConstantInt::get(Int64Ty, uint64_t(Tag) << PointerTagShift)),
1520  GV->getType());
1521  auto *Alias = GlobalAlias::create(GV->getValueType(), GV->getAddressSpace(),
1522  GV->getLinkage(), "", Aliasee, &M);
1523  Alias->setVisibility(GV->getVisibility());
1524  Alias->takeName(GV);
1525  GV->replaceAllUsesWith(Alias);
1526  GV->eraseFromParent();
1527 }
1528 
1530  NamedMDNode *Globals = M.getNamedMetadata("llvm.asan.globals");
1531  if (!Globals)
1532  return DenseSet<GlobalVariable *>();
1533  DenseSet<GlobalVariable *> Excluded(Globals->getNumOperands());
1534  for (auto MDN : Globals->operands()) {
1535  // Metadata node contains the global and the fields of "Entry".
1536  assert(MDN->getNumOperands() == 5);
1537  auto *V = mdconst::extract_or_null<Constant>(MDN->getOperand(0));
1538  // The optimizer may optimize away a global entirely.
1539  if (!V)
1540  continue;
1541  auto *StrippedV = V->stripPointerCasts();
1542  auto *GV = dyn_cast<GlobalVariable>(StrippedV);
1543  if (!GV)
1544  continue;
1545  ConstantInt *IsExcluded = mdconst::extract<ConstantInt>(MDN->getOperand(4));
1546  if (IsExcluded->isOne())
1547  Excluded.insert(GV);
1548  }
1549  return Excluded;
1550 }
1551 
1552 void HWAddressSanitizer::instrumentGlobals() {
1553  std::vector<GlobalVariable *> Globals;
1554  auto ExcludedGlobals = getExcludedGlobals(M);
1555  for (GlobalVariable &GV : M.globals()) {
1556  if (ExcludedGlobals.count(&GV))
1557  continue;
1558 
1559  if (GV.isDeclarationForLinker() || GV.getName().startswith("llvm.") ||
1560  GV.isThreadLocal())
1561  continue;
1562 
1563  // Common symbols can't have aliases point to them, so they can't be tagged.
1564  if (GV.hasCommonLinkage())
1565  continue;
1566 
1567  // Globals with custom sections may be used in __start_/__stop_ enumeration,
1568  // which would be broken both by adding tags and potentially by the extra
1569  // padding/alignment that we insert.
1570  if (GV.hasSection())
1571  continue;
1572 
1573  Globals.push_back(&GV);
1574  }
1575 
1576  MD5 Hasher;
1577  Hasher.update(M.getSourceFileName());
1578  MD5::MD5Result Hash;
1579  Hasher.final(Hash);
1580  uint8_t Tag = Hash[0];
1581 
1582  for (GlobalVariable *GV : Globals) {
1583  Tag &= TagMaskByte;
1584  // Skip tag 0 in order to avoid collisions with untagged memory.
1585  if (Tag == 0)
1586  Tag = 1;
1587  instrumentGlobal(GV, Tag++);
1588  }
1589 }
1590 
1591 void HWAddressSanitizer::instrumentPersonalityFunctions() {
1592  // We need to untag stack frames as we unwind past them. That is the job of
1593  // the personality function wrapper, which either wraps an existing
1594  // personality function or acts as a personality function on its own. Each
1595  // function that has a personality function or that can be unwound past has
1596  // its personality function changed to a thunk that calls the personality
1597  // function wrapper in the runtime.
1599  for (Function &F : M) {
1600  if (F.isDeclaration() || !F.hasFnAttribute(Attribute::SanitizeHWAddress))
1601  continue;
1602 
1603  if (F.hasPersonalityFn()) {
1604  PersonalityFns[F.getPersonalityFn()->stripPointerCasts()].push_back(&F);
1605  } else if (!F.hasFnAttribute(Attribute::NoUnwind)) {
1606  PersonalityFns[nullptr].push_back(&F);
1607  }
1608  }
1609 
1610  if (PersonalityFns.empty())
1611  return;
1612 
1613  FunctionCallee HwasanPersonalityWrapper = M.getOrInsertFunction(
1614  "__hwasan_personality_wrapper", Int32Ty, Int32Ty, Int32Ty, Int64Ty,
1615  Int8PtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy);
1616  FunctionCallee UnwindGetGR = M.getOrInsertFunction("_Unwind_GetGR", VoidTy);
1617  FunctionCallee UnwindGetCFA = M.getOrInsertFunction("_Unwind_GetCFA", VoidTy);
1618 
1619  for (auto &P : PersonalityFns) {
1620  std::string ThunkName = kHwasanPersonalityThunkName;
1621  if (P.first)
1622  ThunkName += ("." + P.first->getName()).str();
1623  FunctionType *ThunkFnTy = FunctionType::get(
1624  Int32Ty, {Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int8PtrTy}, false);
1625  bool IsLocal = P.first && (!isa<GlobalValue>(P.first) ||
1626  cast<GlobalValue>(P.first)->hasLocalLinkage());
1627  auto *ThunkFn = Function::Create(ThunkFnTy,
1630  ThunkName, &M);
1631  if (!IsLocal) {
1632  ThunkFn->setVisibility(GlobalValue::HiddenVisibility);
1633  ThunkFn->setComdat(M.getOrInsertComdat(ThunkName));
1634  }
1635 
1636  auto *BB = BasicBlock::Create(*C, "entry", ThunkFn);
1637  IRBuilder<> IRB(BB);
1638  CallInst *WrapperCall = IRB.CreateCall(
1639  HwasanPersonalityWrapper,
1640  {ThunkFn->getArg(0), ThunkFn->getArg(1), ThunkFn->getArg(2),
1641  ThunkFn->getArg(3), ThunkFn->getArg(4),
1642  P.first ? IRB.CreateBitCast(P.first, Int8PtrTy)
1643  : Constant::getNullValue(Int8PtrTy),
1644  IRB.CreateBitCast(UnwindGetGR.getCallee(), Int8PtrTy),
1645  IRB.CreateBitCast(UnwindGetCFA.getCallee(), Int8PtrTy)});
1646  WrapperCall->setTailCall();
1647  IRB.CreateRet(WrapperCall);
1648 
1649  for (Function *F : P.second)
1650  F->setPersonalityFn(ThunkFn);
1651  }
1652 }
1653 
1655  bool InstrumentWithCalls) {
1656  Scale = kDefaultShadowScale;
1657  if (TargetTriple.isOSFuchsia()) {
1658  // Fuchsia is always PIE, which means that the beginning of the address
1659  // space is always available.
1660  InGlobal = false;
1661  InTls = false;
1662  Offset = 0;
1663  WithFrameRecord = true;
1664  } else if (ClMappingOffset.getNumOccurrences() > 0) {
1665  InGlobal = false;
1666  InTls = false;
1668  WithFrameRecord = false;
1669  } else if (ClEnableKhwasan || InstrumentWithCalls) {
1670  InGlobal = false;
1671  InTls = false;
1672  Offset = 0;
1673  WithFrameRecord = false;
1674  } else if (ClWithIfunc) {
1675  InGlobal = true;
1676  InTls = false;
1678  WithFrameRecord = false;
1679  } else if (ClWithTls) {
1680  InGlobal = false;
1681  InTls = true;
1683  WithFrameRecord = true;
1684  } else {
1685  InGlobal = false;
1686  InTls = false;
1688  WithFrameRecord = false;
1689  }
1690 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:76
kDynamicShadowSentinel
static const uint64_t kDynamicShadowSentinel
Definition: HWAddressSanitizer.cpp:73
llvm::HWASanAccessInfo::AccessSizeShift
@ AccessSizeShift
Definition: HWAddressSanitizer.h:59
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:148
Int32Ty
IntegerType * Int32Ty
Definition: NVVMIntrRange.cpp:67
ClInlineAllChecks
static cl::opt< bool > ClInlineAllChecks("hwasan-inline-all-checks", cl::desc("inline all checks"), cl::Hidden, cl::init(false))
StackSafetyAnalysis.h
llvm::IRBuilderBase::CreateIntCast
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition: IRBuilder.h:2021
llvm::GlobalVariable::eraseFromParent
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition: Globals.cpp:428
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:286
llvm::Type::isSized
bool isSized(SmallPtrSetImpl< Type * > *Visited=nullptr) const
Return true if it makes sense to take the size of this type.
Definition: Type.h:264
llvm::IRBuilderBase::getInt32Ty
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition: IRBuilder.h:501
llvm::IRBuilderBase::CreateStore
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1662
llvm::ELF::NT_LLVM_HWASAN_GLOBALS
@ NT_LLVM_HWASAN_GLOBALS
Definition: ELF.h:1552
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm::IRBuilderBase::SetInsertPoint
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition: IRBuilder.h:179
llvm::GlobalObject::setComdat
void setComdat(Comdat *C)
Definition: Globals.cpp:190
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::NamedMDNode
A tuple of MDNodes.
Definition: Metadata.h:1488
llvm::CallInst::setTailCall
void setTailCall(bool IsTc=true)
Definition: Instructions.h:1681
llvm::MD5::update
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
Definition: MD5.cpp:189
llvm::memtag::StackInfo
Definition: MemoryTaggingSupport.h:54
llvm::StructType::get
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:406
llvm::GlobalValue::hasCommonLinkage
bool hasCommonLinkage() const
Definition: GlobalValue.h:454
llvm::StackSafetyGlobalInfo::isSafe
bool isSafe(const AllocaInst &AI) const
Definition: StackSafetyAnalysis.cpp:966
llvm::Intrinsic::getDeclaration
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:1410
llvm::NamedMDNode::getNumOperands
unsigned getNumOperands() const
Definition: Metadata.cpp:1152
llvm::BasicBlock::getParent
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:104
IntrinsicInst.h
llvm::AnalysisManager::getResult
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:780
DebugInfoMetadata.h
llvm::PassInfoMixin< HWAddressSanitizerPass >
InstIterator.h
llvm::GlobalValue::getLinkage
LinkageTypes getLinkage() const
Definition: GlobalValue.h:466
llvm::GlobalValue::HiddenVisibility
@ HiddenVisibility
The GV is hidden.
Definition: GlobalValue.h:64
llvm::MemTransferInst
This class wraps the llvm.memcpy/memmove intrinsics.
Definition: IntrinsicInst.h:1005
llvm::HWAddressSanitizerOptions::DisableOptimization
bool DisableOptimization
Definition: HWAddressSanitizer.h:34
llvm::Function
Definition: Function.h:60
llvm::IRBuilderBase::CreatePtrToInt
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1942
Note
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles Note
Definition: README.txt:239
StringRef.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::IRBuilderBase::CreateXor
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1394
llvm::Type::getScalarType
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition: Type.h:309
kHwasanPersonalityThunkName
const char kHwasanPersonalityThunkName[]
Definition: HWAddressSanitizer.cpp:64
llvm::AllocaInst::getType
PointerType * getType() const
Overload to return most specific pointer type.
Definition: Instructions.h:100
llvm::ilist_node_with_parent::getNextNode
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition: ilist_node.h:289
llvm::SmallVector< uint64_t, 8 >
InlineAsm.h
llvm::memtag::StackInfo::CallsReturnTwice
bool CallsReturnTwice
Definition: MemoryTaggingSupport.h:58
llvm::Value::hasName
bool hasName() const
Definition: Value.h:261
llvm::GlobalValue::UnnamedAddr::None
@ None
llvm::Type::getPointerAddressSpace
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Definition: DerivedTypes.h:729
llvm::IRBuilder<>
MapVector.h
llvm::GlobalVariable
Definition: GlobalVariable.h:39
llvm::FunctionType::get
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
Definition: Type.cpp:361
ValueTracking.h
llvm::IRBuilderBase::CreateOr
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1372
kShadowBaseAlignment
static const unsigned kShadowBaseAlignment
Definition: HWAddressSanitizer.cpp:76
llvm::DominatorTree
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:166
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::InterestingMemoryOperand
Definition: AddressSanitizerCommon.h:25
FAM
FunctionAnalysisManager FAM
Definition: PassBuilderBindings.cpp:59
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:139
llvm::dwarf::DW_OP_LLVM_tag_offset
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
Definition: Dwarf.h:145
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:155
llvm::HWASanAccessInfo::CompileKernelShift
@ CompileKernelShift
Definition: HWAddressSanitizer.h:64
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Module.h
llvm::Triple::x86_64
@ x86_64
Definition: Triple.h:86
llvm::MemIntrinsic
This is the common base class for memset/memcpy/memmove.
Definition: IntrinsicInst.h:962
llvm::MapVector
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:37
llvm::ValueAsMetadata::get
static ValueAsMetadata * get(Value *V)
Definition: Metadata.cpp:394
STLExtras.h
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:105
llvm::IRBuilderBase::CreateAShr
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1330
llvm::detail::DenseSetImpl< ValueT, DenseMap< ValueT, detail::DenseSetEmpty, DenseMapInfo< ValueT >, detail::DenseSetPair< ValueT > >, DenseMapInfo< ValueT > >::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
llvm::cl::ReallyHidden
@ ReallyHidden
Definition: CommandLine.h:140
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:239
llvm::IRBuilderBase::CreateIntToPtr
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1947
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::MDNode::get
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1300
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::Value::isSwiftError
bool isSwiftError() const
Return true if this value is a swifterror value.
Definition: Value.cpp:1012
llvm::memtag::StackInfo::RetVec
SmallVector< Instruction *, 8 > RetVec
Definition: MemoryTaggingSupport.h:57
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::ConstantExpr::getSub
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
Definition: Constants.cpp:2726
ClInstrumentWithCalls
static cl::opt< bool > ClInstrumentWithCalls("hwasan-instrument-with-calls", cl::desc("instrument reads and writes with callbacks"), cl::Hidden, cl::init(false))
Instruction.h
CommandLine.h
llvm::getOrCreateSanitizerCtorAndInitFunctions
std::pair< Function *, FunctionCallee > getOrCreateSanitizerCtorAndInitFunctions(Module &M, StringRef CtorName, StringRef InitName, ArrayRef< Type * > InitArgTypes, ArrayRef< Value * > InitArgs, function_ref< void(Function *, FunctionCallee)> FunctionsCreatedCallback, StringRef VersionCheckName=StringRef())
Creates sanitizer constructor function lazily.
Definition: ModuleUtils.cpp:157
kNumberOfAccessSizes
static const size_t kNumberOfAccessSizes
Definition: HWAddressSanitizer.cpp:70
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
llvm::AllocaInst::isStaticAlloca
bool isStaticAlloca() const
Return true if this alloca is in the entry block of the function and is a constant size.
Definition: Instructions.cpp:1419
llvm::DIExpression::appendOpsToArg
static DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)
Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...
Definition: DebugInfoMetadata.cpp:1467
llvm::Triple::isAndroid
bool isAndroid() const
Tests whether the target is Android.
Definition: Triple.h:701
llvm::HWAddressSanitizerOptions::CompileKernel
bool CompileKernel
Definition: HWAddressSanitizer.h:31
llvm::Triple::isOSBinFormatELF
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition: Triple.h:656
llvm::MD5::final
void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
Definition: MD5.cpp:234
ELF.h
ClInstrumentAtomics
static cl::opt< bool > ClInstrumentAtomics("hwasan-instrument-atomics", cl::desc("instrument atomic instructions (rmw, cmpxchg)"), cl::Hidden, cl::init(true))
Constants.h
PostDominators.h
ClUsePageAliases
static cl::opt< bool > ClUsePageAliases("hwasan-experimental-use-page-aliases", cl::desc("Use page aliasing in HWASan"), cl::Hidden, cl::init(false))
HWAddressSanitizer.h
llvm::AllocaInst::getAllocatedType
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
Definition: Instructions.h:114
llvm::IRBuilderBase::CreateGEP
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", bool IsInBounds=false)
Definition: IRBuilder.h:1725
llvm::memtag::StackInfoBuilder
Definition: MemoryTaggingSupport.h:61
llvm::User
Definition: User.h:44
llvm::IRBuilderBase::CreateMemSet
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign 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:568
Intrinsics.h
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::ConstantExpr::getIntToPtr
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2244
llvm::IRBuilderBase::CreateLoad
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition: IRBuilder.h:1649
llvm::Triple::isAArch64
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
Definition: Triple.h:809
MAM
ModuleAnalysisManager MAM
Definition: PassBuilderBindings.cpp:61
llvm::MDBuilder::createBranchWeights
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight)
Return metadata containing two branch weights.
Definition: MDBuilder.cpp:37
llvm::ConstantExpr::getPtrToInt
static Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2230
ClUseShortGranules
static cl::opt< bool > ClUseShortGranules("hwasan-use-short-granules", cl::desc("use short granules in allocas and outlined checks"), cl::Hidden, cl::init(false), cl::ZeroOrMore)
ClWithIfunc
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))
AddressSanitizerCommon.h
llvm::memtag::forAllReachableExits
bool forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT, const Instruction *Start, const SmallVectorImpl< IntrinsicInst * > &Ends, const SmallVectorImpl< Instruction * > &RetVec, llvm::function_ref< void(Instruction *)> Callback)
Definition: MemoryTaggingSupport.cpp:40
MemoryTaggingSupport.h
llvm::MaybeAlign
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:109
llvm::Instruction
Definition: Instruction.h:42
MDBuilder.h
llvm::AllocaInst::getArraySize
const Value * getArraySize() const
Get the number of elements allocated.
Definition: Instructions.h:96
kDefaultShadowScale
static const size_t kDefaultShadowScale
Definition: HWAddressSanitizer.cpp:72
llvm::IRBuilderBase::getInt8Ty
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Definition: IRBuilder.h:491
llvm::appendToCompilerUsed
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
Definition: ModuleUtils.cpp:109
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:143
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::HWASanAccessInfo::RecoverShift
@ RecoverShift
Definition: HWAddressSanitizer.h:61
llvm::Value::setName
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:372
LoopDeletionResult::Modified
@ Modified
llvm::Module::getOrInsertGlobal
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::cl::Option::getNumOccurrences
int getNumOccurrences() const
Definition: CommandLine.h:395
llvm::DomTreeUpdater
Definition: DomTreeUpdater.h:28
llvm::ConstantInt::get
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:919
llvm::Use::getUser
User * getUser() const
Returns the User that contains this Use.
Definition: Use.h:72
Info
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
ClInstrumentPersonalityFunctions
static cl::opt< bool > ClInstrumentPersonalityFunctions("hwasan-instrument-personality-functions", cl::desc("instrument personality functions"), cl::Hidden, cl::init(false), cl::ZeroOrMore)
Align
uint64_t Align
Definition: ELFObjHandler.cpp:81
llvm::GlobalValue::InternalLinkage
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:55
llvm::Comdat
Definition: Comdat.h:33
llvm::Triple::getArch
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition: Triple.h:345
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:245
llvm::None
const NoneType None
Definition: None.h:24
llvm::InlineAsm::get
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
Definition: InlineAsm.cpp:41
llvm::IRBuilderBase::CreateRet
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition: IRBuilder.h:959
Type.h
llvm::IRBuilderBase::CreateAnd
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1350
llvm::IRBuilderBase::CreatePointerCast
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1998
llvm::AllocaInst::isSwiftError
bool isSwiftError() const
Return true if this alloca is used as a swifterror argument to a call.
Definition: Instructions.h:149
llvm::Triple::isOSFuchsia
bool isOSFuchsia() const
Definition: Triple.h:538
llvm::IRBuilderBase::CreateZExt
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1860
llvm::cl::ZeroOrMore
@ ZeroOrMore
Definition: CommandLine.h:116
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLFunctionalExtras.h:36
llvm::InlineAsm
Definition: InlineAsm.h:31
llvm::DenseSet
Implements a dense probed hash-table based set.
Definition: DenseSet.h:268
llvm::ConstantExpr::getTrunc
static Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2120
ClMatchAllTag
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))
BasicBlock.h
llvm::cl::opt
Definition: CommandLine.h:1392
llvm::GlobalObject::hasSection
bool hasSection() const
Check if this global has a custom object file section.
Definition: GlobalObject.h:103
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:239
llvm::instructions
inst_range instructions(Function *F)
Definition: InstIterator.h:133
llvm::IRBuilderBase::CreateBitCast
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1952
llvm::StoreInst
An instruction for storing to memory.
Definition: Instructions.h:305
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::GlobalVariable::getInitializer
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
Definition: GlobalVariable.h:135
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:409
uint64_t
llvm::for_each
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1600
llvm::GlobalValue::getVisibility
VisibilityTypes getVisibility() const
Definition: GlobalValue.h:228
llvm::StackSafetyGlobalAnalysis
This pass performs the global (interprocedural) stack safety analysis (new pass manager).
Definition: StackSafetyAnalysis.h:128
llvm::GlobalValue::getParent
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:577
llvm::memtag::StackInfo::UnrecognizedLifetimes
SmallVector< Instruction *, 4 > UnrecognizedLifetimes
Definition: MemoryTaggingSupport.h:56
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:78
llvm::HWASanAccessInfo::RuntimeMask
@ RuntimeMask
Definition: HWAddressSanitizer.h:67
llvm::MD5
Definition: MD5.h:41
llvm::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
PromoteMemToReg.h
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::IRBuilderBase::getInt8PtrTy
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
Definition: IRBuilder.h:549
StringExtras.h
getExcludedGlobals
static DenseSet< GlobalVariable * > getExcludedGlobals(Module &M)
Definition: HWAddressSanitizer.cpp:1529
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
llvm::make_early_inc_range
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:608
ClInstrumentReads
static cl::opt< bool > ClInstrumentReads("hwasan-instrument-reads", cl::desc("instrument read instructions"), cl::Hidden, cl::init(true))
ClMappingOffset
static cl::opt< uint64_t > ClMappingOffset("hwasan-mapping-offset", cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"), cl::Hidden, cl::init(0))
llvm::IRBuilderBase::CreateAdd
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1201
llvm::MDString::get
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:499
llvm::ConstantStruct::getAnon
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
Definition: Constants.h:462
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:137
IRBuilder.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::HWAddressSanitizerPass::run
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
Definition: HWAddressSanitizer.cpp:391
SI
StandardInstrumentations SI(Debug, VerifyEach)
llvm::GlobalValue::isThreadLocal
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
Definition: GlobalValue.h:243
llvm::ArrayType::get
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Definition: Type.cpp:638
llvm::memtag::AllocaInfo
Definition: MemoryTaggingSupport.h:47
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::MDNode
Metadata node.
Definition: Metadata.h:937
ClGlobals
static cl::opt< bool > ClGlobals("hwasan-globals", cl::desc("Instrument globals"), cl::Hidden, cl::init(false), cl::ZeroOrMore)
ClMemoryAccessCallbackPrefix
static cl::opt< std::string > ClMemoryAccessCallbackPrefix("hwasan-memory-access-callback-prefix", cl::desc("Prefix for memory access callbacks"), cl::Hidden, cl::init("__hwasan_"))
kHwasanInitName
const char kHwasanInitName[]
Definition: HWAddressSanitizer.cpp:63
Triple.h
llvm::HWAddressSanitizerOptions::Recover
bool Recover
Definition: HWAddressSanitizer.h:33
llvm::NVPTXISD::Dummy
@ Dummy
Definition: NVPTXISelLowering.h:60
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
DataLayout.h
llvm::countTrailingZeros
unsigned countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition: MathExtras.h:156
llvm::Triple::aarch64_be
@ aarch64_be
Definition: Triple.h:52
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
Dwarf.h
llvm::Instruction::setSuccessor
void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
Definition: Instruction.cpp:801
llvm::PostDominatorTree
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
Definition: PostDominators.h:28
llvm::Value::getType
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
ClInstrumentByval
static cl::opt< bool > ClInstrumentByval("hwasan-instrument-byval", cl::desc("instrument byval arguments"), cl::Hidden, cl::init(true))
llvm::ConstantDataArray::get
static Constant * get(LLVMContext &Context, ArrayRef< ElementTy > Elts)
get() constructor - Return a constant with array type with an element count and element type matching...
Definition: Constants.h:691
llvm::Value::replaceAllUsesWith
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:529
llvm::BasicBlock::Create
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:97
uint32_t
ClRecordStackHistory
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))
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::HWASanAccessInfo::IsWriteShift
@ IsWriteShift
Definition: HWAddressSanitizer.h:60
llvm::IRBuilderBase::CreateICmpUGE
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2078
ClInstrumentWrites
static cl::opt< bool > ClInstrumentWrites("hwasan-instrument-writes", cl::desc("instrument write instructions"), cl::Hidden, cl::init(true))
llvm::Value::getName
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:305
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:176
llvm::Init
Definition: Record.h:281
llvm::GlobalObject::getAlignment
uint64_t getAlignment() const
FIXME: Remove this function once transition to Align is over.
Definition: GlobalObject.h:70
llvm::memtag::StackInfoBuilder::visit
void visit(Instruction &Inst)
Definition: MemoryTaggingSupport.cpp:100
llvm::IRBuilderBase::CreateConstGEP1_32
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
Definition: IRBuilder.h:1740
llvm::NamedMDNode::operands
iterator_range< op_iterator > operands()
Definition: Metadata.h:1584
llvm::AtomicRMWInst
an instruction that atomically reads a memory location, combines it with another value,...
Definition: Instructions.h:727
llvm::cl::Optional
@ Optional
Definition: CommandLine.h:115
llvm::IRBuilderBase::CreateTrunc
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1856
llvm::FunctionCallee::getCallee
Value * getCallee()
Definition: DerivedTypes.h:184
llvm::MD5::MD5Result
Definition: MD5.h:43
Attributes.h
llvm::MapVector::empty
bool empty() const
Definition: MapVector.h:80
Constant.h
llvm::Type::getInt64Ty
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:240
getPointerOperandIndex
static unsigned getPointerOperandIndex(Instruction *I)
Definition: HWAddressSanitizer.cpp:756
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::Constant::getNullValue
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:350
llvm::GlobalAlias::create
static GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition: Globals.cpp:480
llvm::MetadataAsValue::get
static MetadataAsValue * get(LLVMContext &Context, Metadata *MD)
Definition: Metadata.cpp:102
isLifetimeIntrinsic
static bool isLifetimeIntrinsic(Value *V)
Definition: HWAddressSanitizer.cpp:1224
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
llvm::memtag::alignAndPadAlloca
void alignAndPadAlloca(memtag::AllocaInfo &Info, llvm::Align Align)
Definition: MemoryTaggingSupport.cpp:150
llvm::ConstantExpr::getAdd
static Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
Definition: Constants.cpp:2715
kHwasanNoteName
const char kHwasanNoteName[]
Definition: HWAddressSanitizer.cpp:62
llvm::IRBuilderBase::GetInsertBlock
BasicBlock * GetInsertBlock() const
Definition: IRBuilder.h:173
llvm::TypeSize
Definition: TypeSize.h:421
Casting.h
Function.h
ClUARRetagToZero
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))
ClInstrumentLandingPads
static cl::opt< bool > ClInstrumentLandingPads("hwasan-instrument-landing-pads", cl::desc("instrument landing pads"), cl::Hidden, cl::init(false), cl::ZeroOrMore)
llvm::Type::getPointerTo
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
Definition: Type.cpp:774
llvm::memtag::StackInfo::AllocasToInstrument
MapVector< AllocaInst *, AllocaInfo > AllocasToInstrument
Definition: MemoryTaggingSupport.h:55
llvm::IntrinsicInst
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:46
llvm::pdb::PDB_ColorItem::Padding
@ Padding
llvm::MDBuilder
Definition: MDBuilder.h:35
llvm::GlobalValue::getAddressSpace
unsigned getAddressSpace() const
Definition: Globals.cpp:117
ClKasanMemIntrinCallbackPrefix
static cl::opt< bool > ClKasanMemIntrinCallbackPrefix("hwasan-kernel-mem-intrinsic-prefix", cl::desc("Use prefix for memory intrinsics in KASAN mode"), cl::Hidden, cl::init(false))
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
llvm::HWAddressSanitizerPass::printPipeline
void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
Definition: HWAddressSanitizer.cpp:415
llvm::SPIRV::ExecutionMode::Initializer
@ Initializer
llvm::Triple::isAndroidVersionLT
bool isAndroidVersionLT(unsigned Major) const
Definition: Triple.h:703
llvm::DominatorTreeAnalysis
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:267
llvm::Type::getVoidTy
static Type * getVoidTy(LLVMContext &C)
Definition: Type.cpp:222
llvm::StackSafetyGlobalInfo::stackAccessIsSafe
bool stackAccessIsSafe(const Instruction &I) const
Definition: StackSafetyAnalysis.cpp:971
llvm::GlobalValue::PrivateLinkage
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:56
Instructions.h
llvm::AllocaInst::isUsedWithInAlloca
bool isUsedWithInAlloca() const
Return true if this alloca is used as an inalloca argument to a call.
Definition: Instructions.h:139
SmallVector.h
llvm::HWASanAccessInfo::MatchAllShift
@ MatchAllShift
Definition: HWAddressSanitizer.h:62
llvm::GlobalVariable::isConstant
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
Definition: GlobalVariable.h:152
llvm::IRBuilderBase::CreateLShr
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition: IRBuilder.h:1310
Dominators.h
ModuleUtils.h
N
#define N
llvm::IRBuilderBase::CreateShl
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition: IRBuilder.h:1289
llvm::Instruction::getParent
const BasicBlock * getParent() const
Definition: Instruction.h:91
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
llvm::memtag::getAllocaSizeInBytes
uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
Definition: MemoryTaggingSupport.cpp:145
kHwasanModuleCtorName
const char kHwasanModuleCtorName[]
Definition: HWAddressSanitizer.cpp:61
llvm::GlobalValue::isDeclarationForLinker
bool isDeclarationForLinker() const
Definition: GlobalValue.h:539
llvm::FunctionCallee
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Definition: DerivedTypes.h:165
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
TypeSizeToSizeIndex
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
Definition: HWAddressSanitizer.cpp:769
llvm::GlobalValue::getType
PointerType * getType() const
Global values are always pointers.
Definition: GlobalValue.h:270
DerivedTypes.h
llvm::StackSafetyGlobalInfo
Definition: StackSafetyAnalysis.h:58
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
llvm::GlobalValue::getValueType
Type * getValueType() const
Definition: GlobalValue.h:272
llvm::HexStyle::Asm
@ Asm
0ffh
Definition: MCInstPrinter.h:34
llvm::InnerAnalysisManagerProxy
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:937
ClMaxLifetimes
static cl::opt< size_t > ClMaxLifetimes("hwasan-max-lifetimes-for-alloca", cl::Hidden, cl::init(3), cl::ReallyHidden, cl::desc("How many lifetime ends to handle for a single alloca."), cl::Optional)
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1474
llvm::ConstantInt::isOne
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
Definition: Constants.h:200
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::IRBuilderBase::CreateICmpUGT
Value * CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2074
llvm::IRBuilderBase::getVoidTy
Type * getVoidTy()
Fetch the type representing void.
Definition: IRBuilder.h:539
llvm::PostDominatorTreeAnalysis
Analysis pass which computes a PostDominatorTree.
Definition: PostDominators.h:47
llvm::Value::replaceUsesWithIf
void replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
Definition: Value.cpp:537
ClEnableKhwasan
static cl::opt< bool > ClEnableKhwasan("hwasan-kernel", cl::desc("Enable KernelHWAddressSanitizer instrumentation"), cl::Hidden, cl::init(false))
llvm::IRBuilderBase::CreateICmpNE
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:2070
LLVMContext.h
llvm::SplitBlockAndInsertIfThen
Instruction * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights, DominatorTree *DT, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
Definition: BasicBlockUtils.cpp:1446
ClGenerateTagsWithCalls
static cl::opt< bool > ClGenerateTagsWithCalls("hwasan-generate-tags-with-calls", cl::desc("generate new tags with runtime library calls"), cl::Hidden, cl::init(false))
llvm::AMDGPU::HSAMD::Kernel::Key::Args
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Definition: AMDGPUMetadata.h:394
llvm::AllocaInst
an instruction to allocate memory on the stack
Definition: Instructions.h:58
llvm::appendToGlobalCtors
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:65
llvm::cl::desc
Definition: CommandLine.h:405
llvm::HWASanAccessInfo::HasMatchAllShift
@ HasMatchAllShift
Definition: HWAddressSanitizer.h:63
ClInstrumentStack
static cl::opt< bool > ClInstrumentStack("hwasan-instrument-stack", cl::desc("instrument stack (allocas)"), cl::Hidden, cl::init(true))
raw_ostream.h
ClRecover
static cl::opt< bool > ClRecover("hwasan-recover", cl::desc("Enable recovery mode (continue-after-error)."), cl::Hidden, cl::init(false))
llvm::GlobalValue::InitialExecTLSModel
@ InitialExecTLSModel
Definition: GlobalValue.h:181
BasicBlockUtils.h
llvm::GlobalValue::LinkOnceODRLinkage
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:51
llvm::isPowerOf2_64
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:496
Value.h
ClInstrumentMemIntrinsics
static cl::opt< bool > ClInstrumentMemIntrinsics("hwasan-instrument-mem-intrinsics", cl::desc("instrument memory intrinsics"), cl::Hidden, cl::init(true))
ClUseAfterScope
static cl::opt< bool > ClUseAfterScope("hwasan-use-after-scope", cl::desc("detect use after scope within function"), cl::Hidden, cl::init(false))
ClWithTls
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))
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::AtomicCmpXchgInst
An instruction that atomically checks whether a specified value is in a memory location,...
Definition: Instructions.h:522
Debug.h
llvm::Triple::aarch64
@ aarch64
Definition: Triple.h:51
ClUseStackSafety
static cl::opt< bool > ClUseStackSafety("hwasan-use-stack-safety", cl::Hidden, cl::init(true), cl::Hidden, cl::desc("Use Stack Safety analysis results"), cl::Optional)
llvm::IRBuilderBase::CreateCall
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2229
llvm::isAllocaPromotable
bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
Definition: PromoteMemoryToRegister.cpp:63
llvm::memtag::isStandardLifetime
bool isStandardLifetime(const SmallVectorImpl< IntrinsicInst * > &LifetimeStart, const SmallVectorImpl< IntrinsicInst * > &LifetimeEnd, const DominatorTree *DT, size_t MaxLifetimes)
Definition: MemoryTaggingSupport.cpp:76
llvm::findAllocaForValue
AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
Definition: ValueTracking.cpp:4492
kHwasanShadowMemoryDynamicAddress
const char kHwasanShadowMemoryDynamicAddress[]
Definition: HWAddressSanitizer.cpp:66
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:103
llvm::Use
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
llvm::SmallVectorImpl::emplace_back
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:927