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(), std::nullopt);
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(),
766  std::nullopt);
767  } else if (auto CI = dyn_cast<CallInst>(I)) {
768  for (unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
769  if (!ClInstrumentByval || !CI->isByValArgument(ArgNo) ||
770  ignoreAccess(I, CI->getArgOperand(ArgNo)))
771  continue;
772  Type *Ty = CI->getParamByValType(ArgNo);
773  Interesting.emplace_back(I, ArgNo, false, Ty, Align(1));
774  }
775  }
776 }
777 
779  if (LoadInst *LI = dyn_cast<LoadInst>(I))
780  return LI->getPointerOperandIndex();
781  if (StoreInst *SI = dyn_cast<StoreInst>(I))
782  return SI->getPointerOperandIndex();
783  if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I))
784  return RMW->getPointerOperandIndex();
785  if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I))
786  return XCHG->getPointerOperandIndex();
787  report_fatal_error("Unexpected instruction");
788  return -1;
789 }
790 
792  size_t Res = countTrailingZeros(TypeSize / 8);
794  return Res;
795 }
796 
797 void HWAddressSanitizer::untagPointerOperand(Instruction *I, Value *Addr) {
798  if (TargetTriple.isAArch64() || TargetTriple.getArch() == Triple::x86_64)
799  return;
800 
801  IRBuilder<> IRB(I);
802  Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
803  Value *UntaggedPtr =
804  IRB.CreateIntToPtr(untagPointer(IRB, AddrLong), Addr->getType());
805  I->setOperand(getPointerOperandIndex(I), UntaggedPtr);
806 }
807 
808 Value *HWAddressSanitizer::memToShadow(Value *Mem, IRBuilder<> &IRB) {
809  // Mem >> Scale
810  Value *Shadow = IRB.CreateLShr(Mem, Mapping.Scale);
811  if (Mapping.Offset == 0)
812  return IRB.CreateIntToPtr(Shadow, Int8PtrTy);
813  // (Mem >> Scale) + Offset
814  return IRB.CreateGEP(Int8Ty, ShadowBase, Shadow);
815 }
816 
817 int64_t HWAddressSanitizer::getAccessInfo(bool IsWrite,
818  unsigned AccessSizeIndex) {
819  return (CompileKernel << HWASanAccessInfo::CompileKernelShift) +
820  (HasMatchAllTag << HWASanAccessInfo::HasMatchAllShift) +
821  (MatchAllTag << HWASanAccessInfo::MatchAllShift) +
822  (Recover << HWASanAccessInfo::RecoverShift) +
823  (IsWrite << HWASanAccessInfo::IsWriteShift) +
824  (AccessSizeIndex << HWASanAccessInfo::AccessSizeShift);
825 }
826 
827 void HWAddressSanitizer::instrumentMemAccessOutline(Value *Ptr, bool IsWrite,
828  unsigned AccessSizeIndex,
829  Instruction *InsertBefore) {
830  assert(!UsePageAliases);
831  const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
832  IRBuilder<> IRB(InsertBefore);
833  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
834  Ptr = IRB.CreateBitCast(Ptr, Int8PtrTy);
836  M, UseShortGranules
837  ? Intrinsic::hwasan_check_memaccess_shortgranules
838  : Intrinsic::hwasan_check_memaccess),
839  {ShadowBase, Ptr, ConstantInt::get(Int32Ty, AccessInfo)});
840 }
841 
842 void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
843  unsigned AccessSizeIndex,
844  Instruction *InsertBefore) {
845  assert(!UsePageAliases);
846  const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
847  IRBuilder<> IRB(InsertBefore);
848 
849  Value *PtrLong = IRB.CreatePointerCast(Ptr, IntptrTy);
850  Value *PtrTag = IRB.CreateTrunc(IRB.CreateLShr(PtrLong, PointerTagShift),
851  IRB.getInt8Ty());
852  Value *AddrLong = untagPointer(IRB, PtrLong);
853  Value *Shadow = memToShadow(AddrLong, IRB);
854  Value *MemTag = IRB.CreateLoad(Int8Ty, Shadow);
855  Value *TagMismatch = IRB.CreateICmpNE(PtrTag, MemTag);
856 
857  if (HasMatchAllTag) {
858  Value *TagNotIgnored = IRB.CreateICmpNE(
859  PtrTag, ConstantInt::get(PtrTag->getType(), MatchAllTag));
860  TagMismatch = IRB.CreateAnd(TagMismatch, TagNotIgnored);
861  }
862 
863  Instruction *CheckTerm =
864  SplitBlockAndInsertIfThen(TagMismatch, InsertBefore, false,
865  MDBuilder(*C).createBranchWeights(1, 100000));
866 
867  IRB.SetInsertPoint(CheckTerm);
868  Value *OutOfShortGranuleTagRange =
869  IRB.CreateICmpUGT(MemTag, ConstantInt::get(Int8Ty, 15));
870  Instruction *CheckFailTerm =
871  SplitBlockAndInsertIfThen(OutOfShortGranuleTagRange, CheckTerm, !Recover,
872  MDBuilder(*C).createBranchWeights(1, 100000));
873 
874  IRB.SetInsertPoint(CheckTerm);
875  Value *PtrLowBits = IRB.CreateTrunc(IRB.CreateAnd(PtrLong, 15), Int8Ty);
876  PtrLowBits = IRB.CreateAdd(
877  PtrLowBits, ConstantInt::get(Int8Ty, (1 << AccessSizeIndex) - 1));
878  Value *PtrLowBitsOOB = IRB.CreateICmpUGE(PtrLowBits, MemTag);
879  SplitBlockAndInsertIfThen(PtrLowBitsOOB, CheckTerm, false,
880  MDBuilder(*C).createBranchWeights(1, 100000),
881  (DomTreeUpdater *)nullptr, nullptr,
882  CheckFailTerm->getParent());
883 
884  IRB.SetInsertPoint(CheckTerm);
885  Value *InlineTagAddr = IRB.CreateOr(AddrLong, 15);
886  InlineTagAddr = IRB.CreateIntToPtr(InlineTagAddr, Int8PtrTy);
887  Value *InlineTag = IRB.CreateLoad(Int8Ty, InlineTagAddr);
888  Value *InlineTagMismatch = IRB.CreateICmpNE(PtrTag, InlineTag);
889  SplitBlockAndInsertIfThen(InlineTagMismatch, CheckTerm, false,
890  MDBuilder(*C).createBranchWeights(1, 100000),
891  (DomTreeUpdater *)nullptr, nullptr,
892  CheckFailTerm->getParent());
893 
894  IRB.SetInsertPoint(CheckFailTerm);
895  InlineAsm *Asm;
896  switch (TargetTriple.getArch()) {
897  case Triple::x86_64:
898  // The signal handler will find the data address in rdi.
900  FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
901  "int3\nnopl " +
902  itostr(0x40 + (AccessInfo & HWASanAccessInfo::RuntimeMask)) +
903  "(%rax)",
904  "{rdi}",
905  /*hasSideEffects=*/true);
906  break;
907  case Triple::aarch64:
908  case Triple::aarch64_be:
909  // The signal handler will find the data address in x0.
911  FunctionType::get(IRB.getVoidTy(), {PtrLong->getType()}, false),
912  "brk #" + itostr(0x900 + (AccessInfo & HWASanAccessInfo::RuntimeMask)),
913  "{x0}",
914  /*hasSideEffects=*/true);
915  break;
916  default:
917  report_fatal_error("unsupported architecture");
918  }
919  IRB.CreateCall(Asm, PtrLong);
920  if (Recover)
921  cast<BranchInst>(CheckFailTerm)->setSuccessor(0, CheckTerm->getParent());
922 }
923 
924 bool HWAddressSanitizer::ignoreMemIntrinsic(MemIntrinsic *MI) {
925  if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI)) {
926  return (!ClInstrumentWrites || ignoreAccess(MTI, MTI->getDest())) &&
927  (!ClInstrumentReads || ignoreAccess(MTI, MTI->getSource()));
928  }
929  if (isa<MemSetInst>(MI))
930  return !ClInstrumentWrites || ignoreAccess(MI, MI->getDest());
931  return false;
932 }
933 
934 void HWAddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
935  IRBuilder<> IRB(MI);
936  if (isa<MemTransferInst>(MI)) {
937  IRB.CreateCall(
938  isa<MemMoveInst>(MI) ? HWAsanMemmove : HWAsanMemcpy,
939  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
940  IRB.CreatePointerCast(MI->getOperand(1), IRB.getInt8PtrTy()),
941  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
942  } else if (isa<MemSetInst>(MI)) {
943  IRB.CreateCall(
944  HWAsanMemset,
945  {IRB.CreatePointerCast(MI->getOperand(0), IRB.getInt8PtrTy()),
946  IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
947  IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)});
948  }
949  MI->eraseFromParent();
950 }
951 
952 bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O) {
953  Value *Addr = O.getPtr();
954 
955  LLVM_DEBUG(dbgs() << "Instrumenting: " << O.getInsn() << "\n");
956 
957  if (O.MaybeMask)
958  return false; // FIXME
959 
960  IRBuilder<> IRB(O.getInsn());
961  if (isPowerOf2_64(O.TypeSize) &&
962  (O.TypeSize / 8 <= (1ULL << (kNumberOfAccessSizes - 1))) &&
963  (!O.Alignment || *O.Alignment >= Mapping.getObjectAlignment() ||
964  *O.Alignment >= O.TypeSize / 8)) {
965  size_t AccessSizeIndex = TypeSizeToSizeIndex(O.TypeSize);
966  if (InstrumentWithCalls) {
967  IRB.CreateCall(HwasanMemoryAccessCallback[O.IsWrite][AccessSizeIndex],
968  IRB.CreatePointerCast(Addr, IntptrTy));
969  } else if (OutlinedChecks) {
970  instrumentMemAccessOutline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn());
971  } else {
972  instrumentMemAccessInline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn());
973  }
974  } else {
975  IRB.CreateCall(HwasanMemoryAccessCallbackSized[O.IsWrite],
976  {IRB.CreatePointerCast(Addr, IntptrTy),
977  ConstantInt::get(IntptrTy, O.TypeSize / 8)});
978  }
979  untagPointerOperand(O.getInsn(), Addr);
980 
981  return true;
982 }
983 
984 void HWAddressSanitizer::tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag,
985  size_t Size) {
986  size_t AlignedSize = alignTo(Size, Mapping.getObjectAlignment());
987  if (!UseShortGranules)
988  Size = AlignedSize;
989 
990  Value *JustTag = IRB.CreateTrunc(Tag, IRB.getInt8Ty());
991  if (InstrumentWithCalls) {
992  IRB.CreateCall(HwasanTagMemoryFunc,
993  {IRB.CreatePointerCast(AI, Int8PtrTy), JustTag,
994  ConstantInt::get(IntptrTy, AlignedSize)});
995  } else {
996  size_t ShadowSize = Size >> Mapping.Scale;
997  Value *ShadowPtr = memToShadow(IRB.CreatePointerCast(AI, IntptrTy), IRB);
998  // If this memset is not inlined, it will be intercepted in the hwasan
999  // runtime library. That's OK, because the interceptor skips the checks if
1000  // the address is in the shadow region.
1001  // FIXME: the interceptor is not as fast as real memset. Consider lowering
1002  // llvm.memset right here into either a sequence of stores, or a call to
1003  // hwasan_tag_memory.
1004  if (ShadowSize)
1005  IRB.CreateMemSet(ShadowPtr, JustTag, ShadowSize, Align(1));
1006  if (Size != AlignedSize) {
1007  const uint8_t SizeRemainder = Size % Mapping.getObjectAlignment().value();
1008  IRB.CreateStore(ConstantInt::get(Int8Ty, SizeRemainder),
1009  IRB.CreateConstGEP1_32(Int8Ty, ShadowPtr, ShadowSize));
1010  IRB.CreateStore(JustTag, IRB.CreateConstGEP1_32(
1011  Int8Ty, IRB.CreateBitCast(AI, Int8PtrTy),
1012  AlignedSize - 1));
1013  }
1014  }
1015 }
1016 
1017 unsigned HWAddressSanitizer::retagMask(unsigned AllocaNo) {
1018  if (TargetTriple.getArch() == Triple::x86_64)
1019  return AllocaNo & TagMaskByte;
1020 
1021  // A list of 8-bit numbers that have at most one run of non-zero bits.
1022  // x = x ^ (mask << 56) can be encoded as a single armv8 instruction for these
1023  // masks.
1024  // The list does not include the value 255, which is used for UAR.
1025  //
1026  // Because we are more likely to use earlier elements of this list than later
1027  // ones, it is sorted in increasing order of probability of collision with a
1028  // mask allocated (temporally) nearby. The program that generated this list
1029  // can be found at:
1030  // https://github.com/google/sanitizers/blob/master/hwaddress-sanitizer/sort_masks.py
1031  static unsigned FastMasks[] = {0, 128, 64, 192, 32, 96, 224, 112, 240,
1032  48, 16, 120, 248, 56, 24, 8, 124, 252,
1033  60, 28, 12, 4, 126, 254, 62, 30, 14,
1034  6, 2, 127, 63, 31, 15, 7, 3, 1};
1035  return FastMasks[AllocaNo % std::size(FastMasks)];
1036 }
1037 
1038 Value *HWAddressSanitizer::applyTagMask(IRBuilder<> &IRB, Value *OldTag) {
1039  if (TargetTriple.getArch() == Triple::x86_64) {
1040  Constant *TagMask = ConstantInt::get(IntptrTy, TagMaskByte);
1041  Value *NewTag = IRB.CreateAnd(OldTag, TagMask);
1042  return NewTag;
1043  }
1044  // aarch64 uses 8-bit tags, so no mask is needed.
1045  return OldTag;
1046 }
1047 
1048 Value *HWAddressSanitizer::getNextTagWithCall(IRBuilder<> &IRB) {
1049  return IRB.CreateZExt(IRB.CreateCall(HwasanGenerateTagFunc), IntptrTy);
1050 }
1051 
1052 Value *HWAddressSanitizer::getStackBaseTag(IRBuilder<> &IRB) {
1054  return getNextTagWithCall(IRB);
1055  if (StackBaseTag)
1056  return StackBaseTag;
1057  // Extract some entropy from the stack pointer for the tags.
1058  // Take bits 20..28 (ASLR entropy) and xor with bits 0..8 (these differ
1059  // between functions).
1060  Value *StackPointerLong = getSP(IRB);
1061  Value *StackTag =
1062  applyTagMask(IRB, IRB.CreateXor(StackPointerLong,
1063  IRB.CreateLShr(StackPointerLong, 20)));
1064  StackTag->setName("hwasan.stack.base.tag");
1065  return StackTag;
1066 }
1067 
1068 Value *HWAddressSanitizer::getAllocaTag(IRBuilder<> &IRB, Value *StackTag,
1069  AllocaInst *AI, unsigned AllocaNo) {
1071  return getNextTagWithCall(IRB);
1072  return IRB.CreateXor(StackTag,
1073  ConstantInt::get(IntptrTy, retagMask(AllocaNo)));
1074 }
1075 
1076 Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB, Value *StackTag) {
1077  if (ClUARRetagToZero)
1078  return ConstantInt::get(IntptrTy, 0);
1080  return getNextTagWithCall(IRB);
1081  return IRB.CreateXor(StackTag, ConstantInt::get(IntptrTy, TagMaskByte));
1082 }
1083 
1084 // Add a tag to an address.
1085 Value *HWAddressSanitizer::tagPointer(IRBuilder<> &IRB, Type *Ty,
1086  Value *PtrLong, Value *Tag) {
1087  assert(!UsePageAliases);
1088  Value *TaggedPtrLong;
1089  if (CompileKernel) {
1090  // Kernel addresses have 0xFF in the most significant byte.
1091  Value *ShiftedTag =
1092  IRB.CreateOr(IRB.CreateShl(Tag, PointerTagShift),
1093  ConstantInt::get(IntptrTy, (1ULL << PointerTagShift) - 1));
1094  TaggedPtrLong = IRB.CreateAnd(PtrLong, ShiftedTag);
1095  } else {
1096  // Userspace can simply do OR (tag << PointerTagShift);
1097  Value *ShiftedTag = IRB.CreateShl(Tag, PointerTagShift);
1098  TaggedPtrLong = IRB.CreateOr(PtrLong, ShiftedTag);
1099  }
1100  return IRB.CreateIntToPtr(TaggedPtrLong, Ty);
1101 }
1102 
1103 // Remove tag from an address.
1104 Value *HWAddressSanitizer::untagPointer(IRBuilder<> &IRB, Value *PtrLong) {
1105  assert(!UsePageAliases);
1106  Value *UntaggedPtrLong;
1107  if (CompileKernel) {
1108  // Kernel addresses have 0xFF in the most significant byte.
1109  UntaggedPtrLong =
1110  IRB.CreateOr(PtrLong, ConstantInt::get(PtrLong->getType(),
1111  0xFFULL << PointerTagShift));
1112  } else {
1113  // Userspace addresses have 0x00.
1114  UntaggedPtrLong =
1115  IRB.CreateAnd(PtrLong, ConstantInt::get(PtrLong->getType(),
1116  ~(0xFFULL << PointerTagShift)));
1117  }
1118  return UntaggedPtrLong;
1119 }
1120 
1121 Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB, Type *Ty) {
1122  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
1123  if (TargetTriple.isAArch64() && TargetTriple.isAndroid()) {
1124  // Android provides a fixed TLS slot for sanitizers. See TLS_SLOT_SANITIZER
1125  // in Bionic's libc/private/bionic_tls.h.
1126  Function *ThreadPointerFunc =
1127  Intrinsic::getDeclaration(M, Intrinsic::thread_pointer);
1128  Value *SlotPtr = IRB.CreatePointerCast(
1129  IRB.CreateConstGEP1_32(IRB.getInt8Ty(),
1130  IRB.CreateCall(ThreadPointerFunc), 0x30),
1131  Ty->getPointerTo(0));
1132  return SlotPtr;
1133  }
1134  if (ThreadPtrGlobal)
1135  return ThreadPtrGlobal;
1136 
1137  return nullptr;
1138 }
1139 
1140 Value *HWAddressSanitizer::getPC(IRBuilder<> &IRB) {
1141  if (TargetTriple.getArch() == Triple::aarch64)
1142  return readRegister(IRB, "pc");
1143  else
1144  return IRB.CreatePtrToInt(IRB.GetInsertBlock()->getParent(), IntptrTy);
1145 }
1146 
1147 Value *HWAddressSanitizer::getSP(IRBuilder<> &IRB) {
1148  if (!CachedSP) {
1149  // FIXME: use addressofreturnaddress (but implement it in aarch64 backend
1150  // first).
1151  Function *F = IRB.GetInsertBlock()->getParent();
1152  Module *M = F->getParent();
1153  auto GetStackPointerFn = Intrinsic::getDeclaration(
1154  M, Intrinsic::frameaddress,
1155  IRB.getInt8PtrTy(M->getDataLayout().getAllocaAddrSpace()));
1156  CachedSP = IRB.CreatePtrToInt(
1157  IRB.CreateCall(GetStackPointerFn,
1158  {Constant::getNullValue(IRB.getInt32Ty())}),
1159  IntptrTy);
1160  }
1161  return CachedSP;
1162 }
1163 
1164 Value *HWAddressSanitizer::getFrameRecordInfo(IRBuilder<> &IRB) {
1165  // Prepare ring buffer data.
1166  Value *PC = getPC(IRB);
1167  Value *SP = getSP(IRB);
1168 
1169  // Mix SP and PC.
1170  // Assumptions:
1171  // PC is 0x0000PPPPPPPPPPPP (48 bits are meaningful, others are zero)
1172  // SP is 0xsssssssssssSSSS0 (4 lower bits are zero)
1173  // We only really need ~20 lower non-zero bits (SSSS), so we mix like this:
1174  // 0xSSSSPPPPPPPPPPPP
1175  SP = IRB.CreateShl(SP, 44);
1176  return IRB.CreateOr(PC, SP);
1177 }
1178 
1179 void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
1180  if (!Mapping.InTls)
1181  ShadowBase = getShadowNonTls(IRB);
1182  else if (!WithFrameRecord && TargetTriple.isAndroid())
1183  ShadowBase = getDynamicShadowIfunc(IRB);
1184 
1185  if (!WithFrameRecord && ShadowBase)
1186  return;
1187 
1188  Value *SlotPtr = nullptr;
1189  Value *ThreadLong = nullptr;
1190  Value *ThreadLongMaybeUntagged = nullptr;
1191 
1192  auto getThreadLongMaybeUntagged = [&]() {
1193  if (!SlotPtr)
1194  SlotPtr = getHwasanThreadSlotPtr(IRB, IntptrTy);
1195  if (!ThreadLong)
1196  ThreadLong = IRB.CreateLoad(IntptrTy, SlotPtr);
1197  // Extract the address field from ThreadLong. Unnecessary on AArch64 with
1198  // TBI.
1199  return TargetTriple.isAArch64() ? ThreadLong
1200  : untagPointer(IRB, ThreadLong);
1201  };
1202 
1203  if (WithFrameRecord) {
1204  switch (ClRecordStackHistory) {
1205  case libcall: {
1206  // Emit a runtime call into hwasan rather than emitting instructions for
1207  // recording stack history.
1208  Value *FrameRecordInfo = getFrameRecordInfo(IRB);
1209  IRB.CreateCall(HwasanRecordFrameRecordFunc, {FrameRecordInfo});
1210  break;
1211  }
1212  case instr: {
1213  ThreadLongMaybeUntagged = getThreadLongMaybeUntagged();
1214 
1215  StackBaseTag = IRB.CreateAShr(ThreadLong, 3);
1216 
1217  // Store data to ring buffer.
1218  Value *FrameRecordInfo = getFrameRecordInfo(IRB);
1219  Value *RecordPtr = IRB.CreateIntToPtr(ThreadLongMaybeUntagged,
1220  IntptrTy->getPointerTo(0));
1221  IRB.CreateStore(FrameRecordInfo, RecordPtr);
1222 
1223  // Update the ring buffer. Top byte of ThreadLong defines the size of the
1224  // buffer in pages, it must be a power of two, and the start of the buffer
1225  // must be aligned by twice that much. Therefore wrap around of the ring
1226  // buffer is simply Addr &= ~((ThreadLong >> 56) << 12).
1227  // The use of AShr instead of LShr is due to
1228  // https://bugs.llvm.org/show_bug.cgi?id=39030
1229  // Runtime library makes sure not to use the highest bit.
1230  Value *WrapMask = IRB.CreateXor(
1231  IRB.CreateShl(IRB.CreateAShr(ThreadLong, 56), 12, "", true, true),
1232  ConstantInt::get(IntptrTy, (uint64_t)-1));
1233  Value *ThreadLongNew = IRB.CreateAnd(
1234  IRB.CreateAdd(ThreadLong, ConstantInt::get(IntptrTy, 8)), WrapMask);
1235  IRB.CreateStore(ThreadLongNew, SlotPtr);
1236  break;
1237  }
1238  case none: {
1240  "A stack history recording mode should've been selected.");
1241  }
1242  }
1243  }
1244 
1245  if (!ShadowBase) {
1246  if (!ThreadLongMaybeUntagged)
1247  ThreadLongMaybeUntagged = getThreadLongMaybeUntagged();
1248 
1249  // Get shadow base address by aligning RecordPtr up.
1250  // Note: this is not correct if the pointer is already aligned.
1251  // Runtime library will make sure this never happens.
1252  ShadowBase = IRB.CreateAdd(
1253  IRB.CreateOr(
1254  ThreadLongMaybeUntagged,
1255  ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
1256  ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
1257  ShadowBase = IRB.CreateIntToPtr(ShadowBase, Int8PtrTy);
1258  }
1259 }
1260 
1261 Value *HWAddressSanitizer::readRegister(IRBuilder<> &IRB, StringRef Name) {
1262  Module *M = IRB.GetInsertBlock()->getParent()->getParent();
1263  Function *ReadRegister =
1264  Intrinsic::getDeclaration(M, Intrinsic::read_register, IntptrTy);
1265  MDNode *MD = MDNode::get(*C, {MDString::get(*C, Name)});
1266  Value *Args[] = {MetadataAsValue::get(*C, MD)};
1267  return IRB.CreateCall(ReadRegister, Args);
1268 }
1269 
1270 bool HWAddressSanitizer::instrumentLandingPads(
1271  SmallVectorImpl<Instruction *> &LandingPadVec) {
1272  for (auto *LP : LandingPadVec) {
1273  IRBuilder<> IRB(LP->getNextNode());
1274  IRB.CreateCall(
1275  HWAsanHandleVfork,
1276  {readRegister(IRB, (TargetTriple.getArch() == Triple::x86_64) ? "rsp"
1277  : "sp")});
1278  }
1279  return true;
1280 }
1281 
1282 static bool isLifetimeIntrinsic(Value *V) {
1283  auto *II = dyn_cast<IntrinsicInst>(V);
1284  return II && II->isLifetimeStartOrEnd();
1285 }
1286 
1287 bool HWAddressSanitizer::instrumentStack(memtag::StackInfo &SInfo,
1288  Value *StackTag,
1289  const DominatorTree &DT,
1290  const PostDominatorTree &PDT,
1291  const LoopInfo &LI) {
1292  // Ideally, we want to calculate tagged stack base pointer, and rewrite all
1293  // alloca addresses using that. Unfortunately, offsets are not known yet
1294  // (unless we use ASan-style mega-alloca). Instead we keep the base tag in a
1295  // temp, shift-OR it into each alloca address and xor with the retag mask.
1296  // This generates one extra instruction per alloca use.
1297  unsigned int I = 0;
1298 
1299  for (auto &KV : SInfo.AllocasToInstrument) {
1300  auto N = I++;
1301  auto *AI = KV.first;
1302  memtag::AllocaInfo &Info = KV.second;
1303  IRBuilder<> IRB(AI->getNextNode());
1304 
1305  // Replace uses of the alloca with tagged address.
1306  Value *Tag = getAllocaTag(IRB, StackTag, AI, N);
1307  Value *AILong = IRB.CreatePointerCast(AI, IntptrTy);
1308  Value *Replacement = tagPointer(IRB, AI->getType(), AILong, Tag);
1309  std::string Name =
1310  AI->hasName() ? AI->getName().str() : "alloca." + itostr(N);
1311  Replacement->setName(Name + ".hwasan");
1312 
1313  size_t Size = memtag::getAllocaSizeInBytes(*AI);
1314  size_t AlignedSize = alignTo(Size, Mapping.getObjectAlignment());
1315 
1316  Value *AICast = IRB.CreatePointerCast(AI, Int8PtrTy);
1317 
1318  auto HandleLifetime = [&](IntrinsicInst *II) {
1319  // Set the lifetime intrinsic to cover the whole alloca. This reduces the
1320  // set of assumptions we need to make about the lifetime. Without this we
1321  // would need to ensure that we can track the lifetime pointer to a
1322  // constant offset from the alloca, and would still need to change the
1323  // size to include the extra alignment we use for the untagging to make
1324  // the size consistent.
1325  //
1326  // The check for standard lifetime below makes sure that we have exactly
1327  // one set of start / end in any execution (i.e. the ends are not
1328  // reachable from each other), so this will not cause any problems.
1329  II->setArgOperand(0, ConstantInt::get(Int64Ty, AlignedSize));
1330  II->setArgOperand(1, AICast);
1331  };
1332  llvm::for_each(Info.LifetimeStart, HandleLifetime);
1333  llvm::for_each(Info.LifetimeEnd, HandleLifetime);
1334 
1335  AI->replaceUsesWithIf(Replacement, [AICast, AILong](Use &U) {
1336  auto *User = U.getUser();
1337  return User != AILong && User != AICast && !isLifetimeIntrinsic(User);
1338  });
1339 
1340  for (auto *DDI : Info.DbgVariableIntrinsics) {
1341  // Prepend "tag_offset, N" to the dwarf expression.
1342  // Tag offset logically applies to the alloca pointer, and it makes sense
1343  // to put it at the beginning of the expression.
1345  retagMask(N)};
1346  for (size_t LocNo = 0; LocNo < DDI->getNumVariableLocationOps(); ++LocNo)
1347  if (DDI->getVariableLocationOp(LocNo) == AI)
1348  DDI->setExpression(DIExpression::appendOpsToArg(DDI->getExpression(),
1349  NewOps, LocNo));
1350  }
1351 
1352  auto TagEnd = [&](Instruction *Node) {
1353  IRB.SetInsertPoint(Node);
1354  Value *UARTag = getUARTag(IRB, StackTag);
1355  // When untagging, use the `AlignedSize` because we need to set the tags
1356  // for the entire alloca to zero. If we used `Size` here, we would
1357  // keep the last granule tagged, and store zero in the last byte of the
1358  // last granule, due to how short granules are implemented.
1359  tagAlloca(IRB, AI, UARTag, AlignedSize);
1360  };
1361  // Calls to functions that may return twice (e.g. setjmp) confuse the
1362  // postdominator analysis, and will leave us to keep memory tagged after
1363  // function return. Work around this by always untagging at every return
1364  // statement if return_twice functions are called.
1365  bool StandardLifetime =
1366  SInfo.UnrecognizedLifetimes.empty() &&
1367  memtag::isStandardLifetime(Info.LifetimeStart, Info.LifetimeEnd, &DT,
1368  &LI, ClMaxLifetimes) &&
1369  !SInfo.CallsReturnTwice;
1370  if (DetectUseAfterScope && StandardLifetime) {
1371  IntrinsicInst *Start = Info.LifetimeStart[0];
1372  IRB.SetInsertPoint(Start->getNextNode());
1373  tagAlloca(IRB, AI, Tag, Size);
1374  if (!memtag::forAllReachableExits(DT, PDT, LI, Start, Info.LifetimeEnd,
1375  SInfo.RetVec, TagEnd)) {
1376  for (auto *End : Info.LifetimeEnd)
1377  End->eraseFromParent();
1378  }
1379  } else {
1380  tagAlloca(IRB, AI, Tag, Size);
1381  for (auto *RI : SInfo.RetVec)
1382  TagEnd(RI);
1383  // We inserted tagging outside of the lifetimes, so we have to remove
1384  // them.
1385  for (auto &II : Info.LifetimeStart)
1386  II->eraseFromParent();
1387  for (auto &II : Info.LifetimeEnd)
1388  II->eraseFromParent();
1389  }
1390  memtag::alignAndPadAlloca(Info, Mapping.getObjectAlignment());
1391  }
1392  for (auto &I : SInfo.UnrecognizedLifetimes)
1393  I->eraseFromParent();
1394  return true;
1395 }
1396 
1397 bool HWAddressSanitizer::sanitizeFunction(Function &F,
1399  if (&F == HwasanCtorFunction)
1400  return false;
1401 
1402  if (!F.hasFnAttribute(Attribute::SanitizeHWAddress))
1403  return false;
1404 
1405  LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n");
1406 
1407  SmallVector<InterestingMemoryOperand, 16> OperandsToInstrument;
1408  SmallVector<MemIntrinsic *, 16> IntrinToInstrument;
1409  SmallVector<Instruction *, 8> LandingPadVec;
1410 
1411  memtag::StackInfoBuilder SIB(SSI);
1412  for (auto &Inst : instructions(F)) {
1413  if (InstrumentStack) {
1414  SIB.visit(Inst);
1415  }
1416 
1417  if (InstrumentLandingPads && isa<LandingPadInst>(Inst))
1418  LandingPadVec.push_back(&Inst);
1419 
1420  getInterestingMemoryOperands(&Inst, OperandsToInstrument);
1421 
1422  if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(&Inst))
1423  if (!ignoreMemIntrinsic(MI))
1424  IntrinToInstrument.push_back(MI);
1425  }
1426 
1427  memtag::StackInfo &SInfo = SIB.get();
1428 
1429  initializeCallbacks(*F.getParent());
1430 
1431  bool Changed = false;
1432 
1433  if (!LandingPadVec.empty())
1434  Changed |= instrumentLandingPads(LandingPadVec);
1435 
1436  if (SInfo.AllocasToInstrument.empty() && F.hasPersonalityFn() &&
1437  F.getPersonalityFn()->getName() == kHwasanPersonalityThunkName) {
1438  // __hwasan_personality_thunk is a no-op for functions without an
1439  // instrumented stack, so we can drop it.
1440  F.setPersonalityFn(nullptr);
1441  Changed = true;
1442  }
1443 
1444  if (SInfo.AllocasToInstrument.empty() && OperandsToInstrument.empty() &&
1445  IntrinToInstrument.empty())
1446  return Changed;
1447 
1448  assert(!ShadowBase);
1449 
1450  Instruction *InsertPt = &*F.getEntryBlock().begin();
1451  IRBuilder<> EntryIRB(InsertPt);
1452  emitPrologue(EntryIRB,
1453  /*WithFrameRecord*/ ClRecordStackHistory != none &&
1454  Mapping.WithFrameRecord &&
1455  !SInfo.AllocasToInstrument.empty());
1456 
1457  if (!SInfo.AllocasToInstrument.empty()) {
1460  const LoopInfo &LI = FAM.getResult<LoopAnalysis>(F);
1461  Value *StackTag =
1462  ClGenerateTagsWithCalls ? nullptr : getStackBaseTag(EntryIRB);
1463  instrumentStack(SInfo, StackTag, DT, PDT, LI);
1464  }
1465 
1466  // If we split the entry block, move any allocas that were originally in the
1467  // entry block back into the entry block so that they aren't treated as
1468  // dynamic allocas.
1469  if (EntryIRB.GetInsertBlock() != &F.getEntryBlock()) {
1470  InsertPt = &*F.getEntryBlock().begin();
1471  for (Instruction &I :
1472  llvm::make_early_inc_range(*EntryIRB.GetInsertBlock())) {
1473  if (auto *AI = dyn_cast<AllocaInst>(&I))
1474  if (isa<ConstantInt>(AI->getArraySize()))
1475  I.moveBefore(InsertPt);
1476  }
1477  }
1478 
1479  for (auto &Operand : OperandsToInstrument)
1480  instrumentMemAccess(Operand);
1481 
1482  if (ClInstrumentMemIntrinsics && !IntrinToInstrument.empty()) {
1483  for (auto *Inst : IntrinToInstrument)
1484  instrumentMemIntrinsic(Inst);
1485  }
1486 
1487  ShadowBase = nullptr;
1488  StackBaseTag = nullptr;
1489  CachedSP = nullptr;
1490 
1491  return true;
1492 }
1493 
1494 void HWAddressSanitizer::instrumentGlobal(GlobalVariable *GV, uint8_t Tag) {
1495  assert(!UsePageAliases);
1496  Constant *Initializer = GV->getInitializer();
1497  uint64_t SizeInBytes =
1498  M.getDataLayout().getTypeAllocSize(Initializer->getType());
1499  uint64_t NewSize = alignTo(SizeInBytes, Mapping.getObjectAlignment());
1500  if (SizeInBytes != NewSize) {
1501  // Pad the initializer out to the next multiple of 16 bytes and add the
1502  // required short granule tag.
1503  std::vector<uint8_t> Init(NewSize - SizeInBytes, 0);
1504  Init.back() = Tag;
1506  Initializer = ConstantStruct::getAnon({Initializer, Padding});
1507  }
1508 
1509  auto *NewGV = new GlobalVariable(M, Initializer->getType(), GV->isConstant(),
1510  GlobalValue::ExternalLinkage, Initializer,
1511  GV->getName() + ".hwasan");
1512  NewGV->copyAttributesFrom(GV);
1513  NewGV->setLinkage(GlobalValue::PrivateLinkage);
1514  NewGV->copyMetadata(GV, 0);
1515  NewGV->setAlignment(
1516  std::max(GV->getAlign().valueOrOne(), Mapping.getObjectAlignment()));
1517 
1518  // It is invalid to ICF two globals that have different tags. In the case
1519  // where the size of the global is a multiple of the tag granularity the
1520  // contents of the globals may be the same but the tags (i.e. symbol values)
1521  // may be different, and the symbols are not considered during ICF. In the
1522  // case where the size is not a multiple of the granularity, the short granule
1523  // tags would discriminate two globals with different tags, but there would
1524  // otherwise be nothing stopping such a global from being incorrectly ICF'd
1525  // with an uninstrumented (i.e. tag 0) global that happened to have the short
1526  // granule tag in the last byte.
1527  NewGV->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
1528 
1529  // Descriptor format (assuming little-endian):
1530  // bytes 0-3: relative address of global
1531  // bytes 4-6: size of global (16MB ought to be enough for anyone, but in case
1532  // it isn't, we create multiple descriptors)
1533  // byte 7: tag
1534  auto *DescriptorTy = StructType::get(Int32Ty, Int32Ty);
1535  const uint64_t MaxDescriptorSize = 0xfffff0;
1536  for (uint64_t DescriptorPos = 0; DescriptorPos < SizeInBytes;
1537  DescriptorPos += MaxDescriptorSize) {
1538  auto *Descriptor =
1539  new GlobalVariable(M, DescriptorTy, true, GlobalValue::PrivateLinkage,
1540  nullptr, GV->getName() + ".hwasan.descriptor");
1541  auto *GVRelPtr = ConstantExpr::getTrunc(
1544  ConstantExpr::getPtrToInt(NewGV, Int64Ty),
1545  ConstantExpr::getPtrToInt(Descriptor, Int64Ty)),
1546  ConstantInt::get(Int64Ty, DescriptorPos)),
1547  Int32Ty);
1548  uint32_t Size = std::min(SizeInBytes - DescriptorPos, MaxDescriptorSize);
1549  auto *SizeAndTag = ConstantInt::get(Int32Ty, Size | (uint32_t(Tag) << 24));
1550  Descriptor->setComdat(NewGV->getComdat());
1551  Descriptor->setInitializer(ConstantStruct::getAnon({GVRelPtr, SizeAndTag}));
1552  Descriptor->setSection("hwasan_globals");
1553  Descriptor->setMetadata(LLVMContext::MD_associated,
1554  MDNode::get(*C, ValueAsMetadata::get(NewGV)));
1555  appendToCompilerUsed(M, Descriptor);
1556  }
1557 
1560  ConstantExpr::getPtrToInt(NewGV, Int64Ty),
1561  ConstantInt::get(Int64Ty, uint64_t(Tag) << PointerTagShift)),
1562  GV->getType());
1564  GV->getLinkage(), "", Aliasee, &M);
1565  Alias->setVisibility(GV->getVisibility());
1566  Alias->takeName(GV);
1568  GV->eraseFromParent();
1569 }
1570 
1571 void HWAddressSanitizer::instrumentGlobals() {
1572  std::vector<GlobalVariable *> Globals;
1573  for (GlobalVariable &GV : M.globals()) {
1575  continue;
1576 
1577  if (GV.isDeclarationForLinker() || GV.getName().startswith("llvm.") ||
1578  GV.isThreadLocal())
1579  continue;
1580 
1581  // Common symbols can't have aliases point to them, so they can't be tagged.
1582  if (GV.hasCommonLinkage())
1583  continue;
1584 
1585  // Globals with custom sections may be used in __start_/__stop_ enumeration,
1586  // which would be broken both by adding tags and potentially by the extra
1587  // padding/alignment that we insert.
1588  if (GV.hasSection())
1589  continue;
1590 
1591  Globals.push_back(&GV);
1592  }
1593 
1594  MD5 Hasher;
1595  Hasher.update(M.getSourceFileName());
1596  MD5::MD5Result Hash;
1597  Hasher.final(Hash);
1598  uint8_t Tag = Hash[0];
1599 
1600  for (GlobalVariable *GV : Globals) {
1601  Tag &= TagMaskByte;
1602  // Skip tag 0 in order to avoid collisions with untagged memory.
1603  if (Tag == 0)
1604  Tag = 1;
1605  instrumentGlobal(GV, Tag++);
1606  }
1607 }
1608 
1609 void HWAddressSanitizer::instrumentPersonalityFunctions() {
1610  // We need to untag stack frames as we unwind past them. That is the job of
1611  // the personality function wrapper, which either wraps an existing
1612  // personality function or acts as a personality function on its own. Each
1613  // function that has a personality function or that can be unwound past has
1614  // its personality function changed to a thunk that calls the personality
1615  // function wrapper in the runtime.
1617  for (Function &F : M) {
1618  if (F.isDeclaration() || !F.hasFnAttribute(Attribute::SanitizeHWAddress))
1619  continue;
1620 
1621  if (F.hasPersonalityFn()) {
1622  PersonalityFns[F.getPersonalityFn()->stripPointerCasts()].push_back(&F);
1623  } else if (!F.hasFnAttribute(Attribute::NoUnwind)) {
1624  PersonalityFns[nullptr].push_back(&F);
1625  }
1626  }
1627 
1628  if (PersonalityFns.empty())
1629  return;
1630 
1631  FunctionCallee HwasanPersonalityWrapper = M.getOrInsertFunction(
1632  "__hwasan_personality_wrapper", Int32Ty, Int32Ty, Int32Ty, Int64Ty,
1633  Int8PtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy);
1634  FunctionCallee UnwindGetGR = M.getOrInsertFunction("_Unwind_GetGR", VoidTy);
1635  FunctionCallee UnwindGetCFA = M.getOrInsertFunction("_Unwind_GetCFA", VoidTy);
1636 
1637  for (auto &P : PersonalityFns) {
1638  std::string ThunkName = kHwasanPersonalityThunkName;
1639  if (P.first)
1640  ThunkName += ("." + P.first->getName()).str();
1641  FunctionType *ThunkFnTy = FunctionType::get(
1642  Int32Ty, {Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int8PtrTy}, false);
1643  bool IsLocal = P.first && (!isa<GlobalValue>(P.first) ||
1644  cast<GlobalValue>(P.first)->hasLocalLinkage());
1645  auto *ThunkFn = Function::Create(ThunkFnTy,
1648  ThunkName, &M);
1649  if (!IsLocal) {
1650  ThunkFn->setVisibility(GlobalValue::HiddenVisibility);
1651  ThunkFn->setComdat(M.getOrInsertComdat(ThunkName));
1652  }
1653 
1654  auto *BB = BasicBlock::Create(*C, "entry", ThunkFn);
1655  IRBuilder<> IRB(BB);
1656  CallInst *WrapperCall = IRB.CreateCall(
1657  HwasanPersonalityWrapper,
1658  {ThunkFn->getArg(0), ThunkFn->getArg(1), ThunkFn->getArg(2),
1659  ThunkFn->getArg(3), ThunkFn->getArg(4),
1660  P.first ? IRB.CreateBitCast(P.first, Int8PtrTy)
1661  : Constant::getNullValue(Int8PtrTy),
1662  IRB.CreateBitCast(UnwindGetGR.getCallee(), Int8PtrTy),
1663  IRB.CreateBitCast(UnwindGetCFA.getCallee(), Int8PtrTy)});
1664  WrapperCall->setTailCall();
1665  IRB.CreateRet(WrapperCall);
1666 
1667  for (Function *F : P.second)
1668  F->setPersonalityFn(ThunkFn);
1669  }
1670 }
1671 
1673  bool InstrumentWithCalls) {
1674  Scale = kDefaultShadowScale;
1675  if (TargetTriple.isOSFuchsia()) {
1676  // Fuchsia is always PIE, which means that the beginning of the address
1677  // space is always available.
1678  InGlobal = false;
1679  InTls = false;
1680  Offset = 0;
1681  WithFrameRecord = true;
1682  } else if (ClMappingOffset.getNumOccurrences() > 0) {
1683  InGlobal = false;
1684  InTls = false;
1686  WithFrameRecord = false;
1687  } else if (ClEnableKhwasan || InstrumentWithCalls) {
1688  InGlobal = false;
1689  InTls = false;
1690  Offset = 0;
1691  WithFrameRecord = false;
1692  } else if (ClWithIfunc) {
1693  InGlobal = true;
1694  InTls = false;
1696  WithFrameRecord = false;
1697  } else if (ClWithTls) {
1698  InGlobal = false;
1699  InTls = true;
1701  WithFrameRecord = true;
1702  } else {
1703  InGlobal = false;
1704  InTls = false;
1706  WithFrameRecord = false;
1707  }
1708 }
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:2060
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:512
llvm::IRBuilderBase::CreateStore
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition: IRBuilder.h:1701
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:109
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:180
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:1679
llvm::MD5::update
void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
Definition: MD5.cpp:189
llvm::HWASanAccessInfo::IsWriteShift
@ IsWriteShift
Definition: HWAddressSanitizer.h:59
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::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:1108
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:1981
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:1431
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:1409
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:139
llvm::dwarf::DW_OP_LLVM_tag_offset
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
Definition: Dwarf.h:145
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:155
llvm::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:1043
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:1368
llvm::cl::ReallyHidden
@ ReallyHidden
Definition: CommandLine.h:140
clEnumVal
#define clEnumVal(ENUMVAL, DESC)
Definition: CommandLine.h:677
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:1986
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:160
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:1512
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:1764
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:580
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:1688
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:7966
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:1600
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:502
llvm::appendToCompilerUsed
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
Definition: ModuleUtils.cpp:111
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:52
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:205
llvm::cl::Option::getNumOccurrences
int getNumOccurrences() const
Definition: CommandLine.h:402
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
llvm::HWASanAccessInfo::RecoverShift
@ RecoverShift
Definition: HWAddressSanitizer.h:60
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::RuntimeMask
@ RuntimeMask
Definition: HWAddressSanitizer.h:66
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:1002
Type.h
llvm::IRBuilderBase::CreateAnd
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition: IRBuilder.h:1387
llvm::IRBuilderBase::CreatePointerCast
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:2037
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:1899
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:1411
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:1991
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:704
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:419
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:1727
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::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:128
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:560
StringExtras.h
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:446
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:1239
llvm::MDString::get
static MDString * get(LLVMContext &Context, StringRef Str)
Definition: Metadata.cpp:498
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::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
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:838
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:2117
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:1779
llvm::Intrinsic::getDeclaration
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1481
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:115
llvm::IRBuilderBase::CreateTrunc
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
Definition: IRBuilder.h:1895
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:140
llvm::Type::getInt64Ty
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:240
getPointerOperandIndex
static unsigned getPointerOperandIndex(Instruction *I)
Definition: HWAddressSanitizer.cpp:778
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::HWASanAccessInfo::CompileKernelShift
@ CompileKernelShift
Definition: HWAddressSanitizer.h:63
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:174
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:47
llvm::HWASanAccessInfo::AccessSizeShift
@ AccessSizeShift
Definition: HWAddressSanitizer.h:58
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:271
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::HWASanAccessInfo::MatchAllShift
@ MatchAllShift
Definition: HWAddressSanitizer.h:61
llvm::IRBuilderBase::CreateCall
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition: IRBuilder.h:2276
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:1349
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:1328
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:791
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:2113
llvm::IRBuilderBase::getVoidTy
Type * getVoidTy()
Fetch the type representing void.
Definition: IRBuilder.h:550
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:2109
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:1524
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:67
llvm::cl::desc
Definition: CommandLine.h:412
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))
llvm::HWASanAccessInfo::HasMatchAllShift
@ HasMatchAllShift
Definition: HWAddressSanitizer.h:62
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::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:4653
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