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