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