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 =
355 M.getContext().getLibraryOptions().get<InstrumentationOptions>();
356 if (shouldUseStackSafetyAnalysis(Opts, TargetTriple,
357 Options.DisableOptimization))
358 SSI = &MAM.getResult<StackSafetyGlobalAnalysis>(M);
359
360 HWAddressSanitizer HWASan(Opts, M, Options.CompileKernel, Options.Recover,
361 SSI);
362 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
363 for (Function &F : M)
364 HWASan.sanitizeFunction(F, FAM);
365
367 // DominatorTreeAnalysis, PostDominatorTreeAnalysis, and LoopAnalysis
368 // are incrementally updated throughout this pass whenever
369 // SplitBlockAndInsertIfThen is called.
373 // GlobalsAA is considered stateless and does not get invalidated unless
374 // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
375 // make changes that require GlobalsAA to be invalidated.
376 PA.abandon<GlobalsAA>();
377 return PA;
378}
380 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
381 static_cast<PassInfoMixin<HWAddressSanitizerPass> *>(this)->printPipeline(
382 OS, MapClassName2PassName);
383 OS << '<';
384 if (Options.CompileKernel)
385 OS << "kernel;";
386 if (Options.Recover)
387 OS << "recover";
388 OS << '>';
389}
390
391void HWAddressSanitizer::createHwasanNote() {
392 // Create a note that contains pointers to the list of global
393 // descriptors. Adding a note to the output file will cause the linker to
394 // create a PT_NOTE program header pointing to the note that we can use to
395 // find the descriptor list starting from the program headers. A function
396 // provided by the runtime initializes the shadow memory for the globals by
397 // accessing the descriptor list via the note. The dynamic loader needs to
398 // call this function whenever a library is loaded.
399 //
400 // The reason why we use a note for this instead of a more conventional
401 // approach of having a global constructor pass a descriptor list pointer to
402 // the runtime is because of an order of initialization problem. With
403 // constructors we can encounter the following problematic scenario:
404 //
405 // 1) library A depends on library B and also interposes one of B's symbols
406 // 2) B's constructors are called before A's (as required for correctness)
407 // 3) during construction, B accesses one of its "own" globals (actually
408 // interposed by A) and triggers a HWASAN failure due to the initialization
409 // for A not having happened yet
410 //
411 // Even without interposition it is possible to run into similar situations in
412 // cases where two libraries mutually depend on each other.
413 //
414 // We only need one note per binary, so put everything for the note in a
415 // comdat. This needs to be a comdat with an .init_array section to prevent
416 // newer versions of lld from discarding the note.
417 //
418 // Create the note even if we aren't instrumenting globals. This ensures that
419 // binaries linked from object files with both instrumented and
420 // non-instrumented globals will end up with a note, even if a comdat from an
421 // object file with non-instrumented globals is selected. The note is harmless
422 // if the runtime doesn't support it, since it will just be ignored.
423 Comdat *NoteComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
424
425 Type *Int8Arr0Ty = ArrayType::get(Int8Ty, 0);
426 auto *Start =
427 new GlobalVariable(M, Int8Arr0Ty, true, GlobalVariable::ExternalLinkage,
428 nullptr, "__start_hwasan_globals");
429 Start->setVisibility(GlobalValue::HiddenVisibility);
430 auto *Stop =
431 new GlobalVariable(M, Int8Arr0Ty, true, GlobalVariable::ExternalLinkage,
432 nullptr, "__stop_hwasan_globals");
433 Stop->setVisibility(GlobalValue::HiddenVisibility);
434
435 // Null-terminated so actually 8 bytes, which are required in order to align
436 // the note properly.
437 auto *Name = ConstantDataArray::get(*C, "LLVM\0\0\0");
438
439 auto *NoteTy = StructType::get(Int32Ty, Int32Ty, Int32Ty, Name->getType(),
440 Int32Ty, Int32Ty);
441 auto *Note =
442 new GlobalVariable(M, NoteTy, /*isConstant=*/true,
444 Note->setSection(".note.hwasan.globals");
445 Note->setComdat(NoteComdat);
446 Note->setAlignment(Align(4));
447
448 // The pointers in the note need to be relative so that the note ends up being
449 // placed in rodata, which is the standard location for notes.
450 auto CreateRelPtr = [&](Constant *Ptr) {
454 Int32Ty);
455 };
456 Note->setInitializer(ConstantStruct::getAnon(
457 {ConstantInt::get(Int32Ty, 8), // n_namesz
458 ConstantInt::get(Int32Ty, 8), // n_descsz
459 ConstantInt::get(Int32Ty, ELF::NT_LLVM_HWASAN_GLOBALS), // n_type
460 Name, CreateRelPtr(Start), CreateRelPtr(Stop)}));
462
463 // Create a zero-length global in hwasan_globals so that the linker will
464 // always create start and stop symbols.
465 auto *Dummy = new GlobalVariable(
466 M, Int8Arr0Ty, /*isConstantGlobal*/ true, GlobalVariable::PrivateLinkage,
467 Constant::getNullValue(Int8Arr0Ty), "hwasan.dummy.global");
468 Dummy->setSection("hwasan_globals");
469 Dummy->setComdat(NoteComdat);
470 Dummy->setMetadata(LLVMContext::MD_associated,
472 appendToCompilerUsed(M, Dummy);
473}
474
475void HWAddressSanitizer::createHwasanCtorComdat() {
476 std::tie(HwasanCtorFunction, std::ignore) =
479 /*InitArgTypes=*/{},
480 /*InitArgs=*/{},
481 // This callback is invoked when the functions are created the first
482 // time. Hook them into the global ctors list in that case:
483 [&](Function *Ctor, FunctionCallee) {
484 Comdat *CtorComdat = M.getOrInsertComdat(kHwasanModuleCtorName);
485 Ctor->setComdat(CtorComdat);
486 appendToGlobalCtors(M, Ctor, 0, Ctor);
487 });
488
489 // Do not create .note.hwasan.globals for static binaries, as it is only
490 // needed for instrumenting globals from dynamic libraries. In static
491 // binaries, the global variables section can be accessed directly via the
492 // __start_hwasan_globals and __stop_hwasan_globals symbols inserted by the
493 // linker.
494 if (!Opts.hwasan_static_linking)
495 createHwasanNote();
496}
497
498/// Module-level initialization.
499///
500/// inserts a call to __hwasan_init to the module's constructor list.
501void HWAddressSanitizer::initializeModule() {
502 LLVM_DEBUG(dbgs() << "Init " << M.getName() << "\n");
503 TargetTriple = M.getTargetTriple();
504
505 // HWASan may do short granule checks on function arguments read from the
506 // argument memory (last byte of the granule), which invalidates writeonly.
507 for (Function &F : M.functions())
508 removeASanIncompatibleFnAttributes(F, /*ReadsArgMem=*/true);
509
510 // x86_64 currently has two modes:
511 // - Intel LAM (default)
512 // - pointer aliasing (heap only)
513 bool IsX86_64 = TargetTriple.getArch() == Triple::x86_64;
514 UsePageAliases = shouldUsePageAliases(Opts, TargetTriple);
515 InstrumentWithCalls = shouldInstrumentWithCalls(Opts, TargetTriple);
516 InstrumentStack = shouldInstrumentStack(Opts, TargetTriple);
517 DetectUseAfterScope = shouldDetectUseAfterScope(Opts, TargetTriple);
518 PointerTagShift = IsX86_64 ? 57 : 56;
519 TagMaskByte = IsX86_64 ? 0x3F : 0xFF;
520 if (Opts.hwasan_tag_bits) {
521 if (TagMaskByte < 4)
523 "need more than 4 bits of tag to have non-short-granule tags");
524 TagMaskByte &= (1ULL << Opts.hwasan_tag_bits) - 1;
525 }
526
527 Mapping.init(Opts, TargetTriple, InstrumentWithCalls, CompileKernel);
528
529 C = &(M.getContext());
530 IRBuilder<> IRB(M);
531
532 HwasanCtorFunction = nullptr;
533
534 // Older versions of Android do not have the required runtime support for
535 // short granules, global or personality function instrumentation. On other
536 // platforms we currently require using the latest version of the runtime.
537 bool NewRuntime =
538 !TargetTriple.isAndroid() || !TargetTriple.isAndroidVersionLT(30);
539
540 UseShortGranules = valueOr(Opts.hwasan_use_short_granules, NewRuntime);
541 OutlinedChecks = (TargetTriple.isAArch64() || TargetTriple.isRISCV64()) &&
542 TargetTriple.isOSBinFormatELF() &&
543 !valueOr(Opts.hwasan_inline_all_checks, Recover);
544
545 // These platforms may prefer less inlining to reduce binary size.
546 InlineFastPath =
547 valueOr(Opts.hwasan_inline_fast_path_checks,
548 !(TargetTriple.isAndroid() || TargetTriple.isOSFuchsia()));
549
550 if (Opts.hwasan_match_all_tag) {
551 if (*Opts.hwasan_match_all_tag != -1) {
552 MatchAllTag = *Opts.hwasan_match_all_tag & 0xFF;
553 }
554 } else if (CompileKernel) {
555 MatchAllTag = 0xFF;
556 }
557 UseMatchAllCallback = !CompileKernel && MatchAllTag.has_value();
558
559 // If we don't have personality function support, fall back to landing pads.
560 InstrumentLandingPads =
561 valueOr(Opts.hwasan_instrument_landing_pads, !NewRuntime);
562
563 InstrumentGlobals = !CompileKernel && !UsePageAliases &&
564 valueOr(Opts.hwasan_globals, NewRuntime);
565
566 if (!CompileKernel) {
567 if (InstrumentGlobals)
568 instrumentGlobals();
569
570 createHwasanCtorComdat();
571
572 bool InstrumentPersonalityFunctions =
573 valueOr(Opts.hwasan_instrument_personality_functions, NewRuntime);
574 if (InstrumentPersonalityFunctions)
575 instrumentPersonalityFunctions();
576 }
577
578 if (!TargetTriple.isAndroid()) {
579 ThreadPtrGlobal = M.getOrInsertGlobal("__hwasan_tls", IntptrTy, [&] {
580 auto *GV = new GlobalVariable(M, IntptrTy, /*isConstant=*/false,
582 "__hwasan_tls", nullptr,
585 return GV;
586 });
587 }
588}
589
590void HWAddressSanitizer::initializeCallbacks(Module &M) {
591 IRBuilder<> IRB(M);
592 const std::string MatchAllStr = UseMatchAllCallback ? "_match_all" : "";
593 FunctionType *HwasanMemoryAccessCallbackSizedFnTy,
594 *HwasanMemoryAccessCallbackFnTy, *HwasanMemTransferFnTy,
595 *HwasanMemsetFnTy;
596 if (UseMatchAllCallback) {
597 HwasanMemoryAccessCallbackSizedFnTy =
598 FunctionType::get(VoidTy, {IntptrTy, IntptrTy, Int8Ty}, false);
599 HwasanMemoryAccessCallbackFnTy =
600 FunctionType::get(VoidTy, {IntptrTy, Int8Ty}, false);
601 HwasanMemTransferFnTy =
602 FunctionType::get(PtrTy, {PtrTy, PtrTy, IntptrTy, Int8Ty}, false);
603 HwasanMemsetFnTy =
604 FunctionType::get(PtrTy, {PtrTy, Int32Ty, IntptrTy, Int8Ty}, false);
605 } else {
606 HwasanMemoryAccessCallbackSizedFnTy =
607 FunctionType::get(VoidTy, {IntptrTy, IntptrTy}, false);
608 HwasanMemoryAccessCallbackFnTy =
609 FunctionType::get(VoidTy, {IntptrTy}, false);
610 HwasanMemTransferFnTy =
611 FunctionType::get(PtrTy, {PtrTy, PtrTy, IntptrTy}, false);
612 HwasanMemsetFnTy =
613 FunctionType::get(PtrTy, {PtrTy, Int32Ty, IntptrTy}, false);
614 }
615
616 for (size_t AccessIsWrite = 0; AccessIsWrite <= 1; AccessIsWrite++) {
617 const std::string TypeStr = AccessIsWrite ? "store" : "load";
618 const std::string EndingStr = Recover ? "_noabort" : "";
619
620 HwasanMemoryAccessCallbackSized[AccessIsWrite] =
621 M.getOrInsertFunction((Opts.hwasan_memory_access_callback_prefix +
622 TypeStr + "N" + MatchAllStr + EndingStr)
623 .str(),
624 HwasanMemoryAccessCallbackSizedFnTy);
625
626 for (size_t AccessSizeIndex = 0; AccessSizeIndex < kNumberOfAccessSizes;
627 AccessSizeIndex++) {
628 HwasanMemoryAccessCallback[AccessIsWrite][AccessSizeIndex] =
629 M.getOrInsertFunction((Opts.hwasan_memory_access_callback_prefix +
630 TypeStr + itostr(1ULL << AccessSizeIndex) +
631 MatchAllStr + EndingStr)
632 .str(),
633 HwasanMemoryAccessCallbackFnTy);
634 }
635 }
636
637 const std::string MemIntrinCallbackPrefix =
638 (CompileKernel && !Opts.hwasan_kernel_mem_intrinsic_prefix)
639 ? std::string("")
640 : Opts.hwasan_memory_access_callback_prefix.str();
641
642 HwasanMemmove = M.getOrInsertFunction(
643 MemIntrinCallbackPrefix + "memmove" + MatchAllStr, HwasanMemTransferFnTy);
644 HwasanMemcpy = M.getOrInsertFunction(
645 MemIntrinCallbackPrefix + "memcpy" + MatchAllStr, HwasanMemTransferFnTy);
646 HwasanMemset = M.getOrInsertFunction(
647 MemIntrinCallbackPrefix + "memset" + MatchAllStr, HwasanMemsetFnTy);
648
649 HwasanTagMemoryFunc = M.getOrInsertFunction("__hwasan_tag_memory", VoidTy,
650 PtrTy, Int8Ty, IntptrTy);
651 HwasanGenerateTagFunc =
652 M.getOrInsertFunction("__hwasan_generate_tag", Int8Ty);
653
654 HwasanRecordFrameRecordFunc =
655 M.getOrInsertFunction("__hwasan_add_frame_record", VoidTy, Int64Ty);
656
657 ShadowGlobal =
658 M.getOrInsertGlobal("__hwasan_shadow", ArrayType::get(Int8Ty, 0));
659
660 HwasanHandleVfork =
661 M.getOrInsertFunction("__hwasan_handle_vfork", VoidTy, IntptrTy);
662}
663
664Value *HWAddressSanitizer::getOpaqueNoopCast(IRBuilder<> &IRB, Value *Val) {
665 // An empty inline asm with input reg == output reg.
666 // An opaque no-op cast, basically.
667 // This prevents code bloat as a result of rematerializing trivial definitions
668 // such as constants or global addresses at every load and store.
669 InlineAsm *Asm =
670 InlineAsm::get(FunctionType::get(PtrTy, {Val->getType()}, false),
671 StringRef(""), StringRef("=r,0"),
672 /*hasSideEffects=*/false);
673 return IRB.CreateCall(Asm, {Val}, ".hwasan.shadow");
674}
675
676Value *HWAddressSanitizer::getDynamicShadowIfunc(IRBuilder<> &IRB) {
677 return getOpaqueNoopCast(IRB, ShadowGlobal);
678}
679
680Value *HWAddressSanitizer::getShadowNonTls(IRBuilder<> &IRB) {
681 if (Mapping.isFixed()) {
682 return getOpaqueNoopCast(
684 ConstantInt::get(IntptrTy, Mapping.offset()), PtrTy));
685 }
686
687 if (Mapping.isInIfunc())
688 return getDynamicShadowIfunc(IRB);
689
690 Value *GlobalDynamicAddress = IRB.getModule()->getOrInsertGlobal(
692 return IRB.CreateLoad(PtrTy, GlobalDynamicAddress);
693}
694
695bool HWAddressSanitizer::ignoreAccessWithoutRemark(Instruction *Inst,
696 Value *Ptr) {
697 // Do not instrument accesses from different address spaces; we cannot deal
698 // with them.
699 Type *PtrTy = cast<PointerType>(Ptr->getType()->getScalarType());
700 if (PtrTy->getPointerAddressSpace() != 0)
701 return true;
702
703 // Ignore swifterror addresses.
704 // swifterror memory addresses are mem2reg promoted by instruction
705 // selection. As such they cannot have regular uses like an instrumentation
706 // function and it makes no sense to track them as memory.
707 if (Ptr->isSwiftError())
708 return true;
709
710 if (findAllocaForValue(Ptr)) {
711 if (!InstrumentStack)
712 return true;
713 if (SSI && SSI->stackAccessIsSafe(*Inst))
714 return true;
715 }
716
718 if (!InstrumentGlobals)
719 return true;
720 // TODO: Optimize inbound global accesses, like Asan `instrumentMop`.
721 }
722
723 return false;
724}
725
726bool HWAddressSanitizer::ignoreAccess(OptimizationRemarkEmitter &ORE,
727 Instruction *Inst, Value *Ptr) {
728 bool Ignored = ignoreAccessWithoutRemark(Inst, Ptr);
729 if (Ignored) {
730 ORE.emit(
731 [&]() { return OptimizationRemark(DEBUG_TYPE, "ignoreAccess", Inst); });
732 } else {
733 ORE.emit([&]() {
734 return OptimizationRemarkMissed(DEBUG_TYPE, "ignoreAccess", Inst);
735 });
736 }
737 return Ignored;
738}
739
740void HWAddressSanitizer::getInterestingMemoryOperands(
742 const TargetLibraryInfo &TLI,
744 // Skip memory accesses inserted by another instrumentation.
745 if (I->hasMetadata(LLVMContext::MD_nosanitize))
746 return;
747
748 // Do not instrument the load fetching the dynamic shadow address.
749 if (ShadowBase == I)
750 return;
751
752 if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
753 if (!Opts.hwasan_instrument_reads ||
754 ignoreAccess(ORE, I, LI->getPointerOperand()))
755 return;
756 Interesting.emplace_back(I, LI->getPointerOperandIndex(), false,
757 LI->getType(), LI->getAlign());
758 } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
759 if (!Opts.hwasan_instrument_writes ||
760 ignoreAccess(ORE, I, SI->getPointerOperand()))
761 return;
762 Interesting.emplace_back(I, SI->getPointerOperandIndex(), true,
763 SI->getValueOperand()->getType(), SI->getAlign());
764 } else if (AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(I)) {
765 if (!Opts.hwasan_instrument_atomics ||
766 ignoreAccess(ORE, I, RMW->getPointerOperand()))
767 return;
768 Interesting.emplace_back(I, RMW->getPointerOperandIndex(), true,
769 RMW->getValOperand()->getType(), std::nullopt);
770 } else if (AtomicCmpXchgInst *XCHG = dyn_cast<AtomicCmpXchgInst>(I)) {
771 if (!Opts.hwasan_instrument_atomics ||
772 ignoreAccess(ORE, I, XCHG->getPointerOperand()))
773 return;
774 Interesting.emplace_back(I, XCHG->getPointerOperandIndex(), true,
775 XCHG->getCompareOperand()->getType(),
776 std::nullopt);
777 } else if (auto *CI = dyn_cast<CallInst>(I)) {
778 for (unsigned ArgNo = 0; ArgNo < CI->arg_size(); ArgNo++) {
779 if (!Opts.hwasan_instrument_byval || !CI->isByValArgument(ArgNo) ||
780 ignoreAccess(ORE, I, CI->getArgOperand(ArgNo)))
781 continue;
782 Type *Ty = CI->getParamByValType(ArgNo);
783 Interesting.emplace_back(I, ArgNo, false, Ty, Align(1));
784 }
786 }
787}
788
790 if (LoadInst *LI = dyn_cast<LoadInst>(I))
791 return LI->getPointerOperandIndex();
793 return SI->getPointerOperandIndex();
795 return RMW->getPointerOperandIndex();
797 return XCHG->getPointerOperandIndex();
798 report_fatal_error("Unexpected instruction");
799 return -1;
800}
801
803 size_t Res = llvm::countr_zero(TypeSize / 8);
805 return Res;
806}
807
808void HWAddressSanitizer::untagPointerOperand(Instruction *I, Value *Addr) {
809 if (TargetTriple.isAArch64() || TargetTriple.getArch() == Triple::x86_64 ||
810 TargetTriple.isRISCV64())
811 return;
812
813 IRBuilder<> IRB(I);
814 Value *AddrLong = IRB.CreatePointerCast(Addr, IntptrTy);
815 Value *UntaggedPtr =
816 IRB.CreateIntToPtr(untagPointer(IRB, AddrLong), Addr->getType());
817 I->setOperand(getPointerOperandIndex(I), UntaggedPtr);
818}
819
820Value *HWAddressSanitizer::memToShadow(Value *Mem, IRBuilder<> &IRB) {
821 // Mem >> Scale
822 Value *Shadow = IRB.CreateLShr(Mem, Mapping.scale());
823 if (Mapping.isFixed() && Mapping.offset() == 0)
824 return IRB.CreateIntToPtr(Shadow, PtrTy);
825 // (Mem >> Scale) + Offset
826 return IRB.CreatePtrAdd(ShadowBase, Shadow);
827}
828
829int64_t HWAddressSanitizer::getAccessInfo(bool IsWrite,
830 unsigned AccessSizeIndex) {
831 return (CompileKernel << HWASanAccessInfo::CompileKernelShift) |
832 (MatchAllTag.has_value() << HWASanAccessInfo::HasMatchAllShift) |
833 (MatchAllTag.value_or(0) << HWASanAccessInfo::MatchAllShift) |
834 (Recover << HWASanAccessInfo::RecoverShift) |
835 (IsWrite << HWASanAccessInfo::IsWriteShift) |
836 (AccessSizeIndex << HWASanAccessInfo::AccessSizeShift);
837}
838
839HWAddressSanitizer::ShadowTagCheckInfo
840HWAddressSanitizer::insertShadowTagCheck(Value *Ptr, Instruction *InsertBefore,
841 DomTreeUpdater &DTU, LoopInfo *LI) {
842 ShadowTagCheckInfo R;
843
844 IRBuilder<> IRB(InsertBefore);
845
846 R.PtrLong = IRB.CreatePointerCast(Ptr, IntptrTy);
847 R.PtrTag =
848 IRB.CreateTrunc(IRB.CreateLShr(R.PtrLong, PointerTagShift), Int8Ty);
849 R.AddrLong = untagPointer(IRB, R.PtrLong);
850 Value *Shadow = memToShadow(R.AddrLong, IRB);
851 R.MemTag = IRB.CreateLoad(Int8Ty, Shadow);
852 Value *TagMismatch = IRB.CreateICmpNE(R.PtrTag, R.MemTag);
853
854 if (MatchAllTag.has_value()) {
855 Value *TagNotIgnored = IRB.CreateICmpNE(
856 R.PtrTag, ConstantInt::get(R.PtrTag->getType(), *MatchAllTag));
857 TagMismatch = IRB.CreateAnd(TagMismatch, TagNotIgnored);
858 }
859
860 R.TagMismatchTerm = SplitBlockAndInsertIfThen(
861 TagMismatch, InsertBefore, false,
862 MDBuilder(*C).createUnlikelyBranchWeights(), &DTU, LI);
863
864 return R;
865}
866
867void HWAddressSanitizer::instrumentMemAccessOutline(Value *Ptr, bool IsWrite,
868 unsigned AccessSizeIndex,
869 Instruction *InsertBefore,
870 DomTreeUpdater &DTU,
871 LoopInfo *LI) {
872 assert(!UsePageAliases);
873 const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
874
875 if (InlineFastPath)
876 InsertBefore =
877 insertShadowTagCheck(Ptr, InsertBefore, DTU, LI).TagMismatchTerm;
878
879 IRBuilder<> IRB(InsertBefore);
880 bool UseFixedShadowIntrinsic = false;
881 // The memaccess fixed shadow intrinsic is only supported on AArch64,
882 // which allows a 16-bit immediate to be left-shifted by 32.
883 // Since kShadowBaseAlignment == 32, and Linux by default will not
884 // mmap above 48-bits, practically any valid shadow offset is
885 // representable.
886 // In particular, an offset of 4TB (1024 << 32) is representable, and
887 // ought to be good enough for anybody.
888 if (TargetTriple.isAArch64() && Mapping.isFixed()) {
889 uint16_t OffsetShifted = Mapping.offset() >> 32;
890 UseFixedShadowIntrinsic =
891 static_cast<uint64_t>(OffsetShifted) << 32 == Mapping.offset();
892 }
893
894 if (UseFixedShadowIntrinsic) {
895 IRB.CreateIntrinsic(
896 UseShortGranules
897 ? Intrinsic::hwasan_check_memaccess_shortgranules_fixedshadow
898 : Intrinsic::hwasan_check_memaccess_fixedshadow,
899 {Ptr, ConstantInt::get(Int32Ty, AccessInfo),
900 ConstantInt::get(Int64Ty, Mapping.offset())});
901 } else {
902 IRB.CreateIntrinsic(
903 UseShortGranules ? Intrinsic::hwasan_check_memaccess_shortgranules
904 : Intrinsic::hwasan_check_memaccess,
905 {ShadowBase, Ptr, ConstantInt::get(Int32Ty, AccessInfo)});
906 }
907}
908
909void HWAddressSanitizer::instrumentMemAccessInline(Value *Ptr, bool IsWrite,
910 unsigned AccessSizeIndex,
911 Instruction *InsertBefore,
912 DomTreeUpdater &DTU,
913 LoopInfo *LI) {
914 assert(!UsePageAliases);
915 const int64_t AccessInfo = getAccessInfo(IsWrite, AccessSizeIndex);
916
917 ShadowTagCheckInfo TCI = insertShadowTagCheck(Ptr, InsertBefore, DTU, LI);
918
919 IRBuilder<> IRB(TCI.TagMismatchTerm);
920 Value *OutOfShortGranuleTagRange =
921 IRB.CreateICmpUGT(TCI.MemTag, ConstantInt::get(Int8Ty, 15));
922 Instruction *CheckFailTerm = SplitBlockAndInsertIfThen(
923 OutOfShortGranuleTagRange, TCI.TagMismatchTerm, !Recover,
924 MDBuilder(*C).createUnlikelyBranchWeights(), &DTU, LI);
925
926 IRB.SetInsertPoint(TCI.TagMismatchTerm);
927 Value *PtrLowBits = IRB.CreateTrunc(IRB.CreateAnd(TCI.PtrLong, 15), Int8Ty);
928 PtrLowBits = IRB.CreateAdd(
929 PtrLowBits, ConstantInt::get(Int8Ty, (1 << AccessSizeIndex) - 1));
930 Value *PtrLowBitsOOB = IRB.CreateICmpUGE(PtrLowBits, TCI.MemTag);
931 SplitBlockAndInsertIfThen(PtrLowBitsOOB, TCI.TagMismatchTerm, false,
933 LI, CheckFailTerm->getParent());
934
935 IRB.SetInsertPoint(TCI.TagMismatchTerm);
936 Value *InlineTagAddr = IRB.CreateOr(TCI.AddrLong, 15);
937 InlineTagAddr = IRB.CreateIntToPtr(InlineTagAddr, PtrTy);
938 Value *InlineTag = IRB.CreateLoad(Int8Ty, InlineTagAddr);
939 Value *InlineTagMismatch = IRB.CreateICmpNE(TCI.PtrTag, InlineTag);
940 SplitBlockAndInsertIfThen(InlineTagMismatch, TCI.TagMismatchTerm, false,
942 LI, CheckFailTerm->getParent());
943
944 IRB.SetInsertPoint(CheckFailTerm);
945 InlineAsm *Asm;
946 switch (TargetTriple.getArch()) {
947 case Triple::x86_64:
948 // The signal handler will find the data address in rdi.
950 FunctionType::get(VoidTy, {TCI.PtrLong->getType()}, false),
951 "int3\nnopl " +
952 itostr(0x40 + (AccessInfo & HWASanAccessInfo::RuntimeMask)) +
953 "(%rax)",
954 "{rdi}",
955 /*hasSideEffects=*/true);
956 break;
957 case Triple::aarch64:
959 // The signal handler will find the data address in x0.
961 FunctionType::get(VoidTy, {TCI.PtrLong->getType()}, false),
962 "brk #" + itostr(0x900 + (AccessInfo & HWASanAccessInfo::RuntimeMask)),
963 "{x0}",
964 /*hasSideEffects=*/true);
965 break;
966 case Triple::riscv64:
967 // The signal handler will find the data address in x10.
969 FunctionType::get(VoidTy, {TCI.PtrLong->getType()}, false),
970 "ebreak\naddiw x0, x11, " +
971 itostr(0x40 + (AccessInfo & HWASanAccessInfo::RuntimeMask)),
972 "{x10}",
973 /*hasSideEffects=*/true);
974 break;
975 default:
976 report_fatal_error("unsupported architecture");
977 }
978 IRB.CreateCall(Asm, TCI.PtrLong);
979 if (Recover)
980 cast<UncondBrInst>(CheckFailTerm)
981 ->setSuccessor(TCI.TagMismatchTerm->getParent());
982}
983
984bool HWAddressSanitizer::ignoreMemIntrinsic(OptimizationRemarkEmitter &ORE,
985 MemIntrinsic *MI) {
987 return (!Opts.hwasan_instrument_writes ||
988 ignoreAccess(ORE, MTI, MTI->getDest())) &&
989 (!Opts.hwasan_instrument_reads ||
990 ignoreAccess(ORE, MTI, MTI->getSource()));
991 }
992 if (isa<MemSetInst>(MI))
993 return !Opts.hwasan_instrument_writes ||
994 ignoreAccess(ORE, MI, MI->getDest());
995 return false;
996}
997
998void HWAddressSanitizer::instrumentMemIntrinsic(MemIntrinsic *MI) {
999 IRBuilder<> IRB(MI);
1000 if (isa<MemTransferInst>(MI)) {
1002 MI->getOperand(0), MI->getOperand(1),
1003 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)};
1004
1005 if (UseMatchAllCallback)
1006 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1007 IRB.CreateCall(isa<MemMoveInst>(MI) ? HwasanMemmove : HwasanMemcpy, Args);
1008 } else if (isa<MemSetInst>(MI)) {
1010 MI->getOperand(0),
1011 IRB.CreateIntCast(MI->getOperand(1), IRB.getInt32Ty(), false),
1012 IRB.CreateIntCast(MI->getOperand(2), IntptrTy, false)};
1013 if (UseMatchAllCallback)
1014 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1015 IRB.CreateCall(HwasanMemset, Args);
1016 }
1017 MI->eraseFromParent();
1018}
1019
1020bool HWAddressSanitizer::instrumentMemAccess(InterestingMemoryOperand &O,
1021 DomTreeUpdater &DTU, LoopInfo *LI,
1022 const DataLayout &DL) {
1023 Value *Addr = O.getPtr();
1024
1025 LLVM_DEBUG(dbgs() << "Instrumenting: " << O.getInsn() << "\n");
1026
1027 // If the pointer is statically known to be zero, the tag check will pass
1028 // since:
1029 // 1) it has a zero tag
1030 // 2) the shadow memory corresponding to address 0 is initialized to zero and
1031 // never updated.
1032 // We can therefore elide the tag check.
1033 llvm::KnownBits Known(DL.getPointerTypeSizeInBits(Addr->getType()));
1035 if (Known.isZero())
1036 return false;
1037
1038 if (O.MaybeMask)
1039 return false; // FIXME
1040
1041 IRBuilder<> IRB(O.getInsn());
1042 if (!O.TypeStoreSize.isScalable() && isPowerOf2_64(O.TypeStoreSize) &&
1043 (O.TypeStoreSize / 8 <= (1ULL << (kNumberOfAccessSizes - 1))) &&
1044 (!O.Alignment || *O.Alignment >= Mapping.getObjectAlignment() ||
1045 *O.Alignment >= O.TypeStoreSize / 8)) {
1046 size_t AccessSizeIndex = TypeSizeToSizeIndex(O.TypeStoreSize);
1047 if (InstrumentWithCalls) {
1048 SmallVector<Value *, 2> Args{IRB.CreatePointerCast(Addr, IntptrTy)};
1049 if (UseMatchAllCallback)
1050 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1051 IRB.CreateCall(HwasanMemoryAccessCallback[O.IsWrite][AccessSizeIndex],
1052 Args);
1053 } else if (OutlinedChecks) {
1054 instrumentMemAccessOutline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn(),
1055 DTU, LI);
1056 } else {
1057 instrumentMemAccessInline(Addr, O.IsWrite, AccessSizeIndex, O.getInsn(),
1058 DTU, LI);
1059 }
1060 } else {
1062 IRB.CreatePointerCast(Addr, IntptrTy),
1063 IRB.CreateUDiv(IRB.CreateTypeSize(IntptrTy, O.TypeStoreSize),
1064 ConstantInt::get(IntptrTy, 8))};
1065 if (UseMatchAllCallback)
1066 Args.emplace_back(ConstantInt::get(Int8Ty, *MatchAllTag));
1067 IRB.CreateCall(HwasanMemoryAccessCallbackSized[O.IsWrite], Args);
1068 }
1069 untagPointerOperand(O.getInsn(), Addr);
1070
1071 return true;
1072}
1073
1074void HWAddressSanitizer::tagAlloca(IRBuilder<> &IRB, AllocaInst *AI, Value *Tag,
1075 size_t Size) {
1076 size_t AlignedSize = alignTo(Size, Mapping.getObjectAlignment());
1077 if (!UseShortGranules)
1078 Size = AlignedSize;
1079
1080 Tag = IRB.CreateTrunc(Tag, Int8Ty);
1081 if (InstrumentWithCalls) {
1082 IRB.CreateCall(HwasanTagMemoryFunc,
1083 {IRB.CreatePointerCast(AI, PtrTy), Tag,
1084 ConstantInt::get(IntptrTy, AlignedSize)});
1085 } else {
1086 size_t ShadowSize = Size >> Mapping.scale();
1087 Value *AddrLong = untagPointer(IRB, IRB.CreatePointerCast(AI, IntptrTy));
1088 Value *ShadowPtr = memToShadow(AddrLong, IRB);
1089 // If this memset is not inlined, it will be intercepted in the hwasan
1090 // runtime library. That's OK, because the interceptor skips the checks if
1091 // the address is in the shadow region.
1092 // FIXME: the interceptor is not as fast as real memset. Consider lowering
1093 // llvm.memset right here into either a sequence of stores, or a call to
1094 // hwasan_tag_memory.
1095 if (ShadowSize)
1096 IRB.CreateMemSet(ShadowPtr, Tag, ShadowSize, Align(1));
1097 if (Size != AlignedSize) {
1098 const uint8_t SizeRemainder = Size % Mapping.getObjectAlignment().value();
1099 IRB.CreateStore(ConstantInt::get(Int8Ty, SizeRemainder),
1100 IRB.CreateConstGEP1_32(Int8Ty, ShadowPtr, ShadowSize));
1101 IRB.CreateStore(
1102 Tag, IRB.CreateConstGEP1_32(Int8Ty, IRB.CreatePointerCast(AI, PtrTy),
1103 AlignedSize - 1));
1104 }
1105 }
1106}
1107
1108unsigned HWAddressSanitizer::retagMask(unsigned AllocaNo) {
1109 if (TargetTriple.getArch() == Triple::x86_64)
1110 return AllocaNo & TagMaskByte;
1111
1112 // A list of 8-bit numbers that have at most one run of non-zero bits.
1113 // x = x ^ (mask << 56) can be encoded as a single armv8 instruction for these
1114 // masks.
1115 // The list does not include the value 255, which is used for UAR.
1116 //
1117 // Because we are more likely to use earlier elements of this list than later
1118 // ones, it is sorted in increasing order of probability of collision with a
1119 // mask allocated (temporally) nearby. The program that generated this list
1120 // can be found at:
1121 // https://github.com/google/sanitizers/blob/master/hwaddress-sanitizer/sort_masks.py
1122 static const unsigned FastMasks[] = {
1123 0, 128, 64, 192, 32, 96, 224, 112, 240, 48, 16, 120,
1124 248, 56, 24, 8, 124, 252, 60, 28, 12, 4, 126, 254,
1125 62, 30, 14, 6, 2, 127, 63, 31, 15, 7, 3, 1};
1126 return FastMasks[AllocaNo % std::size(FastMasks)];
1127}
1128
1129Value *HWAddressSanitizer::applyTagMask(IRBuilder<> &IRB, Value *OldTag) {
1130 if (TagMaskByte == 0xFF)
1131 return OldTag; // No need to clear the tag byte.
1132 return IRB.CreateAnd(OldTag,
1133 ConstantInt::get(OldTag->getType(), TagMaskByte));
1134}
1135
1136Value *HWAddressSanitizer::getNextTagWithCall(IRBuilder<> &IRB) {
1137 return IRB.CreateZExt(IRB.CreateCall(HwasanGenerateTagFunc), IntptrTy);
1138}
1139
1140Value *HWAddressSanitizer::getStackBaseTag(IRBuilder<> &IRB) {
1141 if (Opts.hwasan_generate_tags_with_calls)
1142 return nullptr;
1143 if (StackBaseTag)
1144 return StackBaseTag;
1145 // Extract some entropy from the stack pointer for the tags.
1146 // Take bits 20..28 (ASLR entropy) and xor with bits 0..8 (these differ
1147 // between functions).
1148 Value *FramePointerLong = getCachedFP(IRB);
1149 Value *StackTag =
1150 applyTagMask(IRB, IRB.CreateXor(FramePointerLong,
1151 IRB.CreateLShr(FramePointerLong, 20)));
1152 StackTag->setName("hwasan.stack.base.tag");
1153 return StackTag;
1154}
1155
1156Value *HWAddressSanitizer::getAllocaTag(IRBuilder<> &IRB, Value *StackTag,
1157 unsigned AllocaNo) {
1158 if (Opts.hwasan_generate_tags_with_calls)
1159 return getNextTagWithCall(IRB);
1160 return IRB.CreateXor(
1161 StackTag, ConstantInt::get(StackTag->getType(), retagMask(AllocaNo)));
1162}
1163
1164Value *HWAddressSanitizer::getUARTag(IRBuilder<> &IRB) {
1165 Value *FramePointerLong = getCachedFP(IRB);
1166 Value *UARTag =
1167 applyTagMask(IRB, IRB.CreateLShr(FramePointerLong, PointerTagShift));
1168
1169 UARTag->setName("hwasan.uar.tag");
1170 return UARTag;
1171}
1172
1173// Add a tag to an address.
1174Value *HWAddressSanitizer::tagPointer(IRBuilder<> &IRB, Type *Ty,
1175 Value *PtrLong, Value *Tag) {
1176 assert(!UsePageAliases);
1177 Value *TaggedPtrLong;
1178 if (CompileKernel) {
1179 // Kernel addresses have 0xFF in the most significant byte.
1180 Value *ShiftedTag =
1181 IRB.CreateOr(IRB.CreateShl(Tag, PointerTagShift),
1182 ConstantInt::get(IntptrTy, (1ULL << PointerTagShift) - 1));
1183 TaggedPtrLong = IRB.CreateAnd(PtrLong, ShiftedTag);
1184 } else {
1185 // Userspace can simply do OR (tag << PointerTagShift);
1186 Value *ShiftedTag = IRB.CreateShl(Tag, PointerTagShift);
1187 TaggedPtrLong = IRB.CreateOr(PtrLong, ShiftedTag);
1188 }
1189 return IRB.CreateIntToPtr(TaggedPtrLong, Ty);
1190}
1191
1192// Remove tag from an address.
1193Value *HWAddressSanitizer::untagPointer(IRBuilder<> &IRB, Value *PtrLong) {
1194 assert(!UsePageAliases);
1195 Value *UntaggedPtrLong;
1196 if (CompileKernel) {
1197 // Kernel addresses have 0xFF in the most significant byte.
1198 UntaggedPtrLong =
1199 IRB.CreateOr(PtrLong, ConstantInt::get(PtrLong->getType(),
1200 TagMaskByte << PointerTagShift));
1201 } else {
1202 // Userspace addresses have 0x00.
1203 UntaggedPtrLong = IRB.CreateAnd(
1204 PtrLong, ConstantInt::get(PtrLong->getType(),
1205 ~(TagMaskByte << PointerTagShift)));
1206 }
1207 return UntaggedPtrLong;
1208}
1209
1210Value *HWAddressSanitizer::getHwasanThreadSlotPtr(IRBuilder<> &IRB) {
1211 // Android provides a fixed TLS slot for sanitizers. See TLS_SLOT_SANITIZER
1212 // in Bionic's libc/platform/bionic/tls_defines.h.
1213 constexpr int SanitizerSlot = 6;
1214 if (TargetTriple.isAArch64() && TargetTriple.isAndroid())
1215 return memtag::getAndroidSlotPtr(IRB, SanitizerSlot);
1216 return ThreadPtrGlobal;
1217}
1218
1219Value *HWAddressSanitizer::getCachedFP(IRBuilder<> &IRB) {
1220 if (!CachedFP)
1221 CachedFP = memtag::getFP(IRB);
1222 return CachedFP;
1223}
1224
1225Value *HWAddressSanitizer::getFrameRecordInfo(IRBuilder<> &IRB) {
1226 // Prepare ring buffer data.
1227 Value *PC = memtag::getPC(TargetTriple, IRB);
1228 Value *FP = getCachedFP(IRB);
1229
1230 // Mix FP and PC.
1231 // Assumptions:
1232 // PC is 0x0000PPPPPPPPPPPP (48 bits are meaningful, others are zero)
1233 // FP is 0xfffffffffffFFFF0 (4 lower bits are zero)
1234 // We only really need ~20 lower non-zero bits (FFFF), so we mix like this:
1235 // 0xFFFFPPPPPPPPPPPP
1236 //
1237 // FP works because in AArch64FrameLowering::getFrameIndexReference, we
1238 // prefer FP-relative offsets for functions compiled with HWASan.
1239 FP = IRB.CreateShl(FP, 44);
1240 return IRB.CreateOr(PC, FP);
1241}
1242
1243void HWAddressSanitizer::emitPrologue(IRBuilder<> &IRB, bool WithFrameRecord) {
1244 if (!Mapping.isInTls())
1245 ShadowBase = getShadowNonTls(IRB);
1246 else if (!WithFrameRecord && TargetTriple.isAndroid())
1247 ShadowBase = getDynamicShadowIfunc(IRB);
1248
1249 if (!WithFrameRecord && ShadowBase)
1250 return;
1251
1252 Value *SlotPtr = nullptr;
1253 Value *ThreadLong = nullptr;
1254 Value *ThreadLongMaybeUntagged = nullptr;
1255
1256 auto getThreadLongMaybeUntagged = [&]() {
1257 if (!SlotPtr)
1258 SlotPtr = getHwasanThreadSlotPtr(IRB);
1259 if (!ThreadLong)
1260 ThreadLong = IRB.CreateLoad(IntptrTy, SlotPtr);
1261 // Extract the address field from ThreadLong. Unnecessary on AArch64 with
1262 // TBI.
1263 return TargetTriple.isAArch64() ? ThreadLong
1264 : untagPointer(IRB, ThreadLong);
1265 };
1266
1267 if (WithFrameRecord) {
1268 switch (Opts.hwasan_record_stack_history) {
1270 // Emit a runtime call into hwasan rather than emitting instructions for
1271 // recording stack history.
1272 Value *FrameRecordInfo = getFrameRecordInfo(IRB);
1273 IRB.CreateCall(HwasanRecordFrameRecordFunc, {FrameRecordInfo});
1274 break;
1275 }
1277 ThreadLongMaybeUntagged = getThreadLongMaybeUntagged();
1278
1279 StackBaseTag = IRB.CreateAShr(ThreadLong, 3);
1280
1281 // Store data to ring buffer.
1282 Value *FrameRecordInfo = getFrameRecordInfo(IRB);
1283 Value *RecordPtr =
1284 IRB.CreateIntToPtr(ThreadLongMaybeUntagged, IRB.getPtrTy(0));
1285 IRB.CreateStore(FrameRecordInfo, RecordPtr);
1286
1287 IRB.CreateStore(memtag::incrementThreadLong(IRB, ThreadLong, 8), SlotPtr);
1288 break;
1289 }
1292 "A stack history recording mode should've been selected.");
1293 }
1294 }
1295 }
1296
1297 if (!ShadowBase) {
1298 if (!ThreadLongMaybeUntagged)
1299 ThreadLongMaybeUntagged = getThreadLongMaybeUntagged();
1300
1301 // Get shadow base address by aligning RecordPtr up.
1302 // Note: this is not correct if the pointer is already aligned.
1303 // Runtime library will make sure this never happens.
1304 ShadowBase = IRB.CreateAdd(
1305 IRB.CreateOr(
1306 ThreadLongMaybeUntagged,
1307 ConstantInt::get(IntptrTy, (1ULL << kShadowBaseAlignment) - 1)),
1308 ConstantInt::get(IntptrTy, 1), "hwasan.shadow");
1309 ShadowBase = IRB.CreateIntToPtr(ShadowBase, PtrTy);
1310 }
1311}
1312
1313void HWAddressSanitizer::instrumentLandingPads(
1314 SmallVectorImpl<Instruction *> &LandingPadVec) {
1315 for (auto *LP : LandingPadVec) {
1316 IRBuilder<> IRB(LP->getNextNode());
1317 IRB.CreateCall(
1318 HwasanHandleVfork,
1320 IRB, (TargetTriple.getArch() == Triple::x86_64) ? "rsp" : "sp")});
1321 }
1322}
1323
1324void HWAddressSanitizer::instrumentStack(OptimizationRemarkEmitter &ORE,
1325 memtag::StackInfo &SInfo,
1326 Value *StackTag, Value *UARTag,
1327 const DominatorTree &DT,
1328 const PostDominatorTree &PDT,
1329 const LoopInfo &LI) {
1330 // Ideally, we want to calculate tagged stack base pointer, and rewrite all
1331 // alloca addresses using that. Unfortunately, offsets are not known yet
1332 // (unless we use ASan-style mega-alloca). Instead we keep the base tag in a
1333 // temp, shift-OR it into each alloca address and xor with the retag mask.
1334 // This generates one extra instruction per alloca use.
1335 unsigned int I = 0;
1336
1337 for (auto &KV : SInfo.AllocasToInstrument) {
1338 auto N = I++;
1339 auto *AI = KV.first;
1340 memtag::AllocaInfo &Info = KV.second;
1341 IRBuilder<> IRB(AI->getNextNode());
1342
1343 // Replace uses of the alloca with tagged address.
1344 Value *Tag = getAllocaTag(IRB, StackTag, N);
1345 Value *AILong = IRB.CreatePointerCast(AI, IntptrTy);
1346 Value *AINoTagLong = untagPointer(IRB, AILong);
1347 Value *Replacement = tagPointer(IRB, AI->getType(), AINoTagLong, Tag);
1348 std::string Name =
1349 AI->hasName() ? AI->getName().str() : "alloca." + itostr(N);
1350 Replacement->setName(Name + ".hwasan");
1351
1352 size_t Size = memtag::getAllocaSizeInBytes(*AI);
1353 size_t AlignedSize = alignTo(Size, Mapping.getObjectAlignment());
1354
1355 AI->replaceUsesWithIf(Replacement, [AILong](const Use &U) {
1356 auto *User = U.getUser();
1357 return User != AILong && !isa<LifetimeIntrinsic>(User);
1358 });
1359
1360 memtag::annotateDebugRecords(Info, retagMask(N));
1361
1362 auto TagStarts = [&]() {
1363 for (IntrinsicInst *Start : Info.LifetimeStart) {
1364 IRB.SetInsertPoint(Start->getNextNode());
1365 tagAlloca(IRB, AI, Tag, Size);
1366 }
1367 };
1368 auto TagEnd = [&](Instruction *Node) {
1369 IRB.SetInsertPoint(Node);
1370 // When untagging, use the `AlignedSize` because we need to set the tags
1371 // for the entire alloca to original. If we used `Size` here, we would
1372 // keep the last granule tagged, and store zero in the last byte of the
1373 // last granule, due to how short granules are implemented.
1374 tagAlloca(IRB, AI, UARTag, AlignedSize);
1375 };
1376 auto EraseLifetimes = [&]() {
1377 for (auto &II : Info.LifetimeStart)
1378 II->eraseFromParent();
1379 for (auto &II : Info.LifetimeEnd)
1380 II->eraseFromParent();
1381 };
1382 // Calls to functions that may return twice (e.g. setjmp) confuse the
1383 // postdominator analysis, and will leave us to keep memory tagged after
1384 // function return. Work around this by always untagging at every return
1385 // statement if return_twice functions are called.
1386 if (DetectUseAfterScope && !SInfo.CallsReturnTwice &&
1387 memtag::isSupportedLifetime(Info, &DT, &LI)) {
1388 TagStarts();
1389 memtag::forAllReachableExits(DT, PDT, LI, Info, SInfo.RetVec, TagEnd);
1390 ORE.emit([&]() {
1391 return OptimizationRemark(DEBUG_TYPE, "supportedLifetime", AI);
1392 });
1393 } else if (DetectUseAfterScope && Opts.hwasan_strict_use_after_scope) {
1394 // SInfo.CallsReturnTwice || !isStandardLifetime
1395 ORE.emit([&]() {
1396 return OptimizationRemarkMissed(DEBUG_TYPE, "supportedLifetime", AI);
1397 });
1398
1399 tagAlloca(IRB, AI, Tag, Size);
1400 TagStarts();
1401 for_each(Info.LifetimeEnd, TagEnd);
1402 for_each(SInfo.RetVec, TagEnd);
1403 EraseLifetimes();
1404 } else {
1405 tagAlloca(IRB, AI, Tag, Size);
1406 for_each(SInfo.RetVec, TagEnd);
1407 EraseLifetimes();
1408 }
1409 memtag::alignAndPadAlloca(Info, Mapping.getObjectAlignment());
1410 }
1411}
1412
1414 bool Skip) {
1415 if (Skip) {
1416 ORE.emit([&]() {
1417 return OptimizationRemark(DEBUG_TYPE, "Skip", &F)
1418 << "Skipped: F=" << ore::NV("Function", &F);
1419 });
1420 } else {
1421 ORE.emit([&]() {
1422 return OptimizationRemarkMissed(DEBUG_TYPE, "Sanitize", &F)
1423 << "Sanitized: F=" << ore::NV("Function", &F);
1424 });
1425 }
1426}
1427
1428bool HWAddressSanitizer::selectiveInstrumentationShouldSkip(
1430 auto SkipHot = [&]() {
1431 if (!Opts.hwasan_percentile_cutoff_hot)
1432 return false;
1434 ProfileSummaryInfo *PSI =
1435 MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
1436 if (!PSI || !PSI->hasProfileSummary()) {
1437 ++NumNoProfileSummaryFuncs;
1438 return false;
1439 }
1440 return PSI->isFunctionHotInCallGraphNthPercentile(
1441 *Opts.hwasan_percentile_cutoff_hot, &F,
1443 };
1444
1445 auto SkipRandom = [&]() {
1446 if (!Opts.hwasan_random_rate)
1447 return false;
1448 std::bernoulli_distribution D(*Opts.hwasan_random_rate);
1449 return !D(*Rng);
1450 };
1451
1452 bool Skip = SkipRandom() || SkipHot();
1454 return Skip;
1455}
1456
1457void HWAddressSanitizer::sanitizeFunction(Function &F,
1459 if (&F == HwasanCtorFunction)
1460 return;
1461
1462 // Do not apply any instrumentation for naked functions.
1463 if (F.hasFnAttribute(Attribute::Naked))
1464 return;
1465
1466 if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
1467 return;
1468
1469 if (!F.hasFnAttribute(Attribute::SanitizeHWAddress))
1470 return;
1471
1472 if (F.empty())
1473 return;
1474
1475 if (F.isPresplitCoroutine())
1476 return;
1477
1478 NumTotalFuncs++;
1479
1482
1483 if (selectiveInstrumentationShouldSkip(F, FAM))
1484 return;
1485
1486 NumInstrumentedFuncs++;
1487
1488 LLVM_DEBUG(dbgs() << "Function: " << F.getName() << "\n");
1489
1490 SmallVector<InterestingMemoryOperand, 16> OperandsToInstrument;
1491 SmallVector<MemIntrinsic *, 16> IntrinToInstrument;
1492 SmallVector<Instruction *, 8> LandingPadVec;
1494
1496 for (auto &Inst : instructions(F)) {
1497 if (InstrumentStack) {
1498 SIB.visit(ORE, Inst);
1499 }
1500
1501 if (InstrumentLandingPads && isa<LandingPadInst>(Inst))
1502 LandingPadVec.push_back(&Inst);
1503
1504 getInterestingMemoryOperands(ORE, &Inst, TLI, OperandsToInstrument);
1505
1507 if (!ignoreMemIntrinsic(ORE, MI))
1508 IntrinToInstrument.push_back(MI);
1509 }
1510
1511 memtag::StackInfo &SInfo = SIB.get();
1512
1513 initializeCallbacks(*F.getParent());
1514
1515 if (!LandingPadVec.empty())
1516 instrumentLandingPads(LandingPadVec);
1517
1518 if (SInfo.AllocasToInstrument.empty() && F.hasPersonalityFn() &&
1519 F.getPersonalityFn()->getName() == kHwasanPersonalityThunkName) {
1520 // __hwasan_personality_thunk is a no-op for functions without an
1521 // instrumented stack, so we can drop it.
1522 F.setPersonalityFn(nullptr);
1523 }
1524
1525 if (SInfo.AllocasToInstrument.empty() && OperandsToInstrument.empty() &&
1526 IntrinToInstrument.empty())
1527 return;
1528
1529 assert(!ShadowBase);
1530
1531 BasicBlock::iterator InsertPt = F.getEntryBlock().begin();
1532 IRBuilder<> EntryIRB(InsertPt);
1533 emitPrologue(EntryIRB,
1534 /*WithFrameRecord*/ Opts.hwasan_record_stack_history !=
1536 Mapping.withFrameRecord() &&
1537 !SInfo.AllocasToInstrument.empty());
1538
1539 if (!SInfo.AllocasToInstrument.empty()) {
1542 const LoopInfo &LI = FAM.getResult<LoopAnalysis>(F);
1543 Value *StackTag = getStackBaseTag(EntryIRB);
1544 Value *UARTag = getUARTag(EntryIRB);
1545 // instrumentStack may replace allocas, invalidating EntryIRB's insert
1546 // point. Save the insert block before calling it.
1547 BasicBlock *EntryBB = EntryIRB.GetInsertBlock();
1548 instrumentStack(ORE, SInfo, StackTag, UARTag, DT, PDT, LI);
1549
1550 // If we split the entry block, move any allocas that were originally in the
1551 // entry block back into the entry block so that they aren't treated as
1552 // dynamic allocas.
1553 if (EntryBB != &F.getEntryBlock()) {
1554 InsertPt = F.getEntryBlock().begin();
1555 for (Instruction &I : llvm::make_early_inc_range(*EntryBB)) {
1556 if (auto *AI = dyn_cast<AllocaInst>(&I))
1557 if (isa<ConstantInt>(AI->getArraySize()))
1558 I.moveBefore(F.getEntryBlock(), InsertPt);
1559 }
1560 }
1561 }
1562
1566 DomTreeUpdater DTU(DT, PDT, DomTreeUpdater::UpdateStrategy::Lazy);
1567 const DataLayout &DL = F.getDataLayout();
1568 for (auto &Operand : OperandsToInstrument)
1569 instrumentMemAccess(Operand, DTU, LI, DL);
1570 DTU.flush();
1571
1572 if (Opts.hwasan_instrument_mem_intrinsics && !IntrinToInstrument.empty()) {
1573 for (auto *Inst : IntrinToInstrument)
1574 instrumentMemIntrinsic(Inst);
1575 }
1576
1577 ShadowBase = nullptr;
1578 StackBaseTag = nullptr;
1579 CachedFP = nullptr;
1580}
1581
1582void HWAddressSanitizer::instrumentGlobal(GlobalVariable *GV, uint8_t Tag) {
1583 assert(!UsePageAliases);
1584 Constant *Initializer = GV->getInitializer();
1585 uint64_t SizeInBytes =
1586 M.getDataLayout().getTypeAllocSize(Initializer->getType());
1587 uint64_t NewSize = alignTo(SizeInBytes, Mapping.getObjectAlignment());
1588 if (SizeInBytes != NewSize) {
1589 // Pad the initializer out to the next multiple of 16 bytes and add the
1590 // required short granule tag.
1591 std::vector<uint8_t> Init(NewSize - SizeInBytes, 0);
1592 Init.back() = Tag;
1594 Initializer = ConstantStruct::getAnon({Initializer, Padding});
1595 }
1596
1597 auto *NewGV = new GlobalVariable(M, Initializer->getType(), GV->isConstant(),
1598 GlobalValue::ExternalLinkage, Initializer,
1599 GV->getName() + ".hwasan");
1600 NewGV->copyAttributesFrom(GV);
1601 NewGV->setLinkage(GlobalValue::PrivateLinkage);
1602 NewGV->copyMetadata(GV, 0);
1603 NewGV->setAlignment(
1604 std::max(GV->getAlign().valueOrOne(), Mapping.getObjectAlignment()));
1605
1606 // It is invalid to ICF two globals that have different tags. In the case
1607 // where the size of the global is a multiple of the tag granularity the
1608 // contents of the globals may be the same but the tags (i.e. symbol values)
1609 // may be different, and the symbols are not considered during ICF. In the
1610 // case where the size is not a multiple of the granularity, the short granule
1611 // tags would discriminate two globals with different tags, but there would
1612 // otherwise be nothing stopping such a global from being incorrectly ICF'd
1613 // with an uninstrumented (i.e. tag 0) global that happened to have the short
1614 // granule tag in the last byte.
1615 NewGV->setUnnamedAddr(GlobalValue::UnnamedAddr::None);
1616
1617 // Descriptor format (assuming little-endian):
1618 // bytes 0-3: relative address of global
1619 // bytes 4-6: size of global (16MB ought to be enough for anyone, but in case
1620 // it isn't, we create multiple descriptors)
1621 // byte 7: tag
1622 auto *DescriptorTy = StructType::get(Int32Ty, Int32Ty);
1623 const uint64_t MaxDescriptorSize = 0xfffff0;
1624 for (uint64_t DescriptorPos = 0; DescriptorPos < SizeInBytes;
1625 DescriptorPos += MaxDescriptorSize) {
1626 auto *Descriptor =
1627 new GlobalVariable(M, DescriptorTy, true, GlobalValue::PrivateLinkage,
1628 nullptr, GV->getName() + ".hwasan.descriptor");
1629 auto *GVRelPtr = ConstantExpr::getTrunc(
1632 ConstantExpr::getPtrToInt(NewGV, Int64Ty),
1633 ConstantExpr::getPtrToInt(Descriptor, Int64Ty)),
1634 ConstantInt::get(Int64Ty, DescriptorPos)),
1635 Int32Ty);
1636 uint32_t Size = std::min(SizeInBytes - DescriptorPos, MaxDescriptorSize);
1637 auto *SizeAndTag = ConstantInt::get(Int32Ty, Size | (uint32_t(Tag) << 24));
1638 Descriptor->setComdat(NewGV->getComdat());
1639 Descriptor->setInitializer(ConstantStruct::getAnon({GVRelPtr, SizeAndTag}));
1640 Descriptor->setSection("hwasan_globals");
1641 Descriptor->setMetadata(LLVMContext::MD_associated,
1643 appendToCompilerUsed(M, Descriptor);
1644 }
1645
1648 ConstantExpr::getPtrToInt(NewGV, Int64Ty),
1649 ConstantInt::get(Int64Ty, uint64_t(Tag) << PointerTagShift)),
1650 GV->getType());
1651 auto *Alias = GlobalAlias::create(GV->getValueType(), GV->getAddressSpace(),
1652 GV->getLinkage(), "", Aliasee, &M);
1653 Alias->setVisibility(GV->getVisibility());
1654 Alias->takeName(GV);
1655 GV->replaceAllUsesWith(Alias);
1656 GV->eraseFromParent();
1657}
1658
1659void HWAddressSanitizer::instrumentGlobals() {
1660 std::vector<GlobalVariable *> Globals;
1661 for (GlobalVariable &GV : M.globals()) {
1663 continue;
1664
1665 if (GV.isDeclarationForLinker() || GV.getName().starts_with("llvm.") ||
1666 GV.isThreadLocal())
1667 continue;
1668
1669 // Common symbols can't have aliases point to them, so they can't be tagged.
1670 if (GV.hasCommonLinkage())
1671 continue;
1672
1673 if (Opts.hwasan_all_globals) {
1674 // Avoid instrumenting intrinsic global variables.
1675 if (GV.getSection() == "llvm.metadata")
1676 continue;
1677 } else {
1678 // Globals with custom sections may be used in __start_/__stop_
1679 // enumeration, which would be broken both by adding tags and potentially
1680 // by the extra padding/alignment that we insert.
1681 if (GV.hasSection())
1682 continue;
1683 }
1684
1685 Globals.push_back(&GV);
1686 }
1687
1688 MD5 Hasher;
1689 Hasher.update(M.getSourceFileName());
1690 MD5::MD5Result Hash;
1691 Hasher.final(Hash);
1692 uint8_t Tag = Hash[0];
1693
1694 assert(TagMaskByte >= 16);
1695
1696 for (GlobalVariable *GV : Globals) {
1697 // Don't allow globals to be tagged with something that looks like a
1698 // short-granule tag, otherwise we lose inter-granule overflow detection, as
1699 // the fast path shadow-vs-address check succeeds.
1700 if (Tag < 16 || Tag > TagMaskByte)
1701 Tag = 16;
1702 instrumentGlobal(GV, Tag++);
1703 }
1704}
1705
1706void HWAddressSanitizer::instrumentPersonalityFunctions() {
1707 // We need to untag stack frames as we unwind past them. That is the job of
1708 // the personality function wrapper, which either wraps an existing
1709 // personality function or acts as a personality function on its own. Each
1710 // function that has a personality function or that can be unwound past has
1711 // its personality function changed to a thunk that calls the personality
1712 // function wrapper in the runtime.
1714 for (Function &F : M) {
1715 if (F.isDeclaration() || !F.hasFnAttribute(Attribute::SanitizeHWAddress) ||
1716 F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
1717 continue;
1718
1719 if (F.hasPersonalityFn()) {
1720 PersonalityFns[F.getPersonalityFn()->stripPointerCasts()].push_back(&F);
1721 } else if (!F.hasFnAttribute(Attribute::NoUnwind)) {
1722 PersonalityFns[nullptr].push_back(&F);
1723 }
1724 }
1725
1726 if (PersonalityFns.empty())
1727 return;
1728
1729 FunctionCallee HwasanPersonalityWrapper = M.getOrInsertFunction(
1730 "__hwasan_personality_wrapper", Int32Ty, Int32Ty, Int32Ty, Int64Ty, PtrTy,
1731 PtrTy, PtrTy, PtrTy, PtrTy);
1732 FunctionCallee UnwindGetGR = M.getOrInsertFunction("_Unwind_GetGR", VoidTy);
1733 FunctionCallee UnwindGetCFA = M.getOrInsertFunction("_Unwind_GetCFA", VoidTy);
1734
1735 for (auto &P : PersonalityFns) {
1736 std::string ThunkName = kHwasanPersonalityThunkName;
1737 if (P.first)
1738 ThunkName += ("." + P.first->getName()).str();
1739 FunctionType *ThunkFnTy = FunctionType::get(
1740 Int32Ty, {Int32Ty, Int32Ty, Int64Ty, PtrTy, PtrTy}, false);
1741 bool IsLocal = P.first && (!isa<GlobalValue>(P.first) ||
1742 cast<GlobalValue>(P.first)->hasLocalLinkage());
1743 auto *ThunkFn = Function::Create(ThunkFnTy,
1746 ThunkName, &M);
1747 // TODO: think about other attributes as well.
1748 if (any_of(P.second, [](const Function *F) {
1749 return F->hasFnAttribute("branch-target-enforcement");
1750 })) {
1751 ThunkFn->addFnAttr("branch-target-enforcement");
1752 }
1753 if (!IsLocal) {
1754 ThunkFn->setVisibility(GlobalValue::HiddenVisibility);
1755 ThunkFn->setComdat(M.getOrInsertComdat(ThunkName));
1756 }
1757
1758 auto *BB = BasicBlock::Create(*C, "entry", ThunkFn);
1759 IRBuilder<> IRB(BB);
1760 CallInst *WrapperCall = IRB.CreateCall(
1761 HwasanPersonalityWrapper,
1762 {ThunkFn->getArg(0), ThunkFn->getArg(1), ThunkFn->getArg(2),
1763 ThunkFn->getArg(3), ThunkFn->getArg(4),
1764 P.first ? P.first : Constant::getNullValue(PtrTy),
1765 UnwindGetGR.getCallee(), UnwindGetCFA.getCallee()});
1766 WrapperCall->setTailCall();
1767 IRB.CreateRet(WrapperCall);
1768
1769 for (Function *F : P.second)
1770 F->setPersonalityFn(ThunkFn);
1771 }
1772}
1773
1774void HWAddressSanitizer::ShadowMapping::init(const InstrumentationOptions &Opts,
1775 Triple &TargetTriple,
1776 bool InstrumentWithCalls,
1777 bool CompileKernel) {
1778 // Start with defaults.
1779 Scale = kDefaultShadowScale;
1780 Kind = OffsetKind::kTls;
1781 WithFrameRecord = true;
1782
1783 // Tune for the target.
1784 if (TargetTriple.isOSFuchsia()) {
1785 // Fuchsia is always PIE, which means that the beginning of the address
1786 // space is always available.
1787 Kind = OffsetKind::kGlobal;
1788 } else if (CompileKernel || InstrumentWithCalls) {
1789 SetFixed(0);
1790 WithFrameRecord = false;
1791 }
1792
1793 WithFrameRecord = valueOr(Opts.hwasan_with_frame_record, WithFrameRecord);
1794
1795 // Apply the last of ClMappingOffset and ClMappingOffsetDynamic.
1796 if (ClMappingOffsetDynamic.getNumOccurrences())
1798 if (ClMappingOffset.getNumOccurrences() > 0 &&
1799 !(ClMappingOffsetDynamic.getNumOccurrences() > 0 &&
1800 ClMappingOffsetDynamic.getPosition() > ClMappingOffset.getPosition())) {
1801 SetFixed(ClMappingOffset);
1802 }
1803}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t 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,...
LLVM Basic Block Representation.
Definition BasicBlock.h:62
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:2024
Value * CreatePointerCast(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2297
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
Definition IRBuilder.h:2238
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1528
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
Definition IRBuilder.h:522
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2092
ReturnInst * CreateRet(Value *V)
Create a 'ret <val>' instruction.
Definition IRBuilder.h:1188
Module * getModule() const
Get the module.
Definition IRBuilder.h:189
Value * CreateUDiv(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1469
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2386
Value * CreateICmpUGT(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:2390
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:1907
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1507
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:596
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Definition IRBuilder.h:2121
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1566
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:1925
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Definition IRBuilder.h:1418
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args={}, const Twine &Name="", MDNode *FPMathTag=nullptr)
Definition IRBuilder.h:2561
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Definition IRBuilder.h:2107
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
Definition IRBuilder.h:565
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:2394
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
Definition IRBuilder.h:2323
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Definition IRBuilder.h:196
Value * CreateAShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Definition IRBuilder.h:1547
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1618
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="", bool IsDisjoint=false)
Definition IRBuilder.h:1588
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2909
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:1176
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:390
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
LLVM_ABI bool isSwiftError() const
Return true if this value is a swifterror value.
Definition Value.cpp:1162
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:557
bool hasName() const
Definition Value.h:263
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
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:3900
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