LLVM 24.0.0git
HWAddressSanitizer.cpp
Go to the documentation of this file.
1//===- HWAddressSanitizer.cpp - memory access error detector --------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// This file is a part of HWAddressSanitizer, an address basic correctness
11/// checker based on tagged addressing.
12//===----------------------------------------------------------------------===//
13
16#include "llvm/ADT/MapVector.h"
17#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/Statistic.h"
21#include "llvm/ADT/StringRef.h"
33#include "llvm/IR/Attributes.h"
34#include "llvm/IR/BasicBlock.h"
35#include "llvm/IR/Constant.h"
36#include "llvm/IR/Constants.h"
37#include "llvm/IR/DataLayout.h"
39#include "llvm/IR/Dominators.h"
40#include "llvm/IR/Function.h"
41#include "llvm/IR/IRBuilder.h"
42#include "llvm/IR/InlineAsm.h"
44#include "llvm/IR/Instruction.h"
47#include "llvm/IR/Intrinsics.h"
48#include "llvm/IR/LLVMContext.h"
49#include "llvm/IR/MDBuilder.h"
50#include "llvm/IR/Module.h"
51#include "llvm/IR/Type.h"
52#include "llvm/IR/Value.h"
55#include "llvm/Support/Debug.h"
57#include "llvm/Support/MD5.h"
68#include <optional>
69#include <random>
70
71using namespace llvm;
72
73#define DEBUG_TYPE "hwasan"
74
75const char kHwasanModuleCtorName[] = "hwasan.module_ctor";
76const char kHwasanNoteName[] = "hwasan.note";
77const char kHwasanInitName[] = "__hwasan_init";
78const char kHwasanPersonalityThunkName[] = "__hwasan_personality_thunk";
79
81 "__hwasan_shadow_memory_dynamic_address";
82
83// Accesses sizes are powers of two: 1, 2, 4, 8, 16.
84static const size_t kNumberOfAccessSizes = 5;
85
86static const size_t kDefaultShadowScale = 4;
87
88static const unsigned kShadowBaseAlignment = 32;
89
90namespace {
91enum class OffsetKind {
92 kFixed = 0,
93 kGlobal,
94 kIfunc,
95 kTls,
96};
97}
98
99// These flags allow to change the shadow mapping and control how shadow memory
100// is accessed. The shadow mapping looks like:
101// Shadow = (Mem >> scale) + offset
102
104 ClMappingOffset("hwasan-mapping-offset",
105 cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"),
106 cl::Hidden);
107
109 "hwasan-mapping-offset-dynamic",
110 cl::desc("HWASan shadow mapping dynamic offset location"), cl::Hidden,
111 cl::values(clEnumValN(OffsetKind::kGlobal, "global", "Use global"),
112 clEnumValN(OffsetKind::kIfunc, "ifunc", "Use ifunc global"),
113 clEnumValN(OffsetKind::kTls, "tls", "Use TLS")));
114
115STATISTIC(NumTotalFuncs, "Number of total funcs");
116STATISTIC(NumInstrumentedFuncs, "Number of instrumented funcs");
117STATISTIC(NumNoProfileSummaryFuncs, "Number of funcs without PS");
118
119namespace {
120
121bool shouldUsePageAliases(const InstrumentationOptions &Opts,
122 const Triple &TargetTriple) {
123 return Opts.hwasan_experimental_use_page_aliases &&
124 TargetTriple.getArch() == Triple::x86_64;
125}
126
127bool shouldInstrumentStack(const InstrumentationOptions &Opts,
128 const Triple &TargetTriple) {
129 return !shouldUsePageAliases(Opts, TargetTriple) &&
130 Opts.hwasan_instrument_stack;
131}
132
133bool shouldInstrumentWithCalls(const InstrumentationOptions &Opts,
134 const Triple &TargetTriple) {
135 return valueOr(Opts.hwasan_instrument_with_calls,
136 TargetTriple.getArch() == Triple::x86_64);
137}
138
139bool mightUseStackSafetyAnalysis(const InstrumentationOptions &Opts,
140 bool DisableOptimization) {
141 return valueOr(Opts.hwasan_use_stack_safety, !DisableOptimization);
142}
143
144bool shouldUseStackSafetyAnalysis(const InstrumentationOptions &Opts,
145 const Triple &TargetTriple,
146 bool DisableOptimization) {
147 return shouldInstrumentStack(Opts, TargetTriple) &&
148 mightUseStackSafetyAnalysis(Opts, DisableOptimization);
149}
150
151bool shouldDetectUseAfterScope(const InstrumentationOptions &Opts,
152 const Triple &TargetTriple) {
153 return Opts.hwasan_use_after_scope &&
154 shouldInstrumentStack(Opts, TargetTriple);
155}
156
157/// An instrumentation pass implementing detection of addressability bugs
158/// using tagged pointers.
159class HWAddressSanitizer {
160public:
161 HWAddressSanitizer(const InstrumentationOptions &Opts, Module &M,
162 bool CompileKernel, bool Recover,
163 const StackSafetyGlobalInfo *SSI)
164 : Opts(Opts), M(M), SSI(SSI) {
165 this->Recover = valueOr(Opts.hwasan_recover, Recover);
166 this->CompileKernel = valueOr(Opts.hwasan_kernel, CompileKernel);
167 this->Rng = Opts.hwasan_random_rate ? M.createRNG(DEBUG_TYPE) : nullptr;
168
169 initializeModule();
170 }
171
172 void sanitizeFunction(Function &F, FunctionAnalysisManager &FAM);
173
174private:
175 struct ShadowTagCheckInfo {
176 Instruction *TagMismatchTerm = nullptr;
177 Value *PtrLong = nullptr;
178 Value *AddrLong = nullptr;
179 Value *PtrTag = nullptr;
180 Value *MemTag = nullptr;
181 };
182
183 bool selectiveInstrumentationShouldSkip(Function &F,
185 void initializeModule();
186 void createHwasanCtorComdat();
187 void createHwasanNote();
188
189 void initializeCallbacks(Module &M);
190
191 Value *getOpaqueNoopCast(IRBuilder<> &IRB, Value *Val);
192
193 Value *getDynamicShadowIfunc(IRBuilder<> &IRB);
194 Value *getShadowNonTls(IRBuilder<> &IRB);
195
196 void untagPointerOperand(Instruction *I, Value *Addr);
197 Value *memToShadow(Value *Shadow, IRBuilder<> &IRB);
198
199 int64_t getAccessInfo(bool IsWrite, unsigned AccessSizeIndex);
200 ShadowTagCheckInfo insertShadowTagCheck(Value *Ptr, Instruction *InsertBefore,
201 DomTreeUpdater &DTU, LoopInfo *LI);
202 void instrumentMemAccessOutline(Value *Ptr, bool IsWrite,
203 unsigned AccessSizeIndex,
204 Instruction *InsertBefore,
205 DomTreeUpdater &DTU, LoopInfo *LI);
206 void instrumentMemAccessInline(Value *Ptr, bool IsWrite,
207 unsigned AccessSizeIndex,
208 Instruction *InsertBefore, DomTreeUpdater &DTU,
209 LoopInfo *LI);
210 bool ignoreMemIntrinsic(OptimizationRemarkEmitter &ORE, MemIntrinsic *MI);
211 void instrumentMemIntrinsic(MemIntrinsic *MI);
212 bool instrumentMemAccess(InterestingMemoryOperand &O, DomTreeUpdater &DTU,
213 LoopInfo *LI, const DataLayout &DL);
214 bool ignoreAccessWithoutRemark(Instruction *Inst, Value *Ptr);
215 bool ignoreAccess(OptimizationRemarkEmitter &ORE, Instruction *Inst,
216 Value *Ptr);
217
219 OptimizationRemarkEmitter &ORE, Instruction *I,
220 const TargetLibraryInfo &TLI,
221 SmallVectorImpl<InterestingMemoryOperand> &Interesting);
222
223 void tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag, size_t Size);
224 Value *tagPointer(IRBuilder<> &IRB, Type *Ty, Value *PtrLong, Value *Tag);
225 Value *untagPointer(IRBuilder<> &IRB, Value *PtrLong);
226 void instrumentStack(OptimizationRemarkEmitter &ORE, memtag::StackInfo &Info,
227 Value *StackTag, Value *UARTag, const DominatorTree &DT,
228 const PostDominatorTree &PDT, const LoopInfo &LI);
229 void instrumentLandingPads(SmallVectorImpl<Instruction *> &RetVec);
230 Value *getNextTagWithCall(IRBuilder<> &IRB);
231 Value *getStackBaseTag(IRBuilder<> &IRB);
232 Value *getAllocaTag(IRBuilder<> &IRB, Value *StackTag, unsigned AllocaNo);
233 Value *getUARTag(IRBuilder<> &IRB);
234
235 Value *getHwasanThreadSlotPtr(IRBuilder<> &IRB);
236 Value *applyTagMask(IRBuilder<> &IRB, Value *OldTag);
237 unsigned retagMask(unsigned AllocaNo);
238
239 void emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord);
240
241 void instrumentGlobal(GlobalVariable *GV, uint8_t Tag);
242 void instrumentGlobals();
243
244 Value *getCachedFP(IRBuilder<> &IRB);
245 Value *getFrameRecordInfo(IRBuilder<> &IRB);
246
247 void instrumentPersonalityFunctions();
248
249 const InstrumentationOptions &Opts;
250 LLVMContext *C;
251 Module &M;
252 const StackSafetyGlobalInfo *SSI;
253 Triple TargetTriple;
254 std::unique_ptr<RandomNumberGenerator> Rng;
255
256 /// This struct defines the shadow mapping using the rule:
257 /// If `kFixed`, then
258 /// shadow = (mem >> Scale) + Offset.
259 /// If `kGlobal`, then
260 /// extern char* __hwasan_shadow_memory_dynamic_address;
261 /// shadow = (mem >> Scale) + __hwasan_shadow_memory_dynamic_address
262 /// If `kIfunc`, then
263 /// extern char __hwasan_shadow[];
264 /// shadow = (mem >> Scale) + &__hwasan_shadow
265 /// If `kTls`, then
266 /// extern char *__hwasan_tls;
267 /// shadow = (mem>>Scale) + align_up(__hwasan_shadow, kShadowBaseAlignment)
268 ///
269 /// If WithFrameRecord is true, then __hwasan_tls will be used to access the
270 /// ring buffer for storing stack allocations on targets that support it.
271 class ShadowMapping {
272 OffsetKind Kind;
273 uint64_t Offset;
274 uint8_t Scale;
275 bool WithFrameRecord;
276
277 void SetFixed(uint64_t O) {
278 Kind = OffsetKind::kFixed;
279 Offset = O;
280 }
281
282 public:
283 void init(const InstrumentationOptions &Opts, Triple &TargetTriple,
284 bool InstrumentWithCalls, bool CompileKernel);
285 Align getObjectAlignment() const { return Align::fromLog2(Scale); }
286 bool isInGlobal() const { return Kind == OffsetKind::kGlobal; }
287 bool isInIfunc() const { return Kind == OffsetKind::kIfunc; }
288 bool isInTls() const { return Kind == OffsetKind::kTls; }
289 bool isFixed() const { return Kind == OffsetKind::kFixed; }
290 uint8_t scale() const { return Scale; };
291 uint64_t offset() const {
292 assert(isFixed());
293 return Offset;
294 };
295 bool withFrameRecord() const { return WithFrameRecord; };
296 };
297
298 ShadowMapping Mapping;
299
300 Type *VoidTy = Type::getVoidTy(M.getContext());
301 Type *IntptrTy = M.getDataLayout().getIntPtrType(M.getContext());
302 PointerType *PtrTy = PointerType::getUnqual(M.getContext());
303 Type *Int8Ty = Type::getInt8Ty(M.getContext());
304 Type *Int32Ty = Type::getInt32Ty(M.getContext());
305 Type *Int64Ty = Type::getInt64Ty(M.getContext());
306
307 bool CompileKernel;
308 bool Recover;
309 bool OutlinedChecks;
310 bool InlineFastPath;
311 bool UseShortGranules;
312 bool InstrumentLandingPads;
313 bool InstrumentWithCalls;
314 bool InstrumentStack;
315 bool InstrumentGlobals;
316 bool DetectUseAfterScope;
317 bool UsePageAliases;
318 bool UseMatchAllCallback;
319
320 std::optional<uint8_t> MatchAllTag;
321
322 unsigned PointerTagShift;
323 uint64_t TagMaskByte;
324
325 Function *HwasanCtorFunction;
326
327 FunctionCallee HwasanMemoryAccessCallback[2][kNumberOfAccessSizes];
328 FunctionCallee HwasanMemoryAccessCallbackSized[2];
329
330 FunctionCallee HwasanMemmove, HwasanMemcpy, HwasanMemset;
331 FunctionCallee HwasanHandleVfork;
332
333 FunctionCallee HwasanTagMemoryFunc;
334 FunctionCallee HwasanGenerateTagFunc;
335 FunctionCallee HwasanRecordFrameRecordFunc;
336
337 Constant *ShadowGlobal;
338
339 Value *ShadowBase = nullptr;
340 Value *StackBaseTag = nullptr;
341 Value *CachedFP = nullptr;
342 GlobalValue *ThreadPtrGlobal = nullptr;
343};
344
345} // end anonymous namespace
346
349 // Return early if nosanitize_hwaddress module flag is present for the module.
350 if (checkIfAlreadyInstrumented(M, "nosanitize_hwaddress"))
351 return PreservedAnalyses::all();
352 const StackSafetyGlobalInfo *SSI = nullptr;
353 const Triple &TargetTriple = M.getTargetTriple();
354 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
355 if (shouldUseStackSafetyAnalysis(Opts, TargetTriple,
356 Options.DisableOptimization))
357 SSI = &MAM.getResult<StackSafetyGlobalAnalysis>(M);
358
359 HWAddressSanitizer HWASan(Opts, M, Options.CompileKernel, Options.Recover,
360 SSI);
361 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
362 for (Function &F : M)
363 HWASan.sanitizeFunction(F, FAM);
364
366 // DominatorTreeAnalysis, PostDominatorTreeAnalysis, and LoopAnalysis
367 // are incrementally updated throughout this pass whenever
368 // SplitBlockAndInsertIfThen is called.
372 // GlobalsAA is considered stateless and does not get invalidated unless
373 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
374 // make changes that require GlobalsAA to be invalidated.
375 PA.abandon<GlobalsAA>();
376 return PA;
377}
379 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
380 static_cast<PassInfoMixin<HWAddressSanitizerPass> *>(this)->printPipeline(
381 OS, MapClassName2PassName);
382 OS << '<';
383 if (Options.CompileKernel)
384 OS << "kernel;";
385 if (Options.Recover)
386 OS << "recover";
387 OS << '>';
388}
389
390void HWAddressSanitizer::createHwasanNote() {
391 // Create a note that contains pointers to the list of global
392 // descriptors. Adding a note to the output file will cause the linker to
393 // create a PT_NOTE program header pointing to the note that we can use to
394 // find the descriptor list starting from the program headers. A function
395 // provided by the runtime initializes the shadow memory for the globals by
396 // accessing the descriptor list via the note. The dynamic loader needs to
397 // call this function whenever a library is loaded.
398 //
399 // The reason why we use a note for this instead of a more conventional
400 // approach of having a global constructor pass a descriptor list pointer to
401 // the runtime is because of an order of initialization problem. With
402 // constructors we can encounter the following problematic scenario:
403 //
404 // 1) library A depends on library B and also interposes one of B's symbols
405 // 2) B's constructors are called before A's (as required for correctness)
406 // 3) during construction, B accesses one of its "own" globals (actually
407 // interposed by A) and triggers a HWASAN failure due to the initialization
408 // for A not having happened yet
409 //
410 // Even without interposition it is possible to run into similar situations in
411 // cases where two libraries mutually depend on each other.
412 //
413 // We only need one note per binary, so put everything for the note in a
414 // comdat. This needs to be a comdat with an .init_array section to prevent
415 // newer versions of lld from discarding the note.
416 //
417 // Create the note even if we aren't instrumenting globals. This ensures that
418 // binaries linked from object files with both instrumented and
419 // non-instrumented globals will end up with a note, even if a comdat from an
420 // object file with non-instrumented globals is selected. The note is harmless
421 // if the runtime doesn't support it, since it will just be ignored.
422 Comdat *NoteComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
423
424 Type *Int8Arr0Ty = ArrayType::get(Int8Ty, 0);
425 auto *Start =
426 new GlobalVariable(M, Int8Arr0Ty, true, GlobalVariable::ExternalLinkage,
427 nullptr, "__start_hwasan_globals");
428 Start->setVisibility(GlobalValue::HiddenVisibility);
429 auto *Stop =
430 new GlobalVariable(M, Int8Arr0Ty, true, GlobalVariable::ExternalLinkage,
431 nullptr, "__stop_hwasan_globals");
432 Stop->setVisibility(GlobalValue::HiddenVisibility);
433
434 // Null-terminated so actually 8 bytes, which are required in order to align
435 // the note properly.
436 auto *Name = ConstantDataArray::get(*C, "LLVM\0\0\0");
437
438 auto *NoteTy = StructType::get(Int32Ty, Int32Ty, Int32Ty, Name->getType(),
439 Int32Ty, Int32Ty);
440 auto *Note =
441 new GlobalVariable(M, NoteTy, /*isConstant=*/true,
443 Note->setSection(".note.hwasan.globals");
444 Note->setComdat(NoteComdat);
445 Note->setAlignment(Align(4));
446
447 // The pointers in the note need to be relative so that the note ends up being
448 // placed in rodata, which is the standard location for notes.
449 auto CreateRelPtr = [&](Constant *Ptr) {
453 Int32Ty);
454 };
455 Note->setInitializer(ConstantStruct::getAnon(
456 {ConstantInt::get(Int32Ty, 8), // n_namesz
457 ConstantInt::get(Int32Ty, 8), // n_descsz
458 ConstantInt::get(Int32Ty, ELF::NT_LLVM_HWASAN_GLOBALS), // n_type
459 Name, CreateRelPtr(Start), CreateRelPtr(Stop)}));
461
462 // Create a zero-length global in hwasan_globals so that the linker will
463 // always create start and stop symbols.
464 auto *Dummy = new GlobalVariable(
465 M, Int8Arr0Ty, /*isConstantGlobal*/ true, GlobalVariable::PrivateLinkage,
466 Constant::getNullValue(Int8Arr0Ty), "hwasan.dummy.global");
467 Dummy->setSection("hwasan_globals");
468 Dummy->setComdat(NoteComdat);
469 Dummy->setMetadata(LLVMContext::MD_associated,
471 appendToCompilerUsed(M, Dummy);
472}
473
474void HWAddressSanitizer::createHwasanCtorComdat() {
475 std::tie(HwasanCtorFunction, std::ignore) =
478 /*InitArgTypes=*/{},
479 /*InitArgs=*/{},
480 // This callback is invoked when the functions are created the first
481 // time. Hook them into the global ctors list in that case:
482 [&](Function *Ctor, FunctionCallee) {
483 Comdat *CtorComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
484 Ctor->setComdat(CtorComdat);
485 appendToGlobalCtors(M, Ctor, 0, Ctor);
486 });
487
488 // Do not create .note.hwasan.globals for static binaries, as it is only
489 // needed for instrumenting globals from dynamic libraries. In static
490 // binaries, the global variables section can be accessed directly via the
491 // __start_hwasan_globals and __stop_hwasan_globals symbols inserted by the
492 // linker.
493 if (!Opts.hwasan_static_linking)
494 createHwasanNote();
495}
496
497/// Module-level initialization.
498///
499/// inserts a call to __hwasan_init to the module's constructor list.
500void HWAddressSanitizer::initializeModule() {
501 LLVM_DEBUG(dbgs() << "Init " << M.getName() << "\n");
502 TargetTriple = M.getTargetTriple();
503
504 // HWASan may do short granule checks on function arguments read from the
505 // argument memory (last byte of the granule), which invalidates writeonly.
506 for (Function &F : M.functions())
507 removeASanIncompatibleFnAttributes(F, /*ReadsArgMem=*/true);
508
509 // x86_64 currently has two modes:
510 // - Intel LAM (default)
511 // - pointer aliasing (heap only)
512 bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64;
513 UsePageAliases = shouldUsePageAliases(Opts, TargetTriple);
514 InstrumentWithCalls = shouldInstrumentWithCalls(Opts, TargetTriple);
515 InstrumentStack = shouldInstrumentStack(Opts, TargetTriple);
516 DetectUseAfterScope = shouldDetectUseAfterScope(Opts, TargetTriple);
517 PointerTagShift = IsX86_64 ? 57 : 56;
518 TagMaskByte = IsX86_64 ? 0x3F : 0xFF;
519 if (Opts.hwasan_tag_bits) {
520 if (TagMaskByte < 4)
522 "need more than 4 bits of tag to have non-short-granule tags");
523 TagMaskByte &= (1ULL << Opts.hwasan_tag_bits) - 1;
524 }
525
526 Mapping.init(Opts, TargetTriple, InstrumentWithCalls, CompileKernel);
527
528 C = &(M.getContext());
529 IRBuilder<> IRB(M);
530
531 HwasanCtorFunction = nullptr;
532
533 // Older versions of Android do not have the required runtime support for
534 // short granules, global or personality function instrumentation. On other
535 // platforms we currently require using the latest version of the runtime.
536 bool NewRuntime =
537 !TargetTriple.isAndroid() || !TargetTriple.isAndroidVersionLT(30);
538
539 UseShortGranules = valueOr(Opts.hwasan_use_short_granules, NewRuntime);
540 OutlinedChecks = (TargetTriple.isAArch64() || TargetTriple.isRISCV64()) &&
541 TargetTriple.isOSBinFormatELF() &&
542 !valueOr(Opts.hwasan_inline_all_checks, Recover);
543
544 // These platforms may prefer less inlining to reduce binary size.
545 InlineFastPath =
546 valueOr(Opts.hwasan_inline_fast_path_checks,
547 !(TargetTriple.isAndroid() || TargetTriple.isOSFuchsia()));
548
549 if (Opts.hwasan_match_all_tag) {
550 if (*Opts.hwasan_match_all_tag != -1) {
551 MatchAllTag = *Opts.hwasan_match_all_tag & 0xFF;
552 }
553 } else if (CompileKernel) {
554 MatchAllTag = 0xFF;
555 }
556 UseMatchAllCallback = !CompileKernel && MatchAllTag.has_value();
557
558 // If we don't have personality function support, fall back to landing pads.
559 InstrumentLandingPads =
560 valueOr(Opts.hwasan_instrument_landing_pads, !NewRuntime);
561
562 InstrumentGlobals = !CompileKernel && !UsePageAliases &&
563 valueOr(Opts.hwasan_globals, NewRuntime);
564
565 if (!CompileKernel) {
566 if (InstrumentGlobals)
567 instrumentGlobals();
568
569 createHwasanCtorComdat();
570
571 bool InstrumentPersonalityFunctions =
572 valueOr(Opts.hwasan_instrument_personality_functions, NewRuntime);
573 if (InstrumentPersonalityFunctions)
574 instrumentPersonalityFunctions();
575 }
576
577 if (!TargetTriple.isAndroid()) {
578 ThreadPtrGlobal = M.getOrInsertGlobal("__hwasan_tls", IntptrTy, [&] {
579 auto *GV = new GlobalVariable(M, IntptrTy, /*isConstant=*/false,
581 "__hwasan_tls", nullptr,
584 return GV;
585 });
586 }
587}
588
589void HWAddressSanitizer::initializeCallbacks(Module &M) {
590 IRBuilder<> IRB(M);
591 const std::string MatchAllStr = UseMatchAllCallback ? "_match_all" : "";
592 FunctionType *HwasanMemoryAccessCallbackSizedFnTy,
593 *HwasanMemoryAccessCallbackFnTy, *HwasanMemTransferFnTy,
594 *HwasanMemsetFnTy;
595 if (UseMatchAllCallback) {
596 HwasanMemoryAccessCallbackSizedFnTy =
597 FunctionType::get(VoidTy, {IntptrTy, IntptrTy, Int8Ty}, false);
598 HwasanMemoryAccessCallbackFnTy =
599 FunctionType::get(VoidTy, {IntptrTy, Int8Ty}, false);
600 HwasanMemTransferFnTy =
601 FunctionType::get(PtrTy, {PtrTy, PtrTy, IntptrTy, Int8Ty}, false);
602 HwasanMemsetFnTy =
603 FunctionType::get(PtrTy, {PtrTy, Int32Ty, IntptrTy, Int8Ty}, false);
604 } else {
605 HwasanMemoryAccessCallbackSizedFnTy =
606 FunctionType::get(VoidTy, {IntptrTy, IntptrTy}, false);
607 HwasanMemoryAccessCallbackFnTy =
608 FunctionType::get(VoidTy, {IntptrTy}, false);
609 HwasanMemTransferFnTy =
610 FunctionType::get(PtrTy, {PtrTy, PtrTy, IntptrTy}, false);
611 HwasanMemsetFnTy =
612 FunctionType::get(PtrTy, {PtrTy, Int32Ty, IntptrTy}, false);
613 }
614
615 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
616 const std::string TypeStr = AccessIsWrite ? "store" : "load";
617 const std::string EndingStr = Recover ? "_noabort" : "";
618
619 HwasanMemoryAccessCallbackSized[AccessIsWrite] =
620 M.getOrInsertFunction((Opts.hwasan_memory_access_callback_prefix +
621 TypeStr + "N" + MatchAllStr + EndingStr)
622 .str(),
623 HwasanMemoryAccessCallbackSizedFnTy);
624
625 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
626 AccessSizeIndex++) {
627 HwasanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] =
628 M.getOrInsertFunction((Opts.hwasan_memory_access_callback_prefix +
629 TypeStr + itostr(1ULL << AccessSizeIndex) +
630 MatchAllStr + EndingStr)
631 .str(),
632 HwasanMemoryAccessCallbackFnTy);
633 }
634 }
635
636 const std::string MemIntrinCallbackPrefix =
637 (CompileKernel && !Opts.hwasan_kernel_mem_intrinsic_prefix)
638 ? std::string("")
639 : Opts.hwasan_memory_access_callback_prefix.str();
640
641 HwasanMemmove = M.getOrInsertFunction(
642 MemIntrinCallbackPrefix + "memmove" + MatchAllStr, HwasanMemTransferFnTy);
643 HwasanMemcpy = M.getOrInsertFunction(
644 MemIntrinCallbackPrefix + "memcpy" + MatchAllStr, HwasanMemTransferFnTy);
645 HwasanMemset = M.getOrInsertFunction(
646 MemIntrinCallbackPrefix + "memset" + MatchAllStr, HwasanMemsetFnTy);
647
648 HwasanTagMemoryFunc = M.getOrInsertFunction("__hwasan_tag_memory", VoidTy,
649 PtrTy, Int8Ty, IntptrTy);
650 HwasanGenerateTagFunc =
651 M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty);
652
653 HwasanRecordFrameRecordFunc =
654 M.getOrInsertFunction("__hwasan_add_frame_record", VoidTy, Int64Ty);
655
656 ShadowGlobal =
657 M.getOrInsertGlobal("__hwasan_shadow", ArrayType::get(Int8Ty, 0));
658
659 HwasanHandleVfork =
660 M.getOrInsertFunction("__hwasan_handle_vfork", VoidTy, IntptrTy);
661}
662
663Value *HWAddressSanitizer::getOpaqueNoopCast(IRBuilder<> &IRB, Value *Val) {
664 // An empty inline asm with input reg == output reg.
665 // An opaque no-op cast, basically.
666 // This prevents code bloat as a result of rematerializing trivial definitions
667 // such as constants or global addresses at every load and store.
668 InlineAsm *Asm =
669 InlineAsm::get(FunctionType::get(PtrTy, {Val->getType()}, false),
670 StringRef(""), StringRef("=r,0"),
671 /*hasSideEffects=*/false);
672 return IRB.CreateCall(Asm, {Val}, ".hwasan.shadow");
673}
674
675Value *HWAddressSanitizer::getDynamicShadowIfunc(IRBuilder<> &IRB) {
676 return getOpaqueNoopCast(IRB, ShadowGlobal);
677}
678
679Value *HWAddressSanitizer::getShadowNonTls(IRBuilder<> &IRB) {
680 if (Mapping.isFixed()) {
681 return getOpaqueNoopCast(
683 ConstantInt::get(IntptrTy, Mapping.offset()), PtrTy));
684 }
685
686 if (Mapping.isInIfunc())
687 return getDynamicShadowIfunc(IRB);
688
689 Value *GlobalDynamicAddress = IRB.getModule()->getOrInsertGlobal(
691 return IRB.CreateLoad(PtrTy, GlobalDynamicAddress);
692}
693
694bool HWAddressSanitizer::ignoreAccessWithoutRemark(Instruction *Inst,
695 Value *Ptr) {
696 // Do not instrument accesses from different address spaces; we cannot deal
697 // with them.
698 Type *PtrTy = cast<PointerType>(Ptr->getType()->getScalarType());
699 if (PtrTy->getPointerAddressSpace() != 0)
700 return true;
701
702 // Ignore swifterror addresses.
703 // swifterror memory addresses are mem2reg promoted by instruction
704 // selection. As such they cannot have regular uses like an instrumentation
705 // function and it makes no sense to track them as memory.
706 if (Ptr->isSwiftError())
707 return true;
708
709 if (findAllocaForValue(Ptr)) {
710 if (!InstrumentStack)
711 return true;
712 if (SSI && SSI->stackAccessIsSafe(*Inst))
713 return true;
714 }
715
717 if (!InstrumentGlobals)
718 return true;
719 // TODO: Optimize inbound global accesses, like Asan `instrumentMop`.
720 }
721
722 return false;
723}
724
725bool HWAddressSanitizer::ignoreAccess(OptimizationRemarkEmitter &ORE,
726 Instruction *Inst, Value *Ptr) {
727 bool Ignored = ignoreAccessWithoutRemark(Inst, Ptr);
728 if (Ignored) {
729 ORE.emit(
730 [&]() { return OptimizationRemark(DEBUG_TYPE, "ignoreAccess", Inst); });
731 } else {
732 ORE.emit([&]() {
733 return OptimizationRemarkMissed(DEBUG_TYPE, "ignoreAccess", Inst);
734 });
735 }
736 return Ignored;
737}
738
739void HWAddressSanitizer::getInterestingMemoryOperands(
741 const TargetLibraryInfo &TLI,
743 // Skip memory accesses inserted by another instrumentation.
744 if (I->hasMetadata(LLVMContext::MD_nosanitize))
745 return;
746
747 // Do not instrument the load fetching the dynamic shadow address.
748 if (ShadowBase == I)
749 return;
750
751 if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
752 if (!Opts.hwasan_instrument_reads ||
753 ignoreAccess(ORE, I, LI->getPointerOperand()))
754 return;
755 Interesting.emplace_back(I, LI->getPointerOperandIndex(), false,
756 LI->getType(), LI->getAlign());
757 } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
758 if (!Opts.hwasan_instrument_writes ||
759 ignoreAccess(ORE, I, SI->getPointerOperand()))
760 return;
761 Interesting.emplace_back(I, SI->getPointerOperandIndex(), true,
762 SI->getValueOperand()->getType(), SI->getAlign());
763 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
764 if (!Opts.hwasan_instrument_atomics ||
765 ignoreAccess(ORE, I, RMW->getPointerOperand()))
766 return;
767 Interesting.emplace_back(I, RMW->getPointerOperandIndex(), true,
768 RMW->getValOperand()->getType(), std::nullopt);
769 } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
770 if (!Opts.hwasan_instrument_atomics ||
771 ignoreAccess(ORE, I, XCHG->getPointerOperand()))
772 return;
773 Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true,
774 XCHG->getCompareOperand()->getType(),
775 std::nullopt);
776 } else if (auto *CI = dyn_cast<CallInst>(I)) {
777 for (unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
778 if (!Opts.hwasan_instrument_byval || !CI->isByValArgument(ArgNo) ||
779 ignoreAccess(ORE, I, CI->getArgOperand(ArgNo)))
780 continue;
781 Type *Ty = CI->getParamByValType(ArgNo);
782 Interesting.emplace_back(I, ArgNo, false, Ty, Align(1));
783 }
785 }
786}
787
789 if (LoadInst *LI = dyn_cast<LoadInst>(I))
790 return LI->getPointerOperandIndex();
792 return SI->getPointerOperandIndex();
794 return RMW->getPointerOperandIndex();
796 return XCHG->getPointerOperandIndex();
797 report_fatal_error("Unexpected instruction");
798 return -1;
799}
800
802 size_t Res = llvm::countr_zero(TypeSize / 8);
804 return Res;
805}
806
807void HWAddressSanitizer::untagPointerOperand(Instruction *I, Value *Addr) {
808 if (TargetTriple.isAArch64() || TargetTriple.getArch() == Triple::x86_64 ||
809 TargetTriple.isRISCV64())
810 return;
811
812 IRBuilder<> IRB(I);
813 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
814 Value *UntaggedPtr =
815 IRB.CreateIntToPtr(untagPointer(IRB, AddrLong), Addr->getType());
816 I->setOperand(getPointerOperandIndex(I), UntaggedPtr);
817}
818
819Value *HWAddressSanitizer::memToShadow(Value *Mem, IRBuilder<> &IRB) {
820 // Mem >> Scale
821 Value *Shadow = IRB.CreateLShr(Mem, Mapping.scale());
822 if (Mapping.isFixed() && Mapping.offset() == 0)
823 return IRB.CreateIntToPtr(Shadow, PtrTy);
824 // (Mem >> Scale) + Offset
825 return IRB.CreatePtrAdd(ShadowBase, Shadow);
826}
827
828int64_t HWAddressSanitizer::getAccessInfo(bool IsWrite,
829 unsigned AccessSizeIndex) {
830 return (CompileKernel << HWASanAccessInfo::CompileKernelShift) |
831 (MatchAllTag.has_value() << HWASanAccessInfo::HasMatchAllShift) |
832 (MatchAllTag.value_or(0) << HWASanAccessInfo::MatchAllShift) |
833 (Recover << HWASanAccessInfo::RecoverShift) |
834 (IsWrite << HWASanAccessInfo::IsWriteShift) |
835 (AccessSizeIndex << HWASanAccessInfo::AccessSizeShift);
836}
837
838HWAddressSanitizer::ShadowTagCheckInfo
839HWAddressSanitizer::insertShadowTagCheck(Value *Ptr, Instruction *InsertBefore,
840 DomTreeUpdater &DTU, LoopInfo *LI) {
841 ShadowTagCheckInfo R;
842
843 IRBuilder<> IRB(InsertBefore);
844
845 R.PtrLong = IRB.CreatePointerCast(Ptr, IntptrTy);
846 R.PtrTag =
847 IRB.CreateTrunc(IRB.CreateLShr(R.PtrLong, PointerTagShift), Int8Ty);
848 R.AddrLong = untagPointer(IRB, R.PtrLong);
849 Value *Shadow = memToShadow(R.AddrLong, IRB);
850 R.MemTag = IRB.CreateLoad(Int8Ty, Shadow);
851 Value *TagMismatch = IRB.CreateICmpNE(R.PtrTag, R.MemTag);
852
853 if (MatchAllTag.has_value()) {
854 Value *TagNotIgnored = IRB.CreateICmpNE(
855 R.PtrTag, ConstantInt::get(R.PtrTag->getType(), *MatchAllTag));
856 TagMismatch = IRB.CreateAnd(TagMismatch, TagNotIgnored);
857 }
858
859 R.TagMismatchTerm = SplitBlockAndInsertIfThen(
860 TagMismatch, InsertBefore, false,
861 MDBuilder(*C).createUnlikelyBranchWeights(), &DTU, LI);
862
863 return R;
864}
865
866void HWAddressSanitizer::instrumentMemAccessOutline(Value *Ptr, bool IsWrite,
867 unsigned AccessSizeIndex,
868 Instruction *InsertBefore,
869 DomTreeUpdater &DTU,
870 LoopInfo *LI) {
871 assert(!UsePageAliases);
872 const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
873
874 if (InlineFastPath)
875 InsertBefore =
876 insertShadowTagCheck(Ptr, InsertBefore, DTU, LI).TagMismatchTerm;
877
878 IRBuilder<> IRB(InsertBefore);
879 bool UseFixedShadowIntrinsic = false;
880 // The memaccess fixed shadow intrinsic is only supported on AArch64,
881 // which allows a 16-bit immediate to be left-shifted by 32.
882 // Since kShadowBaseAlignment == 32, and Linux by default will not
883 // mmap above 48-bits, practically any valid shadow offset is
884 // representable.
885 // In particular, an offset of 4TB (1024 << 32) is representable, and
886 // ought to be good enough for anybody.
887 if (TargetTriple.isAArch64() && Mapping.isFixed()) {
888 uint16_t OffsetShifted = Mapping.offset() >> 32;
889 UseFixedShadowIntrinsic =
890 static_cast<uint64_t>(OffsetShifted) << 32 == Mapping.offset();
891 }
892
893 if (UseFixedShadowIntrinsic) {
894 IRB.CreateIntrinsic(
895 UseShortGranules
896 ? Intrinsic::hwasan_check_memaccess_shortgranules_fixedshadow
897 : Intrinsic::hwasan_check_memaccess_fixedshadow,
898 {Ptr, ConstantInt::get(Int32Ty, AccessInfo),
899 ConstantInt::get(Int64Ty, Mapping.offset())});
900 } else {
901 IRB.CreateIntrinsic(
902 UseShortGranules ? Intrinsic::hwasan_check_memaccess_shortgranules
903 : Intrinsic::hwasan_check_memaccess,
904 {ShadowBase, Ptr, ConstantInt::get(Int32Ty, AccessInfo)});
905 }
906}
907
908void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
909 unsigned AccessSizeIndex,
910 Instruction *InsertBefore,
911 DomTreeUpdater &DTU,
912 LoopInfo *LI) {
913 assert(!UsePageAliases);
914 const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
915
916 ShadowTagCheckInfo TCI = insertShadowTagCheck(Ptr, InsertBefore, DTU, LI);
917
918 IRBuilder<> IRB(TCI.TagMismatchTerm);
919 Value *OutOfShortGranuleTagRange =
920 IRB.CreateICmpUGT(TCI.MemTag, ConstantInt::get(Int8Ty, 15));
921 Instruction *CheckFailTerm = SplitBlockAndInsertIfThen(
922 OutOfShortGranuleTagRange, TCI.TagMismatchTerm, !Recover,
923 MDBuilder(*C).createUnlikelyBranchWeights(), &DTU, LI);
924
925 IRB.SetInsertPoint(TCI.TagMismatchTerm);
926 Value *PtrLowBits = IRB.CreateTrunc(IRB.CreateAnd(TCI.PtrLong, 15), Int8Ty);
927 PtrLowBits = IRB.CreateAdd(
928 PtrLowBits, ConstantInt::get(Int8Ty, (1 << AccessSizeIndex) - 1));
929 Value *PtrLowBitsOOB = IRB.CreateICmpUGE(PtrLowBits, TCI.MemTag);
930 SplitBlockAndInsertIfThen(PtrLowBitsOOB, TCI.TagMismatchTerm, false,
932 LI, CheckFailTerm->getParent());
933
934 IRB.SetInsertPoint(TCI.TagMismatchTerm);
935 Value *InlineTagAddr = IRB.CreateOr(TCI.AddrLong, 15);
936 InlineTagAddr = IRB.CreateIntToPtr(InlineTagAddr, PtrTy);
937 Value *InlineTag = IRB.CreateLoad(Int8Ty, InlineTagAddr);
938 Value *InlineTagMismatch = IRB.CreateICmpNE(TCI.PtrTag, InlineTag);
939 SplitBlockAndInsertIfThen(InlineTagMismatch, TCI.TagMismatchTerm, false,
941 LI, CheckFailTerm->getParent());
942
943 IRB.SetInsertPoint(CheckFailTerm);
944 InlineAsm *Asm;
945 switch (TargetTriple.getArch()) {
946 case Triple::x86_64:
947 // The signal handler will find the data address in rdi.
949 FunctionType::get(VoidTy, {TCI.PtrLong->getType()}, false),
950 "int3\nnopl " +
951 itostr(0x40 + (AccessInfo & HWASanAccessInfo::RuntimeMask)) +
952 "(%rax)",
953 "{rdi}",
954 /*hasSideEffects=*/true);
955 break;
956 case Triple::aarch64:
958 // The signal handler will find the data address in x0.
960 FunctionType::get(VoidTy, {TCI.PtrLong->getType()}, false),
961 "brk #" + itostr(0x900 + (AccessInfo & HWASanAccessInfo::RuntimeMask)),
962 "{x0}",
963 /*hasSideEffects=*/true);
964 break;
965 case Triple::riscv64:
966 // The signal handler will find the data address in x10.
968 FunctionType::get(VoidTy, {TCI.PtrLong->getType()}, false),
969 "ebreak\naddiw x0, x11, " +
970 itostr(0x40 + (AccessInfo & HWASanAccessInfo::RuntimeMask)),
971 "{x10}",
972 /*hasSideEffects=*/true);
973 break;
974 default:
975 report_fatal_error("unsupported architecture");
976 }
977 IRB.CreateCall(Asm, TCI.PtrLong);
978 if (Recover)
979 cast<UncondBrInst>(CheckFailTerm)
980 ->setSuccessor(TCI.TagMismatchTerm->getParent());
981}
982
983bool HWAddressSanitizer::ignoreMemIntrinsic(OptimizationRemarkEmitter &ORE,
984 MemIntrinsic *MI) {
986 return (!Opts.hwasan_instrument_writes ||
987 ignoreAccess(ORE, MTI, MTI->getDest())) &&
988 (!Opts.hwasan_instrument_reads ||
989 ignoreAccess(ORE, MTI, MTI->getSource()));
990 }
991 if (isa<MemSetInst>(MI))
992 return !Opts.hwasan_instrument_writes ||
993 ignoreAccess(ORE, MI, MI->getDest());
994 return false;
995}
996
997void HWAddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
998 IRBuilder<> IRB(MI);
1001 MI->getOperand(0), MI->getOperand(1),
1002 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)};
1003
1004 if (UseMatchAllCallback)
1005 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1006 IRB.CreateCall(isa<MemMoveInst>(MI) ? HwasanMemmove : HwasanMemcpy, Args);
1007 } else if (isa<MemSetInst>(MI)) {
1009 MI->getOperand(0),
1010 IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
1011 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)};
1012 if (UseMatchAllCallback)
1013 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1014 IRB.CreateCall(HwasanMemset, Args);
1015 }
1016 MI->eraseFromParent();
1017}
1018
1019bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O,
1020 DomTreeUpdater &DTU, LoopInfo *LI,
1021 const DataLayout &DL) {
1022 Value *Addr = O.getPtr();
1023
1024 LLVM_DEBUG(dbgs() << "Instrumenting: " << O.getInsn() << "\n");
1025
1026 // If the pointer is statically known to be zero, the tag check will pass
1027 // since:
1028 // 1) it has a zero tag
1029 // 2) the shadow memory corresponding to address 0 is initialized to zero and
1030 // never updated.
1031 // We can therefore elide the tag check.
1032 llvm::KnownBits Known(DL.getPointerTypeSizeInBits(Addr->getType()));
1034 if (Known.isZero())
1035 return false;
1036
1037 if (O.MaybeMask)
1038 return false; // FIXME
1039
1040 IRBuilder<> IRB(O.getInsn());
1041 if (!O.TypeStoreSize.isScalable() && isPowerOf2_64(O.TypeStoreSize) &&
1042 (O.TypeStoreSize / 8 <= (1ULL << (kNumberOfAccessSizes - 1))) &&
1043 (!O.Alignment || *O.Alignment >= Mapping.getObjectAlignment() ||
1044 *O.Alignment >= O.TypeStoreSize / 8)) {
1045 size_t AccessSizeIndex = TypeSizeToSizeIndex(O.TypeStoreSize);
1046 if (InstrumentWithCalls) {
1047 SmallVector<Value *, 2> Args{IRB.CreatePointerCast(Addr, IntptrTy)};
1048 if (UseMatchAllCallback)
1049 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1050 IRB.CreateCall(HwasanMemoryAccessCallback[O.IsWrite][AccessSizeIndex],
1051 Args);
1052 } else if (OutlinedChecks) {
1053 instrumentMemAccessOutline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn(),
1054 DTU, LI);
1055 } else {
1056 instrumentMemAccessInline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn(),
1057 DTU, LI);
1058 }
1059 } else {
1061 IRB.CreatePointerCast(Addr, IntptrTy),
1062 IRB.CreateUDiv(IRB.CreateTypeSize(IntptrTy, O.TypeStoreSize),
1063 ConstantInt::get(IntptrTy, 8))};
1064 if (UseMatchAllCallback)
1065 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1066 IRB.CreateCall(HwasanMemoryAccessCallbackSized[O.IsWrite], Args);
1067 }
1068 untagPointerOperand(O.getInsn(), Addr);
1069
1070 return true;
1071}
1072
1073void HWAddressSanitizer::tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag,
1074 size_t Size) {
1075 size_t AlignedSize = alignTo(Size, Mapping.getObjectAlignment());
1076 if (!UseShortGranules)
1077 Size = AlignedSize;
1078
1079 Tag = IRB.CreateTrunc(Tag, Int8Ty);
1080 if (InstrumentWithCalls) {
1081 IRB.CreateCall(HwasanTagMemoryFunc,
1082 {IRB.CreatePointerCast(AI, PtrTy), Tag,
1083 ConstantInt::get(IntptrTy, AlignedSize)});
1084 } else {
1085 size_t ShadowSize = Size >> Mapping.scale();
1086 Value *AddrLong = untagPointer(IRB, IRB.CreatePointerCast(AI, IntptrTy));
1087 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1088 // If this memset is not inlined, it will be intercepted in the hwasan
1089 // runtime library. That's OK, because the interceptor skips the checks if
1090 // the address is in the shadow region.
1091 // FIXME: the interceptor is not as fast as real memset. Consider lowering
1092 // llvm.memset right here into either a sequence of stores, or a call to
1093 // hwasan_tag_memory.
1094 if (ShadowSize)
1095 IRB.CreateMemSet(ShadowPtr, Tag, ShadowSize, Align(1));
1096 if (Size != AlignedSize) {
1097 const uint8_t SizeRemainder = Size % Mapping.getObjectAlignment().value();
1098 IRB.CreateStore(ConstantInt::get(Int8Ty, SizeRemainder),
1099 IRB.CreateConstGEP1_32(Int8Ty, ShadowPtr, ShadowSize));
1100 IRB.CreateStore(
1101 Tag, IRB.CreateConstGEP1_32(Int8Ty, IRB.CreatePointerCast(AI, PtrTy),
1102 AlignedSize - 1));
1103 }
1104 }
1105}
1106
1107unsigned HWAddressSanitizer::retagMask(unsigned AllocaNo) {
1108 if (TargetTriple.getArch() == Triple::x86_64)
1109 return AllocaNo & TagMaskByte;
1110
1111 // A list of 8-bit numbers that have at most one run of non-zero bits.
1112 // x = x ^ (mask << 56) can be encoded as a single armv8 instruction for these
1113 // masks.
1114 // The list does not include the value 255, which is used for UAR.
1115 //
1116 // Because we are more likely to use earlier elements of this list than later
1117 // ones, it is sorted in increasing order of probability of collision with a
1118 // mask allocated (temporally) nearby. The program that generated this list
1119 // can be found at:
1120 // https://github.com/google/sanitizers/blob/master/hwaddress-sanitizer/sort_masks.py
1121 static const unsigned FastMasks[] = {
1122 0, 128, 64, 192, 32, 96, 224, 112, 240, 48, 16, 120,
1123 248, 56, 24, 8, 124, 252, 60, 28, 12, 4, 126, 254,
1124 62, 30, 14, 6, 2, 127, 63, 31, 15, 7, 3, 1};
1125 return FastMasks[AllocaNo % std::size(FastMasks)];
1126}
1127
1128Value *HWAddressSanitizer::applyTagMask(IRBuilder<> &IRB, Value *OldTag) {
1129 if (TagMaskByte == 0xFF)
1130 return OldTag; // No need to clear the tag byte.
1131 return IRB.CreateAnd(OldTag,
1132 ConstantInt::get(OldTag->getType(), TagMaskByte));
1133}
1134
1135Value *HWAddressSanitizer::getNextTagWithCall(IRBuilder<> &IRB) {
1136 return IRB.CreateZExt(IRB.CreateCall(HwasanGenerateTagFunc), IntptrTy);
1137}
1138
1139Value *HWAddressSanitizer::getStackBaseTag(IRBuilder<> &IRB) {
1140 if (Opts.hwasan_generate_tags_with_calls)
1141 return nullptr;
1142 if (StackBaseTag)
1143 return StackBaseTag;
1144 // Extract some entropy from the stack pointer for the tags.
1145 // Take bits 20..28 (ASLR entropy) and xor with bits 0..8 (these differ
1146 // between functions).
1147 Value *FramePointerLong = getCachedFP(IRB);
1148 Value *StackTag =
1149 applyTagMask(IRB, IRB.CreateXor(FramePointerLong,
1150 IRB.CreateLShr(FramePointerLong, 20)));
1151 StackTag->setName("hwasan.stack.base.tag");
1152 return StackTag;
1153}
1154
1155Value *HWAddressSanitizer::getAllocaTag(IRBuilder<> &IRB, Value *StackTag,
1156 unsigned AllocaNo) {
1157 if (Opts.hwasan_generate_tags_with_calls)
1158 return getNextTagWithCall(IRB);
1159 return IRB.CreateXor(
1160 StackTag, ConstantInt::get(StackTag->getType(), retagMask(AllocaNo)));
1161}
1162
1163Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB) {
1164 Value *FramePointerLong = getCachedFP(IRB);
1165 Value *UARTag =
1166 applyTagMask(IRB, IRB.CreateLShr(FramePointerLong, PointerTagShift));
1167
1168 UARTag->setName("hwasan.uar.tag");
1169 return UARTag;
1170}
1171
1172// Add a tag to an address.
1173Value *HWAddressSanitizer::tagPointer(IRBuilder<> &IRB, Type *Ty,
1174 Value *PtrLong, Value *Tag) {
1175 assert(!UsePageAliases);
1176 Value *TaggedPtrLong;
1177 if (CompileKernel) {
1178 // Kernel addresses have 0xFF in the most significant byte.
1179 Value *ShiftedTag =
1180 IRB.CreateOr(IRB.CreateShl(Tag, PointerTagShift),
1181 ConstantInt::get(IntptrTy, (1ULL << PointerTagShift) - 1));
1182 TaggedPtrLong = IRB.CreateAnd(PtrLong, ShiftedTag);
1183 } else {
1184 // Userspace can simply do OR (tag << PointerTagShift);
1185 Value *ShiftedTag = IRB.CreateShl(Tag, PointerTagShift);
1186 TaggedPtrLong = IRB.CreateOr(PtrLong, ShiftedTag);
1187 }
1188 return IRB.CreateIntToPtr(TaggedPtrLong, Ty);
1189}
1190
1191// Remove tag from an address.
1192Value *HWAddressSanitizer::untagPointer(IRBuilder<> &IRB, Value *PtrLong) {
1193 assert(!UsePageAliases);
1194 Value *UntaggedPtrLong;
1195 if (CompileKernel) {
1196 // Kernel addresses have 0xFF in the most significant byte.
1197 UntaggedPtrLong =
1198 IRB.CreateOr(PtrLong, ConstantInt::get(PtrLong->getType(),
1199 TagMaskByte << PointerTagShift));
1200 } else {
1201 // Userspace addresses have 0x00.
1202 UntaggedPtrLong = IRB.CreateAnd(
1203 PtrLong, ConstantInt::get(PtrLong->getType(),
1204 ~(TagMaskByte << PointerTagShift)));
1205 }
1206 return UntaggedPtrLong;
1207}
1208
1209Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB) {
1210 // Android provides a fixed TLS slot for sanitizers. See TLS_SLOT_SANITIZER
1211 // in Bionic's libc/platform/bionic/tls_defines.h.
1212 constexpr int SanitizerSlot = 6;
1213 if (TargetTriple.isAArch64() && TargetTriple.isAndroid())
1214 return memtag::getAndroidSlotPtr(IRB, SanitizerSlot);
1215 return ThreadPtrGlobal;
1216}
1217
1218Value *HWAddressSanitizer::getCachedFP(IRBuilder<> &IRB) {
1219 if (!CachedFP)
1220 CachedFP = memtag::getFP(IRB);
1221 return CachedFP;
1222}
1223
1224Value *HWAddressSanitizer::getFrameRecordInfo(IRBuilder<> &IRB) {
1225 // Prepare ring buffer data.
1226 Value *PC = memtag::getPC(TargetTriple, IRB);
1227 Value *FP = getCachedFP(IRB);
1228
1229 // Mix FP and PC.
1230 // Assumptions:
1231 // PC is 0x0000PPPPPPPPPPPP (48 bits are meaningful, others are zero)
1232 // FP is 0xfffffffffffFFFF0 (4 lower bits are zero)
1233 // We only really need ~20 lower non-zero bits (FFFF), so we mix like this:
1234 // 0xFFFFPPPPPPPPPPPP
1235 //
1236 // FP works because in AArch64FrameLowering::getFrameIndexReference, we
1237 // prefer FP-relative offsets for functions compiled with HWASan.
1238 FP = IRB.CreateShl(FP, 44);
1239 return IRB.CreateOr(PC, FP);
1240}
1241
1242void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
1243 if (!Mapping.isInTls())
1244 ShadowBase = getShadowNonTls(IRB);
1245 else if (!WithFrameRecord && TargetTriple.isAndroid())
1246 ShadowBase = getDynamicShadowIfunc(IRB);
1247
1248 if (!WithFrameRecord && ShadowBase)
1249 return;
1250
1251 Value *SlotPtr = nullptr;
1252 Value *ThreadLong = nullptr;
1253 Value *ThreadLongMaybeUntagged = nullptr;
1254
1255 auto getThreadLongMaybeUntagged = [&]() {
1256 if (!SlotPtr)
1257 SlotPtr = getHwasanThreadSlotPtr(IRB);
1258 if (!ThreadLong)
1259 ThreadLong = IRB.CreateLoad(IntptrTy, SlotPtr);
1260 // Extract the address field from ThreadLong. Unnecessary on AArch64 with
1261 // TBI.
1262 return TargetTriple.isAArch64() ? ThreadLong
1263 : untagPointer(IRB, ThreadLong);
1264 };
1265
1266 if (WithFrameRecord) {
1267 switch (Opts.hwasan_record_stack_history) {
1269 // Emit a runtime call into hwasan rather than emitting instructions for
1270 // recording stack history.
1271 Value *FrameRecordInfo = getFrameRecordInfo(IRB);
1272 IRB.CreateCall(HwasanRecordFrameRecordFunc, {FrameRecordInfo});
1273 break;
1274 }
1276 ThreadLongMaybeUntagged = getThreadLongMaybeUntagged();
1277
1278 StackBaseTag = IRB.CreateAShr(ThreadLong, 3);
1279
1280 // Store data to ring buffer.
1281 Value *FrameRecordInfo = getFrameRecordInfo(IRB);
1282 Value *RecordPtr =
1283 IRB.CreateIntToPtr(ThreadLongMaybeUntagged, IRB.getPtrTy(0));
1284 IRB.CreateStore(FrameRecordInfo, RecordPtr);
1285
1286 IRB.CreateStore(memtag::incrementThreadLong(IRB, ThreadLong, 8), SlotPtr);
1287 break;
1288 }
1291 "A stack history recording mode should've been selected.");
1292 }
1293 }
1294 }
1295
1296 if (!ShadowBase) {
1297 if (!ThreadLongMaybeUntagged)
1298 ThreadLongMaybeUntagged = getThreadLongMaybeUntagged();
1299
1300 // Get shadow base address by aligning RecordPtr up.
1301 // Note: this is not correct if the pointer is already aligned.
1302 // Runtime library will make sure this never happens.
1303 ShadowBase = IRB.CreateAdd(
1304 IRB.CreateOr(
1305 ThreadLongMaybeUntagged,
1306 ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
1307 ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
1308 ShadowBase = IRB.CreateIntToPtr(ShadowBase, PtrTy);
1309 }
1310}
1311
1312void HWAddressSanitizer::instrumentLandingPads(
1313 SmallVectorImpl<Instruction *> &LandingPadVec) {
1314 for (auto *LP : LandingPadVec) {
1315 IRBuilder<> IRB(LP->getNextNode());
1316 IRB.CreateCall(
1317 HwasanHandleVfork,
1319 IRB, (TargetTriple.getArch() == Triple::x86_64) ? "rsp" : "sp")});
1320 }
1321}
1322
1323void HWAddressSanitizer::instrumentStack(OptimizationRemarkEmitter &ORE,
1324 memtag::StackInfo &SInfo,
1325 Value *StackTag, Value *UARTag,
1326 const DominatorTree &DT,
1327 const PostDominatorTree &PDT,
1328 const LoopInfo &LI) {
1329 // Ideally, we want to calculate tagged stack base pointer, and rewrite all
1330 // alloca addresses using that. Unfortunately, offsets are not known yet
1331 // (unless we use ASan-style mega-alloca). Instead we keep the base tag in a
1332 // temp, shift-OR it into each alloca address and xor with the retag mask.
1333 // This generates one extra instruction per alloca use.
1334 unsigned int I = 0;
1335
1336 for (auto &KV : SInfo.AllocasToInstrument) {
1337 auto N = I++;
1338 auto *AI = KV.first;
1339 memtag::AllocaInfo &Info = KV.second;
1340 IRBuilder<> IRB(AI->getNextNode());
1341
1342 // Replace uses of the alloca with tagged address.
1343 Value *Tag = getAllocaTag(IRB, StackTag, N);
1344 Value *AILong = IRB.CreatePointerCast(AI, IntptrTy);
1345 Value *AINoTagLong = untagPointer(IRB, AILong);
1346 Value *Replacement = tagPointer(IRB, AI->getType(), AINoTagLong, Tag);
1347 std::string Name =
1348 AI->hasName() ? AI->getName().str() : "alloca." + itostr(N);
1349 Replacement->setName(Name + ".hwasan");
1350
1351 size_t Size = memtag::getAllocaSizeInBytes(*AI);
1352 size_t AlignedSize = alignTo(Size, Mapping.getObjectAlignment());
1353
1354 AI->replaceUsesWithIf(Replacement, [AILong](const Use &U) {
1355 auto *User = U.getUser();
1356 return User != AILong && !isa<LifetimeIntrinsic>(User);
1357 });
1358
1359 memtag::annotateDebugRecords(Info, retagMask(N));
1360
1361 auto TagStarts = [&]() {
1362 for (IntrinsicInst *Start : Info.LifetimeStart) {
1363 IRB.SetInsertPoint(Start->getNextNode());
1364 tagAlloca(IRB, AI, Tag, Size);
1365 }
1366 };
1367 auto TagEnd = [&](Instruction *Node) {
1368 IRB.SetInsertPoint(Node);
1369 // When untagging, use the `AlignedSize` because we need to set the tags
1370 // for the entire alloca to original. If we used `Size` here, we would
1371 // keep the last granule tagged, and store zero in the last byte of the
1372 // last granule, due to how short granules are implemented.
1373 tagAlloca(IRB, AI, UARTag, AlignedSize);
1374 };
1375 auto EraseLifetimes = [&]() {
1376 for (auto &II : Info.LifetimeStart)
1377 II->eraseFromParent();
1378 for (auto &II : Info.LifetimeEnd)
1379 II->eraseFromParent();
1380 };
1381 // Calls to functions that may return twice (e.g. setjmp) confuse the
1382 // postdominator analysis, and will leave us to keep memory tagged after
1383 // function return. Work around this by always untagging at every return
1384 // statement if return_twice functions are called.
1385 if (DetectUseAfterScope && !SInfo.CallsReturnTwice &&
1386 memtag::isSupportedLifetime(Info, &DT, &LI)) {
1387 TagStarts();
1388 memtag::forAllReachableExits(DT, PDT, LI, Info, SInfo.RetVec, TagEnd);
1389 ORE.emit([&]() {
1390 return OptimizationRemark(DEBUG_TYPE, "supportedLifetime", AI);
1391 });
1392 } else if (DetectUseAfterScope && Opts.hwasan_strict_use_after_scope) {
1393 // SInfo.CallsReturnTwice || !isStandardLifetime
1394 ORE.emit([&]() {
1395 return OptimizationRemarkMissed(DEBUG_TYPE, "supportedLifetime", AI);
1396 });
1397
1398 tagAlloca(IRB, AI, Tag, Size);
1399 TagStarts();
1400 for_each(Info.LifetimeEnd, TagEnd);
1401 for_each(SInfo.RetVec, TagEnd);
1402 EraseLifetimes();
1403 } else {
1404 tagAlloca(IRB, AI, Tag, Size);
1405 for_each(SInfo.RetVec, TagEnd);
1406 EraseLifetimes();
1407 }
1408 memtag::alignAndPadAlloca(Info, Mapping.getObjectAlignment());
1409 }
1410}
1411
1413 bool Skip) {
1414 if (Skip) {
1415 ORE.emit([&]() {
1416 return OptimizationRemark(DEBUG_TYPE, "Skip", &F)
1417 << "Skipped: F=" << ore::NV("Function", &F);
1418 });
1419 } else {
1420 ORE.emit([&]() {
1421 return OptimizationRemarkMissed(DEBUG_TYPE, "Sanitize", &F)
1422 << "Sanitized: F=" << ore::NV("Function", &F);
1423 });
1424 }
1425}
1426
1427bool HWAddressSanitizer::selectiveInstrumentationShouldSkip(
1429 auto SkipHot = [&]() {
1430 if (!Opts.hwasan_percentile_cutoff_hot)
1431 return false;
1433 ProfileSummaryInfo *PSI =
1434 MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
1435 if (!PSI || !PSI->hasProfileSummary()) {
1436 ++NumNoProfileSummaryFuncs;
1437 return false;
1438 }
1439 return PSI->isFunctionHotInCallGraphNthPercentile(
1440 *Opts.hwasan_percentile_cutoff_hot, &F,
1442 };
1443
1444 auto SkipRandom = [&]() {
1445 if (!Opts.hwasan_random_rate)
1446 return false;
1447 std::bernoulli_distribution D(*Opts.hwasan_random_rate);
1448 return !D(*Rng);
1449 };
1450
1451 bool Skip = SkipRandom() || SkipHot();
1453 return Skip;
1454}
1455
1456void HWAddressSanitizer::sanitizeFunction(Function &F,
1458 if (&F == HwasanCtorFunction)
1459 return;
1460
1461 // Do not apply any instrumentation for naked functions.
1462 if (F.hasFnAttribute(Attribute::Naked))
1463 return;
1464
1465 if (!F.hasFnAttribute(Attribute::SanitizeHWAddress))
1466 return;
1467
1468 if (F.empty())
1469 return;
1470
1471 if (F.isPresplitCoroutine())
1472 return;
1473
1474 NumTotalFuncs++;
1475
1478
1479 if (selectiveInstrumentationShouldSkip(F, FAM))
1480 return;
1481
1482 NumInstrumentedFuncs++;
1483
1484 LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n");
1485
1486 SmallVector<InterestingMemoryOperand, 16> OperandsToInstrument;
1487 SmallVector<MemIntrinsic *, 16> IntrinToInstrument;
1488 SmallVector<Instruction *, 8> LandingPadVec;
1490
1492 for (auto &Inst : instructions(F)) {
1493 if (InstrumentStack) {
1494 SIB.visit(ORE, Inst);
1495 }
1496
1497 if (InstrumentLandingPads && isa<LandingPadInst>(Inst))
1498 LandingPadVec.push_back(&Inst);
1499
1500 getInterestingMemoryOperands(ORE, &Inst, TLI, OperandsToInstrument);
1501
1503 if (!ignoreMemIntrinsic(ORE, MI))
1504 IntrinToInstrument.push_back(MI);
1505 }
1506
1507 memtag::StackInfo &SInfo = SIB.get();
1508
1509 initializeCallbacks(*F.getParent());
1510
1511 if (!LandingPadVec.empty())
1512 instrumentLandingPads(LandingPadVec);
1513
1514 if (SInfo.AllocasToInstrument.empty() && F.hasPersonalityFn() &&
1515 F.getPersonalityFn()->getName() == kHwasanPersonalityThunkName) {
1516 // __hwasan_personality_thunk is a no-op for functions without an
1517 // instrumented stack, so we can drop it.
1518 F.setPersonalityFn(nullptr);
1519 }
1520
1521 if (SInfo.AllocasToInstrument.empty() && OperandsToInstrument.empty() &&
1522 IntrinToInstrument.empty())
1523 return;
1524
1525 assert(!ShadowBase);
1526
1527 BasicBlock::iterator InsertPt = F.getEntryBlock().begin();
1528 IRBuilder<> EntryIRB(InsertPt);
1529 emitPrologue(EntryIRB,
1530 /*WithFrameRecord*/ Opts.hwasan_record_stack_history !=
1532 Mapping.withFrameRecord() &&
1533 !SInfo.AllocasToInstrument.empty());
1534
1535 if (!SInfo.AllocasToInstrument.empty()) {
1538 const LoopInfo &LI = FAM.getResult<LoopAnalysis>(F);
1539 Value *StackTag = getStackBaseTag(EntryIRB);
1540 Value *UARTag = getUARTag(EntryIRB);
1541 instrumentStack(ORE, SInfo, StackTag, UARTag, DT, PDT, LI);
1542 }
1543
1544 // If we split the entry block, move any allocas that were originally in the
1545 // entry block back into the entry block so that they aren't treated as
1546 // dynamic allocas.
1547 if (EntryIRB.GetInsertBlock() != &F.getEntryBlock()) {
1548 InsertPt = F.getEntryBlock().begin();
1549 for (Instruction &I :
1550 llvm::make_early_inc_range(*EntryIRB.GetInsertBlock())) {
1551 if (auto *AI = dyn_cast<AllocaInst>(&I))
1552 if (isa<ConstantInt>(AI->getArraySize()))
1553 I.moveBefore(F.getEntryBlock(), InsertPt);
1554 }
1555 }
1556
1560 DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
1561 const DataLayout &DL = F.getDataLayout();
1562 for (auto &Operand : OperandsToInstrument)
1563 instrumentMemAccess(Operand, DTU, LI, DL);
1564 DTU.flush();
1565
1566 if (Opts.hwasan_instrument_mem_intrinsics && !IntrinToInstrument.empty()) {
1567 for (auto *Inst : IntrinToInstrument)
1568 instrumentMemIntrinsic(Inst);
1569 }
1570
1571 ShadowBase = nullptr;
1572 StackBaseTag = nullptr;
1573 CachedFP = nullptr;
1574}
1575
1576void HWAddressSanitizer::instrumentGlobal(GlobalVariable *GV, uint8_t Tag) {
1577 assert(!UsePageAliases);
1578 Constant *Initializer = GV->getInitializer();
1579 uint64_t SizeInBytes =
1580 M.getDataLayout().getTypeAllocSize(Initializer->getType());
1581 uint64_t NewSize = alignTo(SizeInBytes, Mapping.getObjectAlignment());
1582 if (SizeInBytes != NewSize) {
1583 // Pad the initializer out to the next multiple of 16 bytes and add the
1584 // required short granule tag.
1585 std::vector<uint8_t> Init(NewSize - SizeInBytes, 0);
1586 Init.back() = Tag;
1588 Initializer = ConstantStruct::getAnon({Initializer, Padding});
1589 }
1590
1591 auto *NewGV = new GlobalVariable(M, Initializer->getType(), GV->isConstant(),
1592 GlobalValue::ExternalLinkage, Initializer,
1593 GV->getName() + ".hwasan");
1594 NewGV->copyAttributesFrom(GV);
1595 NewGV->setLinkage(GlobalValue::PrivateLinkage);
1596 NewGV->copyMetadata(GV, 0);
1597 NewGV->setAlignment(
1598 std::max(GV->getAlign().valueOrOne(), Mapping.getObjectAlignment()));
1599
1600 // It is invalid to ICF two globals that have different tags. In the case
1601 // where the size of the global is a multiple of the tag granularity the
1602 // contents of the globals may be the same but the tags (i.e. symbol values)
1603 // may be different, and the symbols are not considered during ICF. In the
1604 // case where the size is not a multiple of the granularity, the short granule
1605 // tags would discriminate two globals with different tags, but there would
1606 // otherwise be nothing stopping such a global from being incorrectly ICF'd
1607 // with an uninstrumented (i.e. tag 0) global that happened to have the short
1608 // granule tag in the last byte.
1609 NewGV->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
1610
1611 // Descriptor format (assuming little-endian):
1612 // bytes 0-3: relative address of global
1613 // bytes 4-6: size of global (16MB ought to be enough for anyone, but in case
1614 // it isn't, we create multiple descriptors)
1615 // byte 7: tag
1616 auto *DescriptorTy = StructType::get(Int32Ty, Int32Ty);
1617 const uint64_t MaxDescriptorSize = 0xfffff0;
1618 for (uint64_t DescriptorPos = 0; DescriptorPos < SizeInBytes;
1619 DescriptorPos += MaxDescriptorSize) {
1620 auto *Descriptor =
1621 new GlobalVariable(M, DescriptorTy, true, GlobalValue::PrivateLinkage,
1622 nullptr, GV->getName() + ".hwasan.descriptor");
1623 auto *GVRelPtr = ConstantExpr::getTrunc(
1626 ConstantExpr::getPtrToInt(NewGV, Int64Ty),
1627 ConstantExpr::getPtrToInt(Descriptor, Int64Ty)),
1628 ConstantInt::get(Int64Ty, DescriptorPos)),
1629 Int32Ty);
1630 uint32_t Size = std::min(SizeInBytes - DescriptorPos, MaxDescriptorSize);
1631 auto *SizeAndTag = ConstantInt::get(Int32Ty, Size | (uint32_t(Tag) << 24));
1632 Descriptor->setComdat(NewGV->getComdat());
1633 Descriptor->setInitializer(ConstantStruct::getAnon({GVRelPtr, SizeAndTag}));
1634 Descriptor->setSection("hwasan_globals");
1635 Descriptor->setMetadata(LLVMContext::MD_associated,
1637 appendToCompilerUsed(M, Descriptor);
1638 }
1639
1642 ConstantExpr::getPtrToInt(NewGV, Int64Ty),
1643 ConstantInt::get(Int64Ty, uint64_t(Tag) << PointerTagShift)),
1644 GV->getType());
1645 auto *Alias = GlobalAlias::create(GV->getValueType(), GV->getAddressSpace(),
1646 GV->getLinkage(), "", Aliasee, &M);
1647 Alias->setVisibility(GV->getVisibility());
1648 Alias->takeName(GV);
1649 GV->replaceAllUsesWith(Alias);
1650 GV->eraseFromParent();
1651}
1652
1653void HWAddressSanitizer::instrumentGlobals() {
1654 std::vector<GlobalVariable *> Globals;
1655 for (GlobalVariable &GV : M.globals()) {
1657 continue;
1658
1659 if (GV.isDeclarationForLinker() || GV.getName().starts_with("llvm.") ||
1660 GV.isThreadLocal())
1661 continue;
1662
1663 // Common symbols can't have aliases point to them, so they can't be tagged.
1664 if (GV.hasCommonLinkage())
1665 continue;
1666
1667 if (Opts.hwasan_all_globals) {
1668 // Avoid instrumenting intrinsic global variables.
1669 if (GV.getSection() == "llvm.metadata")
1670 continue;
1671 } else {
1672 // Globals with custom sections may be used in __start_/__stop_
1673 // enumeration, which would be broken both by adding tags and potentially
1674 // by the extra padding/alignment that we insert.
1675 if (GV.hasSection())
1676 continue;
1677 }
1678
1679 Globals.push_back(&GV);
1680 }
1681
1682 MD5 Hasher;
1683 Hasher.update(M.getSourceFileName());
1684 MD5::MD5Result Hash;
1685 Hasher.final(Hash);
1686 uint8_t Tag = Hash[0];
1687
1688 assert(TagMaskByte >= 16);
1689
1690 for (GlobalVariable *GV : Globals) {
1691 // Don't allow globals to be tagged with something that looks like a
1692 // short-granule tag, otherwise we lose inter-granule overflow detection, as
1693 // the fast path shadow-vs-address check succeeds.
1694 if (Tag < 16 || Tag > TagMaskByte)
1695 Tag = 16;
1696 instrumentGlobal(GV, Tag++);
1697 }
1698}
1699
1700void HWAddressSanitizer::instrumentPersonalityFunctions() {
1701 // We need to untag stack frames as we unwind past them. That is the job of
1702 // the personality function wrapper, which either wraps an existing
1703 // personality function or acts as a personality function on its own. Each
1704 // function that has a personality function or that can be unwound past has
1705 // its personality function changed to a thunk that calls the personality
1706 // function wrapper in the runtime.
1708 for (Function &F : M) {
1709 if (F.isDeclaration() || !F.hasFnAttribute(Attribute::SanitizeHWAddress))
1710 continue;
1711
1712 if (F.hasPersonalityFn()) {
1713 PersonalityFns[F.getPersonalityFn()->stripPointerCasts()].push_back(&F);
1714 } else if (!F.hasFnAttribute(Attribute::NoUnwind)) {
1715 PersonalityFns[nullptr].push_back(&F);
1716 }
1717 }
1718
1719 if (PersonalityFns.empty())
1720 return;
1721
1722 FunctionCallee HwasanPersonalityWrapper = M.getOrInsertFunction(
1723 "__hwasan_personality_wrapper", Int32Ty, Int32Ty, Int32Ty, Int64Ty, PtrTy,
1724 PtrTy, PtrTy, PtrTy, PtrTy);
1725 FunctionCallee UnwindGetGR = M.getOrInsertFunction("_Unwind_GetGR", VoidTy);
1726 FunctionCallee UnwindGetCFA = M.getOrInsertFunction("_Unwind_GetCFA", VoidTy);
1727
1728 for (auto &P : PersonalityFns) {
1729 std::string ThunkName = kHwasanPersonalityThunkName;
1730 if (P.first)
1731 ThunkName += ("." + P.first->getName()).str();
1732 FunctionType *ThunkFnTy = FunctionType::get(
1733 Int32Ty, {Int32Ty, Int32Ty, Int64Ty, PtrTy, PtrTy}, false);
1734 bool IsLocal = P.first && (!isa<GlobalValue>(P.first) ||
1735 cast<GlobalValue>(P.first)->hasLocalLinkage());
1736 auto *ThunkFn = Function::Create(ThunkFnTy,
1739 ThunkName, &M);
1740 // TODO: think about other attributes as well.
1741 if (any_of(P.second, [](const Function *F) {
1742 return F->hasFnAttribute("branch-target-enforcement");
1743 })) {
1744 ThunkFn->addFnAttr("branch-target-enforcement");
1745 }
1746 if (!IsLocal) {
1747 ThunkFn->setVisibility(GlobalValue::HiddenVisibility);
1748 ThunkFn->setComdat(M.getOrInsertComdat(ThunkName));
1749 }
1750
1751 auto *BB = BasicBlock::Create(*C, "entry", ThunkFn);
1752 IRBuilder<> IRB(BB);
1753 CallInst *WrapperCall = IRB.CreateCall(
1754 HwasanPersonalityWrapper,
1755 {ThunkFn->getArg(0), ThunkFn->getArg(1), ThunkFn->getArg(2),
1756 ThunkFn->getArg(3), ThunkFn->getArg(4),
1757 P.first ? P.first : Constant::getNullValue(PtrTy),
1758 UnwindGetGR.getCallee(), UnwindGetCFA.getCallee()});
1759 WrapperCall->setTailCall();
1760 IRB.CreateRet(WrapperCall);
1761
1762 for (Function *F : P.second)
1763 F->setPersonalityFn(ThunkFn);
1764 }
1765}
1766
1767void HWAddressSanitizer::ShadowMapping::init(const InstrumentationOptions &Opts,
1768 Triple &TargetTriple,
1769 bool InstrumentWithCalls,
1770 bool CompileKernel) {
1771 // Start with defaults.
1772 Scale = kDefaultShadowScale;
1773 Kind = OffsetKind::kTls;
1774 WithFrameRecord = true;
1775
1776 // Tune for the target.
1777 if (TargetTriple.isOSFuchsia()) {
1778 // Fuchsia is always PIE, which means that the beginning of the address
1779 // space is always available.
1780 Kind = OffsetKind::kGlobal;
1781 } else if (CompileKernel || InstrumentWithCalls) {
1782 SetFixed(0);
1783 WithFrameRecord = false;
1784 }
1785
1786 WithFrameRecord = valueOr(Opts.hwasan_with_frame_record, WithFrameRecord);
1787
1788 // Apply the last of ClMappingOffset and ClMappingOffsetDynamic.
1789 if (ClMappingOffsetDynamic.getNumOccurrences())
1791 if (ClMappingOffset.getNumOccurrences() > 0 &&
1792 !(ClMappingOffsetDynamic.getNumOccurrences() > 0 &&
1793 ClMappingOffsetDynamic.getPosition() > ClMappingOffset.getPosition())) {
1794 SetFixed(ClMappingOffset);
1795 }
1796}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const uint64_t kDefaultShadowScale
static const size_t kNumberOfAccessSizes
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
static uint64_t scale(uint64_t Num, uint32_t N, uint32_t D)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file contains constants used for implementing Dwarf debug support.
#define DEBUG_TYPE
This is the interface for a simple mod/ref and alias analysis over globals.
static size_t TypeSizeToSizeIndex(uint32_t TypeSize)
static cl::opt< uint64_t > ClMappingOffset("hwasan-mapping-offset", cl::desc("HWASan shadow mapping offset [EXPERIMENTAL]"), cl::Hidden)
const char kHwasanModuleCtorName[]
const char kHwasanNoteName[]
static const unsigned kShadowBaseAlignment
static cl::opt< OffsetKind > ClMappingOffsetDynamic("hwasan-mapping-offset-dynamic", cl::desc("HWASan shadow mapping dynamic offset location"), cl::Hidden, cl::values(clEnumValN(OffsetKind::kGlobal, "global", "Use global"), clEnumValN(OffsetKind::kIfunc, "ifunc", "Use ifunc global"), clEnumValN(OffsetKind::kTls, "tls", "Use TLS")))
static const size_t kNumberOfAccessSizes
const char kHwasanShadowMemoryDynamicAddress[]
static unsigned getPointerOperandIndex(Instruction *I)
#define DEBUG_TYPE
const char kHwasanInitName[]
const char kHwasanPersonalityThunkName[]
static void emitRemark(const Function &F, OptimizationRemarkEmitter &ORE, bool Skip)
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file implements a map that provides insertion order iteration.
uint64_t IntrinsicInst * II
#define P(N)
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This file contains some functions that are useful when dealing with strings.
#define LLVM_DEBUG(...)
Definition Debug.h:119
an instruction to allocate memory on the stack
PointerType * getType() const
Overload to return most specific pointer type.
const Value * getArraySize() const
Get the number of elements allocated.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
An instruction that atomically checks whether a specified value is in a memory location,...
an instruction that atomically reads a memory location, combines it with another value,...
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
Analysis pass which computes BlockFrequencyInfo.
This class represents a function call, abstracting a target machine's calling convention.
void setTailCall(bool IsTc=true)
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:878
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getAdd(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI Constant * getTrunc(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
Definition Constants.h:643
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Class to represent function types.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:169
void flush()
Apply all pending updates to available trees and flush all BasicBlocks awaiting deletion.
static LLVM_ABI 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:692
StringRef getSection() const
Get the custom section of this global if it has one.
LLVM_ABI void setComdat(Comdat *C)
Definition Globals.cpp:287
bool hasSection() const
Check if this global has a custom object file section.
LLVM_ABI const SanitizerMetadata & getSanitizerMetadata() const
Definition Globals.cpp:318
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
VisibilityTypes getVisibility() const
LinkageTypes getLinkage() const
bool isDeclarationForLinker() const
bool hasSanitizerMetadata() const
unsigned getAddressSpace() const
PointerType * getType() const
Global values are always pointers.
@ HiddenVisibility
The GV is hidden.
Definition GlobalValue.h:69
bool hasCommonLinkage() const
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Definition GlobalValue.h:56
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition Globals.cpp:609
Analysis pass providing a never-invalidated alias analysis result.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
Value * CreateConstGEP1_32(Type *Ty, Value *Ptr, unsigned Idx0, const Twine &Name="")
Definition IRBuilder.h:2033
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2306
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2247
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1537
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:531
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2101
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition IRBuilder.h:1197
Module * getModule() const
Get the module.
Definition IRBuilder.h:192
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1478
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2395
Value * CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2399
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:1916
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1516
CallInst * CreateMemSet(Value *Ptr, Value *Val, uint64_t Size, MaybeAlign Align, bool isVolatile=false, const AAMDNodes &AAInfo=AAMDNodes())
Create and insert a memset to the specified pointer and the specified value.
Definition IRBuilder.h:605
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition IRBuilder.h:2130
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1575
LLVM_ABI Value * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={}, function_ref< void(CallInst *)> SetFn=[](CallInst *) {})
Variant to create a possibly constant-folded intrinsic.
StoreInst * CreateStore(Value *Val, Value *Ptr, bool isVolatile=false)
Definition IRBuilder.h:1934
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1427
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2570
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2116
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Definition IRBuilder.h:574
LLVM_ABI Value * CreateTypeSize(Type *Ty, TypeSize Size)
Create an expression which evaluates to the number of units in Size at runtime.
Value * CreateICmpUGE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2403
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition IRBuilder.h:2332
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:199
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1556
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1627
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1597
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2918
static LLVM_ABI InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
Definition InlineAsm.cpp:43
LLVM_ABI void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
Analysis pass that exposes the LoopInfo for a function.
Definition LoopInfo.h:594
LLVM_ABI void update(ArrayRef< uint8_t > Data)
Updates the hash for the byte stream provided.
Definition MD5.cpp:188
LLVM_ABI void final(MD5Result &Result)
Finishes off the hash and puts the result in result.
Definition MD5.cpp:233
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
Definition MDBuilder.cpp:48
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1579
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:38
bool empty() const
Definition MapVector.h:79
This is the common base class for memset/memcpy/memmove.
This class wraps the llvm.memcpy/memmove intrinsics.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
GlobalVariable * getOrInsertGlobal(StringRef Name, Type *Ty, function_ref< GlobalVariable *()> CreateGlobalCallback)
Look up the specified global in the module symbol table.
Definition Module.cpp:262
The optimization diagnostic interface.
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
Diagnostic information for missed-optimization remarks.
Diagnostic information for applied optimization remarks.
Analysis pass which computes a PostDominatorTree.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & abandon()
Mark an analysis as abandoned.
Definition Analysis.h:171
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This pass performs the global (interprocedural) stack safety analysis (new pass manager).
LLVM_ABI bool stackAccessIsSafe(const Instruction &I) const
An instruction for storing to memory.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
static LLVM_ABI 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:467
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool isAndroidVersionLT(unsigned Major) const
Definition Triple.h:913
bool isAndroid() const
Tests whether the target is Android.
Definition Triple.h:911
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition Triple.h:515
bool isRISCV64() const
Tests whether the target is 64-bit RISC-V.
Definition Triple.h:1179
bool isAArch64() const
Tests whether the target is AArch64 (little and big endian).
Definition Triple.h:1099
bool isOSFuchsia() const
Definition Triple.h:751
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition Triple.h:867
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
static LLVM_ABI ValueAsMetadata * get(Value *V)
Definition Metadata.cpp:514
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:394
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror value.
Definition Value.cpp:1164
LLVM_ABI bool 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:561
bool hasName() const
Definition Value.h:263
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
void getInterestingMemoryOperands(Module &M, Instruction *I, SmallVectorImpl< InterestingMemoryOperand > &Interesting)
Get all the memory operands from the instruction that needs to be instrumented.
@ NT_LLVM_HWASAN_GLOBALS
Definition ELF.h:1818
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
LLVM_ABI Value * getFP(IRBuilder<> &IRB)
LLVM_ABI void forAllReachableExits(const DominatorTree &DT, const PostDominatorTree &PDT, const LoopInfo &LI, const AllocaInfo &AInfo, const SmallVectorImpl< Instruction * > &RetVec, llvm::function_ref< void(Instruction *)> Callback)
LLVM_ABI bool isSupportedLifetime(const AllocaInfo &AInfo, const DominatorTree *DT, const LoopInfo *LI)
LLVM_ABI uint64_t getAllocaSizeInBytes(const AllocaInst &AI)
LLVM_ABI Value * getAndroidSlotPtr(IRBuilder<> &IRB, int Slot)
LLVM_ABI Value * readRegister(IRBuilder<> &IRB, StringRef Name)
LLVM_ABI void annotateDebugRecords(AllocaInfo &Info, unsigned int Tag)
LLVM_ABI void alignAndPadAlloca(memtag::AllocaInfo &Info, llvm::Align Align)
LLVM_ABI Value * getPC(const Triple &TargetTriple, IRBuilder<> &IRB)
LLVM_ABI Value * incrementThreadLong(IRBuilder<> &IRB, Value *ThreadLong, unsigned int Inc, bool IsMemtagDarwin=false)
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1748
@ Known
Known to have no common set bits.
LLVM_ABI AllocaInst * findAllocaForValue(Value *V, bool OffsetZero=false)
Returns unique alloca where the value comes from, or nullptr.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:285
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:204
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
LLVM_ABI 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(), bool Weak=false)
Creates sanitizer constructor function lazily.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
LLVM_ABI void removeASanIncompatibleFnAttributes(Function &F, bool ReadsArgMem)
Remove memory attributes that are incompatible with the instrumentation added by AddressSanitizer and...
LLVM_ABI 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.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
constexpr bool valueOr(BoolOrDefault X, bool Default)
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void maybeMarkSanitizerLibraryCallNoBuiltin(CallInst *CI, const TargetLibraryInfo *TLI)
Given a CallInst, check if it calls a string function known to CodeGen, and mark it with NoBuiltin if...
Definition Local.cpp:3902
LLVM_ABI bool checkIfAlreadyInstrumented(Module &M, StringRef Flag)
Check if module has flag attached, if not add the flag.
std::string itostr(int64_t X)
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static constexpr Align fromLog2(unsigned Log2Value)
Returns an alignment of 1 << Log2Value bytes.
Definition Alignment.h:73
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.
Definition Alignment.h:135
MapVector< AllocaInst *, AllocaInfo > AllocasToInstrument
SmallVector< Instruction *, 8 > RetVec